X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fscene.cc;h=0d23930839bdba9b3e91604a526436cc43aee183;hp=8132fe9b7d79735a43bf137caa8f09762df9c740;hb=dbcb9345c23c5c027d808915962843e7db2d14aa;hpb=72b941af07bbf2673539ad4eea073e68d3bcbbfc diff --git a/src/scene.cc b/src/scene.cc index 8132fe9..0d23930 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -1,4 +1,6 @@ +#include #include "scene.h" +#include "objmesh.h" static void destroy_node_tree(SceneNode *n); @@ -6,6 +8,8 @@ Scene::Scene(TextureSet *tset) { nodes = 0; + walk_mesh = 0; + if(tset) { texset = tset; own_texset = false; @@ -25,14 +29,164 @@ void Scene::destroy() destroy_node_tree(nodes); nodes = 0; + for(int i=0; i<(int)meshes.size(); i++) { + delete meshes[i]; + } + meshes.clear(); + + delete walk_mesh; + walk_mesh = 0; + + for(int i=0; i<(int)objects.size(); i++) { + delete objects[i]; + } + objects.clear(); + if(own_texset) { delete texset; } texset = 0; } +static void destroy_node_tree(SceneNode *n) +{ + if(!n) return; + + int nsub = n->get_num_children(); + for(int i=0; iget_child(i)); + } + delete n; +} + // Scene::load defined in sceneload.cc +void Scene::add_object(Object *obj) +{ + objects.push_back(obj); +} + +bool Scene::remove_object(Object *obj) +{ + std::vector::iterator it = std::find(objects.begin(), objects.end(), obj); + if(it != objects.end()) { + objects.erase(it); + return true; + } + return false; +} + +bool Scene::have_object(Object *obj) const +{ + return std::find(objects.begin(), objects.end(), obj) != objects.end(); +} + +void Scene::add_mesh(Mesh *m) +{ + meshes.push_back(m); +} + +bool Scene::remove_mesh(Mesh *m) +{ + std::vector::iterator it = std::find(meshes.begin(), meshes.end(), m); + if(it != meshes.end()) { + meshes.erase(it); + return true; + } + return false; +} + +bool Scene::have_mesh(Mesh *m) const +{ + return std::find(meshes.begin(), meshes.end(), m) != meshes.end(); +} + +void Scene::add_node(SceneNode *n) +{ + // we always want to have a dedicated root node + if(!nodes) { + nodes = new SceneNode; + nodes->scene = this; + nodes->set_name("root"); + } + + nodes->add_child(n); +} + +bool Scene::remove_node(SceneNode *n) +{ + SceneNode *par; + if(!n || !(par = n->get_parent())) { + return false; + } + + int nsub = n->get_num_children(); + for(int i=0; iget_child(i); + n->remove_child(c); + par->add_child(c); + } + + return par->remove_child(n); +} + +bool Scene::have_node(SceneNode *n) const +{ + return n->scene == this; +} + +static void find_nodes_rec(std::list *res, SceneNode *tree, const std::regex &re) +{ + if(std::regex_match(tree->get_name(), re)) { + res->push_back(tree); + } + + int num = tree->get_num_children(); + for(int i=0; iget_child(i), re); + } +} + +Scene *Scene::extract_nodes(const char *qstr) +{ + std::regex re{qstr}; + + std::list nodelist; + find_nodes_rec(&nodelist, nodes, re); + if(nodelist.empty()) { + return 0; + } + + Scene *res = new Scene(texset); + + for(SceneNode *n : nodelist) { + + int nobj = n->get_num_objects(); + for(int i=0; iget_object(i); + if(obj->get_type() == OBJ_MESH) { + // XXX this assumes that meshes aren't shared between objects. + // maybe we'll have to refcount them at some point, and copy if nref>1 + ObjMesh *om = (ObjMesh*)obj; + remove_mesh(om->mesh); + res->add_mesh(om->mesh); + } + + remove_object(obj); + res->add_object(obj); + } + + remove_node(n); + res->add_node(n); + } + return res; +} + +void Scene::apply_xform() +{ + nodes->apply_xform(); +} + void Scene::update(float dt) { if(nodes) { @@ -63,14 +217,3 @@ void Scene::draw() const } } } - -static void destroy_node_tree(SceneNode *n) -{ - if(!n) return; - - int nsub = n->get_num_children(); - for(int i=0; iget_child(i)); - } - delete n; -}