#include <scene.h>
Public Types | |
| typedef std::vector< SceneNode * > | NodeList |
| typedef std::list< NODE_ID > | LightNodeIDList |
| typedef std::vector< Geometry * > | GeometryList |
| typedef std::vector< Material * > | MaterialList |
Public Member Functions | |
| WX_DECLARE_STRING_HASH_MAP (NODE_ID, NodeIDHashMap) | |
| WX_DECLARE_STRING_HASH_MAP (GEOMETRY_ID, GeometryIDHashMap) | |
| WX_DECLARE_STRING_HASH_MAP (MATERIAL_ID, MaterialIDHashMap) | |
| Scene (SCENE_ID id, EventHandler *_msgSink) | |
| Constructor. | |
| ~Scene () | |
| Destructor. | |
| SCENE_ID | GetID () const |
| Get scene ID. | |
| NODE_ID | GetRootID () const |
| Get scene graph root ID. | |
| const SceneNode * | GetNode (NODE_ID id) const |
| Get scene node with given ID. | |
| NODE_ID | GetNodeID (const wxString &uid) const |
| Find node by its unique uid and get its ID. | |
| size_t | GetNodeMaxID () const |
| Get maximum node ID + 1 in scene (number of nodes including previously removed nodes). | |
| void | GetNodeIDs (std::vector< NODE_ID > *nodes) const |
| BVH * | GetBVH () const |
| Get associated BVH. | |
| void | SetName (const wxString &name) |
| Set scene name. | |
| const wxString & | GetName () const |
| Get scene name. | |
| BVH * | UpdateBVH () |
| MATERIAL_ID | AddMaterial (Material *material) |
| Add material to materials list. | |
| bool | RemoveMaterial (MATERIAL_ID matID) |
| MATERIAL_ID | GetMaterialID (const wxString &name) const |
| Get material ID by its name. | |
| const Material * | GetMaterial (MATERIAL_ID mid) const |
| const MaterialList * | GetMaterials () const |
| Get all materials in scene. | |
| const Image * | GetImage (const wxString &texPath) const |
| Get shared texture from scene manager. | |
| GEOMETRY_ID | AddGeometry (Geometry *geometry) |
| bool | RemoveGeometry (GEOMETRY_ID geomID) |
| GEOMETRY_ID | GetGeometryID (const wxString &name) const |
| Get geometry ID by its name. | |
| const Geometry * | GetGeometry (GEOMETRY_ID gid) const |
| const GeometryList * | GetGeometries () const |
| Get all geometries in scene. | |
| const LightNodeIDList * | GetLightIDs () const |
| Get all lights in scene. | |
| NODE_ID | Insert (SceneNode *node, NODE_ID targetID) |
| NODE_ID | Copy (Scene *srcScene, NODE_ID srcID, NODE_ID targetID) |
| void | Move (NODE_ID srcID, NODE_ID targetID) |
| void | Remove (NODE_ID id) |
| Remove node and all subnodes from scene (removed nodes ARE deleted). | |
| void | SetUid (NODE_ID id, const wxString &uid) |
| Set new uid for node. | |
| void | SetName (NODE_ID id, const wxString &name) |
| Set new name for node. | |
| void | SetTransformation (NODE_ID id, const MATRIX &matrix) const |
| Set node's local transformation matrix. | |
| void | Transform (NODE_ID id, const MATRIX &matrix) const |
| void | UpdateTransformation (NODE_ID id) const |
| Update world transformation matrices of given node and its subnodes. | |
| void | TranslateAbs (NODE_ID id, const VECTOR3 &transl) const |
| Special translate (sets new position, use with caution). | |
| void | SetGeometry (NODE_ID id, GEOMETRY_ID geometryID) |
| Assign new geometry to geometry node, geometry must be added first. | |
| void | SetMaterial (NODE_ID id, MATERIAL_ID mid) const |
| void | SetLight (NODE_ID id, Light *light) const |
| Assign new light data to light node. | |
| void | SetInvalid (NODE_ID id) const |
| Set node as invalid. | |
| bool | WriteLock (NODE_ID id) |
| Write lock node - helper method for callers with const only access to node. | |
| bool | WriteUnlock (NODE_ID id) |
| Write unlock node - helper method for callers with const only access to node. | |
| void | SetProjectionParams (NODE_ID camID, unsigned width=0, unsigned height=0, float nearPlane=0.0f, float farPlane=0.0f, float fov=0.0f) const |
| void | Fit (NODE_ID camID, bool updateBVH=true, bool farNearOnly=false) |
| void | ResetView (NODE_ID camID, bool updateBVH=true) |
Private Member Functions | |
| SceneNode * | getNode (NODE_ID id) const |
| Get scene node with given ID. | |
| void | setNodeValid (SceneNode *node, bool _valid=true, bool markBVH=true) const |
Private Attributes | |
| SCENE_ID | sceneID |
| Scene ID. | |
| NodeList | sceneNodes |
| Scene nodes (ordered according to their IDs). | |
| NodeIDHashMap | sceneNodeIDMap |
| Hash map mapping node uid to its ID. | |
| NODE_ID | rootID |
| Scene graph root node ID. | |
| BVH * | bvh |
| BVH built from scene graph. | |
| MaterialIDHashMap | materialIDMap |
Hash map with Material IDs. | |
| MaterialList | materials |
| List of materials used in scene. | |
| GeometryIDHashMap | geometryIDMap |
Hash map with Geometry IDs. | |
| GeometryList | geometries |
| List of geometries used in scene. | |
| LightNodeIDList | lightNodeIDs |
| List of light nodes in scene. | |
| wxString | sceneName |
| Name - filename by default. | |
| SceneManager * | sceneManager |
| Pointer to scene manager instance. | |
| EventHandler * | msgSink |
| Pointer to kernel message sink - auxiliary to enable event posting when called directly from modules. | |
| std::deque< NODE_ID > | itemsPending |
| List of newly inserted nodes since last BVH update. | |
Friends | |
| class | SceneManager |
Definition at line 19 of file scene.h.
| typedef std::vector<SceneNode *> VRUT::Scene::NodeList |
| typedef std::list<NODE_ID> VRUT::Scene::LightNodeIDList |
| typedef std::vector<Geometry *> VRUT::Scene::GeometryList |
| typedef std::vector<Material *> VRUT::Scene::MaterialList |
| Scene::Scene | ( | SCENE_ID | id, | |
| EventHandler * | _msgSink | |||
| ) |
Constructor.
Definition at line 28 of file scene.cpp.
00029 : sceneID(id), 00030 sceneManager((SceneManager *)NULL), 00031 msgSink(_msgSink) 00032 { 00033 rootID = NODE_ID_NONE; 00034 bvh = (BVH *)NULL; 00035 }
| Scene::~Scene | ( | ) |
Destructor.
Definition at line 38 of file scene.cpp.
00039 { 00040 if (bvh) 00041 { 00042 bvh->Destroy(); 00043 delete bvh; 00044 } 00045 SAFE_DELETE_ARR_EACH(sceneNodes, sceneNodes.size()); 00046 SAFE_DELETE_ARR_EACH(geometries, geometries.size()); 00047 SAFE_DELETE_ARR_EACH(materials, materials.size()); 00048 }
| VRUT::Scene::WX_DECLARE_STRING_HASH_MAP | ( | NODE_ID | , | |
| NodeIDHashMap | ||||
| ) |
| VRUT::Scene::WX_DECLARE_STRING_HASH_MAP | ( | GEOMETRY_ID | , | |
| GeometryIDHashMap | ||||
| ) |
| VRUT::Scene::WX_DECLARE_STRING_HASH_MAP | ( | MATERIAL_ID | , | |
| MaterialIDHashMap | ||||
| ) |
Get scene node with given ID.
Definition at line 62 of file scene.h.
00063 { 00064 return ( id < sceneNodes.size() ? sceneNodes[id] : (SceneNode *)NULL ); 00065 }
| void Scene::setNodeValid | ( | SceneNode * | node, | |
| bool | _valid = true, |
|||
| bool | markBVH = true | |||
| ) | const [private] |
Set node validity
| [in] | node | Mark node valid/invalid, if invalid mark also all subnodes invalid |
| [in] | _valid | Valid boolean value |
| [in] | markBVH | If invalid mark also connected BVHNode and all its supernodes invalid |
Definition at line 61 of file scene.cpp.
00062 { 00063 if (!_valid) 00064 { 00065 for (SceneNode::NodeIDList::iterator it = node->children.begin(); 00066 it != node->children.end(); it++) 00067 setNodeValid(getNode(*it), false); 00068 if (markBVH && node->IsOfType(SceneNode::GEOMETRY) && bvh) 00069 bvh->SetInvalid(bvh->GetBVHNodeAssignedTo(node->GetID())); 00070 } 00071 node->valid = _valid; 00072 }
| SCENE_ID VRUT::Scene::GetID | ( | ) | const [inline] |
| NODE_ID VRUT::Scene::GetRootID | ( | ) | const [inline] |
| NODE_ID VRUT::Scene::GetNodeID | ( | const wxString & | uid | ) | const [inline] |
Find node by its unique uid and get its ID.
Definition at line 97 of file scene.h.
00098 { 00099 NodeIDHashMap::const_iterator it = sceneNodeIDMap.find(uid); 00100 return ( it == sceneNodeIDMap.end() ? NODE_ID_NONE : it->second ); 00101 }
| size_t VRUT::Scene::GetNodeMaxID | ( | ) | const [inline] |
Get maximum node ID + 1 in scene (number of nodes including previously removed nodes).
Definition at line 104 of file scene.h.
00105 { 00106 return sceneNodes.size(); 00107 }
| void Scene::GetNodeIDs | ( | std::vector< NODE_ID > * | nodes | ) | const |
Get list of all nodes in scene
| [out] | nodes | Will be filled with all (not NULL) nodes in scene |
Definition at line 51 of file scene.cpp.
00052 { 00053 for (NodeList::const_iterator it = sceneNodes.begin(); it != sceneNodes.end(); it++) 00054 { 00055 if (*it) 00056 nodes->push_back((*it)->GetID()); 00057 } 00058 }
| BVH* VRUT::Scene::GetBVH | ( | ) | const [inline] |
| void VRUT::Scene::SetName | ( | const wxString & | name | ) | [inline] |
| const wxString& VRUT::Scene::GetName | ( | ) | const [inline] |
| BVH * Scene::UpdateBVH | ( | ) |
Update associated BVH with newly inserted nodes since last update DO NOT call from module as newly created nodes would be on module's memory heap
Definition at line 75 of file scene.cpp.
00076 { 00077 if (!itemsPending.empty()) 00078 { 00079 BVH * newbvh = new BVH(this); 00080 newbvh->Build(&itemsPending); 00081 if (newbvh->IsBuilt()) 00082 { 00083 if (bvh) 00084 { 00085 //TODO: rebuild after X dirty inserts 00086 bvh->Insert(newbvh->root); 00087 delete newbvh; 00088 } 00089 else 00090 bvh = newbvh; 00091 } 00092 else 00093 delete newbvh; 00094 00095 itemsPending.clear(); 00096 } 00097 00098 return bvh; 00099 }
| MATERIAL_ID Scene::AddMaterial | ( | Material * | material | ) |
Add material to materials list.
Definition at line 102 of file scene.cpp.
00103 { 00104 if (!material) 00105 LOGERROR(wxT("<Scene>No material to add")); 00106 00107 bool replace = false; 00108 MaterialIDHashMap::iterator old = materialIDMap.find(material->name); 00109 if (old != materialIDMap.end()) 00110 { 00111 replace = true; 00112 LOGWARNING(wxT("<Scene>Material with name '") + material->name + wxT("' already exists, replacing with new one")); 00113 SAFE_DELETE(materials[old->second]); 00114 materials[old->second] = material; 00115 return old->second; 00116 } 00117 00118 MATERIAL_ID mid = MATERIAL_ID(materials.size()); 00119 materials.push_back(material); 00120 MaterialIDHashMap::Insert_Result res = materialIDMap.insert(MaterialIDHashMap::value_type(material->name, mid)); 00121 00122 if (msgSink) 00123 { 00124 if (replace) 00125 { 00126 for (NodeList::const_iterator it = sceneNodes.begin(); 00127 it != sceneNodes.end(); it++) 00128 { 00129 if (*it && (*it)->IsOfType(SceneNode::GEOMETRY) && ((const GeometryNode *)(*it))->GetMaterialID() == mid) 00130 { 00131 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_MATERIAL_CHANGED(sceneID, (*it)->GetID()); 00132 msgSink->PostEvent(ev); 00133 } 00134 } 00135 } 00136 wxCommandEvent ev = Event::GET_EVT_SCENE_MATERIAL_ADDED(sceneID, mid); 00137 msgSink->PostEvent(ev); 00138 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00139 msgSink->PostEvent(ev2); 00140 } 00141 #ifdef __WXDEBUG__ 00142 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00143 LOGDEBUG(wxString::Format(wxT("<Scene>Material '%s' ID '%i' added to scene '%i'"), material->name.c_str(), mid, sceneID)); 00144 #endif 00145 return mid; 00146 }
| bool Scene::RemoveMaterial | ( | MATERIAL_ID | matID | ) |
Remove material from material list and delete its instance, check if not in use first
| [in] | matID | ID of material to be removed |
false if material not found or is in use (referenced) by a node Definition at line 149 of file scene.cpp.
00150 { 00151 if (GetMaterial(matID)) 00152 { 00153 for (NodeList::const_iterator it = sceneNodes.begin(); 00154 it != sceneNodes.end(); it++) 00155 { 00156 if ((*it) && (*it)->IsOfType(SceneNode::GEOMETRY) 00157 && ((GeometryNode *)(*it))->GetMaterialID() == matID) 00158 return false; 00159 } 00160 materialIDMap.erase(materials[matID]->name); 00161 SAFE_DELETE(materials[matID]); 00162 return true; 00163 } 00164 00165 return false; 00166 }
| MATERIAL_ID VRUT::Scene::GetMaterialID | ( | const wxString & | name | ) | const [inline] |
Get material ID by its name.
Definition at line 144 of file scene.h.
00145 { 00146 MaterialIDHashMap::const_iterator it = materialIDMap.find(name); 00147 return ( it != materialIDMap.end() ? it->second : MATERIAL_ID_NONE ); 00148 }
| const Material* VRUT::Scene::GetMaterial | ( | MATERIAL_ID | mid | ) | const [inline] |
| const MaterialList* VRUT::Scene::GetMaterials | ( | ) | const [inline] |
| const Image * Scene::GetImage | ( | const wxString & | texPath | ) | const |
Get shared texture from scene manager.
Definition at line 169 of file scene.cpp.
00170 { 00171 if (sceneManager) 00172 return sceneManager->GetImage(texPath, false); 00173 else return (Image *)NULL; 00174 }
| GEOMETRY_ID Scene::AddGeometry | ( | Geometry * | geometry | ) |
Add geometry to geometry list
| [in] | geometry | Geometry data to be added |
Build local AABB for geometry
Definition at line 177 of file scene.cpp.
00178 { 00179 if (!geometry) 00180 LOGERROR(wxT("<Scene>No geometry to add")); 00181 00182 bool replace = false; 00183 GEOMETRY_ID geomID = GEOMETRY_ID_NONE; 00184 GeometryIDHashMap::iterator old = geometryIDMap.find(geometry->GetName()); 00185 if (old != geometryIDMap.end()) 00186 { 00187 replace = true; 00188 LOGWARNING(wxT("<Scene>Geometry with name '") + geometry->GetName() + wxT("' already exists, replacing with new one")); 00189 SAFE_DELETE(geometries[old->second]); 00190 geometries[old->second] = geometry; 00191 geomID = old->second; 00192 } 00193 else 00194 { 00195 geomID = GEOMETRY_ID(geometries.size()); 00196 geometries.push_back(geometry); 00197 GeometryIDHashMap::Insert_Result res = geometryIDMap.insert(GeometryIDHashMap::value_type(geometry->GetName(), geomID)); 00198 wxASSERT_MSG(res.second, wxT("<Scene>Failed to insert geometry ID to hash map")); 00199 } 00200 00202 geometry->BuildAABB(); 00203 00204 if (replace) 00205 { 00206 for (NodeList::const_iterator it = sceneNodes.begin(); 00207 it != sceneNodes.end(); it++) 00208 { 00209 if (*it && (*it)->IsOfType(SceneNode::GEOMETRY) && ((const GeometryNode *)(*it))->GetGeometryID() == geomID) 00210 { 00211 setNodeValid(*it, false); 00212 if (msgSink) 00213 { 00214 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_GEOMETRY_CHANGED(sceneID, (*it)->GetID()); 00215 msgSink->PostEvent(ev); 00216 } 00217 } 00218 } 00219 } 00220 wxCommandEvent ev = Event::GET_EVT_SCENE_GEOMETRY_ADDED(sceneID, geomID); 00221 msgSink->PostEvent(ev); 00222 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00223 msgSink->PostEvent(ev2); 00224 00225 #ifdef __WXDEBUG__ 00226 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00227 LOGDEBUG(wxString::Format(wxT("<Scene>Geometry '%s' ID '%i' added to scene '%i'"), geometry->GetName().c_str(), geomID, sceneID)); 00228 #endif 00229 return geomID; 00230 }
| bool Scene::RemoveGeometry | ( | GEOMETRY_ID | geomID | ) |
Remove geometry from geometry list and delete its instance, check if not in use first
| [in] | geomID | ID of geometry to be removed |
false if geometry not found or is in use (referenced) by a node Definition at line 233 of file scene.cpp.
00234 { 00235 if (GetGeometry(geomID)) 00236 { 00237 for (NodeList::const_iterator it = sceneNodes.begin(); 00238 it != sceneNodes.end(); it++) 00239 { 00240 if ((*it) && (*it)->IsOfType(SceneNode::GEOMETRY) 00241 && ((GeometryNode *)(*it))->GetGeometryID() == geomID) 00242 return false; 00243 } 00244 geometryIDMap.erase(geometries[geomID]->GetName()); 00245 SAFE_DELETE(geometries[geomID]); 00246 return true; 00247 } 00248 00249 return false; 00250 }
| GEOMETRY_ID VRUT::Scene::GetGeometryID | ( | const wxString & | name | ) | const [inline] |
Get geometry ID by its name.
Definition at line 177 of file scene.h.
00178 { 00179 GeometryIDHashMap::const_iterator it = geometryIDMap.find(name); 00180 return ( it != geometryIDMap.end() ? it->second : GEOMETRY_ID_NONE ); 00181 }
| const Geometry* VRUT::Scene::GetGeometry | ( | GEOMETRY_ID | gid | ) | const [inline] |
Get geometry
Definition at line 185 of file scene.h.
00186 { 00187 return (gid < geometries.size() ? geometries[gid] : (Geometry *)NULL ); 00188 }
| const GeometryList* VRUT::Scene::GetGeometries | ( | ) | const [inline] |
Get all geometries in scene.
Definition at line 191 of file scene.h.
00192 { 00193 return &geometries; 00194 }
| const LightNodeIDList* VRUT::Scene::GetLightIDs | ( | ) | const [inline] |
Get all lights in scene.
Definition at line 197 of file scene.h.
00198 { 00199 return &lightNodeIDs; 00200 }
Node operations ///Insert scene node, parent node takes ownership of node
| [in] | node | Node to be inserted (node's uid has to be unique in scene in order to succeed) |
| [in] | targetID | ID of parent of the new node (if not defined, inserted node will be root) |
Definition at line 360 of file scene.cpp.
00361 { 00362 SceneNode * parentNode = getNode(targetID); 00363 00364 wxASSERT_MSG( (node->parent == NODE_ID_NONE) && (node->GetID() == NODE_ID_NONE), 00365 wxT("<Scene>Inserting node that is probably already part of a scene")); 00366 00367 node->id = NODE_ID(sceneNodes.size()); 00368 if (!parentNode) 00369 { 00370 wxASSERT_MSG(targetID == NODE_ID_NONE, wxT("<Scene>Invalid target node ID when inserting")); 00371 rootID = node->id; 00372 } 00373 else 00374 parentNode->children.push_back(node->id); 00375 00376 node->parent = targetID; 00377 sceneNodes.push_back(node); 00378 setNodeValid(node, false); 00379 00380 wxASSERT_MSG(sceneNodeIDMap.find(node->uid) == sceneNodeIDMap.end(), wxString::Format(wxT("<Scene>Node with same uid '%s' already inserted"), node->uid.c_str())); 00381 NodeIDHashMap::Insert_Result res = sceneNodeIDMap.insert(NodeIDHashMap::value_type(node->uid, node->id)); 00382 wxASSERT_MSG( res.second, wxT("<Scene>Failed to insert node uid into hashmap") ); 00383 00384 if (node->IsOfType(SceneNode::GEOMETRY) && ((GeometryNode *)node)->GetGeometryID() != GEOMETRY_ID_NONE) 00385 itemsPending.push_back(node->id); 00386 00387 if (node->IsOfType(SceneNode::LIGHT)) 00388 lightNodeIDs.push_back(node->id); 00389 00390 if (msgSink) 00391 { 00392 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_INSERTED(sceneID, node->id, node->uid); 00393 msgSink->PostEvent(ev); 00394 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00395 msgSink->PostEvent(ev2); 00396 } 00397 #ifdef __WXDEBUG__ 00398 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00399 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' added to scene '%i'"), node->GetName().c_str(), node->GetID(), sceneID)); 00400 #endif 00401 return node->id; 00402 }
Copy part of srcScene and insert under parent node in this scene Uid of copied nodes are changed if same uid exists in target scene
| [in] | srcScene | Source scene (if not defined, this scene is used as source and target) |
| [in] | srcID | ID of subscene's root in srcScene (where to start copy from) (if not defined, root is used) |
| [in] | targetID | ID of this scene's parent where nodes will be inserted (if not defined, root is used) |
First is where to insert in this scene, second is node to insert from given scene
Make a copy of children list if it is modified during next steps
Get rid of connections to old scene
Check if uid unique before inserting
Check if material should be copied to a new scene
Check if name unique before inserting
Check if geometry should be copied to a new scene
Check if name unique before inserting
Definition at line 405 of file scene.cpp.
00406 { 00407 if (!srcScene) 00408 srcScene = this; 00409 if (srcID == NODE_ID_NONE) 00410 srcID = srcScene->GetRootID(); 00411 if (targetID == NODE_ID_NONE) 00412 targetID = GetRootID(); 00413 00415 std::deque<std::pair<NODE_ID, NODE_ID> > queue; 00416 std::pair<NODE_ID, NODE_ID> rootPair(targetID, srcID); 00417 queue.push_back(rootPair); 00418 00419 while (!queue.empty()) 00420 { 00421 std::pair<NODE_ID, NODE_ID> actPair = queue.front(); 00422 queue.pop_front(); 00423 const SceneNode * node = srcScene->GetNode(actPair.second); 00424 if (node) 00425 { 00427 SceneNode::NodeIDList childrenCpy(node->children); 00428 00429 SceneNode * cloneNode = node->Clone(); 00431 cloneNode->id = NODE_ID_NONE; 00432 cloneNode->parent = NODE_ID_NONE; 00433 cloneNode->children.clear(); 00434 00436 while (GetNodeID(cloneNode->GetUid()) != NODE_ID_NONE) 00437 cloneNode->uid.append(wxT("_")); 00438 00439 NODE_ID parID = Insert(cloneNode, actPair.first); 00440 00441 if (srcScene != this && cloneNode->IsOfType(SceneNode::GEOMETRY)) 00442 { 00443 GeometryNode * gcloneNode = (GeometryNode *)cloneNode; 00445 if (gcloneNode->GetMaterialID() != MATERIAL_ID_NONE) 00446 { 00447 const Material * mat = srcScene->GetMaterial(gcloneNode->GetMaterialID()); 00448 gcloneNode->materialID = MATERIAL_ID_NONE; 00449 if (mat) 00450 { 00451 Material * cloneMat = mat->Clone(); 00453 while (GetMaterialID(cloneMat->name) != MATERIAL_ID_NONE) 00454 cloneMat->name.append(wxT("_")); 00455 if (!mat->name.IsSameAs(cloneMat->name)) 00456 LOGVERBOSE(wxString::Format( 00457 wxT("<Scene>Material '%s' from scene ID %i is copied under new name '%s'"), 00458 mat->name.c_str(), srcScene->GetID(), cloneMat->name.c_str())); 00459 MATERIAL_ID matID = AddMaterial(cloneMat); 00460 SetMaterial(parID, matID); 00461 } 00462 else 00463 LOGERROR(wxString::Format(wxT("<Scene>Invalid material defined in node '%s' from scene ID %i"), node->GetName().c_str(), srcScene->GetID())); 00464 } 00465 00467 if (gcloneNode->GetGeometryID() != GEOMETRY_ID_NONE) 00468 { 00469 const Geometry * geom = srcScene->GetGeometry(gcloneNode->GetGeometryID()); 00470 gcloneNode->geometryID = GEOMETRY_ID_NONE; 00471 if (geom) 00472 { 00473 Geometry * cloneGeom = geom->Clone(); 00475 while (GetGeometryID(cloneGeom->GetName()) != GEOMETRY_ID_NONE) 00476 cloneGeom->name.append(wxT("_")); 00477 if (!geom->GetName().IsSameAs(cloneGeom->GetName())) 00478 LOGVERBOSE(wxString::Format( 00479 wxT("<Scene>Geometry '%s' from scene ID %i is copied under new name '%s'"), 00480 geom->GetName().c_str(), srcScene->GetID(), cloneGeom->GetName().c_str())); 00481 GEOMETRY_ID geomID = AddGeometry(cloneGeom); 00482 SetGeometry(parID, geomID); 00483 } 00484 else 00485 LOGERROR(wxString::Format(wxT("<Scene>Invalid geometry defined in node '%s' from scene ID %i"), node->GetName().c_str(), srcScene->GetID())); 00486 } 00487 } 00488 00489 for (SceneNode::NodeIDList::const_iterator childIt = childrenCpy.begin(); 00490 childIt != childrenCpy.end(); childIt++) 00491 { 00492 std::pair<NODE_ID, NODE_ID> childPair(parID, *childIt); 00493 queue.push_back(childPair); 00494 } 00495 } 00496 } 00497 const SceneNode * oldRoot = srcScene->GetNode(targetID); 00498 if (oldRoot) 00499 return GetNodeID(oldRoot->GetUid()); 00500 else 00501 return NODE_ID_NONE; 00502 }
Move part of scene to another place in the same scene
| [in] | srcID | ID of subscene's root (where to start move from) |
| [in] | targetID | ID of parent where nodes will be inserted (if not defined, root is used) |
First invalidate subtree
Disconnect from old parent
Connect to new parent
Definition at line 505 of file scene.cpp.
00506 { 00507 if (srcID == GetRootID()) 00508 { 00509 LOGERROR(wxT("<Scene>Source cannot be root when moving nodes")); 00510 return; 00511 } 00512 SceneNode * srcNode = getNode(srcID); 00513 SceneNode * tgtNode = getNode(targetID); 00514 if ( !srcNode || !tgtNode) 00515 { 00516 LOGERROR(wxT("<Scene>Source or target not defined properly when moving nodes")); 00517 return; 00518 } 00519 wxASSERT_MSG( srcNode->parent != NODE_ID_NONE, 00520 wxT("<Scene>Source node must have parents when moving")); 00522 setNodeValid(srcNode, false); 00524 SceneNode * parNode = getNode(srcNode->parent); 00525 parNode->children.remove(srcID); 00527 srcNode->parent = targetID; 00528 tgtNode->children.push_back(srcID); 00529 //TODO: rebuild BVH that are dependent on scene hierarchy 00530 if (msgSink) 00531 { 00532 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_MOVED(sceneID, srcID); 00533 msgSink->PostEvent(ev); 00534 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00535 msgSink->PostEvent(ev2); 00536 } 00537 }
| void Scene::Remove | ( | NODE_ID | id | ) |
Remove node and all subnodes from scene (removed nodes ARE deleted).
Definition at line 540 of file scene.cpp.
00541 { 00542 SceneNode * node = getNode(id); 00543 if (node && node->type!=SceneNode::ROOT) 00544 { 00545 while (node->children.begin() != node->children.end()) 00546 Remove(*node->children.begin()); 00547 00548 SceneNode * parNode = getNode(node->parent); 00549 if (parNode) 00550 parNode->children.remove(id); 00551 node->parent = NODE_ID_NONE; 00552 if (node->IsOfType(SceneNode::GEOMETRY) && bvh) 00553 { 00554 BVHNode * bvhNode = bvh->Remove(bvh->GetBVHNodeAssignedTo(node->GetID())); 00555 SAFE_DELETE(bvhNode); 00556 } 00557 00558 setNodeValid(node, false); 00559 node->id = NODE_ID_NONE; 00560 //TODO: remove unreferenced material, geometry if any 00561 if (node->IsOfType(SceneNode::LIGHT)) 00562 lightNodeIDs.remove(id); 00563 00564 NodeIDHashMap::iterator itmap = sceneNodeIDMap.find(node->uid); 00565 wxASSERT_MSG(itmap != sceneNodeIDMap.end(), wxT("<Scene>Removing node that is not in ID map")); 00566 sceneNodeIDMap.erase(itmap); 00567 00568 for (std::deque<NODE_ID>::iterator it = itemsPending.begin(); 00569 it != itemsPending.end(); ) 00570 { 00571 if (*it == id) 00572 it = itemsPending.erase(it); 00573 else 00574 it++; 00575 } 00576 00577 wxString nodeName = node->GetName(); 00578 SAFE_DELETE(sceneNodes[id]); 00579 00580 if (msgSink) 00581 { 00582 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_REMOVED(sceneID, id); 00583 msgSink->PostEvent(ev); 00584 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00585 msgSink->PostEvent(ev2); 00586 } 00587 #ifdef __WXDEBUG__ 00588 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00589 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' removed from scene '%i'"), nodeName.c_str(), id, sceneID)); 00590 #endif 00591 } 00592 else 00593 LOGERROR(wxString::Format(wxT("<Scene>Cannot remove node with ID %i, node not found in scene or ROOT node"), id)); 00594 }
| void Scene::SetUid | ( | NODE_ID | id, | |
| const wxString & | uid | |||
| ) |
Set new uid for node.
Definition at line 597 of file scene.cpp.
00598 { 00599 SceneNode * node = getNode(id); 00600 if (node && node->uid != uid) 00601 { 00602 wxString oldUid = node->uid; 00603 NodeIDHashMap::iterator itmap = sceneNodeIDMap.find(oldUid); 00604 wxASSERT_MSG(itmap != sceneNodeIDMap.end(), wxT("<Scene>Changing of uid of node that is not in ID map")); 00605 if (sceneNodeIDMap.find(uid) != sceneNodeIDMap.end()) 00606 LOGERROR(wxString::Format(wxT("<Scene>Node with same uid '%s' already inserted"), uid.c_str())); 00607 else 00608 { 00609 sceneNodeIDMap.erase(itmap); 00610 NodeIDHashMap::Insert_Result res = sceneNodeIDMap.insert(NodeIDHashMap::value_type(uid, node->id)); 00611 wxASSERT_MSG( res.second, wxT("<Scene>Failed to insert node uid into hashmap") ); 00612 } 00613 node->uid = CloneWxString(uid); 00614 00615 if (msgSink) 00616 { 00617 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_UID_CHANGED(sceneID, id); 00618 msgSink->PostEvent(ev); 00619 } 00620 #ifdef __WXDEBUG__ 00621 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00622 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' uid changed to '%s' in scene '%i'"), oldUid.c_str(), id, node->uid.c_str(), sceneID)); 00623 #endif 00624 } 00625 else 00626 LOGERROR(wxString::Format(wxT("<Scene>Cannot change uid of node with ID %i, node not found in scene"), id)); 00627 }
| void Scene::SetName | ( | NODE_ID | id, | |
| const wxString & | name | |||
| ) |
Set new name for node.
Definition at line 629 of file scene.cpp.
00630 { 00631 SceneNode * node = getNode(id); 00632 if (node && node->name != name) 00633 { 00634 wxString oldName = node->name; 00635 node->name = CloneWxString(name); 00636 if (msgSink) 00637 { 00638 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_NAME_CHANGED(sceneID, id); 00639 msgSink->PostEvent(ev); 00640 } 00641 #ifdef __WXDEBUG__ 00642 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00643 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' renamed to '%s' in scene '%i'"), oldName.c_str(), id, node->name.c_str(), sceneID)); 00644 #endif 00645 } 00646 else 00647 LOGERROR(wxString::Format(wxT("<Scene>Cannot rename node with ID %i, node not found in scene"), id)); 00648 }
Set node's local transformation matrix.
Definition at line 650 of file scene.cpp.
00651 { 00652 SceneNode * node = getNode(id); 00653 if (node) 00654 { 00655 node->localTransMatrix = matrix; 00656 setNodeValid(node, false); 00657 00658 if (msgSink) 00659 { 00660 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_TRANSFORMED(sceneID, id); 00661 msgSink->PostEvent(ev); 00662 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00663 msgSink->PostEvent(ev2); 00664 } 00665 } 00666 else 00667 LOGERROR(wxString::Format(wxT("<Scene>Cannot transform node with ID %i, node not found in scene"), id)); 00668 }
Multiply node's local transformation matrix TODO: check multiply order
Definition at line 671 of file scene.cpp.
00672 { 00673 SceneNode * node = getNode(id); 00674 if (node) 00675 { 00676 node->localTransMatrix *= matrix; 00677 setNodeValid(node, false); 00678 00679 if (msgSink) 00680 { 00681 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_TRANSFORMED(sceneID, id); 00682 msgSink->PostEvent(ev); 00683 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00684 msgSink->PostEvent(ev2); 00685 } 00686 } 00687 else 00688 LOGERROR(wxString::Format(wxT("<Scene>Cannot transform node with ID %i, node not found in scene"), id)); 00689 }
| void Scene::UpdateTransformation | ( | NODE_ID | id | ) | const |
Update world transformation matrices of given node and its subnodes.
Has to be valid for Camera update, should be locked by caller so it is safe
Definition at line 692 of file scene.cpp.
00693 { 00694 SceneNode * node = getNode(id); 00695 if (!node) 00696 { 00697 LOGERROR(wxString::Format(wxT("<Scene>Cannot transform node with ID %i, node not found in scene"), id)); 00698 return; 00699 } 00700 00701 if (!node->IsValid()) 00702 { 00703 SceneNode * parent = getNode(node->parent); 00704 MATRIX parMat; 00705 if (parent) 00706 { 00707 UpdateTransformation(node->parent); 00708 parMat = *parent->GetWorldTransMatrix(); 00709 } 00710 node->worldTransMatrix = node->localTransMatrix * parMat; 00711 00713 setNodeValid(node, true); 00714 00715 if (node->IsOfType(SceneNode::CAMERA)) 00716 { 00717 Camera * cam = (Camera *)node; 00718 cam->updateProjection(); 00719 cam->extractFrustum(); 00720 } 00721 } 00722 }
Special translate (sets new position, use with caution).
Definition at line 725 of file scene.cpp.
00726 { 00727 SceneNode * node = getNode(id); 00728 if (node) 00729 { 00730 node->localTransMatrix._m41 = transl.x; 00731 node->localTransMatrix._m42 = transl.y; 00732 node->localTransMatrix._m43 = transl.z; 00733 setNodeValid(node, false); 00734 00735 if (msgSink) 00736 { 00737 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_TRANSFORMED(sceneID, id); 00738 msgSink->PostEvent(ev); 00739 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00740 msgSink->PostEvent(ev2); 00741 } 00742 } 00743 else 00744 LOGERROR(wxString::Format(wxT("<Scene>Cannot transform node with ID %i, node not found in scene"), id)); 00745 }
| void Scene::SetGeometry | ( | NODE_ID | id, | |
| GEOMETRY_ID | geometryID | |||
| ) |
Assign new geometry to geometry node, geometry must be added first.
Definition at line 748 of file scene.cpp.
00749 { 00750 SceneNode * snode = getNode(id); 00751 GeometryNode * node = ( snode && snode->IsOfType(SceneNode::GEOMETRY) ? (GeometryNode *)snode : (GeometryNode *)NULL ); 00752 if (node) 00753 { 00754 node->geometryID = geometryID; 00755 if (geometryID != GEOMETRY_ID_NONE && (!bvh || !bvh->GetBVHNodeAssignedTo(node->GetID()))) 00756 itemsPending.push_back(id); 00757 00758 setNodeValid(node, false); 00759 00760 if (msgSink) 00761 { 00762 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_GEOMETRY_CHANGED(sceneID, id); 00763 msgSink->PostEvent(ev); 00764 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00765 msgSink->PostEvent(ev2); 00766 } 00767 #ifdef __WXDEBUG__ 00768 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00769 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' has new geometry '%s' ID '%i' in scene '%i'"), 00770 node->GetName().c_str(), node->GetID(), ( GetGeometry(geometryID) ? GetGeometry(geometryID)->GetName().c_str() : wxT("NULL") ), 00771 geometryID, sceneID)); 00772 #endif 00773 } 00774 else 00775 LOGERROR(wxString::Format(wxT("<Scene>Cannot set geometry to node with ID %i, node not found in scene"), id)); 00776 }
| void Scene::SetMaterial | ( | NODE_ID | id, | |
| MATERIAL_ID | mid | |||
| ) | const |
Assign new material to geometry node, material must be added first
| [in] | id | ID if the Node to set material to |
| [in] | mid | Material ID |
Definition at line 779 of file scene.cpp.
00780 { 00781 SceneNode * snode = getNode(id); 00782 GeometryNode * node = ( snode && snode->IsOfType(SceneNode::GEOMETRY) ? (GeometryNode *)snode : (GeometryNode *)NULL ); 00783 if (node) 00784 { 00785 node->materialID = mid; 00786 00787 if (msgSink) 00788 { 00789 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_MATERIAL_CHANGED(sceneID, id); 00790 msgSink->PostEvent(ev); 00791 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00792 msgSink->PostEvent(ev2); 00793 } 00794 #ifdef __WXDEBUG__ 00795 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00796 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' has new material '%s' ID '%i' in scene '%i'"), 00797 node->GetName().c_str(), node->GetID(), ( GetMaterial(mid) ? GetMaterial(mid)->name.c_str() : wxT("NULL") ), 00798 mid, sceneID)); 00799 #endif 00800 } 00801 else 00802 LOGERROR(wxString::Format(wxT("<Scene>Cannot set material to node with ID %i, node not found in scene"), id)); 00803 }
Assign new light data to light node.
Definition at line 806 of file scene.cpp.
00807 { 00808 SceneNode * snode = getNode(id); 00809 if (snode && snode->IsOfType(SceneNode::LIGHT)) 00810 { 00811 ((LightNode *)snode)->light = light; 00812 00813 if (msgSink) 00814 { 00815 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_LIGHT_CHANGED(sceneID, id); 00816 msgSink->PostEvent(ev); 00817 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00818 msgSink->PostEvent(ev2); 00819 } 00820 #ifdef __WXDEBUG__ 00821 if (wxLog::GetLogLevel() >= wxLOG_Debug) 00822 LOGDEBUG(wxString::Format(wxT("<Scene>Node '%s' ID '%i' has new light in scene '%i'"), 00823 snode->GetName().c_str(), id, sceneID)); 00824 #endif 00825 } 00826 else 00827 LOGERROR(wxString::Format(wxT("<Scene>Cannot set light to node with ID %i, node not found in scene or is not of light type"), id)); 00828 }
| void VRUT::Scene::SetInvalid | ( | NODE_ID | id | ) | const [inline] |
Set node as invalid.
Definition at line 270 of file scene.h.
00271 { 00272 setNodeValid(getNode(id), false); 00273 }
| bool VRUT::Scene::WriteLock | ( | NODE_ID | id | ) | [inline] |
| bool VRUT::Scene::WriteUnlock | ( | NODE_ID | id | ) | [inline] |
| void Scene::SetProjectionParams | ( | NODE_ID | camID, | |
| unsigned | width = 0, |
|||
| unsigned | height = 0, |
|||
| float | nearPlane = 0.0f, |
|||
| float | farPlane = 0.0f, |
|||
| float | fov = 0.0f | |||
| ) | const |
Camera operations ///Set camera parameters for projection matrix When parameter is 0 no change is actually made to it
Camera operations ///
Definition at line 836 of file scene.cpp.
00842 { 00843 SceneNode * node = getNode(camID); 00844 if (!node || !node->IsOfType(SceneNode::CAMERA)) 00845 return; 00846 Camera * cam = (Camera *)node; 00847 00848 bool changed = false; 00849 if (width && cam->lastWidth != width) 00850 { 00851 changed = true; 00852 cam->lastWidth = width; 00853 } 00854 if (height && cam->lastHeight != height) 00855 { 00856 changed = true; 00857 cam->lastHeight = height; 00858 } 00859 if (nearPlane && cam->nearPlane != nearPlane) 00860 { 00861 changed = true; 00862 cam->nearPlane = nearPlane; 00863 } 00864 if (farPlane && cam->farPlane != farPlane) 00865 { 00866 changed = true; 00867 cam->farPlane = farPlane; 00868 } 00869 if (fov && cam->fov != fov) 00870 { 00871 changed = true; 00872 cam->fov = fov; 00873 } 00874 00875 if (changed) 00876 { 00877 setNodeValid(cam, false); 00878 00879 if (msgSink) 00880 { 00881 wxCommandEvent ev = Event::GET_EVT_SCENE_CAM_PROJECTION_CHANGED(sceneID, camID); 00882 msgSink->PostEvent(ev); 00883 wxCommandEvent ev2 = Event::GET_EVT_RENDER_UPDATE(sceneID); 00884 msgSink->PostEvent(ev2); 00885 } 00886 } 00887 }
| void Scene::Fit | ( | NODE_ID | camID, | |
| bool | updateBVH = true, |
|||
| bool | farNearOnly = false | |||
| ) |
Move camera to fit whole scene into view frustum (move only, no rotation)
| [in] | camID | ID of camera to be fit |
| [in] | updateBVH | If true BVH is updated with new nodes if any, modules should use false |
| [in] | farNearOnly | Do not modify camera transformation, just update near and far plane to fit scene |
Definition at line 890 of file scene.cpp.
00891 { 00892 SceneNode * node = getNode(camID); 00893 if (!node || !node->IsOfType(SceneNode::CAMERA)) 00894 { 00895 LOGERROR(wxString::Format(wxT("<Scene>Cannot transform camera node with ID %i, node not found in scene"), sceneID)); 00896 return; 00897 } 00898 Camera * cam = (Camera *)node; 00899 00900 if (updateBVH) 00901 UpdateBVH(); 00902 BVH * bvh = GetBVH(); 00903 if (!bvh || !bvh->GetRoot()) 00904 return; 00905 00906 bvh->UpdateBV(); 00907 const BSphere * bsphere = bvh->GetRoot()->GetBSphere(); 00908 float farPlane = (cam->GetWorldTransMatrix()->ExtractTranslation() - bsphere->Center).Length() + bsphere->Radius * 2; 00909 SetProjectionParams(camID, 0, 0, 0, farPlane); 00910 if (!farNearOnly) 00911 { 00912 UpdateTransformation(camID); 00913 VECTOR3 viewDir = cam->GetView().Normalize(); 00914 TranslateAbs(camID, bsphere->Center - viewDir * (bsphere->Radius * 2)); 00915 UpdateTransformation(camID); 00916 cam->centerDist = (cam->GetWorldTransMatrix()->ExtractTranslation() - bsphere->Center).Length(); 00917 UpdateTransformation(camID); 00918 } 00919 }
| void Scene::ResetView | ( | NODE_ID | camID, | |
| bool | updateBVH = true | |||
| ) |
Reset view - like Fit but resets also view direction
| [in] | camID | ID of camera to be reset |
| [in] | updateBVH | If true BVH is updated with new nodes if any, modules should use false |
Definition at line 922 of file scene.cpp.
00923 { 00924 SceneNode * node = getNode(camID); 00925 if (!node || !node->IsOfType(SceneNode::CAMERA)) 00926 { 00927 LOGERROR(wxString::Format(wxT("<Scene>Cannot set parameters to camera node with ID %i, node not found in scene"), sceneID)); 00928 return; 00929 } 00930 Camera * cam = (Camera *)node; 00931 00932 MATRIX mat; 00933 mat.Translate(VECTOR3(0,0,30)); 00934 cam->centerDist = 30.0f; 00935 SetTransformation(camID, mat); 00936 Fit(camID); 00937 }
friend class SceneManager [friend] |
SCENE_ID VRUT::Scene::sceneID [private] |
NodeList VRUT::Scene::sceneNodes [private] |
NodeIDHashMap VRUT::Scene::sceneNodeIDMap [private] |
NODE_ID VRUT::Scene::rootID [private] |
BVH* VRUT::Scene::bvh [private] |
MaterialIDHashMap VRUT::Scene::materialIDMap [private] |
MaterialList VRUT::Scene::materials [private] |
GeometryIDHashMap VRUT::Scene::geometryIDMap [private] |
GeometryList VRUT::Scene::geometries [private] |
LightNodeIDList VRUT::Scene::lightNodeIDs [private] |
wxString VRUT::Scene::sceneName [private] |
SceneManager* VRUT::Scene::sceneManager [private] |
EventHandler* VRUT::Scene::msgSink [private] |
std::deque<NODE_ID> VRUT::Scene::itemsPending [private] |
1.5.5