5 static void destroy_node_tree(SceneNode *n);
7 Scene::Scene(TextureSet *tset)
17 texset = new TextureSet;
29 destroy_node_tree(nodes);
32 for(int i=0; i<(int)meshes.size(); i++) {
40 for(int i=0; i<(int)objects.size(); i++) {
51 static void destroy_node_tree(SceneNode *n)
55 int nsub = n->get_num_children();
56 for(int i=0; i<nsub; i++) {
57 destroy_node_tree(n->get_child(i));
62 // Scene::load defined in sceneload.cc
64 void Scene::add_object(Object *obj)
66 objects.push_back(obj);
69 bool Scene::remove_object(Object *obj)
71 std::vector<Object*>::iterator it = std::find(objects.begin(), objects.end(), obj);
72 if(it != objects.end()) {
79 bool Scene::have_object(Object *obj) const
81 return std::find(objects.begin(), objects.end(), obj) != objects.end();
84 void Scene::add_mesh(Mesh *m)
89 bool Scene::remove_mesh(Mesh *m)
91 std::vector<Mesh*>::iterator it = std::find(meshes.begin(), meshes.end(), m);
92 if(it != meshes.end()) {
99 bool Scene::have_mesh(Mesh *m) const
101 return std::find(meshes.begin(), meshes.end(), m) != meshes.end();
104 void Scene::add_node(SceneNode *n)
106 // we always want to have a dedicated root node
108 nodes = new SceneNode;
110 nodes->set_name("root");
116 bool Scene::remove_node(SceneNode *n)
119 if(!n || !(par = n->get_parent())) {
123 int nsub = n->get_num_children();
124 for(int i=0; i<nsub; i++) {
125 SceneNode *c = n->get_child(i);
130 return par->remove_child(n);
133 bool Scene::have_node(SceneNode *n) const
135 return n->scene == this;
138 static void find_nodes_rec(std::list<SceneNode*> *res, SceneNode *tree, const std::regex &re)
140 if(std::regex_match(tree->get_name(), re)) {
141 res->push_back(tree);
144 int num = tree->get_num_children();
145 for(int i=0; i<num; i++) {
146 find_nodes_rec(res, tree->get_child(i), re);
150 Scene *Scene::extract_nodes(const char *qstr)
154 std::list<SceneNode*> nodelist;
155 find_nodes_rec(&nodelist, nodes, re);
156 if(nodelist.empty()) {
160 Scene *res = new Scene(texset);
162 for(SceneNode *n : nodelist) {
164 int nobj = n->get_num_objects();
165 for(int i=0; i<nobj; i++) {
166 Object *obj = n->get_object(i);
167 if(obj->get_type() == OBJ_MESH) {
168 // XXX this assumes that meshes aren't shared between objects.
169 // maybe we'll have to refcount them at some point, and copy if nref>1
170 ObjMesh *om = (ObjMesh*)obj;
171 remove_mesh(om->mesh);
172 res->add_mesh(om->mesh);
176 res->add_object(obj);
185 void Scene::apply_xform()
187 nodes->apply_xform();
190 void Scene::update(float dt)
196 int nobj = objects.size();
197 for(int i=0; i<nobj; i++) {
198 if(!objects[i]->node) {
199 // only update objects which don't belong to a scenegraph node
200 // to avoid updating objects twice
201 objects[i]->update(dt);
206 void Scene::draw() const
208 if(!objects.empty()) {
209 int nobj = objects.size();
210 for(int i=0; i<nobj; i++) {
214 int nmesh = meshes.size();
215 for(int i=0; i<nmesh; i++) {