diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/COctreeSceneNode.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/COctreeSceneNode.cpp | 1272 |
1 files changed, 636 insertions, 636 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/COctreeSceneNode.cpp b/libraries/irrlicht-1.8/source/Irrlicht/COctreeSceneNode.cpp index 226f6f6..bcddeaf 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/COctreeSceneNode.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/COctreeSceneNode.cpp | |||
@@ -1,636 +1,636 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #include "COctreeSceneNode.h" | 5 | #include "COctreeSceneNode.h" |
6 | #include "Octree.h" | 6 | #include "Octree.h" |
7 | #include "ISceneManager.h" | 7 | #include "ISceneManager.h" |
8 | #include "IVideoDriver.h" | 8 | #include "IVideoDriver.h" |
9 | #include "ICameraSceneNode.h" | 9 | #include "ICameraSceneNode.h" |
10 | #include "IMeshCache.h" | 10 | #include "IMeshCache.h" |
11 | #include "IAnimatedMesh.h" | 11 | #include "IAnimatedMesh.h" |
12 | #include "IMaterialRenderer.h" | 12 | #include "IMaterialRenderer.h" |
13 | #include "os.h" | 13 | #include "os.h" |
14 | #include "CShadowVolumeSceneNode.h" | 14 | #include "CShadowVolumeSceneNode.h" |
15 | 15 | ||
16 | namespace irr | 16 | namespace irr |
17 | { | 17 | { |
18 | namespace scene | 18 | namespace scene |
19 | { | 19 | { |
20 | 20 | ||
21 | 21 | ||
22 | //! constructor | 22 | //! constructor |
23 | COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr, | 23 | COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr, |
24 | s32 id, s32 minimalPolysPerNode) | 24 | s32 id, s32 minimalPolysPerNode) |
25 | : IMeshSceneNode(parent, mgr, id), StdOctree(0), LightMapOctree(0), | 25 | : IMeshSceneNode(parent, mgr, id), StdOctree(0), LightMapOctree(0), |
26 | TangentsOctree(0), VertexType((video::E_VERTEX_TYPE)-1), | 26 | TangentsOctree(0), VertexType((video::E_VERTEX_TYPE)-1), |
27 | MinimalPolysPerNode(minimalPolysPerNode), Mesh(0), Shadow(0), | 27 | MinimalPolysPerNode(minimalPolysPerNode), Mesh(0), Shadow(0), |
28 | UseVBOs(OCTREE_USE_HARDWARE), UseVisibilityAndVBOs(OCTREE_USE_VISIBILITY), | 28 | UseVBOs(OCTREE_USE_HARDWARE), UseVisibilityAndVBOs(OCTREE_USE_VISIBILITY), |
29 | BoxBased(OCTREE_BOX_BASED) | 29 | BoxBased(OCTREE_BOX_BASED) |
30 | { | 30 | { |
31 | #ifdef _DEBUG | 31 | #ifdef _DEBUG |
32 | setDebugName("COctreeSceneNode"); | 32 | setDebugName("COctreeSceneNode"); |
33 | #endif | 33 | #endif |
34 | } | 34 | } |
35 | 35 | ||
36 | 36 | ||
37 | //! destructor | 37 | //! destructor |
38 | COctreeSceneNode::~COctreeSceneNode() | 38 | COctreeSceneNode::~COctreeSceneNode() |
39 | { | 39 | { |
40 | if (Shadow) | 40 | if (Shadow) |
41 | Shadow->drop(); | 41 | Shadow->drop(); |
42 | deleteTree(); | 42 | deleteTree(); |
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
46 | void COctreeSceneNode::OnRegisterSceneNode() | 46 | void COctreeSceneNode::OnRegisterSceneNode() |
47 | { | 47 | { |
48 | if (IsVisible) | 48 | if (IsVisible) |
49 | { | 49 | { |
50 | // because this node supports rendering of mixed mode meshes consisting of | 50 | // because this node supports rendering of mixed mode meshes consisting of |
51 | // transparent and solid material at the same time, we need to go through all | 51 | // transparent and solid material at the same time, we need to go through all |
52 | // materials, check of what type they are and register this node for the right | 52 | // materials, check of what type they are and register this node for the right |
53 | // render pass according to that. | 53 | // render pass according to that. |
54 | 54 | ||
55 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | 55 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); |
56 | 56 | ||
57 | PassCount = 0; | 57 | PassCount = 0; |
58 | u32 transparentCount = 0; | 58 | u32 transparentCount = 0; |
59 | u32 solidCount = 0; | 59 | u32 solidCount = 0; |
60 | 60 | ||
61 | // count transparent and solid materials in this scene node | 61 | // count transparent and solid materials in this scene node |
62 | for (u32 i=0; i<Materials.size(); ++i) | 62 | for (u32 i=0; i<Materials.size(); ++i) |
63 | { | 63 | { |
64 | const video::IMaterialRenderer* const rnd = | 64 | const video::IMaterialRenderer* const rnd = |
65 | driver->getMaterialRenderer(Materials[i].MaterialType); | 65 | driver->getMaterialRenderer(Materials[i].MaterialType); |
66 | 66 | ||
67 | if (rnd && rnd->isTransparent()) | 67 | if (rnd && rnd->isTransparent()) |
68 | ++transparentCount; | 68 | ++transparentCount; |
69 | else | 69 | else |
70 | ++solidCount; | 70 | ++solidCount; |
71 | 71 | ||
72 | if (solidCount && transparentCount) | 72 | if (solidCount && transparentCount) |
73 | break; | 73 | break; |
74 | } | 74 | } |
75 | 75 | ||
76 | // register according to material types counted | 76 | // register according to material types counted |
77 | 77 | ||
78 | if (solidCount) | 78 | if (solidCount) |
79 | SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); | 79 | SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); |
80 | 80 | ||
81 | if (transparentCount) | 81 | if (transparentCount) |
82 | SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); | 82 | SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); |
83 | 83 | ||
84 | ISceneNode::OnRegisterSceneNode(); | 84 | ISceneNode::OnRegisterSceneNode(); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | 88 | ||
89 | //! renders the node. | 89 | //! renders the node. |
90 | void COctreeSceneNode::render() | 90 | void COctreeSceneNode::render() |
91 | { | 91 | { |
92 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | 92 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); |
93 | 93 | ||
94 | if (VertexType == -1 || !driver) | 94 | if (VertexType == -1 || !driver) |
95 | return; | 95 | return; |
96 | 96 | ||
97 | ICameraSceneNode* camera = SceneManager->getActiveCamera(); | 97 | ICameraSceneNode* camera = SceneManager->getActiveCamera(); |
98 | if (!camera) | 98 | if (!camera) |
99 | return; | 99 | return; |
100 | 100 | ||
101 | bool isTransparentPass = | 101 | bool isTransparentPass = |
102 | SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; | 102 | SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; |
103 | ++PassCount; | 103 | ++PassCount; |
104 | 104 | ||
105 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | 105 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); |
106 | 106 | ||
107 | if (Shadow) | 107 | if (Shadow) |
108 | Shadow->updateShadowVolumes(); | 108 | Shadow->updateShadowVolumes(); |
109 | 109 | ||
110 | SViewFrustum frust = *camera->getViewFrustum(); | 110 | SViewFrustum frust = *camera->getViewFrustum(); |
111 | 111 | ||
112 | //transform the frustum to the current absolute transformation | 112 | //transform the frustum to the current absolute transformation |
113 | if ( !AbsoluteTransformation.isIdentity() ) | 113 | if ( !AbsoluteTransformation.isIdentity() ) |
114 | { | 114 | { |
115 | core::matrix4 invTrans(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE); | 115 | core::matrix4 invTrans(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE); |
116 | frust.transform(invTrans); | 116 | frust.transform(invTrans); |
117 | } | 117 | } |
118 | 118 | ||
119 | const core::aabbox3d<float> &box = frust.getBoundingBox(); | 119 | const core::aabbox3d<float> &box = frust.getBoundingBox(); |
120 | 120 | ||
121 | switch (VertexType) | 121 | switch (VertexType) |
122 | { | 122 | { |
123 | case video::EVT_STANDARD: | 123 | case video::EVT_STANDARD: |
124 | { | 124 | { |
125 | if (BoxBased) | 125 | if (BoxBased) |
126 | StdOctree->calculatePolys(box); | 126 | StdOctree->calculatePolys(box); |
127 | else | 127 | else |
128 | StdOctree->calculatePolys(frust); | 128 | StdOctree->calculatePolys(frust); |
129 | 129 | ||
130 | const Octree<video::S3DVertex>::SIndexData* d = StdOctree->getIndexData(); | 130 | const Octree<video::S3DVertex>::SIndexData* d = StdOctree->getIndexData(); |
131 | 131 | ||
132 | for (u32 i=0; i<Materials.size(); ++i) | 132 | for (u32 i=0; i<Materials.size(); ++i) |
133 | { | 133 | { |
134 | if ( 0 == d[i].CurrentSize ) | 134 | if ( 0 == d[i].CurrentSize ) |
135 | continue; | 135 | continue; |
136 | 136 | ||
137 | const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); | 137 | const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); |
138 | const bool transparent = (rnd && rnd->isTransparent()); | 138 | const bool transparent = (rnd && rnd->isTransparent()); |
139 | 139 | ||
140 | // only render transparent buffer if this is the transparent render pass | 140 | // only render transparent buffer if this is the transparent render pass |
141 | // and solid only in solid pass | 141 | // and solid only in solid pass |
142 | if (transparent == isTransparentPass) | 142 | if (transparent == isTransparentPass) |
143 | { | 143 | { |
144 | driver->setMaterial(Materials[i]); | 144 | driver->setMaterial(Materials[i]); |
145 | driver->drawIndexedTriangleList( | 145 | driver->drawIndexedTriangleList( |
146 | &StdMeshes[i].Vertices[0], StdMeshes[i].Vertices.size(), | 146 | &StdMeshes[i].Vertices[0], StdMeshes[i].Vertices.size(), |
147 | d[i].Indices, d[i].CurrentSize / 3); | 147 | d[i].Indices, d[i].CurrentSize / 3); |
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
151 | // for debug purposes only | 151 | // for debug purposes only |
152 | if (DebugDataVisible && !Materials.empty() && PassCount==1) | 152 | if (DebugDataVisible && !Materials.empty() && PassCount==1) |
153 | { | 153 | { |
154 | const core::aabbox3df& box = frust.getBoundingBox(); | 154 | const core::aabbox3df& box = frust.getBoundingBox(); |
155 | core::array< const core::aabbox3d<f32>* > boxes; | 155 | core::array< const core::aabbox3d<f32>* > boxes; |
156 | video::SMaterial m; | 156 | video::SMaterial m; |
157 | m.Lighting = false; | 157 | m.Lighting = false; |
158 | driver->setMaterial(m); | 158 | driver->setMaterial(m); |
159 | if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) | 159 | if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) |
160 | { | 160 | { |
161 | StdOctree->getBoundingBoxes(box, boxes); | 161 | StdOctree->getBoundingBoxes(box, boxes); |
162 | for (u32 b=0; b!=boxes.size(); ++b) | 162 | for (u32 b=0; b!=boxes.size(); ++b) |
163 | driver->draw3DBox(*boxes[b]); | 163 | driver->draw3DBox(*boxes[b]); |
164 | } | 164 | } |
165 | 165 | ||
166 | if ( DebugDataVisible & scene::EDS_BBOX ) | 166 | if ( DebugDataVisible & scene::EDS_BBOX ) |
167 | driver->draw3DBox(Box,video::SColor(0,255,0,0)); | 167 | driver->draw3DBox(Box,video::SColor(0,255,0,0)); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | break; | 170 | break; |
171 | case video::EVT_2TCOORDS: | 171 | case video::EVT_2TCOORDS: |
172 | { | 172 | { |
173 | if (BoxBased) | 173 | if (BoxBased) |
174 | LightMapOctree->calculatePolys(box); | 174 | LightMapOctree->calculatePolys(box); |
175 | else | 175 | else |
176 | LightMapOctree->calculatePolys(frust); | 176 | LightMapOctree->calculatePolys(frust); |
177 | 177 | ||
178 | const Octree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctree->getIndexData(); | 178 | const Octree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctree->getIndexData(); |
179 | 179 | ||
180 | for (u32 i=0; i<Materials.size(); ++i) | 180 | for (u32 i=0; i<Materials.size(); ++i) |
181 | { | 181 | { |
182 | if ( 0 == d[i].CurrentSize ) | 182 | if ( 0 == d[i].CurrentSize ) |
183 | continue; | 183 | continue; |
184 | 184 | ||
185 | const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); | 185 | const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); |
186 | const bool transparent = (rnd && rnd->isTransparent()); | 186 | const bool transparent = (rnd && rnd->isTransparent()); |
187 | 187 | ||
188 | // only render transparent buffer if this is the transparent render pass | 188 | // only render transparent buffer if this is the transparent render pass |
189 | // and solid only in solid pass | 189 | // and solid only in solid pass |
190 | if (transparent == isTransparentPass) | 190 | if (transparent == isTransparentPass) |
191 | { | 191 | { |
192 | driver->setMaterial(Materials[i]); | 192 | driver->setMaterial(Materials[i]); |
193 | if (UseVBOs) | 193 | if (UseVBOs) |
194 | { | 194 | { |
195 | if (UseVisibilityAndVBOs) | 195 | if (UseVisibilityAndVBOs) |
196 | { | 196 | { |
197 | u16* oldPointer = LightMapMeshes[i].Indices.pointer(); | 197 | u16* oldPointer = LightMapMeshes[i].Indices.pointer(); |
198 | const u32 oldSize = LightMapMeshes[i].Indices.size(); | 198 | const u32 oldSize = LightMapMeshes[i].Indices.size(); |
199 | LightMapMeshes[i].Indices.set_free_when_destroyed(false); | 199 | LightMapMeshes[i].Indices.set_free_when_destroyed(false); |
200 | LightMapMeshes[i].Indices.set_pointer(d[i].Indices, d[i].CurrentSize, false, false); | 200 | LightMapMeshes[i].Indices.set_pointer(d[i].Indices, d[i].CurrentSize, false, false); |
201 | LightMapMeshes[i].setDirty(scene::EBT_INDEX); | 201 | LightMapMeshes[i].setDirty(scene::EBT_INDEX); |
202 | driver->drawMeshBuffer ( &LightMapMeshes[i] ); | 202 | driver->drawMeshBuffer ( &LightMapMeshes[i] ); |
203 | LightMapMeshes[i].Indices.set_pointer(oldPointer, oldSize); | 203 | LightMapMeshes[i].Indices.set_pointer(oldPointer, oldSize); |
204 | LightMapMeshes[i].setDirty(scene::EBT_INDEX); | 204 | LightMapMeshes[i].setDirty(scene::EBT_INDEX); |
205 | } | 205 | } |
206 | else | 206 | else |
207 | driver->drawMeshBuffer ( &LightMapMeshes[i] ); | 207 | driver->drawMeshBuffer ( &LightMapMeshes[i] ); |
208 | } | 208 | } |
209 | else | 209 | else |
210 | driver->drawIndexedTriangleList( | 210 | driver->drawIndexedTriangleList( |
211 | &LightMapMeshes[i].Vertices[0], | 211 | &LightMapMeshes[i].Vertices[0], |
212 | LightMapMeshes[i].Vertices.size(), | 212 | LightMapMeshes[i].Vertices.size(), |
213 | d[i].Indices, d[i].CurrentSize / 3); | 213 | d[i].Indices, d[i].CurrentSize / 3); |
214 | } | 214 | } |
215 | } | 215 | } |
216 | 216 | ||
217 | // for debug purposes only | 217 | // for debug purposes only |
218 | if (DebugDataVisible && !Materials.empty() && PassCount==1) | 218 | if (DebugDataVisible && !Materials.empty() && PassCount==1) |
219 | { | 219 | { |
220 | const core::aabbox3d<float> &box = frust.getBoundingBox(); | 220 | const core::aabbox3d<float> &box = frust.getBoundingBox(); |
221 | core::array< const core::aabbox3d<f32>* > boxes; | 221 | core::array< const core::aabbox3d<f32>* > boxes; |
222 | video::SMaterial m; | 222 | video::SMaterial m; |
223 | m.Lighting = false; | 223 | m.Lighting = false; |
224 | driver->setMaterial(m); | 224 | driver->setMaterial(m); |
225 | if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) | 225 | if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) |
226 | { | 226 | { |
227 | LightMapOctree->getBoundingBoxes(box, boxes); | 227 | LightMapOctree->getBoundingBoxes(box, boxes); |
228 | for (u32 b=0; b<boxes.size(); ++b) | 228 | for (u32 b=0; b<boxes.size(); ++b) |
229 | driver->draw3DBox(*boxes[b]); | 229 | driver->draw3DBox(*boxes[b]); |
230 | } | 230 | } |
231 | 231 | ||
232 | if ( DebugDataVisible & scene::EDS_BBOX ) | 232 | if ( DebugDataVisible & scene::EDS_BBOX ) |
233 | driver->draw3DBox(Box,video::SColor(0,255,0,0)); | 233 | driver->draw3DBox(Box,video::SColor(0,255,0,0)); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | break; | 236 | break; |
237 | case video::EVT_TANGENTS: | 237 | case video::EVT_TANGENTS: |
238 | { | 238 | { |
239 | if (BoxBased) | 239 | if (BoxBased) |
240 | TangentsOctree->calculatePolys(box); | 240 | TangentsOctree->calculatePolys(box); |
241 | else | 241 | else |
242 | TangentsOctree->calculatePolys(frust); | 242 | TangentsOctree->calculatePolys(frust); |
243 | 243 | ||
244 | const Octree<video::S3DVertexTangents>::SIndexData* d = TangentsOctree->getIndexData(); | 244 | const Octree<video::S3DVertexTangents>::SIndexData* d = TangentsOctree->getIndexData(); |
245 | 245 | ||
246 | for (u32 i=0; i<Materials.size(); ++i) | 246 | for (u32 i=0; i<Materials.size(); ++i) |
247 | { | 247 | { |
248 | if ( 0 == d[i].CurrentSize ) | 248 | if ( 0 == d[i].CurrentSize ) |
249 | continue; | 249 | continue; |
250 | 250 | ||
251 | const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); | 251 | const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); |
252 | const bool transparent = (rnd && rnd->isTransparent()); | 252 | const bool transparent = (rnd && rnd->isTransparent()); |
253 | 253 | ||
254 | // only render transparent buffer if this is the transparent render pass | 254 | // only render transparent buffer if this is the transparent render pass |
255 | // and solid only in solid pass | 255 | // and solid only in solid pass |
256 | if (transparent == isTransparentPass) | 256 | if (transparent == isTransparentPass) |
257 | { | 257 | { |
258 | driver->setMaterial(Materials[i]); | 258 | driver->setMaterial(Materials[i]); |
259 | driver->drawIndexedTriangleList( | 259 | driver->drawIndexedTriangleList( |
260 | &TangentsMeshes[i].Vertices[0], TangentsMeshes[i].Vertices.size(), | 260 | &TangentsMeshes[i].Vertices[0], TangentsMeshes[i].Vertices.size(), |
261 | d[i].Indices, d[i].CurrentSize / 3); | 261 | d[i].Indices, d[i].CurrentSize / 3); |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | // for debug purposes only | 265 | // for debug purposes only |
266 | if (DebugDataVisible && !Materials.empty() && PassCount==1) | 266 | if (DebugDataVisible && !Materials.empty() && PassCount==1) |
267 | { | 267 | { |
268 | const core::aabbox3d<float> &box = frust.getBoundingBox(); | 268 | const core::aabbox3d<float> &box = frust.getBoundingBox(); |
269 | core::array< const core::aabbox3d<f32>* > boxes; | 269 | core::array< const core::aabbox3d<f32>* > boxes; |
270 | video::SMaterial m; | 270 | video::SMaterial m; |
271 | m.Lighting = false; | 271 | m.Lighting = false; |
272 | driver->setMaterial(m); | 272 | driver->setMaterial(m); |
273 | if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) | 273 | if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) |
274 | { | 274 | { |
275 | TangentsOctree->getBoundingBoxes(box, boxes); | 275 | TangentsOctree->getBoundingBoxes(box, boxes); |
276 | for (u32 b=0; b<boxes.size(); ++b) | 276 | for (u32 b=0; b<boxes.size(); ++b) |
277 | driver->draw3DBox(*boxes[b]); | 277 | driver->draw3DBox(*boxes[b]); |
278 | } | 278 | } |
279 | 279 | ||
280 | if ( DebugDataVisible & scene::EDS_BBOX ) | 280 | if ( DebugDataVisible & scene::EDS_BBOX ) |
281 | driver->draw3DBox(Box,video::SColor(0,255,0,0)); | 281 | driver->draw3DBox(Box,video::SColor(0,255,0,0)); |
282 | } | 282 | } |
283 | } | 283 | } |
284 | break; | 284 | break; |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | 288 | ||
289 | //! Removes a child from this scene node. | 289 | //! Removes a child from this scene node. |
290 | //! Implemented here, to be able to remove the shadow properly, if there is one, | 290 | //! Implemented here, to be able to remove the shadow properly, if there is one, |
291 | //! or to remove attached childs. | 291 | //! or to remove attached childs. |
292 | bool COctreeSceneNode::removeChild(ISceneNode* child) | 292 | bool COctreeSceneNode::removeChild(ISceneNode* child) |
293 | { | 293 | { |
294 | if (child && Shadow == child) | 294 | if (child && Shadow == child) |
295 | { | 295 | { |
296 | Shadow->drop(); | 296 | Shadow->drop(); |
297 | Shadow = 0; | 297 | Shadow = 0; |
298 | } | 298 | } |
299 | 299 | ||
300 | return ISceneNode::removeChild(child); | 300 | return ISceneNode::removeChild(child); |
301 | } | 301 | } |
302 | 302 | ||
303 | 303 | ||
304 | //! Creates shadow volume scene node as child of this node | 304 | //! Creates shadow volume scene node as child of this node |
305 | //! and returns a pointer to it. | 305 | //! and returns a pointer to it. |
306 | IShadowVolumeSceneNode* COctreeSceneNode::addShadowVolumeSceneNode( | 306 | IShadowVolumeSceneNode* COctreeSceneNode::addShadowVolumeSceneNode( |
307 | const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) | 307 | const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) |
308 | { | 308 | { |
309 | if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) | 309 | if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) |
310 | return 0; | 310 | return 0; |
311 | 311 | ||
312 | if (!shadowMesh) | 312 | if (!shadowMesh) |
313 | shadowMesh = Mesh; // if null is given, use the mesh of node | 313 | shadowMesh = Mesh; // if null is given, use the mesh of node |
314 | 314 | ||
315 | if (Shadow) | 315 | if (Shadow) |
316 | Shadow->drop(); | 316 | Shadow->drop(); |
317 | 317 | ||
318 | Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); | 318 | Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); |
319 | return Shadow; | 319 | return Shadow; |
320 | } | 320 | } |
321 | 321 | ||
322 | 322 | ||
323 | //! returns the axis aligned bounding box of this node | 323 | //! returns the axis aligned bounding box of this node |
324 | const core::aabbox3d<f32>& COctreeSceneNode::getBoundingBox() const | 324 | const core::aabbox3d<f32>& COctreeSceneNode::getBoundingBox() const |
325 | { | 325 | { |
326 | return Box; | 326 | return Box; |
327 | } | 327 | } |
328 | 328 | ||
329 | 329 | ||
330 | //! creates the tree | 330 | //! creates the tree |
331 | /* This method has a lot of duplication and overhead. Moreover, the tangents mesh conversion does not really work. I think we need a a proper mesh implementation for octrees, which handle all vertex types internally. Converting all structures to just one vertex type is always problematic. | 331 | /* This method has a lot of duplication and overhead. Moreover, the tangents mesh conversion does not really work. I think we need a a proper mesh implementation for octrees, which handle all vertex types internally. Converting all structures to just one vertex type is always problematic. |
332 | Thanks to Auria for fixing major parts of this method. */ | 332 | Thanks to Auria for fixing major parts of this method. */ |
333 | bool COctreeSceneNode::createTree(IMesh* mesh) | 333 | bool COctreeSceneNode::createTree(IMesh* mesh) |
334 | { | 334 | { |
335 | if (!mesh) | 335 | if (!mesh) |
336 | return false; | 336 | return false; |
337 | 337 | ||
338 | MeshName = SceneManager->getMeshCache()->getMeshName(mesh); | 338 | MeshName = SceneManager->getMeshCache()->getMeshName(mesh); |
339 | 339 | ||
340 | mesh->grab(); | 340 | mesh->grab(); |
341 | deleteTree(); | 341 | deleteTree(); |
342 | 342 | ||
343 | Mesh = mesh; | 343 | Mesh = mesh; |
344 | 344 | ||
345 | const u32 beginTime = os::Timer::getRealTime(); | 345 | const u32 beginTime = os::Timer::getRealTime(); |
346 | 346 | ||
347 | u32 nodeCount = 0; | 347 | u32 nodeCount = 0; |
348 | u32 polyCount = 0; | 348 | u32 polyCount = 0; |
349 | u32 i; | 349 | u32 i; |
350 | 350 | ||
351 | Box = mesh->getBoundingBox(); | 351 | Box = mesh->getBoundingBox(); |
352 | 352 | ||
353 | if (mesh->getMeshBufferCount()) | 353 | if (mesh->getMeshBufferCount()) |
354 | { | 354 | { |
355 | // check for "larger" buffer types | 355 | // check for "larger" buffer types |
356 | VertexType = video::EVT_STANDARD; | 356 | VertexType = video::EVT_STANDARD; |
357 | u32 meshReserve = 0; | 357 | u32 meshReserve = 0; |
358 | for (i=0; i<mesh->getMeshBufferCount(); ++i) | 358 | for (i=0; i<mesh->getMeshBufferCount(); ++i) |
359 | { | 359 | { |
360 | const IMeshBuffer* b = mesh->getMeshBuffer(i); | 360 | const IMeshBuffer* b = mesh->getMeshBuffer(i); |
361 | if (b->getVertexCount() && b->getIndexCount()) | 361 | if (b->getVertexCount() && b->getIndexCount()) |
362 | { | 362 | { |
363 | ++meshReserve; | 363 | ++meshReserve; |
364 | if (b->getVertexType() == video::EVT_2TCOORDS) | 364 | if (b->getVertexType() == video::EVT_2TCOORDS) |
365 | VertexType = video::EVT_2TCOORDS; | 365 | VertexType = video::EVT_2TCOORDS; |
366 | else if (b->getVertexType() == video::EVT_TANGENTS) | 366 | else if (b->getVertexType() == video::EVT_TANGENTS) |
367 | VertexType = video::EVT_TANGENTS; | 367 | VertexType = video::EVT_TANGENTS; |
368 | } | 368 | } |
369 | } | 369 | } |
370 | Materials.reallocate(Materials.size()+meshReserve); | 370 | Materials.reallocate(Materials.size()+meshReserve); |
371 | 371 | ||
372 | switch(VertexType) | 372 | switch(VertexType) |
373 | { | 373 | { |
374 | case video::EVT_STANDARD: | 374 | case video::EVT_STANDARD: |
375 | { | 375 | { |
376 | StdMeshes.reallocate(StdMeshes.size() + meshReserve); | 376 | StdMeshes.reallocate(StdMeshes.size() + meshReserve); |
377 | for (i=0; i<mesh->getMeshBufferCount(); ++i) | 377 | for (i=0; i<mesh->getMeshBufferCount(); ++i) |
378 | { | 378 | { |
379 | IMeshBuffer* b = mesh->getMeshBuffer(i); | 379 | IMeshBuffer* b = mesh->getMeshBuffer(i); |
380 | 380 | ||
381 | if (b->getVertexCount() && b->getIndexCount()) | 381 | if (b->getVertexCount() && b->getIndexCount()) |
382 | { | 382 | { |
383 | Materials.push_back(b->getMaterial()); | 383 | Materials.push_back(b->getMaterial()); |
384 | 384 | ||
385 | StdMeshes.push_back(Octree<video::S3DVertex>::SMeshChunk()); | 385 | StdMeshes.push_back(Octree<video::S3DVertex>::SMeshChunk()); |
386 | Octree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes.getLast(); | 386 | Octree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes.getLast(); |
387 | nchunk.MaterialId = Materials.size() - 1; | 387 | nchunk.MaterialId = Materials.size() - 1; |
388 | 388 | ||
389 | u32 v; | 389 | u32 v; |
390 | nchunk.Vertices.reallocate(b->getVertexCount()); | 390 | nchunk.Vertices.reallocate(b->getVertexCount()); |
391 | switch (b->getVertexType()) | 391 | switch (b->getVertexType()) |
392 | { | 392 | { |
393 | case video::EVT_STANDARD: | 393 | case video::EVT_STANDARD: |
394 | for (v=0; v<b->getVertexCount(); ++v) | 394 | for (v=0; v<b->getVertexCount(); ++v) |
395 | nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); | 395 | nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); |
396 | break; | 396 | break; |
397 | case video::EVT_2TCOORDS: | 397 | case video::EVT_2TCOORDS: |
398 | for (v=0; v<b->getVertexCount(); ++v) | 398 | for (v=0; v<b->getVertexCount(); ++v) |
399 | nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); | 399 | nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); |
400 | break; | 400 | break; |
401 | case video::EVT_TANGENTS: | 401 | case video::EVT_TANGENTS: |
402 | for (v=0; v<b->getVertexCount(); ++v) | 402 | for (v=0; v<b->getVertexCount(); ++v) |
403 | nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); | 403 | nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); |
404 | break; | 404 | break; |
405 | } | 405 | } |
406 | 406 | ||
407 | polyCount += b->getIndexCount(); | 407 | polyCount += b->getIndexCount(); |
408 | 408 | ||
409 | nchunk.Indices.reallocate(b->getIndexCount()); | 409 | nchunk.Indices.reallocate(b->getIndexCount()); |
410 | for (v=0; v<b->getIndexCount(); ++v) | 410 | for (v=0; v<b->getIndexCount(); ++v) |
411 | nchunk.Indices.push_back(b->getIndices()[v]); | 411 | nchunk.Indices.push_back(b->getIndices()[v]); |
412 | } | 412 | } |
413 | } | 413 | } |
414 | 414 | ||
415 | StdOctree = new Octree<video::S3DVertex>(StdMeshes, MinimalPolysPerNode); | 415 | StdOctree = new Octree<video::S3DVertex>(StdMeshes, MinimalPolysPerNode); |
416 | nodeCount = StdOctree->getNodeCount(); | 416 | nodeCount = StdOctree->getNodeCount(); |
417 | } | 417 | } |
418 | break; | 418 | break; |
419 | case video::EVT_2TCOORDS: | 419 | case video::EVT_2TCOORDS: |
420 | { | 420 | { |
421 | LightMapMeshes.reallocate(LightMapMeshes.size() + meshReserve); | 421 | LightMapMeshes.reallocate(LightMapMeshes.size() + meshReserve); |
422 | 422 | ||
423 | for ( i=0; i < mesh->getMeshBufferCount(); ++i) | 423 | for ( i=0; i < mesh->getMeshBufferCount(); ++i) |
424 | { | 424 | { |
425 | IMeshBuffer* b = mesh->getMeshBuffer(i); | 425 | IMeshBuffer* b = mesh->getMeshBuffer(i); |
426 | 426 | ||
427 | if (b->getVertexCount() && b->getIndexCount()) | 427 | if (b->getVertexCount() && b->getIndexCount()) |
428 | { | 428 | { |
429 | Materials.push_back(b->getMaterial()); | 429 | Materials.push_back(b->getMaterial()); |
430 | LightMapMeshes.push_back(Octree<video::S3DVertex2TCoords>::SMeshChunk()); | 430 | LightMapMeshes.push_back(Octree<video::S3DVertex2TCoords>::SMeshChunk()); |
431 | Octree<video::S3DVertex2TCoords>::SMeshChunk& nchunk = LightMapMeshes.getLast(); | 431 | Octree<video::S3DVertex2TCoords>::SMeshChunk& nchunk = LightMapMeshes.getLast(); |
432 | nchunk.MaterialId = Materials.size() - 1; | 432 | nchunk.MaterialId = Materials.size() - 1; |
433 | 433 | ||
434 | if (UseVisibilityAndVBOs) | 434 | if (UseVisibilityAndVBOs) |
435 | { | 435 | { |
436 | nchunk.setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_VERTEX); | 436 | nchunk.setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_VERTEX); |
437 | nchunk.setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_INDEX); | 437 | nchunk.setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_INDEX); |
438 | } | 438 | } |
439 | else | 439 | else |
440 | nchunk.setHardwareMappingHint(scene::EHM_STATIC); | 440 | nchunk.setHardwareMappingHint(scene::EHM_STATIC); |
441 | 441 | ||
442 | u32 v; | 442 | u32 v; |
443 | nchunk.Vertices.reallocate(b->getVertexCount()); | 443 | nchunk.Vertices.reallocate(b->getVertexCount()); |
444 | switch (b->getVertexType()) | 444 | switch (b->getVertexType()) |
445 | { | 445 | { |
446 | case video::EVT_STANDARD: | 446 | case video::EVT_STANDARD: |
447 | for (v=0; v<b->getVertexCount(); ++v) | 447 | for (v=0; v<b->getVertexCount(); ++v) |
448 | nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); | 448 | nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); |
449 | break; | 449 | break; |
450 | case video::EVT_2TCOORDS: | 450 | case video::EVT_2TCOORDS: |
451 | for (v=0; v<b->getVertexCount(); ++v) | 451 | for (v=0; v<b->getVertexCount(); ++v) |
452 | nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); | 452 | nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); |
453 | break; | 453 | break; |
454 | case video::EVT_TANGENTS: | 454 | case video::EVT_TANGENTS: |
455 | for (v=0; v<b->getVertexCount(); ++v) | 455 | for (v=0; v<b->getVertexCount(); ++v) |
456 | nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); | 456 | nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); |
457 | break; | 457 | break; |
458 | } | 458 | } |
459 | 459 | ||
460 | polyCount += b->getIndexCount(); | 460 | polyCount += b->getIndexCount(); |
461 | nchunk.Indices.reallocate(b->getIndexCount()); | 461 | nchunk.Indices.reallocate(b->getIndexCount()); |
462 | for (v=0; v<b->getIndexCount(); ++v) | 462 | for (v=0; v<b->getIndexCount(); ++v) |
463 | nchunk.Indices.push_back(b->getIndices()[v]); | 463 | nchunk.Indices.push_back(b->getIndices()[v]); |
464 | } | 464 | } |
465 | } | 465 | } |
466 | 466 | ||
467 | LightMapOctree = new Octree<video::S3DVertex2TCoords>(LightMapMeshes, MinimalPolysPerNode); | 467 | LightMapOctree = new Octree<video::S3DVertex2TCoords>(LightMapMeshes, MinimalPolysPerNode); |
468 | nodeCount = LightMapOctree->getNodeCount(); | 468 | nodeCount = LightMapOctree->getNodeCount(); |
469 | } | 469 | } |
470 | break; | 470 | break; |
471 | case video::EVT_TANGENTS: | 471 | case video::EVT_TANGENTS: |
472 | { | 472 | { |
473 | TangentsMeshes.reallocate(TangentsMeshes.size() + meshReserve); | 473 | TangentsMeshes.reallocate(TangentsMeshes.size() + meshReserve); |
474 | 474 | ||
475 | for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) | 475 | for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) |
476 | { | 476 | { |
477 | IMeshBuffer* b = mesh->getMeshBuffer(i); | 477 | IMeshBuffer* b = mesh->getMeshBuffer(i); |
478 | 478 | ||
479 | if (b->getVertexCount() && b->getIndexCount()) | 479 | if (b->getVertexCount() && b->getIndexCount()) |
480 | { | 480 | { |
481 | Materials.push_back(b->getMaterial()); | 481 | Materials.push_back(b->getMaterial()); |
482 | TangentsMeshes.push_back(Octree<video::S3DVertexTangents>::SMeshChunk()); | 482 | TangentsMeshes.push_back(Octree<video::S3DVertexTangents>::SMeshChunk()); |
483 | Octree<video::S3DVertexTangents>::SMeshChunk& nchunk = TangentsMeshes.getLast(); | 483 | Octree<video::S3DVertexTangents>::SMeshChunk& nchunk = TangentsMeshes.getLast(); |
484 | nchunk.MaterialId = Materials.size() - 1; | 484 | nchunk.MaterialId = Materials.size() - 1; |
485 | 485 | ||
486 | u32 v; | 486 | u32 v; |
487 | nchunk.Vertices.reallocate(b->getVertexCount()); | 487 | nchunk.Vertices.reallocate(b->getVertexCount()); |
488 | switch (b->getVertexType()) | 488 | switch (b->getVertexType()) |
489 | { | 489 | { |
490 | case video::EVT_STANDARD: | 490 | case video::EVT_STANDARD: |
491 | for (v=0; v<b->getVertexCount(); ++v) | 491 | for (v=0; v<b->getVertexCount(); ++v) |
492 | { | 492 | { |
493 | const video::S3DVertex& tmpV = ((video::S3DVertex*)b->getVertices())[v]; | 493 | const video::S3DVertex& tmpV = ((video::S3DVertex*)b->getVertices())[v]; |
494 | nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); | 494 | nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); |
495 | } | 495 | } |
496 | break; | 496 | break; |
497 | case video::EVT_2TCOORDS: | 497 | case video::EVT_2TCOORDS: |
498 | for (v=0; v<b->getVertexCount(); ++v) | 498 | for (v=0; v<b->getVertexCount(); ++v) |
499 | { | 499 | { |
500 | const video::S3DVertex2TCoords& tmpV = ((video::S3DVertex2TCoords*)b->getVertices())[v]; | 500 | const video::S3DVertex2TCoords& tmpV = ((video::S3DVertex2TCoords*)b->getVertices())[v]; |
501 | nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); | 501 | nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); |
502 | } | 502 | } |
503 | break; | 503 | break; |
504 | case video::EVT_TANGENTS: | 504 | case video::EVT_TANGENTS: |
505 | for (v=0; v<b->getVertexCount(); ++v) | 505 | for (v=0; v<b->getVertexCount(); ++v) |
506 | nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); | 506 | nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); |
507 | break; | 507 | break; |
508 | } | 508 | } |
509 | 509 | ||
510 | polyCount += b->getIndexCount(); | 510 | polyCount += b->getIndexCount(); |
511 | nchunk.Indices.reallocate(b->getIndexCount()); | 511 | nchunk.Indices.reallocate(b->getIndexCount()); |
512 | for (v=0; v<b->getIndexCount(); ++v) | 512 | for (v=0; v<b->getIndexCount(); ++v) |
513 | nchunk.Indices.push_back(b->getIndices()[v]); | 513 | nchunk.Indices.push_back(b->getIndices()[v]); |
514 | } | 514 | } |
515 | } | 515 | } |
516 | 516 | ||
517 | TangentsOctree = new Octree<video::S3DVertexTangents>(TangentsMeshes, MinimalPolysPerNode); | 517 | TangentsOctree = new Octree<video::S3DVertexTangents>(TangentsMeshes, MinimalPolysPerNode); |
518 | nodeCount = TangentsOctree->getNodeCount(); | 518 | nodeCount = TangentsOctree->getNodeCount(); |
519 | } | 519 | } |
520 | break; | 520 | break; |
521 | } | 521 | } |
522 | } | 522 | } |
523 | 523 | ||
524 | const u32 endTime = os::Timer::getRealTime(); | 524 | const u32 endTime = os::Timer::getRealTime(); |
525 | c8 tmp[255]; | 525 | c8 tmp[255]; |
526 | sprintf(tmp, "Needed %ums to create Octree SceneNode.(%u nodes, %u polys)", | 526 | sprintf(tmp, "Needed %ums to create Octree SceneNode.(%u nodes, %u polys)", |
527 | endTime - beginTime, nodeCount, polyCount/3); | 527 | endTime - beginTime, nodeCount, polyCount/3); |
528 | os::Printer::log(tmp, ELL_INFORMATION); | 528 | os::Printer::log(tmp, ELL_INFORMATION); |
529 | 529 | ||
530 | return true; | 530 | return true; |
531 | } | 531 | } |
532 | 532 | ||
533 | 533 | ||
534 | //! returns the material based on the zero based index i. To get the amount | 534 | //! returns the material based on the zero based index i. To get the amount |
535 | //! of materials used by this scene node, use getMaterialCount(). | 535 | //! of materials used by this scene node, use getMaterialCount(). |
536 | //! This function is needed for inserting the node into the scene hirachy on a | 536 | //! This function is needed for inserting the node into the scene hirachy on a |
537 | //! optimal position for minimizing renderstate changes, but can also be used | 537 | //! optimal position for minimizing renderstate changes, but can also be used |
538 | //! to directly modify the material of a scene node. | 538 | //! to directly modify the material of a scene node. |
539 | video::SMaterial& COctreeSceneNode::getMaterial(u32 i) | 539 | video::SMaterial& COctreeSceneNode::getMaterial(u32 i) |
540 | { | 540 | { |
541 | if ( i >= Materials.size() ) | 541 | if ( i >= Materials.size() ) |
542 | return ISceneNode::getMaterial(i); | 542 | return ISceneNode::getMaterial(i); |
543 | 543 | ||
544 | return Materials[i]; | 544 | return Materials[i]; |
545 | } | 545 | } |
546 | 546 | ||
547 | 547 | ||
548 | //! returns amount of materials used by this scene node. | 548 | //! returns amount of materials used by this scene node. |
549 | u32 COctreeSceneNode::getMaterialCount() const | 549 | u32 COctreeSceneNode::getMaterialCount() const |
550 | { | 550 | { |
551 | return Materials.size(); | 551 | return Materials.size(); |
552 | } | 552 | } |
553 | 553 | ||
554 | 554 | ||
555 | //! Writes attributes of the scene node. | 555 | //! Writes attributes of the scene node. |
556 | void COctreeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | 556 | void COctreeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const |
557 | { | 557 | { |
558 | ISceneNode::serializeAttributes(out, options); | 558 | ISceneNode::serializeAttributes(out, options); |
559 | 559 | ||
560 | out->addInt("MinimalPolysPerNode", MinimalPolysPerNode); | 560 | out->addInt("MinimalPolysPerNode", MinimalPolysPerNode); |
561 | out->addString("Mesh", MeshName.c_str()); | 561 | out->addString("Mesh", MeshName.c_str()); |
562 | } | 562 | } |
563 | 563 | ||
564 | 564 | ||
565 | //! Reads attributes of the scene node. | 565 | //! Reads attributes of the scene node. |
566 | void COctreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | 566 | void COctreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) |
567 | { | 567 | { |
568 | const s32 oldMinimal = MinimalPolysPerNode; | 568 | const s32 oldMinimal = MinimalPolysPerNode; |
569 | 569 | ||
570 | MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode"); | 570 | MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode"); |
571 | io::path newMeshStr = in->getAttributeAsString("Mesh"); | 571 | io::path newMeshStr = in->getAttributeAsString("Mesh"); |
572 | 572 | ||
573 | IMesh* newMesh = 0; | 573 | IMesh* newMesh = 0; |
574 | 574 | ||
575 | if (newMeshStr == "") | 575 | if (newMeshStr == "") |
576 | newMeshStr = MeshName; | 576 | newMeshStr = MeshName; |
577 | 577 | ||
578 | IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); | 578 | IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); |
579 | 579 | ||
580 | if (newAnimatedMesh) | 580 | if (newAnimatedMesh) |
581 | newMesh = newAnimatedMesh->getMesh(0); | 581 | newMesh = newAnimatedMesh->getMesh(0); |
582 | 582 | ||
583 | if (newMesh && ((MeshName != newMeshStr) || (MinimalPolysPerNode != oldMinimal))) | 583 | if (newMesh && ((MeshName != newMeshStr) || (MinimalPolysPerNode != oldMinimal))) |
584 | { | 584 | { |
585 | // recalculate tree | 585 | // recalculate tree |
586 | createTree(newMesh); | 586 | createTree(newMesh); |
587 | } | 587 | } |
588 | 588 | ||
589 | ISceneNode::deserializeAttributes(in, options); | 589 | ISceneNode::deserializeAttributes(in, options); |
590 | } | 590 | } |
591 | 591 | ||
592 | 592 | ||
593 | void COctreeSceneNode::deleteTree() | 593 | void COctreeSceneNode::deleteTree() |
594 | { | 594 | { |
595 | delete StdOctree; | 595 | delete StdOctree; |
596 | StdOctree = 0; | 596 | StdOctree = 0; |
597 | StdMeshes.clear(); | 597 | StdMeshes.clear(); |
598 | 598 | ||
599 | delete LightMapOctree; | 599 | delete LightMapOctree; |
600 | LightMapOctree = 0; | 600 | LightMapOctree = 0; |
601 | LightMapMeshes.clear(); | 601 | LightMapMeshes.clear(); |
602 | 602 | ||
603 | delete TangentsOctree; | 603 | delete TangentsOctree; |
604 | TangentsOctree = 0; | 604 | TangentsOctree = 0; |
605 | TangentsMeshes.clear(); | 605 | TangentsMeshes.clear(); |
606 | 606 | ||
607 | Materials.clear(); | 607 | Materials.clear(); |
608 | 608 | ||
609 | if(Mesh) | 609 | if(Mesh) |
610 | Mesh->drop(); | 610 | Mesh->drop(); |
611 | } | 611 | } |
612 | 612 | ||
613 | void COctreeSceneNode::setMesh(IMesh* mesh) | 613 | void COctreeSceneNode::setMesh(IMesh* mesh) |
614 | { | 614 | { |
615 | createTree(mesh); | 615 | createTree(mesh); |
616 | } | 616 | } |
617 | 617 | ||
618 | IMesh* COctreeSceneNode::getMesh(void) | 618 | IMesh* COctreeSceneNode::getMesh(void) |
619 | { | 619 | { |
620 | return Mesh; | 620 | return Mesh; |
621 | } | 621 | } |
622 | 622 | ||
623 | void COctreeSceneNode::setReadOnlyMaterials(bool readonly) | 623 | void COctreeSceneNode::setReadOnlyMaterials(bool readonly) |
624 | { | 624 | { |
625 | // Do nothing | 625 | // Do nothing |
626 | } | 626 | } |
627 | 627 | ||
628 | bool COctreeSceneNode::isReadOnlyMaterials() const | 628 | bool COctreeSceneNode::isReadOnlyMaterials() const |
629 | { | 629 | { |
630 | return false; | 630 | return false; |
631 | } | 631 | } |
632 | 632 | ||
633 | 633 | ||
634 | } // end namespace scene | 634 | } // end namespace scene |
635 | } // end namespace irr | 635 | } // end namespace irr |
636 | 636 | ||