From 5b36296c1d021899cfe00a99139d1c749c43b46f Mon Sep 17 00:00:00 2001 From: Anselme Date: Sat, 10 Dec 2016 15:21:14 +0100 Subject: [PATCH] added transform inheritance for graphical objects --- src/scene/graphicalcontainernode.cpp | 11 ++++-- src/scene/graphicalcontainernode.h | 5 +-- src/scene/graphicalnode.cpp | 52 +++++++++++++++++++++++++--- src/scene/graphicalnode.h | 27 ++++++++++++--- src/scene/lightnode.cpp | 33 ++++++++++++++++++ src/scene/lightnode.h | 2 +- src/scene/meshnode.cpp | 10 ++++++ src/scene/meshnode.h | 8 +---- 8 files changed, 126 insertions(+), 22 deletions(-) diff --git a/src/scene/graphicalcontainernode.cpp b/src/scene/graphicalcontainernode.cpp index 81fbdf4..9a1de2c 100644 --- a/src/scene/graphicalcontainernode.cpp +++ b/src/scene/graphicalcontainernode.cpp @@ -1,8 +1,15 @@ #include "graphicalcontainernode.h" -GraphicalContainerNode::GraphicalContainerNode() +void GraphicalContainerNode::update() { - + if(m_transformChanged) + m_combinedTransform = m_transform * m_parentTransform; + for(GraphicalNode* child : m_children) + { + if(m_transformChanged) + child->setParentTransform(m_combinedTransform); + child->update(); + } } void GraphicalContainerNode::setSceneTree(SceneTree* tree) diff --git a/src/scene/graphicalcontainernode.h b/src/scene/graphicalcontainernode.h index 90ab947..7e43427 100644 --- a/src/scene/graphicalcontainernode.h +++ b/src/scene/graphicalcontainernode.h @@ -9,12 +9,13 @@ class GraphicalContainerNode : public GraphicalNode { protected: std::vector m_children; + glm::mat4 m_combinedTransform; + public: - virtual void update() {} + virtual void update(); virtual void setSceneTree(SceneTree* tree); - GraphicalContainerNode(); void addChild(GraphicalNode* node); void removeChild(GraphicalNode* node); }; diff --git a/src/scene/graphicalnode.cpp b/src/scene/graphicalnode.cpp index 24bc571..024e4c2 100644 --- a/src/scene/graphicalnode.cpp +++ b/src/scene/graphicalnode.cpp @@ -1,10 +1,6 @@ #include "graphicalnode.h" #include "scenetree.h" - -GraphicalNode::GraphicalNode() : m_visible(true) -{ - -} +#include "glm/ext.hpp" void GraphicalNode::setSceneTree(SceneTree *tree){ SceneNode::setSceneTree(tree); @@ -20,3 +16,49 @@ void GraphicalNode::toggleVisibility(){ m_scene->removeFromIndex(this); } } + +// tools +void GraphicalNode::moveTo(const glm::vec3 &position) +{ + m_transform = glm::translate(glm::mat4(), position); + m_transformChanged = true; +} + +void GraphicalNode::translate(const glm::vec3 &vector) +{ + m_transform = glm::translate(m_transform, vector); + m_transformChanged = true; +} + +void GraphicalNode::lookAt(const glm::vec3 &target, const glm::vec3 &upVector) +{ + glm::vec3 pos = glm::vec3(m_transform[3]); + m_transform = glm::lookAt(pos, target, upVector); + m_transformChanged = true; +} + +void GraphicalNode::rotate(float angle, const glm::vec3 &vector) +{ + m_transform = glm::rotate(m_transform, angle, vector); + m_transformChanged = true; +} + +void GraphicalNode::scale(const glm::vec3 &scaleFactor) +{ + m_transform = glm::scale(m_transform, scaleFactor); + m_transformChanged = true; +} + +// setters +void GraphicalNode::setTransform(const glm::mat4 &transform) +{ + m_transform = transform; + m_transformChanged = true; +} + +// could be optimised by just storing a pointer, but unexpected behavior may happen ? +void GraphicalNode::setParentTransform(const glm::mat4 &transform) +{ + m_parentTransform = transform; + m_transformChanged = true; +} diff --git a/src/scene/graphicalnode.h b/src/scene/graphicalnode.h index f0e1223..dc65e74 100644 --- a/src/scene/graphicalnode.h +++ b/src/scene/graphicalnode.h @@ -2,24 +2,41 @@ #define GRAPHICALNODE_H #include "scenenode.h" -#include "glm/mat4x4.hpp" +#include +#include class SceneTree; class GraphicalNode : public SceneNode { -private: - glm::mat4 m_transform; protected: + // m_parentTransform is the base transform for this element + glm::mat4 m_parentTransform; + // m_transform is the relative transformation matrix of this node + glm::mat4 m_transform; + bool m_visible; + + bool m_transformChanged; + public: - GraphicalNode(); + GraphicalNode() : m_visible(true), m_transformChanged(true) {} void toggleVisibility(); virtual void setSceneTree(SceneTree* tree); - void setTransform(const glm::mat4 &transform) { m_transform = transform; } + void setTransform(const glm::mat4 &transform); + + void setParentTransform(const glm::mat4 &transform); + const glm::mat4& getTransform() { return m_transform; } + + // transformation tools : + void moveTo(const glm::vec3 &position); + void translate(const glm::vec3 &vector); + void lookAt(const glm::vec3 &target, const glm::vec3 &upVector = glm::vec3(0, 1, 0)); + void rotate(float angle, const glm::vec3 &vector); + void scale(const glm::vec3 &scaleFactor); }; #endif // GRAPHICALNODE_H diff --git a/src/scene/lightnode.cpp b/src/scene/lightnode.cpp index ed9155c..eef653c 100644 --- a/src/scene/lightnode.cpp +++ b/src/scene/lightnode.cpp @@ -1,4 +1,37 @@ #include "lightnode.h" #include "scenetree.h" #include +#include +void LightNode::update() +{ + if(m_transformChanged) + { + glm::mat4 combinedTransform(m_parentTransform * m_transform); + + switch(m_light->getType()) + { + case Light::DIRECTIONNAL : + { + DirectionnalLight *l = (DirectionnalLight*)m_light; + l->setDir(glm::mat3(combinedTransform) * l->getDir()); + } + break; + + case Light::POINT : + { + PointLight *l = (PointLight*)m_light; + l->setPos(l->getPos() + glm::vec3(combinedTransform[3])); + } + break; + + case Light::SPOT : + // TODO + break; + + case Light::AMBIENT : + default: + break; + } + } +} diff --git a/src/scene/lightnode.h b/src/scene/lightnode.h index f19d6be..fd95741 100644 --- a/src/scene/lightnode.h +++ b/src/scene/lightnode.h @@ -11,7 +11,7 @@ class LightNode : public GraphicalNode public: LightNode(Light* light) : m_light(light) {} - virtual void update() {} + virtual void update(); virtual Light* getLight() { return m_light; } }; diff --git a/src/scene/meshnode.cpp b/src/scene/meshnode.cpp index a5c2131..5109d83 100644 --- a/src/scene/meshnode.cpp +++ b/src/scene/meshnode.cpp @@ -10,6 +10,16 @@ void MeshNode::setDepth(float depth){ m_geometry.mesh->setDepth(depth); } +void MeshNode::update() +{ + // temp animation system + m_movement = m_acceleration * m_movement; + m_geometry.modelMatrix = m_movement * m_geometry.modelMatrix; + + if(m_transformChanged) + m_geometry.modelMatrix = m_parentTransform * m_transform; +} + btRigidBody* MeshNode::buildStaticCollider() { bulletMesh = new btIndexedMesh(); diff --git a/src/scene/meshnode.h b/src/scene/meshnode.h index 8f3f138..bb21532 100644 --- a/src/scene/meshnode.h +++ b/src/scene/meshnode.h @@ -24,14 +24,8 @@ public: MeshNode(Mesh* mesh) : m_geometry(mesh, glm::mat4()), bulletMesh(nullptr) {} - virtual void update() - { - m_movement = m_acceleration * m_movement; - m_geometry.modelMatrix = m_movement * m_geometry.modelMatrix; - } + virtual void update(); - void setTransform(const glm::mat4 &transform) { m_geometry.modelMatrix = transform; } - const glm::mat4& getTransform() { return m_geometry.modelMatrix; } void setDepth(float depth); virtual GeometryNode* getGeometryNode() { return &m_geometry; }