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 6cb91c4..ed714ae 100644 --- a/src/scene/graphicalnode.cpp +++ b/src/scene/graphicalnode.cpp @@ -1,15 +1,6 @@ #include "graphicalnode.h" #include "scenetree.h" - -GraphicalNode::GraphicalNode() : m_visible(true) -{ - -} - -GraphicalNode::GraphicalNode(bool visible) : m_visible(visible) -{ - -} +#include "glm/ext.hpp" void GraphicalNode::setSceneTree(SceneTree *tree){ SceneNode::setSceneTree(tree); @@ -25,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 bd44aef..d44f002 100644 --- a/src/scene/graphicalnode.h +++ b/src/scene/graphicalnode.h @@ -2,26 +2,46 @@ #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(bool); +// GraphicalNode(); +// GraphicalNode(bool); + GraphicalNode(bool visible = true) : m_visible(visible), m_transformChanged(true) {} + + bool isVisible(){return m_visible;} 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 8ec727c..ef02ac4 100644 --- a/src/scene/meshnode.h +++ b/src/scene/meshnode.h @@ -24,14 +24,8 @@ public: MeshNode(Mesh* mesh, bool visible = true) : GraphicalNode(visible), 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; } diff --git a/src/sparrowshell/shellscrollbar.cpp b/src/sparrowshell/shellscrollbar.cpp index 3c406b9..dce7590 100644 --- a/src/sparrowshell/shellscrollbar.cpp +++ b/src/sparrowshell/shellscrollbar.cpp @@ -24,7 +24,7 @@ ShellScrollBar::ShellScrollBar(SparrowShell* shell):m_shell(shell){ mesh->setMaterial(mat); mesh->initGL(); - m_mesh = new MeshNode(mesh); + m_mesh = new MeshNode(mesh,false); utils::setPosition2D(m_mesh,m_position); m_shell->addChild(m_mesh); }