From ab2b28264f20ccfb2fc1f11b38138d7aecaf42a7 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Tue, 8 Mar 2016 18:10:36 +0100 Subject: [PATCH] Caching absolute positions, etc. Has not been tested yet. --- src/Engine/Core/Transform.cpp | 145 +++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 44 deletions(-) diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index 333c3532..788f0984 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -1,5 +1,22 @@ #include "Core/Transform.h" +namespace Transform +{ +struct Values +{ + glm::vec3 Position; + glm::quat Orientation; + glm::vec3 Scale; + Values() + : Position() + , Orientation() + , Scale(1.f) + {} +}; + +std::unordered_map Cache; +} + glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity) { glm::mat4 t = glm::mat4(1.f); @@ -12,22 +29,38 @@ glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity) return t; } -glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) -{ - return AbsolutePosition(entity.World, entity.ID); -} - glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) { - glm::vec3 position; + return Transform::AbsolutePosition(EntityWrapper(world, entity)); +} - while (entity != EntityID_Invalid) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - EntityID parent = world->GetParent(entity); - position += Transform::AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"]; - entity = parent; +glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) +{ + glm::vec3 position; + if (!entity.Valid()) { + 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; } @@ -44,57 +77,81 @@ glm::vec3 Transform::AbsoluteOrientationEuler(EntityWrapper entity) return orientation; } -glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) -{ - return AbsoluteOrientation(entity.World, entity.ID); -} - glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) { - glm::quat orientation; - - while (entity != EntityID_Invalid) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation; - entity = world->GetParent(entity); - } - - return orientation; + return Transform::AbsoluteOrientation(EntityWrapper(world, entity)); } -glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) +glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) { - return AbsoluteScale(entity.World, entity.ID); + glm::quat orientation; + if (!entity.Valid()) { + 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) { - glm::vec3 scale(1.f); - - while (entity != EntityID_Invalid) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - scale *= (glm::vec3)transform["Scale"]; - entity = world->GetParent(entity); - } - - return scale; + return Transform::AbsoluteScale(EntityWrapper(world, entity)); } -glm::mat4 Transform::ModelMatrix(EntityWrapper entity) +glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) { - return ModelMatrix(entity.ID, entity.World); + glm::vec3 scale(1.f); + if (!entity.Valid()) { + 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) { return AbsoluteTransformation(EntityWrapper(world, entity)); +} - glm::vec3 position = Transform::AbsolutePosition(world, entity); - glm::quat orientation = Transform::AbsoluteOrientation(world, entity); - glm::vec3 scale = Transform::AbsoluteScale(world, entity); - - glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); - return modelMatrix; +glm::mat4 Transform::ModelMatrix(EntityWrapper entity) +{ + return AbsoluteTransformation(entity); } glm::vec3 Transform::TransformPoint(const glm::vec3& point, const glm::mat4& matrix)