added folder scene for differents nodes

This commit is contained in:
Lendemor 2016-10-07 15:10:41 +02:00
parent 2705651565
commit ea06b027f8
20 changed files with 293 additions and 204 deletions

View File

@ -7,8 +7,8 @@ SET(VERSION_MINOR 1)
set(EXTRA_INCLUDES ${PROJECT_SOURCE_DIR}/src) set(EXTRA_INCLUDES ${PROJECT_SOURCE_DIR}/src)
# choose source file # choose source file
file(GLOB LIB_SRC_LIST src/*.cpp src/tools/*.cpp) file(GLOB LIB_SRC_LIST src/*.cpp src/tools/*.cpp src/scene/*.cpp)
file(GLOB LIB_HEAD_LIST src/*.h src/tools/*.h) file(GLOB LIB_HEAD_LIST src/*.h src/tools/*.h src/scene/*.h)
set(EXEC_SRC_LIST src/test/main.cpp) set(EXEC_SRC_LIST src/test/main.cpp)
#set compilation option #set compilation option

View File

@ -8,7 +8,7 @@
#include <btBulletCollisionCommon.h> #include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
#include "resourcemanager.h" #include "resourcemanager.h"
#include "scenetree.h" #include "scene/scenetree.h"
#include "sparrowshell.h" #include "sparrowshell.h"
Engine::Engine() : Engine::Engine() :
@ -108,6 +108,7 @@ void Engine::setScene(SceneTree *scene)
m_scene = scene; m_scene = scene;
m_renderer->setScene(m_scene); m_renderer->setScene(m_scene);
m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y); m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y);
m_sparrowshell->setScene(scene);
scene->addObject(scene->getRootObject(), m_sparrowshell); scene->addObject(scene->getRootObject(), m_sparrowshell);
} }

1
src/scene/cameranode.cpp Normal file
View File

@ -0,0 +1 @@
#include "cameranode.h"

16
src/scene/cameranode.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef CAMERANODE_H
#define CAMERANODE_H
#include "scenenode.h"
#include "trackballcamera.h"
/**
* @brief The CameraNode class is a scene node that can be used by the renderer
*/
class CameraNode : public TrackBallCamera, SceneNode
{
public:
CameraNode() {}
};
#endif // CAMERANODE_H

View File

@ -0,0 +1,39 @@
#include "containernode.h"
// Container Node
void ContainerNode::update()
{
for(SceneNode* sn : m_children)
sn->update();
}
void ContainerNode::addChild(SceneNode* node)
{
if(node != nullptr)
{
m_children.push_back(node);
node->m_parent = this;
}
}
void ContainerNode::removeChild(SceneNode* node)
{
if(node != nullptr)
{
for(auto it = m_children.begin(); it != m_children.end(); ++it)
{
if(*it == node)
{
m_children.erase(it);
break;
}
}
}
}
void ContainerNode::setSceneTree(SceneTree *tree)
{
SceneNode::setSceneTree(tree);
for(auto child : m_children)
child->setSceneTree(tree);
}

34
src/scene/containernode.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef CONTAINERNODE_H
#define CONTAINERNODE_H
#include "scenenode.h"
#include <vector>
/**
* @brief The ContainerNode class represents a node which main use is to contain a collection of nodes
*/
class ContainerNode : public SceneNode
{
public:
virtual void update();
/**
* @brief addChild adds node in the ContainerNode's children list
*/
void addChild(SceneNode* node);
/**
* @brief removeChild removes the first iteration of node of the children list
*/
void removeChild(SceneNode* node);
/**
* @brief addedToSceneTree is called when this node is added to a SceneTree
*
* @param tree
*/
void setSceneTree(SceneTree *tree);
protected:
std::vector<SceneNode*> m_children;
};
#endif // CONTAINERNODE_H

12
src/scene/meshnode.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "meshnode.h"
#include "mesh.h"
#include "scenetree.h"
void MeshNode::setDepth(float depth){
geometry.mesh->setDepth(depth);
}
void MeshNode::setSceneTree(SceneTree *tree){
SceneNode::setSceneTree(tree);
tree->addToIndex(this);
}

37
src/scene/meshnode.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef MESHNODE_H
#define MESHNODE_H
#include "scenenode.h"
#include "glm/mat4x4.hpp"
#include "scene.h"
/**
* @brief The MeshNode class holds a mesh
*/
class MeshNode : public SceneNode
{
GeometryNode geometry;
public:
// temp
glm::mat4 m_movement;
glm::mat4 m_acceleration;
MeshNode(Mesh* mesh) : geometry(mesh, glm::mat4()) {}
virtual void update()
{
m_movement = m_acceleration * m_movement;
geometry.modelMatrix = m_movement * geometry.modelMatrix;
}
void setSceneTree(SceneTree *tree);
void setTransform(const glm::mat4 &transform) { geometry.modelMatrix = transform; }
const glm::mat4& getTransform() { return geometry.modelMatrix; }
void setDepth(float depth);
GeometryNode* getGeometryNode() { return &geometry; }
};
#endif // MESHNODE_H

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

@ -0,0 +1,19 @@
#ifndef SCENENODE_H
#define SCENENODE_H
class SceneTree;
class Light;
class GeometryNode;
class SceneNode
{
public:
SceneNode* m_parent;
SceneTree* m_scene;
virtual void update() = 0;
virtual Light* getLight() {return nullptr;}
virtual GeometryNode* getGeometryNode() {return nullptr;}
virtual void setSceneTree(SceneTree* tree){m_scene = tree;}
};
#endif // SCENENODE_H

View File

@ -1,10 +1,12 @@
#include "scenetree.h" #include "scene/scenetree.h"
#include "resourcemanager.h" #include "resourcemanager.h"
#include <pipeline.h> #include <pipeline.h>
#include <deferredpipeline.h> #include <deferredpipeline.h>
#include <algorithm> #include <algorithm>
// Scene // Scene
#include <mesh.h>
#include <iostream> #include <iostream>
#include "scene/scenenode.h"
SceneTree::SceneTree() : SceneTree::SceneTree() :
Scene(), Scene(),
@ -44,7 +46,7 @@ void SceneTree::addObject(ContainerNode *parent, SceneNode *node)
{ {
parent->addChild(node); parent->addChild(node);
addToIndex(node); addToIndex(node);
node->addedToSceneTree(this); node->setSceneTree(this);
((DeferredPipeline*) m_pipeline)->refreshScene(this); ((DeferredPipeline*) m_pipeline)->refreshScene(this);
} }
@ -74,43 +76,3 @@ void SceneTree::removeFromIndex(SceneNode *node){
} }
} }
// Container Node
void ContainerNode::update()
{
for(SceneNode* sn : m_children)
sn->update();
}
void ContainerNode::addChild(SceneNode* node)
{
if(node != NULL)
{
m_children.push_back(node);
node->m_parent = this;
}
}
void ContainerNode::removeChild(SceneNode* node)
{
if(node != NULL)
{
for(auto it = m_children.begin(); it != m_children.end(); ++it)
{
if(*it == node)
{
m_children.erase(it);
break;
}
}
}
}
void ContainerNode::addedToSceneTree(SceneTree *tree)
{
for(auto child : m_children)
{
tree->addToIndex(child);
child->addedToSceneTree(tree);
}
}

47
src/scene/scenetree.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef SCENETREE_H
#define SCENETREE_H
#include <vector>
#include <string>
#include "scene.h"
#include "light.h"
#include "resourcemanager.h"
#include "containernode.h"
class CameraNode;
/**
* @brief The SceneNode class represents a class of the game
* that will be updated or used for rendering every frame
*/
class SceneTree : public Scene
{
public:
SceneTree();
~SceneTree();
virtual SceneIterator<Light*>* getLights();
virtual SceneIterator<GeometryNode*>* getGeometry();
void update();
Texture* getSkybox() {return m_skybox;}
void setSkybox(Texture* skybox) {m_skybox = skybox;}
void setMainCamera(CameraNode *camera);
ContainerNode* getRootObject(){return &m_root;}
void addObject(ContainerNode *parent, SceneNode *node);
void addToIndex(SceneNode* node);
void removeObject(ContainerNode* parent,SceneNode *node);
void removeFromIndex(SceneNode *node);
private:
ContainerNode m_root;
std::vector<Light*> m_lights;
std::vector<GeometryNode*> m_geometries;
Texture* m_skybox;
};
#endif // SCENETREE_H

6
src/scene/textnode.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "textnode.h"
/*TextNode::TextNode()
{
}*/

15
src/scene/textnode.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef TEXTNODE_H
#define TEXTNODE_H
#include "meshnode.h"
class TextNode : public MeshNode
{
private:
float m_fontSize;
public:
TextNode(Mesh* mesh,float fontSize) : MeshNode(mesh),m_fontSize(fontSize) {}
float getFontSize(){return m_fontSize;}
};
#endif // TEXTNODE_H

View File

@ -1,119 +0,0 @@
#ifndef SCENETREE_H
#define SCENETREE_H
#include <vector>
#include <string>
#include "scene.h"
#include "light.h"
#include "resourcemanager.h"
#include <trackballcamera.h>
class SceneTree;
/**
* @brief The SceneNode class represents a class of the game
* that will be updated or used for rendering every frame
*/
class SceneNode
{
public:
SceneNode* m_parent;
virtual void update() = 0;
virtual Light* getLight() {return nullptr;}
virtual GeometryNode* getGeometryNode() {return nullptr;}
virtual void addedToSceneTree(SceneTree* tree){}
};
/**
* @brief The ContainerNode class represents a node which main use is to contain a collection of nodes
*/
class ContainerNode : public SceneNode
{
public:
virtual void update();
/**
* @brief addChild adds node in the ContainerNode's children list
*/
void addChild(SceneNode* node);
/**
* @brief removeChild removes the first iteration of node of the children list
*/
void removeChild(SceneNode* node);
/**
* @brief addedToSceneTree is called when this node is added to a SceneTree
*
* @param tree
*/
void addedToSceneTree(SceneTree *tree);
protected:
std::vector<SceneNode*> m_children;
};
/**
* @brief The MeshNode class holds a mesh
*/
class MeshNode : public SceneNode
{
GeometryNode geometry;
public:
// temp
glm::mat4 m_movement;
glm::mat4 m_acceleration;
MeshNode(Mesh* mesh) : geometry(mesh, glm::mat4()) {}
virtual void update()
{
m_movement = m_acceleration * m_movement;
geometry.modelMatrix = m_movement * geometry.modelMatrix;
}
void setTransform(const glm::mat4 &transform) { geometry.modelMatrix = transform; }
const glm::mat4& getTransform() { return geometry.modelMatrix; }
GeometryNode* getGeometryNode() { return &geometry; }
};
/**
* @brief The CameraNode class is a scene node that can be used by the renderer
*/
class CameraNode : public TrackBallCamera, SceneNode
{
public:
CameraNode() {}
};
class SceneTree : public Scene
{
public:
SceneTree();
~SceneTree();
virtual SceneIterator<Light*>* getLights();
virtual SceneIterator<GeometryNode*>* getGeometry();
void update();
Texture* getSkybox() {return m_skybox;}
void setSkybox(Texture* skybox) {m_skybox = skybox;}
void setMainCamera(CameraNode *camera);
ContainerNode* getRootObject(){return &m_root;}
void addObject(ContainerNode *parent, SceneNode *node);
void addToIndex(SceneNode* node);
void removeObject(ContainerNode* parent,SceneNode *node);
void removeFromIndex(SceneNode *node);
private:
ContainerNode m_root;
std::vector<Light*> m_lights;
std::vector<GeometryNode*> m_geometries;
Texture* m_skybox;
};
// Additionnal Nodes :
#endif // SCENETREE_H

View File

@ -2,7 +2,9 @@
#include "message.h" #include "message.h"
#include "input.h" #include "input.h"
#include "scenetree.h" #include "scene/scenetree.h"
#include "scene/meshnode.h"
#include "scene/textnode.h"
#include "mesh.h" #include "mesh.h"
#include "phongmaterial.h" #include "phongmaterial.h"
#include "tools/utils.h" #include "tools/utils.h"
@ -42,31 +44,38 @@ void SparrowShell::out(std::string s)
} }
void SparrowShell::scrollUp(){ void SparrowShell::scrollUp(){
if (m_index + BUFFER_DISPLAYED_NUMBER < m_buffer.size()) m_index++; if (m_index + BUFFER_DISPLAYED_NUMBER < m_buffer.size()){
// std::cout << "scroll up" << std::endl; m_index++;
m_indexMoved = true;
}
} }
void SparrowShell::scrollDown(){ void SparrowShell::scrollDown(){
if (m_index > 0) m_index--; if (m_index > 0){
// std::cout << "scroll down" << std::endl; m_index--;
m_indexMoved = true;
}
} }
void SparrowShell::update() void SparrowShell::update()
{ {
//TODO : update TextMesh
Font *shellfont = RESOURCE_GET(Font,"shellfont"); Font *shellfont = RESOURCE_GET(Font,"shellfont");
MeshNode* mnode; TextNode* mnode;
glm::vec2 text_pos(0); glm::vec2 text_pos(0);
//std::vector<MeshNode*> textMeshes; //std::vector<MeshNode*> textMeshes;
for(auto textMesh: m_textMeshes) if(m_indexMoved){
removeChild(textMesh); for(auto textMesh: m_textMeshes)
m_textMeshes.clear(); m_currentScene->removeObject(this,textMesh);
for(unsigned int i = m_index;i<m_index+BUFFER_DISPLAYED_NUMBER;i++){ m_textMeshes.clear();
mnode = new MeshNode(shellfont->getTextMesh(m_buffer[i],glm::vec3(0.7,1,0.3))); for(unsigned int i = m_index;i<m_index+BUFFER_DISPLAYED_NUMBER;i++){
utils::setPosition2D(mnode,text_pos); mnode = shellfont->getTextNode(m_buffer[i],glm::vec3(0.7,1,0.3),12.f);
text_pos.y += shellfont->getLineHeight(); utils::setPosition2D((TextNode*)mnode,text_pos);
m_textMeshes.push_back(mnode); text_pos.y += shellfont->getLineHeight();
addChild(mnode); mnode->setDepth(SHELL_DEPTH+1);
m_textMeshes.push_back(mnode);
m_currentScene->addObject(this,mnode);
}
m_indexMoved = false;
} }
m_scrollbar.update(); m_scrollbar.update();
} }
@ -80,8 +89,6 @@ void SparrowShell::ShellBuffer::push(std::string s){
m_buffer.push_back(s); m_buffer.push_back(s);
} }
//SparrowShell::ScrollBar::ScrollBar();
SparrowShell::ScrollBar::ScrollBar(SparrowShell* shell):m_shell(shell){ SparrowShell::ScrollBar::ScrollBar(SparrowShell* shell):m_shell(shell){
m_position = glm::ivec2(m_shell->m_dimension.x - SparrowShell::SCROLLBAR_PIXEL_WIDTH,0); m_position = glm::ivec2(m_shell->m_dimension.x - SparrowShell::SCROLLBAR_PIXEL_WIDTH,0);
m_dimension = glm::ivec2(SparrowShell::SCROLLBAR_PIXEL_WIDTH,m_shell->m_dimension.y); m_dimension = glm::ivec2(SparrowShell::SCROLLBAR_PIXEL_WIDTH,m_shell->m_dimension.y);
@ -110,5 +117,6 @@ void SparrowShell::ScrollBar::update(){
utils::resize2D(m_mesh,m_dimension,new_dim); utils::resize2D(m_mesh,m_dimension,new_dim);
m_shell->m_resizeScrollBar = false; m_shell->m_resizeScrollBar = false;
} }
utils::setPosition2D(m_mesh,new_pos); if (m_shell->m_resizeScrollBar || m_shell->m_indexMoved)
utils::setPosition2D(m_mesh,new_pos);
} }

View File

@ -4,10 +4,11 @@
#include <list> #include <list>
#include "system.h" #include "system.h"
#include "scenetree.h" #include "scene/scenetree.h"
#include "glm/glm.hpp" #include "glm/glm.hpp"
class Input; class Input;
class MeshNode;
namespace sf { namespace sf {
class Window; class Window;
@ -16,9 +17,9 @@ class Window;
class SparrowShell : public ContainerNode class SparrowShell : public ContainerNode
{ {
private: private:
class BackGround : public MeshNode { //class BackGround : public MeshNode {
}; // };
class ScrollBar{ class ScrollBar{
SparrowShell* m_shell; SparrowShell* m_shell;
@ -52,13 +53,15 @@ private:
sf::Window* m_window; sf::Window* m_window;
Input* m_input; Input* m_input;
SceneTree* m_currentScene;
glm::ivec2 m_position; glm::ivec2 m_position;
glm::ivec2 m_dimension; glm::ivec2 m_dimension;
std::vector<MeshNode*> m_textMeshes; std::vector<MeshNode*> m_textMeshes;
ShellBuffer m_buffer; ShellBuffer m_buffer;
int m_index = 0; int m_index = 0;
bool m_resizeScrollBar = false; bool m_resizeScrollBar = false;
bool m_indexMoved = false;
//textMesh //textMesh
MeshNode* m_background; MeshNode* m_background;
ScrollBar m_scrollbar; ScrollBar m_scrollbar;
@ -67,6 +70,7 @@ public:
SparrowShell(sf::Window*, Input*); SparrowShell(sf::Window*, Input*);
void update(); void update();
void setScene(SceneTree *scene){m_currentScene = scene;}
void scrollUp(); void scrollUp();
void scrollDown(); void scrollDown();

View File

@ -6,9 +6,10 @@
#include <phongmaterial.h> #include <phongmaterial.h>
#include <resourcemanager.h> #include <resourcemanager.h>
#include <sparrowrenderer.h> #include <sparrowrenderer.h>
#include <scenetree.h>
#include <texture.h> #include <texture.h>
#include <scene/scenetree.h>
#include <tools/graph.h> #include <tools/graph.h>
#include <tools/pathfinder.h> #include <tools/pathfinder.h>
#include <tools/loader.h> #include <tools/loader.h>
@ -52,7 +53,7 @@ int main(){
Font* fonte_des_neiges = Loader::loadFont("../data/consolas.fnt","../data/consolas.png"); Font* fonte_des_neiges = Loader::loadFont("../data/consolas.fnt","../data/consolas.png");
RESOURCE_ADD(fonte_des_neiges,Font,"shellfont"); RESOURCE_ADD(fonte_des_neiges,Font,"shellfont");
MeshNode* mnode/* = new MeshNode(fonte_des_neiges->getTextMesh("Hello World!")); TextNode* tnode/* = new MeshNode(fonte_des_neiges->getTextMesh("Hello World!"));
scene.addObject(scene.getRootObject(),mnode)*/; scene.addObject(scene.getRootObject(),mnode)*/;
// mnode = new MeshNode(fonte_des_neiges->getTextMesh("Portez ce vieux whisky au juge blond qui fume.", glm::vec3(0.5, 0.7, 0.2))); // mnode = new MeshNode(fonte_des_neiges->getTextMesh("Portez ce vieux whisky au juge blond qui fume.", glm::vec3(0.5, 0.7, 0.2)));
@ -61,17 +62,17 @@ int main(){
// utils::rotate2D(mnode, glm::vec2(10,10),0.5); // utils::rotate2D(mnode, glm::vec2(10,10),0.5);
// scene.addObject(scene.getRootObject(),mnode); // scene.addObject(scene.getRootObject(),mnode);
mnode = new MeshNode(fonte_des_neiges->getTextMesh("Such Text", glm::vec3(0.7, 0.4, 0.2))); tnode = fonte_des_neiges->getTextNode("Such Text", glm::vec3(0.7, 0.4, 0.2));
utils::setPosition2D(mnode,glm::vec2(200, 170)); utils::setPosition2D((MeshNode*)tnode,glm::vec2(200, 170));
utils::rotate2D(mnode, glm::vec2(0),-0.5); utils::rotate2D((MeshNode*)tnode, glm::vec2(0),-0.5);
// mnode->setTransform(glm::rotate(glm::translate(glm::mat4(), glm::vec3(200, 170, 0)), -0.5f, glm::vec3(0, 0, 1))); // mnode->setTransform(glm::rotate(glm::translate(glm::mat4(), glm::vec3(200, 170, 0)), -0.5f, glm::vec3(0, 0, 1)));
scene.addObject(scene.getRootObject(),mnode); scene.addObject(scene.getRootObject(),(SceneNode*)tnode);
mnode = new MeshNode(fonte_des_neiges->getTextMesh("Such Text", glm::vec3(0.7, 0.4, 0.2))); //tnode = fonte_des_neiges->getTextNode("Such Text", glm::vec3(0.7, 0.4, 0.2));
mnode->setTransform(glm::rotate(glm::translate(glm::mat4(), glm::vec3(200, 170, 0)), -0.5f, glm::vec3(0, 0, 1))); //tnode->setTransform(glm::rotate(glm::translate(glm::mat4(), glm::vec3(200, 170, 0)), -0.5f, glm::vec3(0, 0, 1)));
scene.addObject(scene.getRootObject(),mnode); //scene.addObject(scene.getRootObject(),tnode);
// mnode = new MeshNode(fonte_des_neiges->getTextMesh("Very font", glm::vec3(0.7, 0.2, 0.8))); // mnode = new MeshNode(fonte_des_neiges->getTextMesh("Very font", glm::vec3(0.7, 0.2, 0.8)));

View File

@ -1,14 +1,16 @@
#include "font.h" #include "font.h"
#include <phongmaterial.h> #include <phongmaterial.h>
#include "mesh.h"
#include "scene/textnode.h"
Font::Font() Font::Font()
{ {
} }
Mesh* Font::getTextMesh(std::string s, glm::vec3 color) TextNode* Font::getTextNode(std::string s, glm::vec3 color, float font_size)
{ {
Mesh* text = new Mesh(); Mesh* textmesh = new Mesh();
glm::ivec2 current_pos; glm::ivec2 current_pos;
for(char c : s){ for(char c : s){
if(c == '\n') if(c == '\n')
@ -19,7 +21,7 @@ Mesh* Font::getTextMesh(std::string s, glm::vec3 color)
else else
{ {
CharInfo charInfo = m_charTable[c]; CharInfo charInfo = m_charTable[c];
text->addRectangle2D(current_pos + charInfo.offset, textmesh->addRectangle2D(current_pos + charInfo.offset,
charInfo.dim, charInfo.dim,
glm::vec2(charInfo.pos)/m_scale, glm::vec2(charInfo.pos)/m_scale,
glm::vec2(charInfo.dim)/m_scale); glm::vec2(charInfo.dim)/m_scale);
@ -30,7 +32,8 @@ Mesh* Font::getTextMesh(std::string s, glm::vec3 color)
// TODO : delete this material somewhere (garbage collector ?) // TODO : delete this material somewhere (garbage collector ?)
mat->setTexture(PhongMaterial::ALPHA_SLOT, m_tex, "font_texture"); mat->setTexture(PhongMaterial::ALPHA_SLOT, m_tex, "font_texture");
mat->diffuse = color; mat->diffuse = color;
text->setMaterial((Material*)mat); textmesh->setMaterial((Material*)mat);
text->initGL(); textmesh->initGL();
TextNode *text = new TextNode(textmesh,font_size);
return text; return text;
} }

View File

@ -3,9 +3,10 @@
#include <map> #include <map>
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include "mesh.h" #include <glm/vec3.hpp>
class Texture; class Texture;
class TextNode;
class Font class Font
{ {
@ -30,7 +31,7 @@ public:
void setScale(glm::vec2 scale){m_scale = scale;} void setScale(glm::vec2 scale){m_scale = scale;}
void setTexture(Texture *tex){m_tex = tex;} void setTexture(Texture *tex){m_tex = tex;}
Mesh* getTextMesh(std::string s, glm::vec3 color = glm::vec3(1)); TextNode* getTextNode(std::string s, glm::vec3 color = glm::vec3(1),float font_size = 0);
private: private:
std::string m_name; std::string m_name;
Texture *m_tex; Texture *m_tex;

View File

@ -1,5 +1,7 @@
#include "utils.h" #include "utils.h"
#include "scenetree.h" #include "glm/ext.hpp"
//#include "scene/scenetree.h"
#include "scene/meshnode.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;