SparrowEngine/src/scene/scenenode.h

185 lines
5.9 KiB
C++

#ifndef SCENENODE_H
#define SCENENODE_H
#include <glm/ext.hpp>
#include "LinearMath/btMotionState.h"
#include <SparrowRenderer/scene.h>
#include <cereal/archives/binary.hpp>
class SceneTree;
class Transform;
class Engine;
class Light;
class btRigidBody;
class SceneNode
{
public:
class SparrowMotionState : public btMotionState
{
SceneNode* m_node;
public:
SparrowMotionState(SceneNode* node) : m_node(node) {}
/// bullet physics uses this getter to access the node's transform
virtual void getWorldTransform(btTransform& worldTrans ) const;
/// bullet physics calls this setter to move objects (only on active rigidbodies)
virtual void setWorldTransform(const btTransform& worldTrans);
};
class Script
{
public:
virtual void begin(SceneNode* node) {}
virtual void update(SceneNode* node) = 0;
virtual void end(SceneNode* node) {}
};
private:
bool m_toDestroy;
std::vector<SceneNode*> m_nodesToRemove;
std::vector<SceneNode*> m_nodesToAdd;
std::string m_id;
bool m_parentVisible;
bool m_visible;
bool m_enabled;
bool m_transformChanged;
SceneNode* m_parent;
SceneTree* m_scene;
// contains the mesh if this node has one
GeometryNode m_geometry;
// contains the light source if the node has one
Light* m_light;
// m_transform is the relative transformation matrix of this node
glm::mat4 m_transform;
// m_parentTransform is the base transform for this element
glm::mat4 m_parentTransform;
// m_script allows to add some game logic in a generic way
Script* m_script;
// bullet physics rigidbody
btRigidBody *m_rigidBody;
// bullet physics handle for our transformation matrix
SparrowMotionState m_motionState;
// node's children
std::vector<SceneNode*> m_children;
void updateVisibility(bool visible);
void setParent(SceneNode* parent);
void updateLightSource();
bool m_showInfo;
public:
// constructor/destructor
SceneNode(std::string node_id = "undefined id",Script *script = nullptr);
virtual ~SceneNode();
// game logic methods
/// @brief update this method is called every tick by the engine
virtual void update();
bool isEnabled() { return m_enabled; }
void setEnabled(bool isEnabled) { m_enabled = isEnabled; }
Script* getScript();
std::string getID();
void setID(std::string id){m_id = id;}
// methods called to access the graphic propeties of the node
void setMesh(Mesh* mesh) { m_geometry.mesh = mesh; }
Mesh* getMesh() { return m_geometry.mesh; }
GeometryNode* getGeometryNode() { return &m_geometry; }
void setLight(Light* light) { m_light = light; }
Light* getLight() { return m_light; }
// scene tree structure methods
/// @brief setSceneTree this method can be used to change the scene of the node
virtual void setSceneTree(SceneTree* tree);
/// @brief getScene this method returns the scene this node is in
SceneTree* getScene() { return m_scene; }
/// @brief addChild this method can be used to add a child to a node
void addChild(SceneNode* node);
/// @brief removeChild this method can be used to remove a child from a node
void removeChild(SceneNode* node);
/// @brief getParent returns the parent of this node, or nullptr if this node is the scene tree root
virtual SceneNode* getParent() { return m_parent; }
/// @brief killWhenOrphan this method can be called if you wish to delete this object as soon as it has no parent.
virtual void destroyWhenOrphan() { m_toDestroy = true; }
/// @brief getChildren returns a vector containing all this node's children
const std::vector<SceneNode*> getChildren() { return m_children; }
// transform methods
void setTransform(const Transform& t);
void getTransform(Transform& t);
void setTransform(const glm::mat4 &transform);
const glm::mat4& getTransform() { return m_transform; }
void setParentTransform(const glm::mat4 &transform);
const glm::mat4& getParentTransform() { return m_parentTransform; }
void resetTransform();
// visibility methods
bool isVisible() { return m_parentVisible && m_visible; }
void toggleVisibility() { setVisible(!m_visible); }
void setVisible(bool visible);
void setParentVisible(bool visible);
// 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);
//2D tools:
void moveTo2D(const glm::vec2 &position) { setTransform(glm::translate(m_transform,glm::vec3(position.x,position.y,0) - glm::vec3(m_transform[3]))); }
void rotate2D(const glm::vec2 &center, float angle) { setTransform(glm::rotate(m_transform,angle,glm::vec3(0,0,1))); }
void scale2D(const glm::vec2 scaleFactor) { setTransform(glm::scale(m_transform, glm::vec3(scaleFactor.x,scaleFactor.y,1))); }
void resize2D(const glm::vec2 oldDimension, glm::vec2 newDimension) { scale2D(glm::vec2(newDimension / oldDimension)); }
float getDepth();
void setDepth(float depth);
// physics methods
/// @brief getMotionState this is used to synchronize a bullet rigidbody's transform with a GraphicalNode transform
SparrowMotionState* getMotionState() { return &m_motionState; }
/// @brief setRigidBody sets a rigidbody to the node
void setRigidBody(btRigidBody* body);
btRigidBody* getRigidBody() { return m_rigidBody; }
/// the scene node clones itself, with no parent
virtual SceneNode* clone();
//serialization methods
template <class Archive>
void serialize(Archive & archive)
{
archive(m_transform);
}
void openInfoWindow();
void gui();
// global engine methods
Engine& getEngine();
};
#endif // SCENENODE_H