diff --git a/include/Engine/Core/ComponentWrapper.h b/include/Engine/Core/ComponentWrapper.h index cc2827a4..170cdddf 100644 --- a/include/Engine/Core/ComponentWrapper.h +++ b/include/Engine/Core/ComponentWrapper.h @@ -56,7 +56,6 @@ struct ComponentWrapper void SetAllDirty(const std::string& fieldName, bool dirty = true) { - LOG_DEBUG("DIRTY: %s %s", Info.Name.c_str(), fieldName.c_str()); for (auto& kv : *DirtyBitField) { SetDirty(kv.first, fieldName); } diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index bd381e8b..80f59971 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -8,7 +8,7 @@ namespace Transform { -glm::mat4 AbsoluteTransformation(EntityWrapper entity); +//glm::mat4 AbsoluteTransformation(EntityWrapper entity); glm::vec3 AbsolutePosition(EntityWrapper entity); glm::vec3 AbsolutePosition(World* world, EntityID entity); glm::vec3 AbsoluteOrientationEuler(EntityWrapper entity); @@ -20,6 +20,11 @@ glm::mat4 ModelMatrix(EntityWrapper entity); glm::mat4 ModelMatrix(EntityID entity, World* world); glm::vec3 TransformPoint(const glm::vec3& point, const glm::mat4& matrix); + +extern int RecalculatedPositions; +extern int RecalculatedOrientations; +extern int RecalculatedScales; + } #endif \ No newline at end of file diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index b7f15ffd..94246f26 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -638,7 +638,7 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity, bool takeM return boost::none; } - glm::mat4 modelMat = Transform::AbsoluteTransformation(entity); + glm::mat4 modelMat = Transform::ModelMatrix(entity); glm::vec3 mini(INFINITY); glm::vec3 maxi(-INFINITY); glm::vec3 maxCorner = modelSpaceBox.MaxCorner(); diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index e18ce9e0..0a736421 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -2,32 +2,29 @@ namespace Transform { -struct Values -{ - glm::vec3 Position; - glm::quat Orientation; - glm::vec3 Scale; - Values() - : Position() - , Orientation() - , Scale(1.f) - {} -}; -std::unordered_map Cache; +std::unordered_map PositionCache; +std::unordered_map OrientationCache; +std::unordered_map ScaleCache; +std::unordered_map MatrixCache; + +int RecalculatedPositions = 0; +int RecalculatedOrientations = 0; +int RecalculatedScales = 0; + } -glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity) -{ - glm::mat4 t = glm::mat4(1.f); - - while (entity.Valid()) { - t = glm::translate((const glm::vec3&)entity["Transform"]["Position"]) * glm::toMat4(glm::quat((const glm::vec3&)entity["Transform"]["Orientation"])) * glm::scale((const glm::vec3&)entity["Transform"]["Scale"]) * t; - entity = entity.Parent(); - } - - return t; -} +//glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity) +//{ +// glm::mat4 t = glm::mat4(1.f); +// +// while (entity.Valid()) { +// t = glm::translate((const glm::vec3&)entity["Transform"]["Position"]) * glm::toMat4(glm::quat((const glm::vec3&)entity["Transform"]["Orientation"])) * glm::scale((const glm::vec3&)entity["Transform"]["Scale"]) * t; +// entity = entity.Parent(); +// } +// +// return t; +//} glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) { @@ -36,32 +33,30 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) { - glm::vec3 position; if (!entity.Valid()) { + return glm::vec3(); + } + + auto cacheIt = PositionCache.find(entity); + ComponentWrapper cTransform = entity["Transform"]; + ComponentWrapper::SubscriptProxy cTransformPosition = cTransform["Position"]; + if (cacheIt != PositionCache.end() && !cTransformPosition.Dirty(DirtySetType::Transform)) { + return cacheIt->second; + } else { + EntityWrapper parent = entity.Parent(); + // Calculate position + glm::vec3 position = AbsolutePosition(parent) + Transform::AbsoluteScale(parent) * (Transform::AbsoluteOrientation(parent) * (const glm::vec3&)cTransformPosition); + // Cache it + PositionCache[entity] = position; + RecalculatedPositions++; + // Unset dirty flag + cTransformPosition.SetDirty(DirtySetType::Transform, false); + // Flag children as dirty + for (auto& child : entity.ChildrenWithComponent("Transform")) { + child["Transform"]["Position"].SetDirty(DirtySetType::Transform, true); + } return position; } - - ComponentWrapper entityTransform = entity["Transform"]; - if (!entityTransform["Position"].Dirty(DirtySet::Transform)) { - return Cache[entity].Position; - } - - EntityWrapper e = entity; - while (e.Valid()) { - ComponentWrapper transform = e["Transform"]; - EntityWrapper parent = e.Parent(); - position += Transform::AbsoluteOrientation(parent) * (glm::vec3)transform["Position"]; - e = parent; - } - - Cache[entity].Position = position; - entityTransform["Position"].SetDirty(false); - - auto dirtyChildren = entity.ChildrenWithComponent("Transform"); - for (auto& child : dirtyChildren) { - child["Transform"]["Position"].SetDirty(true); - } - return position; } glm::vec3 Transform::AbsoluteOrientationEuler(EntityWrapper entity) @@ -84,30 +79,30 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) { - glm::quat orientation; if (!entity.Valid()) { + return glm::quat(); + } + + auto cacheIt = OrientationCache.find(entity); + ComponentWrapper cTransform = entity["Transform"]; + ComponentWrapper::SubscriptProxy cTransformOrientation = cTransform["Orientation"]; + if (cacheIt != OrientationCache.end() && !cTransformOrientation.Dirty(DirtySetType::Transform)) { + return cacheIt->second; + } else { + EntityWrapper parent = entity.Parent(); + // Calculate orientation + glm::quat orientation = AbsoluteOrientation(parent) * glm::quat((const glm::vec3&)cTransformOrientation); + // Cache it + OrientationCache[entity] = orientation; + RecalculatedOrientations++; + // Unset dirty flag + cTransformOrientation.SetDirty(DirtySetType::Transform, false); + // Flag children as dirty + for (auto& child : entity.ChildrenWithComponent("Transform")) { + child["Transform"]["Orientation"].SetDirty(DirtySetType::Transform, true); + } return orientation; } - ComponentWrapper entityTransform = entity["Transform"]; - if (!entityTransform["Orientation"].Dirty(DirtySet::Transform)) { - return Cache[entity].Orientation; - } - - EntityWrapper e = entity; - while (e.Valid()) { - ComponentWrapper transform = e["Transform"]; - orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation; - e = e.Parent(); - } - - Cache[entity].Orientation = orientation; - entityTransform["Orientation"].SetDirty(false); - - auto dirtyChildren = entity.ChildrenWithComponent("Transform"); - for (auto& child : dirtyChildren) { - child["Transform"]["Orientation"].SetDirty(true); - } - return orientation; } glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) @@ -117,41 +112,40 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) { - glm::vec3 scale(1.f); if (!entity.Valid()) { + return glm::vec3(1.f); + } + + auto cacheIt = ScaleCache.find(entity); + ComponentWrapper cTransform = entity["Transform"]; + ComponentWrapper::SubscriptProxy cTransformScale = cTransform["Scale"]; + if (cacheIt != ScaleCache.end() && !cTransformScale.Dirty(DirtySetType::Transform)) { + return cacheIt->second; + } else { + EntityWrapper parent = entity.Parent(); + // Calculate scale + glm::vec3 scale = AbsoluteScale(parent) * (const glm::vec3&)cTransformScale; + // Cache it + ScaleCache[entity] = scale; + RecalculatedPositions++; + // Unset dirty flag + cTransformScale.SetDirty(DirtySetType::Transform, false); + // Flag children as dirty + for (auto& child : entity.ChildrenWithComponent("Transform")) { + child["Transform"]["Scale"].SetDirty(DirtySetType::Transform, true); + } return scale; } - - ComponentWrapper entityTransform = entity["Transform"]; - if (!entityTransform["Scale"].Dirty(DirtySet::Transform)) { - return Cache[entity].Scale; - } - - EntityWrapper e = entity; - while (e.Valid()) { - ComponentWrapper transform = e["Transform"]; - scale *= (glm::vec3)transform["Scale"]; - e = e.Parent(); - } - - Cache[entity].Scale = scale; - entityTransform["Scale"].SetDirty(false); - - auto dirtyChildren = entity.ChildrenWithComponent("Transform"); - for (auto& child : dirtyChildren) { - child["Transform"]["Scale"].SetDirty(true); - } - return scale; } -glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) +glm::mat4 Transform::ModelMatrix(EntityID entityID, World* world) { - return AbsoluteTransformation(EntityWrapper(world, entity)); + return ModelMatrix(EntityWrapper(world, entityID)); } glm::mat4 Transform::ModelMatrix(EntityWrapper entity) { - return AbsoluteTransformation(entity); + return glm::translate(AbsolutePosition(entity)) * glm::toMat4(AbsoluteOrientation(entity)) * glm::scale(AbsoluteScale(entity)); } glm::vec3 Transform::TransformPoint(const glm::vec3& point, const glm::mat4& matrix) diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index a1f00c88..740d7211 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -176,7 +176,7 @@ bool RenderSystem::isEntityVisible(EntityWrapper& entity) } // Hide things parented to local player if they have the HiddenFromLocalPlayer component - bool outOfBodyExperience = ResourceManager::Load("Config.ini")->Get("Debug.OutOfBodyExperience", false); + bool outOfBodyExperience = false; // ResourceManager::Load("Config.ini")->Get("Debug.OutOfBodyExperience", false); if ( (entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid()) && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 69a9ad57..c864735f 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -240,6 +240,13 @@ void Game::Tick() m_RenderFrame->Clear(); m_EventBroker->Swap(); m_EventBroker->Clear(); + + //LOG_DEBUG("Recalculated positions: %i", Transform::RecalculatedPositions); + //LOG_DEBUG("Recalculated orientations: %i", Transform::RecalculatedOrientations); + //LOG_DEBUG("Recalculated scales: %i", Transform::RecalculatedScales); + Transform::RecalculatedPositions = 0; + Transform::RecalculatedOrientations = 0; + Transform::RecalculatedScales = 0; } int Game::parseArgs(int argc, char* argv[])