From 89d0d5753f8745b58ef561f5aa76e239550075fd Mon Sep 17 00:00:00 2001 From: William Moberg Date: Thu, 25 Feb 2016 16:16:24 +0100 Subject: [PATCH] Fix for player teleporting to (0,0,0). Saves player previous position in CollisionSystem instead of Physics component so it won't be saved when editing Players. --- include/Engine/Collision/CollisionSystem.h | 1 + resources/Schema/Components/Physics.xml | 1 - resources/Schema/Components/Physics.xsd | 1 - resources/Schema/Entities/Player.xml | 1 - resources/Schema/Entities/PlayerRed.xml | 1 - src/Engine/Collision/CollisionSystem.cpp | 88 +++++++++++----------- 6 files changed, 46 insertions(+), 47 deletions(-) diff --git a/include/Engine/Collision/CollisionSystem.h b/include/Engine/Collision/CollisionSystem.h index 9cd2fe63..19adea35 100644 --- a/include/Engine/Collision/CollisionSystem.h +++ b/include/Engine/Collision/CollisionSystem.h @@ -24,6 +24,7 @@ public: private: Octree* m_Octree; std::vector m_OctreeResult; + std::unordered_map m_PrevPositions; }; #endif \ No newline at end of file diff --git a/resources/Schema/Components/Physics.xml b/resources/Schema/Components/Physics.xml index 84b6aba3..6cb73c75 100644 --- a/resources/Schema/Components/Physics.xml +++ b/resources/Schema/Components/Physics.xml @@ -2,7 +2,6 @@ true - false 0.33 diff --git a/resources/Schema/Components/Physics.xsd b/resources/Schema/Components/Physics.xsd index 206e2a23..7fed1fb5 100644 --- a/resources/Schema/Components/Physics.xsd +++ b/resources/Schema/Components/Physics.xsd @@ -13,7 +13,6 @@ m/s^2 - The largest height of a "stair-step" that can be walked over diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 7a5d2eb4..4f012955 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -13,7 +13,6 @@ - diff --git a/resources/Schema/Entities/PlayerRed.xml b/resources/Schema/Entities/PlayerRed.xml index cd01632e..d56fa3c1 100644 --- a/resources/Schema/Entities/PlayerRed.xml +++ b/resources/Schema/Entities/PlayerRed.xml @@ -13,7 +13,6 @@ - diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index fcc3665f..9689bf13 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -16,51 +16,51 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c EntityAABB& boxA = *boundingBox; bool everHitTheGround = false; - glm::vec3 size = boxA.Size(); - float diameter = std::min(size.x, size.z); - glm::vec3 prevOrigin = (glm::vec3)cPhysics["PrevOrigin"]; - glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin; - float rayLength = glm::length(toCurrentPos) + 0.5f*diameter; - //If the entity has moved farther than the size of its box, we need to handle it specially. - bool traceCollision = rayLength > diameter; - //hack solution: If prevOrigin is less than -9000 in all dimensions, - //then it means it is not set, i.e. this is the first collision check for the entity. - if (traceCollision && glm::any(glm::greaterThan((glm::vec3)cPhysics["PrevOrigin"], glm::vec3(-9000.f)))) { - Ray ray(prevOrigin, toCurrentPos); - m_OctreeResult.clear(); - m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult); - for (auto& boxB : m_OctreeResult) { - if (boxA.Entity == boxB.Entity) { - continue; - } - bool hit; - float dist; - if (boxB.Entity.HasComponent("Model")) { - RawModel* model; - std::string res = (std::string)boxB.Entity["Model"]["Resource"]; - try { - model = ResourceManager::Load(res); - } catch (const std::exception&) { + auto prevPosIt = m_PrevPositions.find(entity); + if (prevPosIt != m_PrevPositions.end()) { + glm::vec3 size = boxA.Size(); + float diameter = std::min(size.x, size.z); + glm::vec3 prevOrigin = prevPosIt->second; + glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin; + float rayLength = glm::length(toCurrentPos) + 0.5f*diameter; + //If the entity has moved farther than the size of its box, we need to handle it specially. + if (rayLength > diameter) { + Ray ray(prevOrigin, toCurrentPos); + m_OctreeResult.clear(); + m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult); + for (auto& boxB : m_OctreeResult) { + if (boxA.Entity == boxB.Entity) { continue; } - float u, v; - hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v); - } else { - hit = Collision::RayVsAABB(ray, boxB, dist); - } - if (hit && dist < rayLength) { - //Set the entity to where it was colliding, minus the maximum box size. - //TODO: Perhaps this should be done slightly more properly. - glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction(); - glm::vec3 resolve = newOriginPos - boxA.Origin(); - (glm::vec3&)cTransform["Position"] += resolve; - boxA = *Collision::EntityAbsoluteAABB(entity); - if (resolve.y > 0) { - everHitTheGround = true; - (bool)cPhysics["IsOnGround"] = true; - ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; + bool hit; + float dist; + if (boxB.Entity.HasComponent("Model")) { + RawModel* model; + std::string res = (std::string)boxB.Entity["Model"]["Resource"]; + try { + model = ResourceManager::Load(res); + } catch (const std::exception&) { + continue; + } + float u, v; + hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v); + } else { + hit = Collision::RayVsAABB(ray, boxB, dist); + } + if (hit && dist < rayLength) { + //Set the entity to where it was colliding, minus the maximum box size. + //TODO: Perhaps this should be done slightly more properly. + glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction(); + glm::vec3 resolve = newOriginPos - boxA.Origin(); + (glm::vec3&)cTransform["Position"] += resolve; + boxA = *Collision::EntityAbsoluteAABB(entity); + if (resolve.y > 0) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; + ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; + } + break; } - break; } } } @@ -90,6 +90,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; + boxA = *Collision::EntityAbsoluteAABB(entity); cPhysics["Velocity"] = inOutVelocity; if (isOnGround) { everHitTheGround = true; @@ -99,6 +100,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; + boxA = *Collision::EntityAbsoluteAABB(entity); if (resolutionVector.y > 0) { everHitTheGround = true; (bool)cPhysics["IsOnGround"] = true; @@ -112,5 +114,5 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c (bool)cPhysics["IsOnGround"] = false; } - (glm::vec3&)cPhysics["PrevOrigin"] = boxA.Origin(); + m_PrevPositions[entity] = boxA.Origin(); }