diff --git a/src/keymapper.cpp b/src/keymapper.cpp index 8eb1488..2328363 100644 --- a/src/keymapper.cpp +++ b/src/keymapper.cpp @@ -110,7 +110,7 @@ void KeyMapper::gui() ImGui::Begin("KeyMapper"); std::vector& keys = m_keysmap.data(); - for(unsigned int i = 0;iexpiration < getEngine().getTime()) { getEngine().getScene()->getPhysics()->removeCollisionObject(g->body); + g->graphics->destroyWhenOrphan(); removeChild(g->graphics); it = m_gibs.erase(it); - delete g->graphics; delete g; } else diff --git a/src/scene/gui/backgroundnode.cpp b/src/scene/gui/backgroundnode.cpp index e646ff2..31850cd 100644 --- a/src/scene/gui/backgroundnode.cpp +++ b/src/scene/gui/backgroundnode.cpp @@ -24,7 +24,8 @@ BackGroundNode::BackGroundNode(glm::vec2 dimension, glm::vec3 color, float opaci mesh->setMaterial(mat); mesh->setDepth(depth); mesh->initGL(); - m_mesh = new MeshNode(mesh); + m_mesh = new SceneNode(); + m_mesh->getGeometryNode()->mesh = mesh; addChild(m_mesh); } diff --git a/src/scene/gui/backgroundnode.h b/src/scene/gui/backgroundnode.h index 062d56b..1ddc864 100644 --- a/src/scene/gui/backgroundnode.h +++ b/src/scene/gui/backgroundnode.h @@ -3,12 +3,10 @@ #include "scene/gui/guinode.h" -#include "scene/meshnode.h" - class BackGroundNode : public GUINode { protected: - MeshNode* m_mesh; + SceneNode* m_mesh; glm::vec2 m_dimension; glm::vec3 m_color; bool m_color_updated; @@ -21,7 +19,7 @@ public: void setOpacity(float opacity); void setDepth(float depth); glm::vec2 getDimension(); - MeshNode* getMeshNode() { return m_mesh; } + SceneNode* getMeshNode() { return m_mesh; } }; diff --git a/src/scene/gui/buttonnode.h b/src/scene/gui/buttonnode.h index 21e8309..20e24b2 100644 --- a/src/scene/gui/buttonnode.h +++ b/src/scene/gui/buttonnode.h @@ -1,7 +1,6 @@ #ifndef BUTTONNODE_H #define BUTTONNODE_H -#include "scene/meshnode.h" #include "scene/gui/guinode.h" #include "scene/gui/callback.h" #include "scene/textnode.h" diff --git a/src/scene/gui/scrollbarnode.cpp b/src/scene/gui/scrollbarnode.cpp index 875c12a..a5f910a 100644 --- a/src/scene/gui/scrollbarnode.cpp +++ b/src/scene/gui/scrollbarnode.cpp @@ -2,8 +2,6 @@ #include -#include "scene/meshnode.h" - #include "SparrowRenderer/mesh.h" #include "SparrowRenderer/pbrmaterial.h" #include "sparrowshell/sparrowshell.h" @@ -28,7 +26,8 @@ ScrollBarNode::ScrollBarNode(glm::vec2 dimension, glm::vec3 bar_color): mesh->setMaterial(mat); mesh->setDepth(SparrowShell::SHELL_DEPTH+1); mesh->initGL(); - m_bar = new MeshNode(mesh); + m_bar = new SceneNode(); + m_bar->getGeometryNode()->mesh = mesh; addChild(m_bar); } diff --git a/src/scene/gui/scrollbarnode.h b/src/scene/gui/scrollbarnode.h index 4f8d6a4..fde2313 100644 --- a/src/scene/gui/scrollbarnode.h +++ b/src/scene/gui/scrollbarnode.h @@ -3,8 +3,6 @@ #include "scene/gui/guinode.h" -class MeshNode; - class ScrollBarNode : public GUINode { protected: @@ -16,7 +14,7 @@ protected: int m_index_position; int m_bar_size; int m_total_size; - MeshNode* m_bar; + SceneNode* m_bar; bool m_bar_resized; bool m_bar_moved; diff --git a/src/scene/gui/textinputnode.cpp b/src/scene/gui/textinputnode.cpp index 4cc1f7b..e008c89 100644 --- a/src/scene/gui/textinputnode.cpp +++ b/src/scene/gui/textinputnode.cpp @@ -33,7 +33,8 @@ TextInputNode::TextInputNode(glm::vec2 dimension): mesh->setMaterial(mat); mesh->setDepth(30); mesh->initGL(); - m_cursor_mesh = new MeshNode(mesh,false); + m_cursor_mesh = new SceneNode(false); + m_cursor_mesh->getGeometryNode()->mesh = mesh; addChild(m_cursor_mesh); } diff --git a/src/scene/gui/textinputnode.h b/src/scene/gui/textinputnode.h index ba8b270..6ac0ac3 100644 --- a/src/scene/gui/textinputnode.h +++ b/src/scene/gui/textinputnode.h @@ -27,7 +27,7 @@ class TextInputNode : public GUINode bool m_text_updated; glm::vec3 m_text_color; - MeshNode* m_cursor_mesh; + SceneNode* m_cursor_mesh; unsigned int m_cursor_pos; bool m_cursor_pos_updated; diff --git a/src/scene/meshnode.cpp b/src/scene/meshnode.cpp deleted file mode 100644 index 80812dd..0000000 --- a/src/scene/meshnode.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "meshnode.h" -#include "SparrowRenderer/mesh.h" -#include "scenetree.h" -#include - -#include -#include - -void MeshNode::setSceneTree(SceneTree *tree) -{ - SceneNode::setSceneTree(tree); - if(m_scene != nullptr) - m_scene->registerMeshType(m_geometry.mesh->getFlags()); -} - -float MeshNode::getDepth() -{ - return m_geometry.mesh->getDepth(); -} - -void MeshNode::setDepth(float depth) -{ - m_geometry.mesh->setDepth(depth); -} - -void MeshNode::update() -{ - if(m_transformChanged) - m_geometry.modelMatrix = m_parentTransform * m_transform; -} - -btRigidBody* MeshNode::buildStaticCollider() -{ - btIndexedMesh *bulletMesh = new btIndexedMesh(); - Mesh *m = m_geometry.mesh; - // vertices - bulletMesh->m_numVertices = m->m_positions3D.size(); - bulletMesh->m_vertexBase = (unsigned char*)(m->m_positions3D.data()); - bulletMesh->m_vertexStride = sizeof(glm::vec3); - bulletMesh->m_vertexType = PHY_FLOAT; - // indices - bulletMesh->m_numTriangles = m->m_indices.size()/3; - bulletMesh->m_triangleIndexBase = (unsigned char*)(m->m_indices.data()); - bulletMesh->m_triangleIndexStride = 3*sizeof(GLuint); - bulletMesh->m_indexType = PHY_INTEGER; - - // building bullet rigidbody - btTriangleIndexVertexArray* indexArray = new btTriangleIndexVertexArray(); - indexArray->addIndexedMesh(*bulletMesh, PHY_INTEGER); - btBvhTriangleMeshShape *shape = new btBvhTriangleMeshShape(indexArray, true); - shape->setLocalScaling(btVector3(m_transform[0].x, m_transform[1].y, m_transform[2].z)); - - btTransform transform; - transform.setIdentity(); - transform.setOrigin(btVector3(m_transform[3].x, m_transform[3].y, m_transform[3].z)); - // IMPORTANT ! collisions on static meshes does not work if the transform is modified after the rigidbody construction - m_rigidBody = new btRigidBody(0., nullptr, shape); - m_rigidBody->setWorldTransform(transform); - m_rigidBody->setUserPointer(this); - return m_rigidBody; -} diff --git a/src/scene/meshnode.h b/src/scene/meshnode.h deleted file mode 100644 index 7e72409..0000000 --- a/src/scene/meshnode.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef MESHNODE_H -#define MESHNODE_H - -#include "scenenode.h" -#include "glm/mat4x4.hpp" -#include "SparrowRenderer/scene.h" - -class btRigidBody; -class btIndexedMesh; -class btRigidBody; - -/** - * @brief The MeshNode class holds a mesh - */ - -class MeshNode : public SceneNode -{ -protected: - GeometryNode m_geometry; - - // physics - btRigidBody *m_rigidBody; - -public: - // WARNING ! this class doesn't handle the destruction of the rendered mesh and the eventually generated rigidbody - // this behaviour allows the use of the same meshes in multiple nodes - MeshNode(Mesh* mesh, bool visible = true) : SceneNode(visible), m_geometry(mesh, glm::mat4()), m_rigidBody(nullptr) {} - - virtual void setSceneTree(SceneTree* tree); - - virtual void update(); - - float getDepth(); - void setDepth(float depth); - - virtual GeometryNode* getGeometryNode() { return &m_geometry; } - - // this creates a new rigidbody, you must handle its destruction manually - btRigidBody* buildStaticCollider(); -}; - -#endif // MESHNODE_H diff --git a/src/scene/objectnode.cpp b/src/scene/objectnode.cpp deleted file mode 100644 index 864526c..0000000 --- a/src/scene/objectnode.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "objectnode.h" -#include "tools/transform.h" - -ObjectNode::ObjectNode() -{ - -} - -void ObjectNode::init() -{ - // TODO : lua init -} - -void ObjectNode::update() -{ - // TODO : lua update - - // children update - ContainerNode::update(); -} - -void ObjectNode::gui() -{ - // imgui editor -} diff --git a/src/scene/objectnode.h b/src/scene/objectnode.h deleted file mode 100644 index 9b2fd21..0000000 --- a/src/scene/objectnode.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef OBJECTNODE_H -#define OBJECTNODE_H - -#include "containernode.h" -#include -#include -#include - -struct Transform; - -class ContainerNode; - -class ObjectNode : public ContainerNode -{ - std::string name; - -public: - ObjectNode(); - - virtual void init(); - - virtual void update(); - - void gui(); - - // LUA accessible methods - - // instanciation - //static ObjectNode* create() { return new ObjectNode(); } - ObjectNode* clone(); - - // positionning - - - // physics - - - // graphics - - -}; - -#endif // OBJECTNODE_H diff --git a/src/scene/physicsdebugnode.cpp b/src/scene/physicsdebugnode.cpp index 707a93b..95ca175 100644 --- a/src/scene/physicsdebugnode.cpp +++ b/src/scene/physicsdebugnode.cpp @@ -4,9 +4,9 @@ #include "scene/scenetree.h" -PhysicsDebugNode::PhysicsDebugNode() : - MeshNode(new Mesh()) +PhysicsDebugNode::PhysicsDebugNode() { + m_geometry.mesh = new Mesh(); m_geometry.mesh->setMaterial(new PBRMaterial()); m_geometry.mesh->setPrimitiveType(GL_LINES); m_geometry.mesh->setWireframe(true); diff --git a/src/scene/physicsdebugnode.h b/src/scene/physicsdebugnode.h index 038b859..01625fb 100644 --- a/src/scene/physicsdebugnode.h +++ b/src/scene/physicsdebugnode.h @@ -1,11 +1,11 @@ #ifndef PHYSICSDEBUGNODE_H #define PHYSICSDEBUGNODE_H -#include "meshnode.h" +#include "scenenode.h" #include #include -class PhysicsDebugNode : public MeshNode, public btIDebugDraw +class PhysicsDebugNode : public SceneNode, public btIDebugDraw { int m_debugMode; diff --git a/src/scene/scenenode.cpp b/src/scene/scenenode.cpp new file mode 100644 index 0000000..8140302 --- /dev/null +++ b/src/scene/scenenode.cpp @@ -0,0 +1,168 @@ +#include "scenenode.h" +#include "scenetree.h" +#include "glm/ext.hpp" +#include +#include +#include +#include +#include + +Engine &SceneNode::getEngine() +{ + return m_scene->getEngine(); +} + +void SceneNode::setParent(SceneNode* parent) +{ + if(m_toDestroy && parent == nullptr) + delete this; + else + m_parent = parent; +} + +SceneNode::SceneNode(bool visible) : + m_toDestroy(false), + m_parent(nullptr), + m_scene(nullptr), + m_geometry(nullptr, glm::mat4()), + m_transform(m_geometry.modelMatrix), + m_rigidBody(nullptr), + m_parentVisible(true), + m_visible(visible), + m_transformChanged(true), + m_motionState(this) +{} + +void SceneNode::update() +{ + if(m_transformChanged) + m_geometry.modelMatrix = m_parentTransform * m_transform; +} + +void SceneNode::setSceneTree(SceneTree *tree) +{ + if(isVisible()) + { + if(m_scene != nullptr) + m_scene->removeFromIndex(this); + if(tree != nullptr) + tree->addToIndex(this); + } + m_scene = tree; + if(m_scene != nullptr && m_geometry.mesh != nullptr) + m_scene->registerMeshType(m_geometry.mesh->getFlags()); +} + +void SceneNode::resetTransform() +{ + setTransform(glm::mat4()); +} + +// tools +void SceneNode::moveTo(const glm::vec3 &position) +{ + m_transform = glm::translate(glm::mat4(), position); + m_transformChanged = true; +} + +void SceneNode::translate(const glm::vec3 &vector) +{ + m_transform = glm::translate(m_transform, vector); + m_transformChanged = true; +} + +void SceneNode::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 SceneNode::rotate(float angle, const glm::vec3 &vector) +{ + m_transform = glm::rotate(m_transform, angle, vector); + m_transformChanged = true; +} + +void SceneNode::scale(const glm::vec3 &scaleFactor) +{ + m_transform = glm::scale(m_transform, scaleFactor); + m_transformChanged = true; +} + +float SceneNode::getDepth() +{ + m_geometry.mesh->getDepth(); +} + +void SceneNode::setDepth(float depth) +{ + m_geometry.mesh->setDepth(depth); +} + +// setters +void SceneNode::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 SceneNode::setParentTransform(const glm::mat4 &transform) +{ + m_parentTransform = transform; + m_transformChanged = true; +} + +void SceneNode::setVisible(bool visible) +{ + if(m_parentVisible) + { + if(m_visible && !visible) + updateVisibility(false); + if(visible && !m_visible) + updateVisibility(true); + } + m_visible = visible; +} + +void SceneNode::setParentVisible(bool visible) +{ + if(m_visible) + { + if(m_parentVisible && !visible) + updateVisibility(false); + if(visible && !m_parentVisible) + updateVisibility(true); + } + m_parentVisible = visible; +} + +void SceneNode::updateVisibility(bool visible) +{ + if(!m_scene) + return; + if(visible) + m_scene->addToIndex(this); + else + m_scene->removeFromIndex(this); +} + +void SceneNode::SparrowMotionState::getWorldTransform(btTransform& worldTrans ) const +{ + worldTrans.setFromOpenGLMatrix(glm::value_ptr(m_node->getTransform())); +} + +void SceneNode::SparrowMotionState::setWorldTransform(const btTransform& worldTrans) +{ + glm::mat4 t; + worldTrans.getOpenGLMatrix(glm::value_ptr(t)); + m_node->setTransform(t); +} + +void SceneNode::setRigidBody(btRigidBody* body) +{ + m_rigidBody = body; + if(m_rigidBody != nullptr) + m_rigidBody->setUserPointer(this); +} diff --git a/src/scene/scenenode.h b/src/scene/scenenode.h new file mode 100644 index 0000000..971c995 --- /dev/null +++ b/src/scene/scenenode.h @@ -0,0 +1,125 @@ +#ifndef SCENENODE_H +#define SCENENODE_H + +#include +#include +#include "LinearMath/btMotionState.h" +#include + +class SceneTree; +class Transform; +class Engine; +class Light; +class btRigidBody; + +class SceneNode +{ +private: + bool m_toDestroy; + +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); + }; + +protected: + SceneNode* m_parent; + SceneTree* m_scene; + + /// contains the mesh if this node has one + GeometryNode m_geometry; + + /// 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; + + /// bullet physics rigidbody + btRigidBody *m_rigidBody; + + bool m_parentVisible; + bool m_visible; + + bool m_transformChanged; + + SparrowMotionState m_motionState; + + virtual void updateVisibility(bool visible); + + Engine& getEngine(); + +public: + // constructor/destructor + SceneNode(bool visible = true); + virtual ~SceneNode() { setVisible(false); } + + // game logic methods + /// @brief update this method is called every tick + virtual void update(); + + // methods called by the renderer + virtual Light* getLight() { return nullptr; } + virtual GeometryNode* getGeometryNode() { return &m_geometry; } + + // scene tree structure methods + /// @brief setSceneTree this method can be used to change the scene of the node + virtual void setSceneTree(SceneTree* tree); + /// @brief setParent this method can be used to modify the scene tree + virtual void setParent(SceneNode *parent); + /// @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; } + + // 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 ¢er, 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; } +}; + +#endif // SCENENODE_H diff --git a/src/scene/scenetree.cpp b/src/scene/scenetree.cpp index 04eb9f6..41c9359 100644 --- a/src/scene/scenetree.cpp +++ b/src/scene/scenetree.cpp @@ -95,7 +95,7 @@ void SceneTree::addToIndex(SceneNode* node){ GeometryNode *geometrynode = node->getGeometryNode(); //TODO : Check for doublon in m_lights et m_geometries => not necessary if correctly removed ? if (light != nullptr) m_lights.push_back(light); - if (geometrynode != nullptr) m_geometries.push_back(geometrynode); + if (geometrynode->mesh != nullptr) m_geometries.push_back(geometrynode); } void SceneTree::removeFromIndex(SceneNode *node){ @@ -110,7 +110,7 @@ void SceneTree::removeFromIndex(SceneNode *node){ m_lights.pop_back(); } } - if(geometrynode != nullptr) + if(geometrynode->mesh != nullptr) { auto it_g = std::find(m_geometries.begin(),m_geometries.end(),node->getGeometryNode()); if (it_g != m_geometries.end()){ diff --git a/src/scene/textnode.h b/src/scene/textnode.h index eaafe73..a494fa2 100644 --- a/src/scene/textnode.h +++ b/src/scene/textnode.h @@ -1,14 +1,14 @@ #ifndef TEXTNODE_H #define TEXTNODE_H -#include "meshnode.h" +#include "scenenode.h" #include "SparrowRenderer/mesh.h" #include "SparrowRenderer/pbrmaterial.h" #include "glm/vec2.hpp" -class TextNode : public MeshNode +class TextNode : public SceneNode { private: std::wstring m_string; @@ -17,8 +17,9 @@ private: friend class LabelNode; public: - TextNode(Mesh* mesh,std::wstring s,float fontSize,bool visible = true) : MeshNode(mesh,visible),m_string(s),m_fontSize(fontSize) {} - TextNode(Mesh* mesh,std::string s,float fontSize,bool visible = true) : MeshNode(mesh,visible),m_fontSize(fontSize) { + TextNode(Mesh* mesh,std::wstring s,float fontSize,bool visible = true) : SceneNode(visible),m_string(s),m_fontSize(fontSize) { m_geometry.mesh = mesh; } + TextNode(Mesh* mesh,std::string s,float fontSize,bool visible = true) : SceneNode(visible),m_fontSize(fontSize) { + m_geometry.mesh = mesh; m_string.assign(s.begin(),s.end()); } ~TextNode(){delete m_geometry.mesh;} diff --git a/src/sparrowshell/shellbuffer.cpp b/src/sparrowshell/shellbuffer.cpp index b62990e..ba2afc6 100644 --- a/src/sparrowshell/shellbuffer.cpp +++ b/src/sparrowshell/shellbuffer.cpp @@ -1,5 +1,4 @@ #include "shellbuffer.h" -#include "scene/meshnode.h" #include "scene/textnode.h" #include "sparrowshell/sparrowshell.h" #include "tools/utils.h" diff --git a/src/sparrowshell/shellscrollbar.cpp b/src/sparrowshell/shellscrollbar.cpp index f88fb40..2123858 100644 --- a/src/sparrowshell/shellscrollbar.cpp +++ b/src/sparrowshell/shellscrollbar.cpp @@ -2,7 +2,6 @@ #include "sparrowshell.h" #include "SparrowRenderer/mesh.h" #include "SparrowRenderer/pbrmaterial.h" -#include "scene/meshnode.h" #include "tools/utils.h" #include diff --git a/src/sparrowshell/sparrowshell.cpp b/src/sparrowshell/sparrowshell.cpp index d140ea7..727f9cf 100644 --- a/src/sparrowshell/sparrowshell.cpp +++ b/src/sparrowshell/sparrowshell.cpp @@ -2,7 +2,6 @@ #include "SparrowInput/input.h" #include "scene/scenetree.h" -#include "scene/meshnode.h" #include "scene/textnode.h" #include "scene/gui/backgroundnode.h" #include "scene/gui/textinputnode.h" diff --git a/src/test/main.cpp b/src/test/main.cpp index 35fa829..2a3621f 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -105,10 +105,14 @@ void generateTerrain(SceneTree *scene, btDiscreteDynamicsWorld *world) { chunk->mesh->setMaterial(mat); chunk->mesh->initGL(); - MeshNode *node = new MeshNode(chunk->mesh); - node->setTransform(glm::translate(glm::scale(glm::mat4(), glm::vec3(2.f)), pos*8.f)); + SceneNode *node = new SceneNode(); + node->getGeometryNode()->mesh = chunk->mesh; + node->getGeometryNode()->modelMatrix = glm::translate(glm::scale(glm::mat4(), glm::vec3(2.f)), pos*8.f); + node->setTransform(node->getGeometryNode()->modelMatrix); terrainContainer->addChild(node); - world->addRigidBody(node->buildStaticCollider()); + btRigidBody* body = utils::buildStaticCollider(node->getGeometryNode()); + node->setRigidBody(body); + world->addRigidBody(body); } } } @@ -127,10 +131,14 @@ void generateSponza(SceneTree *scene, btDiscreteDynamicsWorld *world) else { m->initGL(); - MeshNode *node = new MeshNode(m); - node->setTransform(glm::scale(glm::mat4(), glm::vec3(0.01f))); + SceneNode *node = new SceneNode(); + node->getGeometryNode()->mesh = m; + node->getGeometryNode()->modelMatrix = glm::scale(glm::mat4(), glm::vec3(0.01f)); + node->setTransform(node->getGeometryNode()->modelMatrix); sponzaContainer->addChild(node); - world->addRigidBody(node->buildStaticCollider()); + btRigidBody* body = utils::buildStaticCollider(node->getGeometryNode()); + node->setRigidBody(body); + world->addRigidBody(body); } } } @@ -242,9 +250,12 @@ public: for(Mesh* m : meshes) { m->initGL(); - MeshNode *node = new MeshNode(m); + SceneNode *node = new SceneNode(); + node->getGeometryNode()->mesh = m; sandboxContainer->addChild(node); - scene->getPhysics()->addRigidBody(node->buildStaticCollider()); + btRigidBody* body = utils::buildStaticCollider(node->getGeometryNode()); + node->setRigidBody(body); + scene->getPhysics()->addRigidBody(body); } m_player->setPosition(0.f, 1.4f, 0.f); sun->setShadowView(glm::vec3(80)); diff --git a/src/test/potator.cpp b/src/test/potator.cpp index 1528aeb..4aa9f04 100644 --- a/src/test/potator.cpp +++ b/src/test/potator.cpp @@ -5,7 +5,6 @@ #include "scene/scenetree.h" #include "SparrowRenderer/parametricmesh.h" #include "SparrowRenderer/pbrmaterial.h" -#include "scene/meshnode.h" #include "tools/loader.h" #include "tools/loadingthread.h" #include "SparrowRenderer/texture.h" @@ -92,7 +91,11 @@ void Potator::throwShield() ContainerNode *node = new ContainerNode(); for(Mesh * m : m_shieldMeshes) - node->addChild(new MeshNode(m)); + { + SceneNode* meshNode = new SceneNode(); + meshNode->getGeometryNode()->mesh = m; + node->addChild(meshNode); + } createGib(node, m_shieldShape, m_shieldMass, pos, dir*throwForce, 30000); } @@ -109,7 +112,11 @@ void Potator::throwBottle() ContainerNode *node = new ContainerNode(); for(Mesh * m : m_bottleMeshes) - node->addChild(new MeshNode(m)); + { + SceneNode* meshNode = new SceneNode(); + meshNode->getGeometryNode()->mesh = m; + node->addChild(meshNode); + } createGib(node, m_bottleShape, m_bottleMass, pos, dir*throwForce, 30000); } @@ -126,7 +133,11 @@ void Potator::throwSword() ContainerNode *node = new ContainerNode(); for(Mesh * m : m_swordMeshes) - node->addChild(new MeshNode(m)); + { + SceneNode* meshNode = new SceneNode(); + meshNode->getGeometryNode()->mesh = m; + node->addChild(meshNode); + } createGib(node, m_swordShape, m_swordMass, pos, dir*throwForce, 30000); } diff --git a/src/tools/scenepicker.cpp b/src/tools/scenepicker.cpp index 2b672da..7b2cea2 100644 --- a/src/tools/scenepicker.cpp +++ b/src/tools/scenepicker.cpp @@ -32,9 +32,9 @@ Mesh* ScenePicker::generateMesh() } ScenePicker::ScenePicker() : - MeshNode(generateMesh()), m_pickSucceeded(false) { + m_geometry.mesh = generateMesh(); } ScenePicker::~ScenePicker() diff --git a/src/tools/scenepicker.h b/src/tools/scenepicker.h index 33489ca..b4dc83c 100644 --- a/src/tools/scenepicker.h +++ b/src/tools/scenepicker.h @@ -1,10 +1,11 @@ #ifndef SCENEPICKER_H #define SCENEPICKER_H -#include "scene/meshnode.h" +#include "scene/scenenode.h" + #include -class ScenePicker : public MeshNode +class ScenePicker : public SceneNode { static Mesh* generateMesh(); diff --git a/src/tools/utils.cpp b/src/tools/utils.cpp index 435c872..6307b1f 100644 --- a/src/tools/utils.cpp +++ b/src/tools/utils.cpp @@ -1,10 +1,13 @@ #include "utils.h" #include "glm/ext.hpp" //#include "scene/scenetree.h" -#include "scene/meshnode.h" #include "iostream" #include "sparrowshell/scriptnode.h" #include "transform.h" +#include "SparrowRenderer/mesh.h" + +#include +#include std::vector utils::split(const std::string &line, char sep){ std::vector tokens; @@ -84,3 +87,32 @@ void setDepth2D(MeshNode* mnode, float depth){ } */ +btRigidBody* utils::buildStaticCollider(GeometryNode* node) +{ + btIndexedMesh *bulletMesh = new btIndexedMesh(); + Mesh* m = node->mesh; + // vertices + bulletMesh->m_numVertices = m->m_positions3D.size(); + bulletMesh->m_vertexBase = (unsigned char*)(m->m_positions3D.data()); + bulletMesh->m_vertexStride = sizeof(glm::vec3); + bulletMesh->m_vertexType = PHY_FLOAT; + // indices + bulletMesh->m_numTriangles = m->m_indices.size()/3; + bulletMesh->m_triangleIndexBase = (unsigned char*)(m->m_indices.data()); + bulletMesh->m_triangleIndexStride = 3*sizeof(GLuint); + bulletMesh->m_indexType = PHY_INTEGER; + + // building bullet rigidbody + btTriangleIndexVertexArray* indexArray = new btTriangleIndexVertexArray(); + indexArray->addIndexedMesh(*bulletMesh, PHY_INTEGER); + btBvhTriangleMeshShape *shape = new btBvhTriangleMeshShape(indexArray, true); + shape->setLocalScaling(btVector3(node->modelMatrix[0].x, node->modelMatrix[1].y, node->modelMatrix[2].z)); + + btTransform transform; + transform.setIdentity(); + transform.setOrigin(btVector3(node->modelMatrix[3].x, node->modelMatrix[3].y, node->modelMatrix[3].z)); + // IMPORTANT ! collisions on static meshes does not work if the transform is modified after the rigidbody construction + btRigidBody* rigidBody = new btRigidBody(0., nullptr, shape); + rigidBody->setWorldTransform(transform); + return rigidBody; +} diff --git a/src/tools/utils.h b/src/tools/utils.h index 00c18a4..e6950e7 100644 --- a/src/tools/utils.h +++ b/src/tools/utils.h @@ -5,8 +5,9 @@ #include #include -class MeshNode; class ScriptNode; +class btRigidBody; +class GeometryNode; namespace utils { @@ -18,6 +19,7 @@ void initStandardScene(); //void scale2D(MeshNode*, glm::vec2); //void rotate2D(MeshNode* mnode, glm::vec2 center, float angle); //void setDepth2D(MeshNode* mnode, float depth); +btRigidBody* buildStaticCollider(GeometryNode* node); } #endif // UTILS_H