Merged MeshNode class with SceneNode class, now all nodes can hold geometry

This commit is contained in:
Anselme 2018-01-30 12:29:03 +01:00
parent 5a2bf29fba
commit bed507b501
28 changed files with 392 additions and 219 deletions

View File

@ -110,7 +110,7 @@ void KeyMapper::gui()
ImGui::Begin("KeyMapper"); ImGui::Begin("KeyMapper");
std::vector<Binding>& keys = m_keysmap.data(); std::vector<Binding>& keys = m_keysmap.data();
for(unsigned int i = 0;i<m_keysmap.data().size();i++) for(unsigned int i = 0; i < m_keysmap.data().size() ;i++)
{ {
Binding& b = keys[i]; Binding& b = keys[i];
std::string action_label; std::string action_label;
@ -130,7 +130,7 @@ void KeyMapper::gui()
ImGui::Text("%s",action_label.data()); ImGui::Text("%s",action_label.data());
ImGui::SameLine(200); ImGui::SameLine(200);
ImGui::PushID(action_label.data()); ImGui::PushID(action_label.data());
if(m_waiting_for_input == i) if(m_waiting_for_input == int(i))
ImGui::Button("...",ImVec2(100,30)); ImGui::Button("...",ImVec2(100,30));
else else
{ {
@ -143,7 +143,7 @@ void KeyMapper::gui()
{ {
for(unsigned int j = 0;j < types_binding.size();j++) for(unsigned int j = 0;j < types_binding.size();j++)
{ {
bool is_selected = (b.type == j); bool is_selected = (b.type == int(j));
if(ImGui::Selectable(types_binding[j].data(),is_selected)) if(ImGui::Selectable(types_binding[j].data(),is_selected))
b.type = j; b.type = j;
if(is_selected) if(is_selected)

View File

@ -39,9 +39,9 @@ void GibGeneratorNode::update()
if(g->expiration < getEngine().getTime()) if(g->expiration < getEngine().getTime())
{ {
getEngine().getScene()->getPhysics()->removeCollisionObject(g->body); getEngine().getScene()->getPhysics()->removeCollisionObject(g->body);
g->graphics->destroyWhenOrphan();
removeChild(g->graphics); removeChild(g->graphics);
it = m_gibs.erase(it); it = m_gibs.erase(it);
delete g->graphics;
delete g; delete g;
} }
else else

View File

@ -24,7 +24,8 @@ BackGroundNode::BackGroundNode(glm::vec2 dimension, glm::vec3 color, float opaci
mesh->setMaterial(mat); mesh->setMaterial(mat);
mesh->setDepth(depth); mesh->setDepth(depth);
mesh->initGL(); mesh->initGL();
m_mesh = new MeshNode(mesh); m_mesh = new SceneNode();
m_mesh->getGeometryNode()->mesh = mesh;
addChild(m_mesh); addChild(m_mesh);
} }

View File

@ -3,12 +3,10 @@
#include "scene/gui/guinode.h" #include "scene/gui/guinode.h"
#include "scene/meshnode.h"
class BackGroundNode : public GUINode class BackGroundNode : public GUINode
{ {
protected: protected:
MeshNode* m_mesh; SceneNode* m_mesh;
glm::vec2 m_dimension; glm::vec2 m_dimension;
glm::vec3 m_color; glm::vec3 m_color;
bool m_color_updated; bool m_color_updated;
@ -21,7 +19,7 @@ public:
void setOpacity(float opacity); void setOpacity(float opacity);
void setDepth(float depth); void setDepth(float depth);
glm::vec2 getDimension(); glm::vec2 getDimension();
MeshNode* getMeshNode() { return m_mesh; } SceneNode* getMeshNode() { return m_mesh; }
}; };

View File

@ -1,7 +1,6 @@
#ifndef BUTTONNODE_H #ifndef BUTTONNODE_H
#define BUTTONNODE_H #define BUTTONNODE_H
#include "scene/meshnode.h"
#include "scene/gui/guinode.h" #include "scene/gui/guinode.h"
#include "scene/gui/callback.h" #include "scene/gui/callback.h"
#include "scene/textnode.h" #include "scene/textnode.h"

View File

@ -2,8 +2,6 @@
#include <iostream> #include <iostream>
#include "scene/meshnode.h"
#include "SparrowRenderer/mesh.h" #include "SparrowRenderer/mesh.h"
#include "SparrowRenderer/pbrmaterial.h" #include "SparrowRenderer/pbrmaterial.h"
#include "sparrowshell/sparrowshell.h" #include "sparrowshell/sparrowshell.h"
@ -28,7 +26,8 @@ ScrollBarNode::ScrollBarNode(glm::vec2 dimension, glm::vec3 bar_color):
mesh->setMaterial(mat); mesh->setMaterial(mat);
mesh->setDepth(SparrowShell::SHELL_DEPTH+1); mesh->setDepth(SparrowShell::SHELL_DEPTH+1);
mesh->initGL(); mesh->initGL();
m_bar = new MeshNode(mesh); m_bar = new SceneNode();
m_bar->getGeometryNode()->mesh = mesh;
addChild(m_bar); addChild(m_bar);
} }

View File

@ -3,8 +3,6 @@
#include "scene/gui/guinode.h" #include "scene/gui/guinode.h"
class MeshNode;
class ScrollBarNode : public GUINode class ScrollBarNode : public GUINode
{ {
protected: protected:
@ -16,7 +14,7 @@ protected:
int m_index_position; int m_index_position;
int m_bar_size; int m_bar_size;
int m_total_size; int m_total_size;
MeshNode* m_bar; SceneNode* m_bar;
bool m_bar_resized; bool m_bar_resized;
bool m_bar_moved; bool m_bar_moved;

View File

@ -33,7 +33,8 @@ TextInputNode::TextInputNode(glm::vec2 dimension):
mesh->setMaterial(mat); mesh->setMaterial(mat);
mesh->setDepth(30); mesh->setDepth(30);
mesh->initGL(); 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); addChild(m_cursor_mesh);
} }

View File

@ -27,7 +27,7 @@ class TextInputNode : public GUINode
bool m_text_updated; bool m_text_updated;
glm::vec3 m_text_color; glm::vec3 m_text_color;
MeshNode* m_cursor_mesh; SceneNode* m_cursor_mesh;
unsigned int m_cursor_pos; unsigned int m_cursor_pos;
bool m_cursor_pos_updated; bool m_cursor_pos_updated;

View File

@ -1,61 +0,0 @@
#include "meshnode.h"
#include "SparrowRenderer/mesh.h"
#include "scenetree.h"
#include <glm/ext.hpp>
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
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;
}

View File

@ -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

View File

@ -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
}

View File

@ -1,43 +0,0 @@
#ifndef OBJECTNODE_H
#define OBJECTNODE_H
#include "containernode.h"
#include <glm/vec3.hpp>
#include <glm/ext.hpp>
#include <string>
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

View File

@ -4,9 +4,9 @@
#include "scene/scenetree.h" #include "scene/scenetree.h"
PhysicsDebugNode::PhysicsDebugNode() : PhysicsDebugNode::PhysicsDebugNode()
MeshNode(new Mesh())
{ {
m_geometry.mesh = new Mesh();
m_geometry.mesh->setMaterial(new PBRMaterial()); m_geometry.mesh->setMaterial(new PBRMaterial());
m_geometry.mesh->setPrimitiveType(GL_LINES); m_geometry.mesh->setPrimitiveType(GL_LINES);
m_geometry.mesh->setWireframe(true); m_geometry.mesh->setWireframe(true);

View File

@ -1,11 +1,11 @@
#ifndef PHYSICSDEBUGNODE_H #ifndef PHYSICSDEBUGNODE_H
#define PHYSICSDEBUGNODE_H #define PHYSICSDEBUGNODE_H
#include "meshnode.h" #include "scenenode.h"
#include <SparrowRenderer/mesh.h> #include <SparrowRenderer/mesh.h>
#include <LinearMath/btIDebugDraw.h> #include <LinearMath/btIDebugDraw.h>
class PhysicsDebugNode : public MeshNode, public btIDebugDraw class PhysicsDebugNode : public SceneNode, public btIDebugDraw
{ {
int m_debugMode; int m_debugMode;

168
src/scene/scenenode.cpp Normal file
View File

@ -0,0 +1,168 @@
#include "scenenode.h"
#include "scenetree.h"
#include "glm/ext.hpp"
#include <iostream>
#include <imgui/imgui.h>
#include <SparrowRenderer/mesh.h>
#include <bullet/btBulletCollisionCommon.h>
#include <bullet/btBulletDynamicsCommon.h>
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);
}

125
src/scene/scenenode.h Normal file
View File

@ -0,0 +1,125 @@
#ifndef SCENENODE_H
#define SCENENODE_H
#include <glm/mat4x4.hpp>
#include <glm/vec3.hpp>
#include "LinearMath/btMotionState.h"
#include <SparrowRenderer/scene.h>
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 &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; }
};
#endif // SCENENODE_H

View File

@ -95,7 +95,7 @@ void SceneTree::addToIndex(SceneNode* node){
GeometryNode *geometrynode = node->getGeometryNode(); GeometryNode *geometrynode = node->getGeometryNode();
//TODO : Check for doublon in m_lights et m_geometries => not necessary if correctly removed ? //TODO : Check for doublon in m_lights et m_geometries => not necessary if correctly removed ?
if (light != nullptr) m_lights.push_back(light); 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){ void SceneTree::removeFromIndex(SceneNode *node){
@ -110,7 +110,7 @@ void SceneTree::removeFromIndex(SceneNode *node){
m_lights.pop_back(); m_lights.pop_back();
} }
} }
if(geometrynode != nullptr) if(geometrynode->mesh != nullptr)
{ {
auto it_g = std::find(m_geometries.begin(),m_geometries.end(),node->getGeometryNode()); auto it_g = std::find(m_geometries.begin(),m_geometries.end(),node->getGeometryNode());
if (it_g != m_geometries.end()){ if (it_g != m_geometries.end()){

View File

@ -1,14 +1,14 @@
#ifndef TEXTNODE_H #ifndef TEXTNODE_H
#define TEXTNODE_H #define TEXTNODE_H
#include "meshnode.h" #include "scenenode.h"
#include "SparrowRenderer/mesh.h" #include "SparrowRenderer/mesh.h"
#include "SparrowRenderer/pbrmaterial.h" #include "SparrowRenderer/pbrmaterial.h"
#include "glm/vec2.hpp" #include "glm/vec2.hpp"
class TextNode : public MeshNode class TextNode : public SceneNode
{ {
private: private:
std::wstring m_string; std::wstring m_string;
@ -17,8 +17,9 @@ private:
friend class LabelNode; friend class LabelNode;
public: 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::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) : MeshNode(mesh,visible),m_fontSize(fontSize) { 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()); m_string.assign(s.begin(),s.end());
} }
~TextNode(){delete m_geometry.mesh;} ~TextNode(){delete m_geometry.mesh;}

View File

@ -1,5 +1,4 @@
#include "shellbuffer.h" #include "shellbuffer.h"
#include "scene/meshnode.h"
#include "scene/textnode.h" #include "scene/textnode.h"
#include "sparrowshell/sparrowshell.h" #include "sparrowshell/sparrowshell.h"
#include "tools/utils.h" #include "tools/utils.h"

View File

@ -2,7 +2,6 @@
#include "sparrowshell.h" #include "sparrowshell.h"
#include "SparrowRenderer/mesh.h" #include "SparrowRenderer/mesh.h"
#include "SparrowRenderer/pbrmaterial.h" #include "SparrowRenderer/pbrmaterial.h"
#include "scene/meshnode.h"
#include "tools/utils.h" #include "tools/utils.h"
#include <iostream> #include <iostream>

View File

@ -2,7 +2,6 @@
#include "SparrowInput/input.h" #include "SparrowInput/input.h"
#include "scene/scenetree.h" #include "scene/scenetree.h"
#include "scene/meshnode.h"
#include "scene/textnode.h" #include "scene/textnode.h"
#include "scene/gui/backgroundnode.h" #include "scene/gui/backgroundnode.h"
#include "scene/gui/textinputnode.h" #include "scene/gui/textinputnode.h"

View File

@ -105,10 +105,14 @@ void generateTerrain(SceneTree *scene, btDiscreteDynamicsWorld *world)
{ {
chunk->mesh->setMaterial(mat); chunk->mesh->setMaterial(mat);
chunk->mesh->initGL(); chunk->mesh->initGL();
MeshNode *node = new MeshNode(chunk->mesh); SceneNode *node = new SceneNode();
node->setTransform(glm::translate(glm::scale(glm::mat4(), glm::vec3(2.f)), pos*8.f)); 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); 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 else
{ {
m->initGL(); m->initGL();
MeshNode *node = new MeshNode(m); SceneNode *node = new SceneNode();
node->setTransform(glm::scale(glm::mat4(), glm::vec3(0.01f))); node->getGeometryNode()->mesh = m;
node->getGeometryNode()->modelMatrix = glm::scale(glm::mat4(), glm::vec3(0.01f));
node->setTransform(node->getGeometryNode()->modelMatrix);
sponzaContainer->addChild(node); 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) for(Mesh* m : meshes)
{ {
m->initGL(); m->initGL();
MeshNode *node = new MeshNode(m); SceneNode *node = new SceneNode();
node->getGeometryNode()->mesh = m;
sandboxContainer->addChild(node); 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); m_player->setPosition(0.f, 1.4f, 0.f);
sun->setShadowView(glm::vec3(80)); sun->setShadowView(glm::vec3(80));

View File

@ -5,7 +5,6 @@
#include "scene/scenetree.h" #include "scene/scenetree.h"
#include "SparrowRenderer/parametricmesh.h" #include "SparrowRenderer/parametricmesh.h"
#include "SparrowRenderer/pbrmaterial.h" #include "SparrowRenderer/pbrmaterial.h"
#include "scene/meshnode.h"
#include "tools/loader.h" #include "tools/loader.h"
#include "tools/loadingthread.h" #include "tools/loadingthread.h"
#include "SparrowRenderer/texture.h" #include "SparrowRenderer/texture.h"
@ -92,7 +91,11 @@ void Potator::throwShield()
ContainerNode *node = new ContainerNode(); ContainerNode *node = new ContainerNode();
for(Mesh * m : m_shieldMeshes) 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); createGib(node, m_shieldShape, m_shieldMass, pos, dir*throwForce, 30000);
} }
@ -109,7 +112,11 @@ void Potator::throwBottle()
ContainerNode *node = new ContainerNode(); ContainerNode *node = new ContainerNode();
for(Mesh * m : m_bottleMeshes) 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); createGib(node, m_bottleShape, m_bottleMass, pos, dir*throwForce, 30000);
} }
@ -126,7 +133,11 @@ void Potator::throwSword()
ContainerNode *node = new ContainerNode(); ContainerNode *node = new ContainerNode();
for(Mesh * m : m_swordMeshes) 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); createGib(node, m_swordShape, m_swordMass, pos, dir*throwForce, 30000);
} }

View File

@ -32,9 +32,9 @@ Mesh* ScenePicker::generateMesh()
} }
ScenePicker::ScenePicker() : ScenePicker::ScenePicker() :
MeshNode(generateMesh()),
m_pickSucceeded(false) m_pickSucceeded(false)
{ {
m_geometry.mesh = generateMesh();
} }
ScenePicker::~ScenePicker() ScenePicker::~ScenePicker()

View File

@ -1,10 +1,11 @@
#ifndef SCENEPICKER_H #ifndef SCENEPICKER_H
#define SCENEPICKER_H #define SCENEPICKER_H
#include "scene/meshnode.h" #include "scene/scenenode.h"
#include <bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h> #include <bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h>
class ScenePicker : public MeshNode class ScenePicker : public SceneNode
{ {
static Mesh* generateMesh(); static Mesh* generateMesh();

View File

@ -1,10 +1,13 @@
#include "utils.h" #include "utils.h"
#include "glm/ext.hpp" #include "glm/ext.hpp"
//#include "scene/scenetree.h" //#include "scene/scenetree.h"
#include "scene/meshnode.h"
#include "iostream" #include "iostream"
#include "sparrowshell/scriptnode.h" #include "sparrowshell/scriptnode.h"
#include "transform.h" #include "transform.h"
#include "SparrowRenderer/mesh.h"
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
std::vector<std::string> utils::split(const std::string &line, char sep){ std::vector<std::string> utils::split(const std::string &line, char sep){
std::vector<std::string> tokens; std::vector<std::string> 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;
}

View File

@ -5,8 +5,9 @@
#include <string> #include <string>
#include <glm/glm.hpp> #include <glm/glm.hpp>
class MeshNode;
class ScriptNode; class ScriptNode;
class btRigidBody;
class GeometryNode;
namespace utils namespace utils
{ {
@ -18,6 +19,7 @@ void initStandardScene();
//void scale2D(MeshNode*, glm::vec2); //void scale2D(MeshNode*, glm::vec2);
//void rotate2D(MeshNode* mnode, glm::vec2 center, float angle); //void rotate2D(MeshNode* mnode, glm::vec2 center, float angle);
//void setDepth2D(MeshNode* mnode, float depth); //void setDepth2D(MeshNode* mnode, float depth);
btRigidBody* buildStaticCollider(GeometryNode* node);
} }
#endif // UTILS_H #endif // UTILS_H