diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CMeshSceneNode.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CMeshSceneNode.cpp | 892 |
1 files changed, 446 insertions, 446 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CMeshSceneNode.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CMeshSceneNode.cpp index 9fde479..f9273c4 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CMeshSceneNode.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CMeshSceneNode.cpp | |||
@@ -1,446 +1,446 @@ | |||
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 "CMeshSceneNode.h" | 5 | #include "CMeshSceneNode.h" |
6 | #include "IVideoDriver.h" | 6 | #include "IVideoDriver.h" |
7 | #include "ISceneManager.h" | 7 | #include "ISceneManager.h" |
8 | #include "S3DVertex.h" | 8 | #include "S3DVertex.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 "IFileSystem.h" | 13 | #include "IFileSystem.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 | 22 | ||
23 | //! constructor | 23 | //! constructor |
24 | CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, | 24 | CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, |
25 | const core::vector3df& position, const core::vector3df& rotation, | 25 | const core::vector3df& position, const core::vector3df& rotation, |
26 | const core::vector3df& scale) | 26 | const core::vector3df& scale) |
27 | : IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0), | 27 | : IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0), |
28 | PassCount(0), ReadOnlyMaterials(false) | 28 | PassCount(0), ReadOnlyMaterials(false) |
29 | { | 29 | { |
30 | #ifdef _DEBUG | 30 | #ifdef _DEBUG |
31 | setDebugName("CMeshSceneNode"); | 31 | setDebugName("CMeshSceneNode"); |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | setMesh(mesh); | 34 | setMesh(mesh); |
35 | } | 35 | } |
36 | 36 | ||
37 | 37 | ||
38 | //! destructor | 38 | //! destructor |
39 | CMeshSceneNode::~CMeshSceneNode() | 39 | CMeshSceneNode::~CMeshSceneNode() |
40 | { | 40 | { |
41 | if (Shadow) | 41 | if (Shadow) |
42 | Shadow->drop(); | 42 | Shadow->drop(); |
43 | if (Mesh) | 43 | if (Mesh) |
44 | Mesh->drop(); | 44 | Mesh->drop(); |
45 | } | 45 | } |
46 | 46 | ||
47 | 47 | ||
48 | //! frame | 48 | //! frame |
49 | void CMeshSceneNode::OnRegisterSceneNode() | 49 | void CMeshSceneNode::OnRegisterSceneNode() |
50 | { | 50 | { |
51 | if (IsVisible) | 51 | if (IsVisible) |
52 | { | 52 | { |
53 | // because this node supports rendering of mixed mode meshes consisting of | 53 | // because this node supports rendering of mixed mode meshes consisting of |
54 | // transparent and solid material at the same time, we need to go through all | 54 | // transparent and solid material at the same time, we need to go through all |
55 | // materials, check of what type they are and register this node for the right | 55 | // materials, check of what type they are and register this node for the right |
56 | // render pass according to that. | 56 | // render pass according to that. |
57 | 57 | ||
58 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | 58 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); |
59 | 59 | ||
60 | PassCount = 0; | 60 | PassCount = 0; |
61 | int transparentCount = 0; | 61 | int transparentCount = 0; |
62 | int solidCount = 0; | 62 | int solidCount = 0; |
63 | 63 | ||
64 | // count transparent and solid materials in this scene node | 64 | // count transparent and solid materials in this scene node |
65 | if (ReadOnlyMaterials && Mesh) | 65 | if (ReadOnlyMaterials && Mesh) |
66 | { | 66 | { |
67 | // count mesh materials | 67 | // count mesh materials |
68 | 68 | ||
69 | for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) | 69 | for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) |
70 | { | 70 | { |
71 | scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); | 71 | scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); |
72 | video::IMaterialRenderer* rnd = mb ? driver->getMaterialRenderer(mb->getMaterial().MaterialType) : 0; | 72 | video::IMaterialRenderer* rnd = mb ? driver->getMaterialRenderer(mb->getMaterial().MaterialType) : 0; |
73 | 73 | ||
74 | if (rnd && rnd->isTransparent()) | 74 | if (rnd && rnd->isTransparent()) |
75 | ++transparentCount; | 75 | ++transparentCount; |
76 | else | 76 | else |
77 | ++solidCount; | 77 | ++solidCount; |
78 | 78 | ||
79 | if (solidCount && transparentCount) | 79 | if (solidCount && transparentCount) |
80 | break; | 80 | break; |
81 | } | 81 | } |
82 | } | 82 | } |
83 | else | 83 | else |
84 | { | 84 | { |
85 | // count copied materials | 85 | // count copied materials |
86 | 86 | ||
87 | for (u32 i=0; i<Materials.size(); ++i) | 87 | for (u32 i=0; i<Materials.size(); ++i) |
88 | { | 88 | { |
89 | video::IMaterialRenderer* rnd = | 89 | video::IMaterialRenderer* rnd = |
90 | driver->getMaterialRenderer(Materials[i].MaterialType); | 90 | driver->getMaterialRenderer(Materials[i].MaterialType); |
91 | 91 | ||
92 | if (rnd && rnd->isTransparent()) | 92 | if (rnd && rnd->isTransparent()) |
93 | ++transparentCount; | 93 | ++transparentCount; |
94 | else | 94 | else |
95 | ++solidCount; | 95 | ++solidCount; |
96 | 96 | ||
97 | if (solidCount && transparentCount) | 97 | if (solidCount && transparentCount) |
98 | break; | 98 | break; |
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | // register according to material types counted | 102 | // register according to material types counted |
103 | 103 | ||
104 | if (solidCount) | 104 | if (solidCount) |
105 | SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); | 105 | SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); |
106 | 106 | ||
107 | if (transparentCount) | 107 | if (transparentCount) |
108 | SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); | 108 | SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); |
109 | 109 | ||
110 | ISceneNode::OnRegisterSceneNode(); | 110 | ISceneNode::OnRegisterSceneNode(); |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | 114 | ||
115 | //! renders the node. | 115 | //! renders the node. |
116 | void CMeshSceneNode::render() | 116 | void CMeshSceneNode::render() |
117 | { | 117 | { |
118 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | 118 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); |
119 | 119 | ||
120 | if (!Mesh || !driver) | 120 | if (!Mesh || !driver) |
121 | return; | 121 | return; |
122 | 122 | ||
123 | bool isTransparentPass = | 123 | bool isTransparentPass = |
124 | SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; | 124 | SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; |
125 | 125 | ||
126 | ++PassCount; | 126 | ++PassCount; |
127 | 127 | ||
128 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | 128 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); |
129 | Box = Mesh->getBoundingBox(); | 129 | Box = Mesh->getBoundingBox(); |
130 | 130 | ||
131 | if (Shadow && PassCount==1) | 131 | if (Shadow && PassCount==1) |
132 | Shadow->updateShadowVolumes(); | 132 | Shadow->updateShadowVolumes(); |
133 | 133 | ||
134 | // for debug purposes only: | 134 | // for debug purposes only: |
135 | 135 | ||
136 | bool renderMeshes = true; | 136 | bool renderMeshes = true; |
137 | video::SMaterial mat; | 137 | video::SMaterial mat; |
138 | if (DebugDataVisible && PassCount==1) | 138 | if (DebugDataVisible && PassCount==1) |
139 | { | 139 | { |
140 | // overwrite half transparency | 140 | // overwrite half transparency |
141 | if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) | 141 | if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) |
142 | { | 142 | { |
143 | for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g) | 143 | for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g) |
144 | { | 144 | { |
145 | mat = Materials[g]; | 145 | mat = Materials[g]; |
146 | mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; | 146 | mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; |
147 | driver->setMaterial(mat); | 147 | driver->setMaterial(mat); |
148 | driver->drawMeshBuffer(Mesh->getMeshBuffer(g)); | 148 | driver->drawMeshBuffer(Mesh->getMeshBuffer(g)); |
149 | } | 149 | } |
150 | renderMeshes = false; | 150 | renderMeshes = false; |
151 | } | 151 | } |
152 | } | 152 | } |
153 | 153 | ||
154 | // render original meshes | 154 | // render original meshes |
155 | if (renderMeshes) | 155 | if (renderMeshes) |
156 | { | 156 | { |
157 | for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) | 157 | for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) |
158 | { | 158 | { |
159 | scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); | 159 | scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); |
160 | if (mb) | 160 | if (mb) |
161 | { | 161 | { |
162 | const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; | 162 | const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; |
163 | 163 | ||
164 | video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); | 164 | video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); |
165 | bool transparent = (rnd && rnd->isTransparent()); | 165 | bool transparent = (rnd && rnd->isTransparent()); |
166 | 166 | ||
167 | // only render transparent buffer if this is the transparent render pass | 167 | // only render transparent buffer if this is the transparent render pass |
168 | // and solid only in solid pass | 168 | // and solid only in solid pass |
169 | if (transparent == isTransparentPass) | 169 | if (transparent == isTransparentPass) |
170 | { | 170 | { |
171 | driver->setMaterial(material); | 171 | driver->setMaterial(material); |
172 | driver->drawMeshBuffer(mb); | 172 | driver->drawMeshBuffer(mb); |
173 | } | 173 | } |
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | 178 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); |
179 | 179 | ||
180 | // for debug purposes only: | 180 | // for debug purposes only: |
181 | if (DebugDataVisible && PassCount==1) | 181 | if (DebugDataVisible && PassCount==1) |
182 | { | 182 | { |
183 | video::SMaterial m; | 183 | video::SMaterial m; |
184 | m.Lighting = false; | 184 | m.Lighting = false; |
185 | m.AntiAliasing=0; | 185 | m.AntiAliasing=0; |
186 | driver->setMaterial(m); | 186 | driver->setMaterial(m); |
187 | 187 | ||
188 | if (DebugDataVisible & scene::EDS_BBOX) | 188 | if (DebugDataVisible & scene::EDS_BBOX) |
189 | { | 189 | { |
190 | driver->draw3DBox(Box, video::SColor(255,255,255,255)); | 190 | driver->draw3DBox(Box, video::SColor(255,255,255,255)); |
191 | } | 191 | } |
192 | if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) | 192 | if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) |
193 | { | 193 | { |
194 | for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g) | 194 | for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g) |
195 | { | 195 | { |
196 | driver->draw3DBox( | 196 | driver->draw3DBox( |
197 | Mesh->getMeshBuffer(g)->getBoundingBox(), | 197 | Mesh->getMeshBuffer(g)->getBoundingBox(), |
198 | video::SColor(255,190,128,128)); | 198 | video::SColor(255,190,128,128)); |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | if (DebugDataVisible & scene::EDS_NORMALS) | 202 | if (DebugDataVisible & scene::EDS_NORMALS) |
203 | { | 203 | { |
204 | // draw normals | 204 | // draw normals |
205 | const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); | 205 | const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); |
206 | const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); | 206 | const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); |
207 | const u32 count = Mesh->getMeshBufferCount(); | 207 | const u32 count = Mesh->getMeshBufferCount(); |
208 | 208 | ||
209 | for (u32 i=0; i != count; ++i) | 209 | for (u32 i=0; i != count; ++i) |
210 | { | 210 | { |
211 | driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor); | 211 | driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor); |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | // show mesh | 215 | // show mesh |
216 | if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) | 216 | if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) |
217 | { | 217 | { |
218 | m.Wireframe = true; | 218 | m.Wireframe = true; |
219 | driver->setMaterial(m); | 219 | driver->setMaterial(m); |
220 | 220 | ||
221 | for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g) | 221 | for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g) |
222 | { | 222 | { |
223 | driver->drawMeshBuffer(Mesh->getMeshBuffer(g)); | 223 | driver->drawMeshBuffer(Mesh->getMeshBuffer(g)); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | 229 | ||
230 | //! Removes a child from this scene node. | 230 | //! Removes a child from this scene node. |
231 | //! Implemented here, to be able to remove the shadow properly, if there is one, | 231 | //! Implemented here, to be able to remove the shadow properly, if there is one, |
232 | //! or to remove attached childs. | 232 | //! or to remove attached childs. |
233 | bool CMeshSceneNode::removeChild(ISceneNode* child) | 233 | bool CMeshSceneNode::removeChild(ISceneNode* child) |
234 | { | 234 | { |
235 | if (child && Shadow == child) | 235 | if (child && Shadow == child) |
236 | { | 236 | { |
237 | Shadow->drop(); | 237 | Shadow->drop(); |
238 | Shadow = 0; | 238 | Shadow = 0; |
239 | } | 239 | } |
240 | 240 | ||
241 | return ISceneNode::removeChild(child); | 241 | return ISceneNode::removeChild(child); |
242 | } | 242 | } |
243 | 243 | ||
244 | 244 | ||
245 | //! returns the axis aligned bounding box of this node | 245 | //! returns the axis aligned bounding box of this node |
246 | const core::aabbox3d<f32>& CMeshSceneNode::getBoundingBox() const | 246 | const core::aabbox3d<f32>& CMeshSceneNode::getBoundingBox() const |
247 | { | 247 | { |
248 | return Mesh ? Mesh->getBoundingBox() : Box; | 248 | return Mesh ? Mesh->getBoundingBox() : Box; |
249 | } | 249 | } |
250 | 250 | ||
251 | 251 | ||
252 | //! returns the material based on the zero based index i. To get the amount | 252 | //! returns the material based on the zero based index i. To get the amount |
253 | //! of materials used by this scene node, use getMaterialCount(). | 253 | //! of materials used by this scene node, use getMaterialCount(). |
254 | //! This function is needed for inserting the node into the scene hierarchy on a | 254 | //! This function is needed for inserting the node into the scene hierarchy on a |
255 | //! optimal position for minimizing renderstate changes, but can also be used | 255 | //! optimal position for minimizing renderstate changes, but can also be used |
256 | //! to directly modify the material of a scene node. | 256 | //! to directly modify the material of a scene node. |
257 | video::SMaterial& CMeshSceneNode::getMaterial(u32 i) | 257 | video::SMaterial& CMeshSceneNode::getMaterial(u32 i) |
258 | { | 258 | { |
259 | if (Mesh && ReadOnlyMaterials && i<Mesh->getMeshBufferCount()) | 259 | if (Mesh && ReadOnlyMaterials && i<Mesh->getMeshBufferCount()) |
260 | { | 260 | { |
261 | ReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial(); | 261 | ReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial(); |
262 | return ReadOnlyMaterial; | 262 | return ReadOnlyMaterial; |
263 | } | 263 | } |
264 | 264 | ||
265 | if (i >= Materials.size()) | 265 | if (i >= Materials.size()) |
266 | return ISceneNode::getMaterial(i); | 266 | return ISceneNode::getMaterial(i); |
267 | 267 | ||
268 | return Materials[i]; | 268 | return Materials[i]; |
269 | } | 269 | } |
270 | 270 | ||
271 | 271 | ||
272 | //! returns amount of materials used by this scene node. | 272 | //! returns amount of materials used by this scene node. |
273 | u32 CMeshSceneNode::getMaterialCount() const | 273 | u32 CMeshSceneNode::getMaterialCount() const |
274 | { | 274 | { |
275 | if (Mesh && ReadOnlyMaterials) | 275 | if (Mesh && ReadOnlyMaterials) |
276 | return Mesh->getMeshBufferCount(); | 276 | return Mesh->getMeshBufferCount(); |
277 | 277 | ||
278 | return Materials.size(); | 278 | return Materials.size(); |
279 | } | 279 | } |
280 | 280 | ||
281 | 281 | ||
282 | //! Sets a new mesh | 282 | //! Sets a new mesh |
283 | void CMeshSceneNode::setMesh(IMesh* mesh) | 283 | void CMeshSceneNode::setMesh(IMesh* mesh) |
284 | { | 284 | { |
285 | if (mesh) | 285 | if (mesh) |
286 | { | 286 | { |
287 | mesh->grab(); | 287 | mesh->grab(); |
288 | if (Mesh) | 288 | if (Mesh) |
289 | Mesh->drop(); | 289 | Mesh->drop(); |
290 | 290 | ||
291 | Mesh = mesh; | 291 | Mesh = mesh; |
292 | copyMaterials(); | 292 | copyMaterials(); |
293 | } | 293 | } |
294 | } | 294 | } |
295 | 295 | ||
296 | 296 | ||
297 | //! Creates shadow volume scene node as child of this node | 297 | //! Creates shadow volume scene node as child of this node |
298 | //! and returns a pointer to it. | 298 | //! and returns a pointer to it. |
299 | IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode( | 299 | IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode( |
300 | const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) | 300 | const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) |
301 | { | 301 | { |
302 | if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) | 302 | if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) |
303 | return 0; | 303 | return 0; |
304 | 304 | ||
305 | if (!shadowMesh) | 305 | if (!shadowMesh) |
306 | shadowMesh = Mesh; // if null is given, use the mesh of node | 306 | shadowMesh = Mesh; // if null is given, use the mesh of node |
307 | 307 | ||
308 | if (Shadow) | 308 | if (Shadow) |
309 | Shadow->drop(); | 309 | Shadow->drop(); |
310 | 310 | ||
311 | Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); | 311 | Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); |
312 | return Shadow; | 312 | return Shadow; |
313 | } | 313 | } |
314 | 314 | ||
315 | 315 | ||
316 | void CMeshSceneNode::copyMaterials() | 316 | void CMeshSceneNode::copyMaterials() |
317 | { | 317 | { |
318 | Materials.clear(); | 318 | Materials.clear(); |
319 | 319 | ||
320 | if (Mesh) | 320 | if (Mesh) |
321 | { | 321 | { |
322 | video::SMaterial mat; | 322 | video::SMaterial mat; |
323 | 323 | ||
324 | for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) | 324 | for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) |
325 | { | 325 | { |
326 | IMeshBuffer* mb = Mesh->getMeshBuffer(i); | 326 | IMeshBuffer* mb = Mesh->getMeshBuffer(i); |
327 | if (mb) | 327 | if (mb) |
328 | mat = mb->getMaterial(); | 328 | mat = mb->getMaterial(); |
329 | 329 | ||
330 | Materials.push_back(mat); | 330 | Materials.push_back(mat); |
331 | } | 331 | } |
332 | } | 332 | } |
333 | } | 333 | } |
334 | 334 | ||
335 | 335 | ||
336 | //! Writes attributes of the scene node. | 336 | //! Writes attributes of the scene node. |
337 | void CMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | 337 | void CMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const |
338 | { | 338 | { |
339 | IMeshSceneNode::serializeAttributes(out, options); | 339 | IMeshSceneNode::serializeAttributes(out, options); |
340 | 340 | ||
341 | if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename) | 341 | if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename) |
342 | { | 342 | { |
343 | const io::path path = SceneManager->getFileSystem()->getRelativeFilename( | 343 | const io::path path = SceneManager->getFileSystem()->getRelativeFilename( |
344 | SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()), | 344 | SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()), |
345 | options->Filename); | 345 | options->Filename); |
346 | out->addString("Mesh", path.c_str()); | 346 | out->addString("Mesh", path.c_str()); |
347 | } | 347 | } |
348 | else | 348 | else |
349 | out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str()); | 349 | out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str()); |
350 | out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); | 350 | out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); |
351 | } | 351 | } |
352 | 352 | ||
353 | 353 | ||
354 | //! Reads attributes of the scene node. | 354 | //! Reads attributes of the scene node. |
355 | void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | 355 | void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) |
356 | { | 356 | { |
357 | io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh); | 357 | io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh); |
358 | io::path newMeshStr = in->getAttributeAsString("Mesh"); | 358 | io::path newMeshStr = in->getAttributeAsString("Mesh"); |
359 | ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); | 359 | ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); |
360 | 360 | ||
361 | if (newMeshStr != "" && oldMeshStr != newMeshStr) | 361 | if (newMeshStr != "" && oldMeshStr != newMeshStr) |
362 | { | 362 | { |
363 | IMesh* newMesh = 0; | 363 | IMesh* newMesh = 0; |
364 | IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); | 364 | IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); |
365 | 365 | ||
366 | if (newAnimatedMesh) | 366 | if (newAnimatedMesh) |
367 | newMesh = newAnimatedMesh->getMesh(0); | 367 | newMesh = newAnimatedMesh->getMesh(0); |
368 | 368 | ||
369 | if (newMesh) | 369 | if (newMesh) |
370 | setMesh(newMesh); | 370 | setMesh(newMesh); |
371 | } | 371 | } |
372 | 372 | ||
373 | // optional attribute to assign the hint to the whole mesh | 373 | // optional attribute to assign the hint to the whole mesh |
374 | if (in->existsAttribute("HardwareMappingHint") && | 374 | if (in->existsAttribute("HardwareMappingHint") && |
375 | in->existsAttribute("HardwareMappingBufferType")) | 375 | in->existsAttribute("HardwareMappingBufferType")) |
376 | { | 376 | { |
377 | scene::E_HARDWARE_MAPPING mapping = scene::EHM_NEVER; | 377 | scene::E_HARDWARE_MAPPING mapping = scene::EHM_NEVER; |
378 | scene::E_BUFFER_TYPE bufferType = scene::EBT_NONE; | 378 | scene::E_BUFFER_TYPE bufferType = scene::EBT_NONE; |
379 | 379 | ||
380 | core::stringc smapping = in->getAttributeAsString("HardwareMappingHint"); | 380 | core::stringc smapping = in->getAttributeAsString("HardwareMappingHint"); |
381 | if (smapping.equals_ignore_case("static")) | 381 | if (smapping.equals_ignore_case("static")) |
382 | mapping = scene::EHM_STATIC; | 382 | mapping = scene::EHM_STATIC; |
383 | else if (smapping.equals_ignore_case("dynamic")) | 383 | else if (smapping.equals_ignore_case("dynamic")) |
384 | mapping = scene::EHM_DYNAMIC; | 384 | mapping = scene::EHM_DYNAMIC; |
385 | else if (smapping.equals_ignore_case("stream")) | 385 | else if (smapping.equals_ignore_case("stream")) |
386 | mapping = scene::EHM_STREAM; | 386 | mapping = scene::EHM_STREAM; |
387 | 387 | ||
388 | core::stringc sbufferType = in->getAttributeAsString("HardwareMappingBufferType"); | 388 | core::stringc sbufferType = in->getAttributeAsString("HardwareMappingBufferType"); |
389 | if (sbufferType.equals_ignore_case("vertex")) | 389 | if (sbufferType.equals_ignore_case("vertex")) |
390 | bufferType = scene::EBT_VERTEX; | 390 | bufferType = scene::EBT_VERTEX; |
391 | else if (sbufferType.equals_ignore_case("index")) | 391 | else if (sbufferType.equals_ignore_case("index")) |
392 | bufferType = scene::EBT_INDEX; | 392 | bufferType = scene::EBT_INDEX; |
393 | else if (sbufferType.equals_ignore_case("vertexindex")) | 393 | else if (sbufferType.equals_ignore_case("vertexindex")) |
394 | bufferType = scene::EBT_VERTEX_AND_INDEX; | 394 | bufferType = scene::EBT_VERTEX_AND_INDEX; |
395 | 395 | ||
396 | IMesh* mesh = getMesh(); | 396 | IMesh* mesh = getMesh(); |
397 | if (mesh) | 397 | if (mesh) |
398 | mesh->setHardwareMappingHint(mapping, bufferType); | 398 | mesh->setHardwareMappingHint(mapping, bufferType); |
399 | } | 399 | } |
400 | 400 | ||
401 | IMeshSceneNode::deserializeAttributes(in, options); | 401 | IMeshSceneNode::deserializeAttributes(in, options); |
402 | } | 402 | } |
403 | 403 | ||
404 | 404 | ||
405 | //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. | 405 | //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. |
406 | /* In this way it is possible to change the materials a mesh causing all mesh scene nodes | 406 | /* In this way it is possible to change the materials a mesh causing all mesh scene nodes |
407 | referencing this mesh to change too. */ | 407 | referencing this mesh to change too. */ |
408 | void CMeshSceneNode::setReadOnlyMaterials(bool readonly) | 408 | void CMeshSceneNode::setReadOnlyMaterials(bool readonly) |
409 | { | 409 | { |
410 | ReadOnlyMaterials = readonly; | 410 | ReadOnlyMaterials = readonly; |
411 | } | 411 | } |
412 | 412 | ||
413 | 413 | ||
414 | //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style | 414 | //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style |
415 | bool CMeshSceneNode::isReadOnlyMaterials() const | 415 | bool CMeshSceneNode::isReadOnlyMaterials() const |
416 | { | 416 | { |
417 | return ReadOnlyMaterials; | 417 | return ReadOnlyMaterials; |
418 | } | 418 | } |
419 | 419 | ||
420 | 420 | ||
421 | //! Creates a clone of this scene node and its children. | 421 | //! Creates a clone of this scene node and its children. |
422 | ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) | 422 | ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) |
423 | { | 423 | { |
424 | if (!newParent) | 424 | if (!newParent) |
425 | newParent = Parent; | 425 | newParent = Parent; |
426 | if (!newManager) | 426 | if (!newManager) |
427 | newManager = SceneManager; | 427 | newManager = SceneManager; |
428 | 428 | ||
429 | CMeshSceneNode* nb = new CMeshSceneNode(Mesh, newParent, | 429 | CMeshSceneNode* nb = new CMeshSceneNode(Mesh, newParent, |
430 | newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale); | 430 | newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale); |
431 | 431 | ||
432 | nb->cloneMembers(this, newManager); | 432 | nb->cloneMembers(this, newManager); |
433 | nb->ReadOnlyMaterials = ReadOnlyMaterials; | 433 | nb->ReadOnlyMaterials = ReadOnlyMaterials; |
434 | nb->Materials = Materials; | 434 | nb->Materials = Materials; |
435 | nb->Shadow = Shadow; | 435 | nb->Shadow = Shadow; |
436 | nb->Shadow->grab(); | 436 | nb->Shadow->grab(); |
437 | 437 | ||
438 | if (newParent) | 438 | if (newParent) |
439 | nb->drop(); | 439 | nb->drop(); |
440 | return nb; | 440 | return nb; |
441 | } | 441 | } |
442 | 442 | ||
443 | 443 | ||
444 | } // end namespace scene | 444 | } // end namespace scene |
445 | } // end namespace irr | 445 | } // end namespace irr |
446 | 446 | ||