aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp2258
1 files changed, 1129 insertions, 1129 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp
index a9f1276..bded2b2 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshSceneNode.cpp
@@ -1,1129 +1,1129 @@
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 "CAnimatedMeshSceneNode.h" 5#include "CAnimatedMeshSceneNode.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 "os.h" 9#include "os.h"
10#include "CShadowVolumeSceneNode.h" 10#include "CShadowVolumeSceneNode.h"
11#include "IAnimatedMeshMD3.h" 11#include "IAnimatedMeshMD3.h"
12#include "CSkinnedMesh.h" 12#include "CSkinnedMesh.h"
13#include "IDummyTransformationSceneNode.h" 13#include "IDummyTransformationSceneNode.h"
14#include "IBoneSceneNode.h" 14#include "IBoneSceneNode.h"
15#include "IMaterialRenderer.h" 15#include "IMaterialRenderer.h"
16#include "IMesh.h" 16#include "IMesh.h"
17#include "IMeshCache.h" 17#include "IMeshCache.h"
18#include "IAnimatedMesh.h" 18#include "IAnimatedMesh.h"
19#include "quaternion.h" 19#include "quaternion.h"
20 20
21 21
22namespace irr 22namespace irr
23{ 23{
24namespace scene 24namespace scene
25{ 25{
26 26
27 27
28//! constructor 28//! constructor
29CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh, 29CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh,
30 ISceneNode* parent, ISceneManager* mgr, s32 id, 30 ISceneNode* parent, ISceneManager* mgr, s32 id,
31 const core::vector3df& position, 31 const core::vector3df& position,
32 const core::vector3df& rotation, 32 const core::vector3df& rotation,
33 const core::vector3df& scale) 33 const core::vector3df& scale)
34: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), 34: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
35 StartFrame(0), EndFrame(0), FramesPerSecond(0.025f), 35 StartFrame(0), EndFrame(0), FramesPerSecond(0.025f),
36 CurrentFrameNr(0.f), LastTimeMs(0), 36 CurrentFrameNr(0.f), LastTimeMs(0),
37 TransitionTime(0), Transiting(0.f), TransitingBlend(0.f), 37 TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
38 JointMode(EJUOR_NONE), JointsUsed(false), 38 JointMode(EJUOR_NONE), JointsUsed(false),
39 Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false), 39 Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
40 LoopCallBack(0), PassCount(0), Shadow(0), MD3Special(0) 40 LoopCallBack(0), PassCount(0), Shadow(0), MD3Special(0)
41{ 41{
42 #ifdef _DEBUG 42 #ifdef _DEBUG
43 setDebugName("CAnimatedMeshSceneNode"); 43 setDebugName("CAnimatedMeshSceneNode");
44 #endif 44 #endif
45 45
46 setMesh(mesh); 46 setMesh(mesh);
47} 47}
48 48
49 49
50//! destructor 50//! destructor
51CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode() 51CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()
52{ 52{
53 if (MD3Special) 53 if (MD3Special)
54 MD3Special->drop(); 54 MD3Special->drop();
55 55
56 if (Mesh) 56 if (Mesh)
57 Mesh->drop(); 57 Mesh->drop();
58 58
59 if (Shadow) 59 if (Shadow)
60 Shadow->drop(); 60 Shadow->drop();
61 61
62 if (LoopCallBack) 62 if (LoopCallBack)
63 LoopCallBack->drop(); 63 LoopCallBack->drop();
64} 64}
65 65
66 66
67//! Sets the current frame. From now on the animation is played from this frame. 67//! Sets the current frame. From now on the animation is played from this frame.
68void CAnimatedMeshSceneNode::setCurrentFrame(f32 frame) 68void CAnimatedMeshSceneNode::setCurrentFrame(f32 frame)
69{ 69{
70 // if you pass an out of range value, we just clamp it 70 // if you pass an out of range value, we just clamp it
71 CurrentFrameNr = core::clamp ( frame, (f32)StartFrame, (f32)EndFrame ); 71 CurrentFrameNr = core::clamp ( frame, (f32)StartFrame, (f32)EndFrame );
72 72
73 beginTransition(); //transit to this frame if enabled 73 beginTransition(); //transit to this frame if enabled
74} 74}
75 75
76 76
77//! Returns the currently displayed frame number. 77//! Returns the currently displayed frame number.
78f32 CAnimatedMeshSceneNode::getFrameNr() const 78f32 CAnimatedMeshSceneNode::getFrameNr() const
79{ 79{
80 return CurrentFrameNr; 80 return CurrentFrameNr;
81} 81}
82 82
83 83
84//! Get CurrentFrameNr and update transiting settings 84//! Get CurrentFrameNr and update transiting settings
85void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs) 85void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
86{ 86{
87 if (Transiting!=0.f) 87 if (Transiting!=0.f)
88 { 88 {
89 TransitingBlend += (f32)(timeMs) * Transiting; 89 TransitingBlend += (f32)(timeMs) * Transiting;
90 if (TransitingBlend > 1.f) 90 if (TransitingBlend > 1.f)
91 { 91 {
92 Transiting=0.f; 92 Transiting=0.f;
93 TransitingBlend=0.f; 93 TransitingBlend=0.f;
94 } 94 }
95 } 95 }
96 96
97 if ((StartFrame==EndFrame)) 97 if ((StartFrame==EndFrame))
98 { 98 {
99 CurrentFrameNr = (f32)StartFrame; //Support for non animated meshes 99 CurrentFrameNr = (f32)StartFrame; //Support for non animated meshes
100 } 100 }
101 else if (Looping) 101 else if (Looping)
102 { 102 {
103 // play animation looped 103 // play animation looped
104 CurrentFrameNr += timeMs * FramesPerSecond; 104 CurrentFrameNr += timeMs * FramesPerSecond;
105 105
106 // We have no interpolation between EndFrame and StartFrame, 106 // We have no interpolation between EndFrame and StartFrame,
107 // the last frame must be identical to first one with our current solution. 107 // the last frame must be identical to first one with our current solution.
108 if (FramesPerSecond > 0.f) //forwards... 108 if (FramesPerSecond > 0.f) //forwards...
109 { 109 {
110 if (CurrentFrameNr > EndFrame) 110 if (CurrentFrameNr > EndFrame)
111 CurrentFrameNr = StartFrame + fmod(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame)); 111 CurrentFrameNr = StartFrame + fmod(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));
112 } 112 }
113 else //backwards... 113 else //backwards...
114 { 114 {
115 if (CurrentFrameNr < StartFrame) 115 if (CurrentFrameNr < StartFrame)
116 CurrentFrameNr = EndFrame - fmod(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame)); 116 CurrentFrameNr = EndFrame - fmod(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));
117 } 117 }
118 } 118 }
119 else 119 else
120 { 120 {
121 // play animation non looped 121 // play animation non looped
122 122
123 CurrentFrameNr += timeMs * FramesPerSecond; 123 CurrentFrameNr += timeMs * FramesPerSecond;
124 if (FramesPerSecond > 0.f) //forwards... 124 if (FramesPerSecond > 0.f) //forwards...
125 { 125 {
126 if (CurrentFrameNr > (f32)EndFrame) 126 if (CurrentFrameNr > (f32)EndFrame)
127 { 127 {
128 CurrentFrameNr = (f32)EndFrame; 128 CurrentFrameNr = (f32)EndFrame;
129 if (LoopCallBack) 129 if (LoopCallBack)
130 LoopCallBack->OnAnimationEnd(this); 130 LoopCallBack->OnAnimationEnd(this);
131 } 131 }
132 } 132 }
133 else //backwards... 133 else //backwards...
134 { 134 {
135 if (CurrentFrameNr < (f32)StartFrame) 135 if (CurrentFrameNr < (f32)StartFrame)
136 { 136 {
137 CurrentFrameNr = (f32)StartFrame; 137 CurrentFrameNr = (f32)StartFrame;
138 if (LoopCallBack) 138 if (LoopCallBack)
139 LoopCallBack->OnAnimationEnd(this); 139 LoopCallBack->OnAnimationEnd(this);
140 } 140 }
141 } 141 }
142 } 142 }
143} 143}
144 144
145 145
146void CAnimatedMeshSceneNode::OnRegisterSceneNode() 146void CAnimatedMeshSceneNode::OnRegisterSceneNode()
147{ 147{
148 if (IsVisible) 148 if (IsVisible)
149 { 149 {
150 // because this node supports rendering of mixed mode meshes consisting of 150 // because this node supports rendering of mixed mode meshes consisting of
151 // transparent and solid material at the same time, we need to go through all 151 // transparent and solid material at the same time, we need to go through all
152 // materials, check of what type they are and register this node for the right 152 // materials, check of what type they are and register this node for the right
153 // render pass according to that. 153 // render pass according to that.
154 154
155 video::IVideoDriver* driver = SceneManager->getVideoDriver(); 155 video::IVideoDriver* driver = SceneManager->getVideoDriver();
156 156
157 PassCount = 0; 157 PassCount = 0;
158 int transparentCount = 0; 158 int transparentCount = 0;
159 int solidCount = 0; 159 int solidCount = 0;
160 160
161 // count transparent and solid materials in this scene node 161 // count transparent and solid materials in this scene node
162 for (u32 i=0; i<Materials.size(); ++i) 162 for (u32 i=0; i<Materials.size(); ++i)
163 { 163 {
164 video::IMaterialRenderer* rnd = 164 video::IMaterialRenderer* rnd =
165 driver->getMaterialRenderer(Materials[i].MaterialType); 165 driver->getMaterialRenderer(Materials[i].MaterialType);
166 166
167 if (rnd && rnd->isTransparent()) 167 if (rnd && rnd->isTransparent())
168 ++transparentCount; 168 ++transparentCount;
169 else 169 else
170 ++solidCount; 170 ++solidCount;
171 171
172 if (solidCount && transparentCount) 172 if (solidCount && transparentCount)
173 break; 173 break;
174 } 174 }
175 175
176 // register according to material types counted 176 // register according to material types counted
177 177
178 if (solidCount) 178 if (solidCount)
179 SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); 179 SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
180 180
181 if (transparentCount) 181 if (transparentCount)
182 SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); 182 SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
183 183
184 ISceneNode::OnRegisterSceneNode(); 184 ISceneNode::OnRegisterSceneNode();
185 } 185 }
186} 186}
187 187
188IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame() 188IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
189{ 189{
190 if(Mesh->getMeshType() != EAMT_SKINNED) 190 if(Mesh->getMeshType() != EAMT_SKINNED)
191 { 191 {
192 s32 frameNr = (s32) getFrameNr(); 192 s32 frameNr = (s32) getFrameNr();
193 s32 frameBlend = (s32) (core::fract ( getFrameNr() ) * 1000.f); 193 s32 frameBlend = (s32) (core::fract ( getFrameNr() ) * 1000.f);
194 return Mesh->getMesh(frameNr, frameBlend, StartFrame, EndFrame); 194 return Mesh->getMesh(frameNr, frameBlend, StartFrame, EndFrame);
195 } 195 }
196 else 196 else
197 { 197 {
198#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ 198#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
199 return 0; 199 return 0;
200#else 200#else
201 201
202 // As multiple scene nodes may be sharing the same skinned mesh, we have to 202 // As multiple scene nodes may be sharing the same skinned mesh, we have to
203 // re-animate it every frame to ensure that this node gets the mesh that it needs. 203 // re-animate it every frame to ensure that this node gets the mesh that it needs.
204 204
205 CSkinnedMesh* skinnedMesh = reinterpret_cast<CSkinnedMesh*>(Mesh); 205 CSkinnedMesh* skinnedMesh = reinterpret_cast<CSkinnedMesh*>(Mesh);
206 206
207 if (JointMode == EJUOR_CONTROL)//write to mesh 207 if (JointMode == EJUOR_CONTROL)//write to mesh
208 skinnedMesh->transferJointsToMesh(JointChildSceneNodes); 208 skinnedMesh->transferJointsToMesh(JointChildSceneNodes);
209 else 209 else
210 skinnedMesh->animateMesh(getFrameNr(), 1.0f); 210 skinnedMesh->animateMesh(getFrameNr(), 1.0f);
211 211
212 // Update the skinned mesh for the current joint transforms. 212 // Update the skinned mesh for the current joint transforms.
213 skinnedMesh->skinMesh(); 213 skinnedMesh->skinMesh();
214 214
215 if (JointMode == EJUOR_READ)//read from mesh 215 if (JointMode == EJUOR_READ)//read from mesh
216 { 216 {
217 skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes); 217 skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes);
218 218
219 //---slow--- 219 //---slow---
220 for (u32 n=0;n<JointChildSceneNodes.size();++n) 220 for (u32 n=0;n<JointChildSceneNodes.size();++n)
221 if (JointChildSceneNodes[n]->getParent()==this) 221 if (JointChildSceneNodes[n]->getParent()==this)
222 { 222 {
223 JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option 223 JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option
224 } 224 }
225 } 225 }
226 226
227 if(JointMode == EJUOR_CONTROL) 227 if(JointMode == EJUOR_CONTROL)
228 { 228 {
229 // For meshes other than EJUOR_CONTROL, this is done by calling animateMesh() 229 // For meshes other than EJUOR_CONTROL, this is done by calling animateMesh()
230 skinnedMesh->updateBoundingBox(); 230 skinnedMesh->updateBoundingBox();
231 } 231 }
232 232
233 return skinnedMesh; 233 return skinnedMesh;
234#endif 234#endif
235 } 235 }
236} 236}
237 237
238 238
239//! OnAnimate() is called just before rendering the whole scene. 239//! OnAnimate() is called just before rendering the whole scene.
240void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs) 240void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
241{ 241{
242 if (LastTimeMs==0) // first frame 242 if (LastTimeMs==0) // first frame
243 { 243 {
244 LastTimeMs = timeMs; 244 LastTimeMs = timeMs;
245 } 245 }
246 246
247 // set CurrentFrameNr 247 // set CurrentFrameNr
248 buildFrameNr(timeMs-LastTimeMs); 248 buildFrameNr(timeMs-LastTimeMs);
249 249
250 // update bbox 250 // update bbox
251 if (Mesh) 251 if (Mesh)
252 { 252 {
253 scene::IMesh * mesh = getMeshForCurrentFrame(); 253 scene::IMesh * mesh = getMeshForCurrentFrame();
254 254
255 if (mesh) 255 if (mesh)
256 Box = mesh->getBoundingBox(); 256 Box = mesh->getBoundingBox();
257 } 257 }
258 LastTimeMs = timeMs; 258 LastTimeMs = timeMs;
259 259
260 IAnimatedMeshSceneNode::OnAnimate(timeMs); 260 IAnimatedMeshSceneNode::OnAnimate(timeMs);
261} 261}
262 262
263 263
264//! renders the node. 264//! renders the node.
265void CAnimatedMeshSceneNode::render() 265void CAnimatedMeshSceneNode::render()
266{ 266{
267 video::IVideoDriver* driver = SceneManager->getVideoDriver(); 267 video::IVideoDriver* driver = SceneManager->getVideoDriver();
268 268
269 if (!Mesh || !driver) 269 if (!Mesh || !driver)
270 return; 270 return;
271 271
272 272
273 bool isTransparentPass = 273 bool isTransparentPass =
274 SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; 274 SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
275 275
276 ++PassCount; 276 ++PassCount;
277 277
278 scene::IMesh* m = getMeshForCurrentFrame(); 278 scene::IMesh* m = getMeshForCurrentFrame();
279 279
280 if(m) 280 if(m)
281 { 281 {
282 Box = m->getBoundingBox(); 282 Box = m->getBoundingBox();
283 } 283 }
284 else 284 else
285 { 285 {
286 #ifdef _DEBUG 286 #ifdef _DEBUG
287 os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING); 287 os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING);
288 #endif 288 #endif
289 } 289 }
290 290
291 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); 291 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
292 292
293 if (Shadow && PassCount==1) 293 if (Shadow && PassCount==1)
294 Shadow->updateShadowVolumes(); 294 Shadow->updateShadowVolumes();
295 295
296 // for debug purposes only: 296 // for debug purposes only:
297 297
298 bool renderMeshes = true; 298 bool renderMeshes = true;
299 video::SMaterial mat; 299 video::SMaterial mat;
300 if (DebugDataVisible && PassCount==1) 300 if (DebugDataVisible && PassCount==1)
301 { 301 {
302 // overwrite half transparency 302 // overwrite half transparency
303 if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) 303 if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY)
304 { 304 {
305 305
306 for (u32 i=0; i<m->getMeshBufferCount(); ++i) 306 for (u32 i=0; i<m->getMeshBufferCount(); ++i)
307 { 307 {
308 scene::IMeshBuffer* mb = m->getMeshBuffer(i); 308 scene::IMeshBuffer* mb = m->getMeshBuffer(i);
309 mat = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; 309 mat = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
310 mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; 310 mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
311 if (RenderFromIdentity) 311 if (RenderFromIdentity)
312 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); 312 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix );
313 else if (Mesh->getMeshType() == EAMT_SKINNED) 313 else if (Mesh->getMeshType() == EAMT_SKINNED)
314 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); 314 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation);
315 315
316 driver->setMaterial(mat); 316 driver->setMaterial(mat);
317 driver->drawMeshBuffer(mb); 317 driver->drawMeshBuffer(mb);
318 } 318 }
319 renderMeshes = false; 319 renderMeshes = false;
320 } 320 }
321 } 321 }
322 322
323 // render original meshes 323 // render original meshes
324 if (renderMeshes) 324 if (renderMeshes)
325 { 325 {
326 for (u32 i=0; i<m->getMeshBufferCount(); ++i) 326 for (u32 i=0; i<m->getMeshBufferCount(); ++i)
327 { 327 {
328 video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); 328 video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
329 bool transparent = (rnd && rnd->isTransparent()); 329 bool transparent = (rnd && rnd->isTransparent());
330 330
331 // only render transparent buffer if this is the transparent render pass 331 // only render transparent buffer if this is the transparent render pass
332 // and solid only in solid pass 332 // and solid only in solid pass
333 if (transparent == isTransparentPass) 333 if (transparent == isTransparentPass)
334 { 334 {
335 scene::IMeshBuffer* mb = m->getMeshBuffer(i); 335 scene::IMeshBuffer* mb = m->getMeshBuffer(i);
336 const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; 336 const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
337 if (RenderFromIdentity) 337 if (RenderFromIdentity)
338 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); 338 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix );
339 else if (Mesh->getMeshType() == EAMT_SKINNED) 339 else if (Mesh->getMeshType() == EAMT_SKINNED)
340 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); 340 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation);
341 341
342 driver->setMaterial(material); 342 driver->setMaterial(material);
343 driver->drawMeshBuffer(mb); 343 driver->drawMeshBuffer(mb);
344 } 344 }
345 } 345 }
346 } 346 }
347 347
348 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); 348 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
349 349
350 // for debug purposes only: 350 // for debug purposes only:
351 if (DebugDataVisible && PassCount==1) 351 if (DebugDataVisible && PassCount==1)
352 { 352 {
353 video::SMaterial debug_mat; 353 video::SMaterial debug_mat;
354 debug_mat.Lighting = false; 354 debug_mat.Lighting = false;
355 debug_mat.AntiAliasing=0; 355 debug_mat.AntiAliasing=0;
356 driver->setMaterial(debug_mat); 356 driver->setMaterial(debug_mat);
357 // show normals 357 // show normals
358 if (DebugDataVisible & scene::EDS_NORMALS) 358 if (DebugDataVisible & scene::EDS_NORMALS)
359 { 359 {
360 const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); 360 const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH);
361 const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); 361 const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR);
362 const u32 count = m->getMeshBufferCount(); 362 const u32 count = m->getMeshBufferCount();
363 363
364 // draw normals 364 // draw normals
365 for (u32 g=0; g < count; ++g) 365 for (u32 g=0; g < count; ++g)
366 { 366 {
367 driver->drawMeshBufferNormals(m->getMeshBuffer(g), debugNormalLength, debugNormalColor); 367 driver->drawMeshBufferNormals(m->getMeshBuffer(g), debugNormalLength, debugNormalColor);
368 } 368 }
369 } 369 }
370 370
371 debug_mat.ZBuffer = video::ECFN_NEVER; 371 debug_mat.ZBuffer = video::ECFN_NEVER;
372 debug_mat.Lighting = false; 372 debug_mat.Lighting = false;
373 driver->setMaterial(debug_mat); 373 driver->setMaterial(debug_mat);
374 374
375 if (DebugDataVisible & scene::EDS_BBOX) 375 if (DebugDataVisible & scene::EDS_BBOX)
376 driver->draw3DBox(Box, video::SColor(255,255,255,255)); 376 driver->draw3DBox(Box, video::SColor(255,255,255,255));
377 377
378 // show bounding box 378 // show bounding box
379 if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) 379 if (DebugDataVisible & scene::EDS_BBOX_BUFFERS)
380 { 380 {
381 for (u32 g=0; g< m->getMeshBufferCount(); ++g) 381 for (u32 g=0; g< m->getMeshBufferCount(); ++g)
382 { 382 {
383 const IMeshBuffer* mb = m->getMeshBuffer(g); 383 const IMeshBuffer* mb = m->getMeshBuffer(g);
384 384
385 if (Mesh->getMeshType() == EAMT_SKINNED) 385 if (Mesh->getMeshType() == EAMT_SKINNED)
386 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); 386 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation);
387 driver->draw3DBox(mb->getBoundingBox(), video::SColor(255,190,128,128)); 387 driver->draw3DBox(mb->getBoundingBox(), video::SColor(255,190,128,128));
388 } 388 }
389 } 389 }
390 390
391 // show skeleton 391 // show skeleton
392 if (DebugDataVisible & scene::EDS_SKELETON) 392 if (DebugDataVisible & scene::EDS_SKELETON)
393 { 393 {
394 if (Mesh->getMeshType() == EAMT_SKINNED) 394 if (Mesh->getMeshType() == EAMT_SKINNED)
395 { 395 {
396 // draw skeleton 396 // draw skeleton
397 397
398 for (u32 g=0; g < ((ISkinnedMesh*)Mesh)->getAllJoints().size(); ++g) 398 for (u32 g=0; g < ((ISkinnedMesh*)Mesh)->getAllJoints().size(); ++g)
399 { 399 {
400 ISkinnedMesh::SJoint *joint=((ISkinnedMesh*)Mesh)->getAllJoints()[g]; 400 ISkinnedMesh::SJoint *joint=((ISkinnedMesh*)Mesh)->getAllJoints()[g];
401 401
402 for (u32 n=0;n<joint->Children.size();++n) 402 for (u32 n=0;n<joint->Children.size();++n)
403 { 403 {
404 driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(), 404 driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(),
405 joint->Children[n]->GlobalAnimatedMatrix.getTranslation(), 405 joint->Children[n]->GlobalAnimatedMatrix.getTranslation(),
406 video::SColor(255,51,66,255)); 406 video::SColor(255,51,66,255));
407 } 407 }
408 } 408 }
409 } 409 }
410 410
411 // show tag for quake3 models 411 // show tag for quake3 models
412 if (Mesh->getMeshType() == EAMT_MD3) 412 if (Mesh->getMeshType() == EAMT_MD3)
413 { 413 {
414 IAnimatedMesh * arrow = 414 IAnimatedMesh * arrow =
415 SceneManager->addArrowMesh ( 415 SceneManager->addArrowMesh (
416 "__tag_show", 416 "__tag_show",
417 0xFF0000FF, 0xFF000088, 417 0xFF0000FF, 0xFF000088,
418 4, 8, 5.f, 4.f, 0.5f, 418 4, 8, 5.f, 4.f, 0.5f,
419 1.f); 419 1.f);
420 if (!arrow) 420 if (!arrow)
421 { 421 {
422 arrow = SceneManager->getMesh ( "__tag_show" ); 422 arrow = SceneManager->getMesh ( "__tag_show" );
423 } 423 }
424 IMesh *arrowMesh = arrow->getMesh(0); 424 IMesh *arrowMesh = arrow->getMesh(0);
425 425
426 core::matrix4 matr; 426 core::matrix4 matr;
427 427
428 SMD3QuaternionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList( 428 SMD3QuaternionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList(
429 (s32)getFrameNr(), 255, 429 (s32)getFrameNr(), 255,
430 getStartFrame(), getEndFrame()); 430 getStartFrame(), getEndFrame());
431 if (taglist) 431 if (taglist)
432 { 432 {
433 for ( u32 ts = 0; ts != taglist->size(); ++ts ) 433 for ( u32 ts = 0; ts != taglist->size(); ++ts )
434 { 434 {
435 (*taglist)[ts].setto(matr); 435 (*taglist)[ts].setto(matr);
436 436
437 driver->setTransform(video::ETS_WORLD, matr ); 437 driver->setTransform(video::ETS_WORLD, matr );
438 438
439 for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a ) 439 for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a )
440 driver->drawMeshBuffer(arrowMesh->getMeshBuffer(a)); 440 driver->drawMeshBuffer(arrowMesh->getMeshBuffer(a));
441 } 441 }
442 } 442 }
443 } 443 }
444 } 444 }
445 445
446 // show mesh 446 // show mesh
447 if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) 447 if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)
448 { 448 {
449 debug_mat.Lighting = false; 449 debug_mat.Lighting = false;
450 debug_mat.Wireframe = true; 450 debug_mat.Wireframe = true;
451 debug_mat.ZBuffer = video::ECFN_NEVER; 451 debug_mat.ZBuffer = video::ECFN_NEVER;
452 driver->setMaterial(debug_mat); 452 driver->setMaterial(debug_mat);
453 453
454 for (u32 g=0; g<m->getMeshBufferCount(); ++g) 454 for (u32 g=0; g<m->getMeshBufferCount(); ++g)
455 { 455 {
456 const IMeshBuffer* mb = m->getMeshBuffer(g); 456 const IMeshBuffer* mb = m->getMeshBuffer(g);
457 if (RenderFromIdentity) 457 if (RenderFromIdentity)
458 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); 458 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix );
459 else if (Mesh->getMeshType() == EAMT_SKINNED) 459 else if (Mesh->getMeshType() == EAMT_SKINNED)
460 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); 460 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation);
461 driver->drawMeshBuffer(mb); 461 driver->drawMeshBuffer(mb);
462 } 462 }
463 } 463 }
464 } 464 }
465} 465}
466 466
467 467
468//! Returns the current start frame number. 468//! Returns the current start frame number.
469s32 CAnimatedMeshSceneNode::getStartFrame() const 469s32 CAnimatedMeshSceneNode::getStartFrame() const
470{ 470{
471 return StartFrame; 471 return StartFrame;
472} 472}
473 473
474 474
475//! Returns the current start frame number. 475//! Returns the current start frame number.
476s32 CAnimatedMeshSceneNode::getEndFrame() const 476s32 CAnimatedMeshSceneNode::getEndFrame() const
477{ 477{
478 return EndFrame; 478 return EndFrame;
479} 479}
480 480
481 481
482//! sets the frames between the animation is looped. 482//! sets the frames between the animation is looped.
483//! the default is 0 - MaximalFrameCount of the mesh. 483//! the default is 0 - MaximalFrameCount of the mesh.
484bool CAnimatedMeshSceneNode::setFrameLoop(s32 begin, s32 end) 484bool CAnimatedMeshSceneNode::setFrameLoop(s32 begin, s32 end)
485{ 485{
486 const s32 maxFrameCount = Mesh->getFrameCount() - 1; 486 const s32 maxFrameCount = Mesh->getFrameCount() - 1;
487 if (end < begin) 487 if (end < begin)
488 { 488 {
489 StartFrame = core::s32_clamp(end, 0, maxFrameCount); 489 StartFrame = core::s32_clamp(end, 0, maxFrameCount);
490 EndFrame = core::s32_clamp(begin, StartFrame, maxFrameCount); 490 EndFrame = core::s32_clamp(begin, StartFrame, maxFrameCount);
491 } 491 }
492 else 492 else
493 { 493 {
494 StartFrame = core::s32_clamp(begin, 0, maxFrameCount); 494 StartFrame = core::s32_clamp(begin, 0, maxFrameCount);
495 EndFrame = core::s32_clamp(end, StartFrame, maxFrameCount); 495 EndFrame = core::s32_clamp(end, StartFrame, maxFrameCount);
496 } 496 }
497 if (FramesPerSecond < 0) 497 if (FramesPerSecond < 0)
498 setCurrentFrame((f32)EndFrame); 498 setCurrentFrame((f32)EndFrame);
499 else 499 else
500 setCurrentFrame((f32)StartFrame); 500 setCurrentFrame((f32)StartFrame);
501 501
502 return true; 502 return true;
503} 503}
504 504
505 505
506//! sets the speed with witch the animation is played 506//! sets the speed with witch the animation is played
507void CAnimatedMeshSceneNode::setAnimationSpeed(f32 framesPerSecond) 507void CAnimatedMeshSceneNode::setAnimationSpeed(f32 framesPerSecond)
508{ 508{
509 FramesPerSecond = framesPerSecond * 0.001f; 509 FramesPerSecond = framesPerSecond * 0.001f;
510} 510}
511 511
512 512
513f32 CAnimatedMeshSceneNode::getAnimationSpeed() const 513f32 CAnimatedMeshSceneNode::getAnimationSpeed() const
514{ 514{
515 return FramesPerSecond * 1000.f; 515 return FramesPerSecond * 1000.f;
516} 516}
517 517
518 518
519//! returns the axis aligned bounding box of this node 519//! returns the axis aligned bounding box of this node
520const core::aabbox3d<f32>& CAnimatedMeshSceneNode::getBoundingBox() const 520const core::aabbox3d<f32>& CAnimatedMeshSceneNode::getBoundingBox() const
521{ 521{
522 return Box; 522 return Box;
523} 523}
524 524
525 525
526//! returns the material based on the zero based index i. To get the amount 526//! returns the material based on the zero based index i. To get the amount
527//! of materials used by this scene node, use getMaterialCount(). 527//! of materials used by this scene node, use getMaterialCount().
528//! This function is needed for inserting the node into the scene hirachy on a 528//! This function is needed for inserting the node into the scene hirachy on a
529//! optimal position for minimizing renderstate changes, but can also be used 529//! optimal position for minimizing renderstate changes, but can also be used
530//! to directly modify the material of a scene node. 530//! to directly modify the material of a scene node.
531video::SMaterial& CAnimatedMeshSceneNode::getMaterial(u32 i) 531video::SMaterial& CAnimatedMeshSceneNode::getMaterial(u32 i)
532{ 532{
533 if (i >= Materials.size()) 533 if (i >= Materials.size())
534 return ISceneNode::getMaterial(i); 534 return ISceneNode::getMaterial(i);
535 535
536 return Materials[i]; 536 return Materials[i];
537} 537}
538 538
539 539
540 540
541//! returns amount of materials used by this scene node. 541//! returns amount of materials used by this scene node.
542u32 CAnimatedMeshSceneNode::getMaterialCount() const 542u32 CAnimatedMeshSceneNode::getMaterialCount() const
543{ 543{
544 return Materials.size(); 544 return Materials.size();
545} 545}
546 546
547 547
548//! Creates shadow volume scene node as child of this node 548//! Creates shadow volume scene node as child of this node
549//! and returns a pointer to it. 549//! and returns a pointer to it.
550IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode( 550IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(
551 const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) 551 const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)
552{ 552{
553 if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) 553 if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))
554 return 0; 554 return 0;
555 555
556 if (!shadowMesh) 556 if (!shadowMesh)
557 shadowMesh = Mesh; // if null is given, use the mesh of node 557 shadowMesh = Mesh; // if null is given, use the mesh of node
558 558
559 if (Shadow) 559 if (Shadow)
560 Shadow->drop(); 560 Shadow->drop();
561 561
562 Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); 562 Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity);
563 return Shadow; 563 return Shadow;
564} 564}
565 565
566//! Returns a pointer to a child node, which has the same transformation as 566//! Returns a pointer to a child node, which has the same transformation as
567//! the corresponding joint, if the mesh in this scene node is a skinned mesh. 567//! the corresponding joint, if the mesh in this scene node is a skinned mesh.
568IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName) 568IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName)
569{ 569{
570#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ 570#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
571 os::Printer::log("Compiled without _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_", ELL_WARNING); 571 os::Printer::log("Compiled without _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_", ELL_WARNING);
572 return 0; 572 return 0;
573#else 573#else
574 574
575 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) 575 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
576 { 576 {
577 os::Printer::log("No mesh, or mesh not of skinned mesh type", ELL_WARNING); 577 os::Printer::log("No mesh, or mesh not of skinned mesh type", ELL_WARNING);
578 return 0; 578 return 0;
579 } 579 }
580 580
581 checkJoints(); 581 checkJoints();
582 582
583 ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh; 583 ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh;
584 584
585 const s32 number = skinnedMesh->getJointNumber(jointName); 585 const s32 number = skinnedMesh->getJointNumber(jointName);
586 586
587 if (number == -1) 587 if (number == -1)
588 { 588 {
589 os::Printer::log("Joint with specified name not found in skinned mesh", jointName, ELL_DEBUG); 589 os::Printer::log("Joint with specified name not found in skinned mesh", jointName, ELL_DEBUG);
590 return 0; 590 return 0;
591 } 591 }
592 592
593 if ((s32)JointChildSceneNodes.size() <= number) 593 if ((s32)JointChildSceneNodes.size() <= number)
594 { 594 {
595 os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING); 595 os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING);
596 return 0; 596 return 0;
597 } 597 }
598 598
599 return JointChildSceneNodes[number]; 599 return JointChildSceneNodes[number];
600#endif 600#endif
601} 601}
602 602
603 603
604 604
605//! Returns a pointer to a child node, which has the same transformation as 605//! Returns a pointer to a child node, which has the same transformation as
606//! the corresponding joint, if the mesh in this scene node is a skinned mesh. 606//! the corresponding joint, if the mesh in this scene node is a skinned mesh.
607IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(u32 jointID) 607IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(u32 jointID)
608{ 608{
609#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ 609#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
610 os::Printer::log("Compiled without _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_", ELL_WARNING); 610 os::Printer::log("Compiled without _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_", ELL_WARNING);
611 return 0; 611 return 0;
612#else 612#else
613 613
614 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) 614 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
615 { 615 {
616 os::Printer::log("No mesh, or mesh not of skinned mesh type", ELL_WARNING); 616 os::Printer::log("No mesh, or mesh not of skinned mesh type", ELL_WARNING);
617 return 0; 617 return 0;
618 } 618 }
619 619
620 checkJoints(); 620 checkJoints();
621 621
622 if (JointChildSceneNodes.size() <= jointID) 622 if (JointChildSceneNodes.size() <= jointID)
623 { 623 {
624 os::Printer::log("Joint not loaded into node", ELL_WARNING); 624 os::Printer::log("Joint not loaded into node", ELL_WARNING);
625 return 0; 625 return 0;
626 } 626 }
627 627
628 return JointChildSceneNodes[jointID]; 628 return JointChildSceneNodes[jointID];
629#endif 629#endif
630} 630}
631 631
632//! Gets joint count. 632//! Gets joint count.
633u32 CAnimatedMeshSceneNode::getJointCount() const 633u32 CAnimatedMeshSceneNode::getJointCount() const
634{ 634{
635#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ 635#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
636 return 0; 636 return 0;
637#else 637#else
638 638
639 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) 639 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
640 return 0; 640 return 0;
641 641
642 ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh; 642 ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh;
643 643
644 return skinnedMesh->getJointCount(); 644 return skinnedMesh->getJointCount();
645#endif 645#endif
646} 646}
647 647
648 648
649//! Returns a pointer to a child node, which has the same transformation as 649//! Returns a pointer to a child node, which has the same transformation as
650//! the corresponding joint, if the mesh in this scene node is a ms3d mesh. 650//! the corresponding joint, if the mesh in this scene node is a ms3d mesh.
651ISceneNode* CAnimatedMeshSceneNode::getMS3DJointNode(const c8* jointName) 651ISceneNode* CAnimatedMeshSceneNode::getMS3DJointNode(const c8* jointName)
652{ 652{
653 return getJointNode(jointName); 653 return getJointNode(jointName);
654} 654}
655 655
656 656
657//! Returns a pointer to a child node, which has the same transformation as 657//! Returns a pointer to a child node, which has the same transformation as
658//! the corresponding joint, if the mesh in this scene node is a .x mesh. 658//! the corresponding joint, if the mesh in this scene node is a .x mesh.
659ISceneNode* CAnimatedMeshSceneNode::getXJointNode(const c8* jointName) 659ISceneNode* CAnimatedMeshSceneNode::getXJointNode(const c8* jointName)
660{ 660{
661 return getJointNode(jointName); 661 return getJointNode(jointName);
662} 662}
663 663
664//! Removes a child from this scene node. 664//! Removes a child from this scene node.
665//! Implemented here, to be able to remove the shadow properly, if there is one, 665//! Implemented here, to be able to remove the shadow properly, if there is one,
666//! or to remove attached childs. 666//! or to remove attached childs.
667bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child) 667bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child)
668{ 668{
669 if (child && Shadow == child) 669 if (child && Shadow == child)
670 { 670 {
671 Shadow->drop(); 671 Shadow->drop();
672 Shadow = 0; 672 Shadow = 0;
673 } 673 }
674 674
675 if (ISceneNode::removeChild(child)) 675 if (ISceneNode::removeChild(child))
676 { 676 {
677 if (JointsUsed) //stop weird bugs caused while changing parents as the joints are being created 677 if (JointsUsed) //stop weird bugs caused while changing parents as the joints are being created
678 { 678 {
679 for (u32 i=0; i<JointChildSceneNodes.size(); ++i) 679 for (u32 i=0; i<JointChildSceneNodes.size(); ++i)
680 { 680 {
681 if (JointChildSceneNodes[i] == child) 681 if (JointChildSceneNodes[i] == child)
682 { 682 {
683 JointChildSceneNodes[i] = 0; //remove link to child 683 JointChildSceneNodes[i] = 0; //remove link to child
684 break; 684 break;
685 } 685 }
686 } 686 }
687 } 687 }
688 return true; 688 return true;
689 } 689 }
690 690
691 return false; 691 return false;
692} 692}
693 693
694 694
695//! Starts a MD2 animation. 695//! Starts a MD2 animation.
696bool CAnimatedMeshSceneNode::setMD2Animation(EMD2_ANIMATION_TYPE anim) 696bool CAnimatedMeshSceneNode::setMD2Animation(EMD2_ANIMATION_TYPE anim)
697{ 697{
698 if (!Mesh || Mesh->getMeshType() != EAMT_MD2) 698 if (!Mesh || Mesh->getMeshType() != EAMT_MD2)
699 return false; 699 return false;
700 700
701 IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh; 701 IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh;
702 702
703 s32 begin, end, speed; 703 s32 begin, end, speed;
704 md->getFrameLoop(anim, begin, end, speed); 704 md->getFrameLoop(anim, begin, end, speed);
705 705
706 setAnimationSpeed( f32(speed) ); 706 setAnimationSpeed( f32(speed) );
707 setFrameLoop(begin, end); 707 setFrameLoop(begin, end);
708 return true; 708 return true;
709} 709}
710 710
711 711
712//! Starts a special MD2 animation. 712//! Starts a special MD2 animation.
713bool CAnimatedMeshSceneNode::setMD2Animation(const c8* animationName) 713bool CAnimatedMeshSceneNode::setMD2Animation(const c8* animationName)
714{ 714{
715 if (!Mesh || Mesh->getMeshType() != EAMT_MD2) 715 if (!Mesh || Mesh->getMeshType() != EAMT_MD2)
716 return false; 716 return false;
717 717
718 IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh; 718 IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh;
719 719
720 s32 begin, end, speed; 720 s32 begin, end, speed;
721 if (!md->getFrameLoop(animationName, begin, end, speed)) 721 if (!md->getFrameLoop(animationName, begin, end, speed))
722 return false; 722 return false;
723 723
724 setAnimationSpeed( (f32)speed ); 724 setAnimationSpeed( (f32)speed );
725 setFrameLoop(begin, end); 725 setFrameLoop(begin, end);
726 return true; 726 return true;
727} 727}
728 728
729 729
730//! Sets looping mode which is on by default. If set to false, 730//! Sets looping mode which is on by default. If set to false,
731//! animations will not be looped. 731//! animations will not be looped.
732void CAnimatedMeshSceneNode::setLoopMode(bool playAnimationLooped) 732void CAnimatedMeshSceneNode::setLoopMode(bool playAnimationLooped)
733{ 733{
734 Looping = playAnimationLooped; 734 Looping = playAnimationLooped;
735} 735}
736 736
737//! returns the current loop mode 737//! returns the current loop mode
738bool CAnimatedMeshSceneNode::getLoopMode() const 738bool CAnimatedMeshSceneNode::getLoopMode() const
739{ 739{
740 return Looping; 740 return Looping;
741} 741}
742 742
743 743
744//! Sets a callback interface which will be called if an animation 744//! Sets a callback interface which will be called if an animation
745//! playback has ended. Set this to 0 to disable the callback again. 745//! playback has ended. Set this to 0 to disable the callback again.
746void CAnimatedMeshSceneNode::setAnimationEndCallback(IAnimationEndCallBack* callback) 746void CAnimatedMeshSceneNode::setAnimationEndCallback(IAnimationEndCallBack* callback)
747{ 747{
748 if (callback == LoopCallBack) 748 if (callback == LoopCallBack)
749 return; 749 return;
750 750
751 if (LoopCallBack) 751 if (LoopCallBack)
752 LoopCallBack->drop(); 752 LoopCallBack->drop();
753 753
754 LoopCallBack = callback; 754 LoopCallBack = callback;
755 755
756 if (LoopCallBack) 756 if (LoopCallBack)
757 LoopCallBack->grab(); 757 LoopCallBack->grab();
758} 758}
759 759
760 760
761//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. 761//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
762void CAnimatedMeshSceneNode::setReadOnlyMaterials(bool readonly) 762void CAnimatedMeshSceneNode::setReadOnlyMaterials(bool readonly)
763{ 763{
764 ReadOnlyMaterials = readonly; 764 ReadOnlyMaterials = readonly;
765} 765}
766 766
767 767
768//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style 768//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
769bool CAnimatedMeshSceneNode::isReadOnlyMaterials() const 769bool CAnimatedMeshSceneNode::isReadOnlyMaterials() const
770{ 770{
771 return ReadOnlyMaterials; 771 return ReadOnlyMaterials;
772} 772}
773 773
774 774
775//! Writes attributes of the scene node. 775//! Writes attributes of the scene node.
776void CAnimatedMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const 776void CAnimatedMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
777{ 777{
778 IAnimatedMeshSceneNode::serializeAttributes(out, options); 778 IAnimatedMeshSceneNode::serializeAttributes(out, options);
779 779
780 if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename) 780 if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename)
781 { 781 {
782 const io::path path = SceneManager->getFileSystem()->getRelativeFilename( 782 const io::path path = SceneManager->getFileSystem()->getRelativeFilename(
783 SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()), 783 SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()),
784 options->Filename); 784 options->Filename);
785 out->addString("Mesh", path.c_str()); 785 out->addString("Mesh", path.c_str());
786 } 786 }
787 else 787 else
788 out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str()); 788 out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str());
789 out->addBool("Looping", Looping); 789 out->addBool("Looping", Looping);
790 out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); 790 out->addBool("ReadOnlyMaterials", ReadOnlyMaterials);
791 out->addFloat("FramesPerSecond", FramesPerSecond); 791 out->addFloat("FramesPerSecond", FramesPerSecond);
792 out->addInt("StartFrame", StartFrame); 792 out->addInt("StartFrame", StartFrame);
793 out->addInt("EndFrame", EndFrame); 793 out->addInt("EndFrame", EndFrame);
794} 794}
795 795
796 796
797//! Reads attributes of the scene node. 797//! Reads attributes of the scene node.
798void CAnimatedMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) 798void CAnimatedMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
799{ 799{
800 IAnimatedMeshSceneNode::deserializeAttributes(in, options); 800 IAnimatedMeshSceneNode::deserializeAttributes(in, options);
801 801
802 io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh); 802 io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh);
803 io::path newMeshStr = in->getAttributeAsString("Mesh"); 803 io::path newMeshStr = in->getAttributeAsString("Mesh");
804 804
805 Looping = in->getAttributeAsBool("Looping"); 805 Looping = in->getAttributeAsBool("Looping");
806 ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); 806 ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials");
807 FramesPerSecond = in->getAttributeAsFloat("FramesPerSecond"); 807 FramesPerSecond = in->getAttributeAsFloat("FramesPerSecond");
808 StartFrame = in->getAttributeAsInt("StartFrame"); 808 StartFrame = in->getAttributeAsInt("StartFrame");
809 EndFrame = in->getAttributeAsInt("EndFrame"); 809 EndFrame = in->getAttributeAsInt("EndFrame");
810 810
811 if (newMeshStr != "" && oldMeshStr != newMeshStr) 811 if (newMeshStr != "" && oldMeshStr != newMeshStr)
812 { 812 {
813 IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); 813 IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());
814 814
815 if (newAnimatedMesh) 815 if (newAnimatedMesh)
816 setMesh(newAnimatedMesh); 816 setMesh(newAnimatedMesh);
817 } 817 }
818 818
819 // TODO: read animation names instead of frame begin and ends 819 // TODO: read animation names instead of frame begin and ends
820} 820}
821 821
822 822
823//! Sets a new mesh 823//! Sets a new mesh
824void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh) 824void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh)
825{ 825{
826 if (!mesh) 826 if (!mesh)
827 return; // won't set null mesh 827 return; // won't set null mesh
828 828
829 if (Mesh != mesh) 829 if (Mesh != mesh)
830 { 830 {
831 if (Mesh) 831 if (Mesh)
832 Mesh->drop(); 832 Mesh->drop();
833 833
834 Mesh = mesh; 834 Mesh = mesh;
835 835
836 // grab the mesh (it's non-null!) 836 // grab the mesh (it's non-null!)
837 Mesh->grab(); 837 Mesh->grab();
838 } 838 }
839 839
840 // get materials and bounding box 840 // get materials and bounding box
841 Box = Mesh->getBoundingBox(); 841 Box = Mesh->getBoundingBox();
842 842
843 IMesh* m = Mesh->getMesh(0,0); 843 IMesh* m = Mesh->getMesh(0,0);
844 if (m) 844 if (m)
845 { 845 {
846 Materials.clear(); 846 Materials.clear();
847 Materials.reallocate(m->getMeshBufferCount()); 847 Materials.reallocate(m->getMeshBufferCount());
848 848
849 for (u32 i=0; i<m->getMeshBufferCount(); ++i) 849 for (u32 i=0; i<m->getMeshBufferCount(); ++i)
850 { 850 {
851 IMeshBuffer* mb = m->getMeshBuffer(i); 851 IMeshBuffer* mb = m->getMeshBuffer(i);
852 if (mb) 852 if (mb)
853 Materials.push_back(mb->getMaterial()); 853 Materials.push_back(mb->getMaterial());
854 else 854 else
855 Materials.push_back(video::SMaterial()); 855 Materials.push_back(video::SMaterial());
856 } 856 }
857 } 857 }
858 858
859 // clean up joint nodes 859 // clean up joint nodes
860 if (JointsUsed) 860 if (JointsUsed)
861 { 861 {
862 JointsUsed=false; 862 JointsUsed=false;
863 checkJoints(); 863 checkJoints();
864 } 864 }
865 865
866 // get start and begin time 866 // get start and begin time
867// setAnimationSpeed(Mesh->getAnimationSpeed()); 867// setAnimationSpeed(Mesh->getAnimationSpeed());
868 setFrameLoop(0, Mesh->getFrameCount()); 868 setFrameLoop(0, Mesh->getFrameCount());
869} 869}
870 870
871 871
872// returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, 872// returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh,
873// or the absolutetransformation if it's a normal scenenode 873// or the absolutetransformation if it's a normal scenenode
874const SMD3QuaternionTag* CAnimatedMeshSceneNode::getMD3TagTransformation(const core::stringc& tagname) 874const SMD3QuaternionTag* CAnimatedMeshSceneNode::getMD3TagTransformation(const core::stringc& tagname)
875{ 875{
876 return MD3Special ? MD3Special->AbsoluteTagList.get(tagname) : 0; 876 return MD3Special ? MD3Special->AbsoluteTagList.get(tagname) : 0;
877} 877}
878 878
879 879
880//! updates the absolute position based on the relative and the parents position 880//! updates the absolute position based on the relative and the parents position
881void CAnimatedMeshSceneNode::updateAbsolutePosition() 881void CAnimatedMeshSceneNode::updateAbsolutePosition()
882{ 882{
883 IAnimatedMeshSceneNode::updateAbsolutePosition(); 883 IAnimatedMeshSceneNode::updateAbsolutePosition();
884 884
885 if (!Mesh || Mesh->getMeshType() != EAMT_MD3) 885 if (!Mesh || Mesh->getMeshType() != EAMT_MD3)
886 return; 886 return;
887 887
888 SMD3QuaternionTagList *taglist; 888 SMD3QuaternionTagList *taglist;
889 taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( (s32)getFrameNr(),255,getStartFrame (),getEndFrame () ); 889 taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( (s32)getFrameNr(),255,getStartFrame (),getEndFrame () );
890 if (taglist) 890 if (taglist)
891 { 891 {
892 if (!MD3Special) 892 if (!MD3Special)
893 { 893 {
894 MD3Special = new SMD3Special(); 894 MD3Special = new SMD3Special();
895 } 895 }
896 896
897 SMD3QuaternionTag parent ( MD3Special->Tagname ); 897 SMD3QuaternionTag parent ( MD3Special->Tagname );
898 if (Parent && Parent->getType() == ESNT_ANIMATED_MESH) 898 if (Parent && Parent->getType() == ESNT_ANIMATED_MESH)
899 { 899 {
900 const SMD3QuaternionTag * p = ((IAnimatedMeshSceneNode*) Parent)->getMD3TagTransformation 900 const SMD3QuaternionTag * p = ((IAnimatedMeshSceneNode*) Parent)->getMD3TagTransformation
901 ( MD3Special->Tagname ); 901 ( MD3Special->Tagname );
902 902
903 if (p) 903 if (p)
904 parent = *p; 904 parent = *p;
905 } 905 }
906 906
907 SMD3QuaternionTag relative( RelativeTranslation, RelativeRotation ); 907 SMD3QuaternionTag relative( RelativeTranslation, RelativeRotation );
908 908
909 MD3Special->AbsoluteTagList.set_used ( taglist->size () ); 909 MD3Special->AbsoluteTagList.set_used ( taglist->size () );
910 for ( u32 i=0; i!= taglist->size (); ++i ) 910 for ( u32 i=0; i!= taglist->size (); ++i )
911 { 911 {
912 MD3Special->AbsoluteTagList[i].position = parent.position + (*taglist)[i].position + relative.position; 912 MD3Special->AbsoluteTagList[i].position = parent.position + (*taglist)[i].position + relative.position;
913 MD3Special->AbsoluteTagList[i].rotation = parent.rotation * (*taglist)[i].rotation * relative.rotation; 913 MD3Special->AbsoluteTagList[i].rotation = parent.rotation * (*taglist)[i].rotation * relative.rotation;
914 } 914 }
915 } 915 }
916} 916}
917 917
918//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set) 918//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
919void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode) 919void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode)
920{ 920{
921 checkJoints(); 921 checkJoints();
922 JointMode=mode; 922 JointMode=mode;
923} 923}
924 924
925//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2) 925//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
926//! you must call animateJoints(), or the mesh will not animate 926//! you must call animateJoints(), or the mesh will not animate
927void CAnimatedMeshSceneNode::setTransitionTime(f32 time) 927void CAnimatedMeshSceneNode::setTransitionTime(f32 time)
928{ 928{
929 const u32 ttime = (u32)core::floor32(time*1000.0f); 929 const u32 ttime = (u32)core::floor32(time*1000.0f);
930 if (TransitionTime==ttime) 930 if (TransitionTime==ttime)
931 return; 931 return;
932 TransitionTime = ttime; 932 TransitionTime = ttime;
933 if (ttime != 0) 933 if (ttime != 0)
934 setJointMode(EJUOR_CONTROL); 934 setJointMode(EJUOR_CONTROL);
935 else 935 else
936 setJointMode(EJUOR_NONE); 936 setJointMode(EJUOR_NONE);
937} 937}
938 938
939 939
940//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected) 940//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected)
941void CAnimatedMeshSceneNode::setRenderFromIdentity(bool enable) 941void CAnimatedMeshSceneNode::setRenderFromIdentity(bool enable)
942{ 942{
943 RenderFromIdentity=enable; 943 RenderFromIdentity=enable;
944} 944}
945 945
946 946
947//! updates the joint positions of this mesh 947//! updates the joint positions of this mesh
948void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions) 948void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
949{ 949{
950#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ 950#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
951 return; 951 return;
952#else 952#else
953 if (Mesh && Mesh->getMeshType() == EAMT_SKINNED ) 953 if (Mesh && Mesh->getMeshType() == EAMT_SKINNED )
954 { 954 {
955 checkJoints(); 955 checkJoints();
956 const f32 frame = getFrameNr(); //old? 956 const f32 frame = getFrameNr(); //old?
957 957
958 CSkinnedMesh* skinnedMesh=reinterpret_cast<CSkinnedMesh*>(Mesh); 958 CSkinnedMesh* skinnedMesh=reinterpret_cast<CSkinnedMesh*>(Mesh);
959 959
960 skinnedMesh->transferOnlyJointsHintsToMesh( JointChildSceneNodes ); 960 skinnedMesh->transferOnlyJointsHintsToMesh( JointChildSceneNodes );
961 skinnedMesh->animateMesh(frame, 1.0f); 961 skinnedMesh->animateMesh(frame, 1.0f);
962 skinnedMesh->recoverJointsFromMesh( JointChildSceneNodes); 962 skinnedMesh->recoverJointsFromMesh( JointChildSceneNodes);
963 963
964 //----------------------------------------- 964 //-----------------------------------------
965 // Transition 965 // Transition
966 //----------------------------------------- 966 //-----------------------------------------
967 967
968 if (Transiting != 0.f) 968 if (Transiting != 0.f)
969 { 969 {
970 // Init additional matrices 970 // Init additional matrices
971 if (PretransitingSave.size()<JointChildSceneNodes.size()) 971 if (PretransitingSave.size()<JointChildSceneNodes.size())
972 { 972 {
973 for(u32 n=PretransitingSave.size(); n<JointChildSceneNodes.size(); ++n) 973 for(u32 n=PretransitingSave.size(); n<JointChildSceneNodes.size(); ++n)
974 PretransitingSave.push_back(core::matrix4()); 974 PretransitingSave.push_back(core::matrix4());
975 } 975 }
976 976
977 for (u32 n=0; n<JointChildSceneNodes.size(); ++n) 977 for (u32 n=0; n<JointChildSceneNodes.size(); ++n)
978 { 978 {
979 //------Position------ 979 //------Position------
980 980
981 JointChildSceneNodes[n]->setPosition( 981 JointChildSceneNodes[n]->setPosition(
982 core::lerp( 982 core::lerp(
983 PretransitingSave[n].getTranslation(), 983 PretransitingSave[n].getTranslation(),
984 JointChildSceneNodes[n]->getPosition(), 984 JointChildSceneNodes[n]->getPosition(),
985 TransitingBlend)); 985 TransitingBlend));
986 986
987 //------Rotation------ 987 //------Rotation------
988 988
989 //Code is slow, needs to be fixed up 989 //Code is slow, needs to be fixed up
990 990
991 const core::quaternion RotationStart(PretransitingSave[n].getRotationDegrees()*core::DEGTORAD); 991 const core::quaternion RotationStart(PretransitingSave[n].getRotationDegrees()*core::DEGTORAD);
992 const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation()*core::DEGTORAD); 992 const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation()*core::DEGTORAD);
993 993
994 core::quaternion QRotation; 994 core::quaternion QRotation;
995 QRotation.slerp(RotationStart, RotationEnd, TransitingBlend); 995 QRotation.slerp(RotationStart, RotationEnd, TransitingBlend);
996 996
997 core::vector3df tmpVector; 997 core::vector3df tmpVector;
998 QRotation.toEuler(tmpVector); 998 QRotation.toEuler(tmpVector);
999 tmpVector*=core::RADTODEG; //convert from radians back to degrees 999 tmpVector*=core::RADTODEG; //convert from radians back to degrees
1000 JointChildSceneNodes[n]->setRotation( tmpVector ); 1000 JointChildSceneNodes[n]->setRotation( tmpVector );
1001 1001
1002 //------Scale------ 1002 //------Scale------
1003 1003
1004 //JointChildSceneNodes[n]->setScale( 1004 //JointChildSceneNodes[n]->setScale(
1005 // core::lerp( 1005 // core::lerp(
1006 // PretransitingSave[n].getScale(), 1006 // PretransitingSave[n].getScale(),
1007 // JointChildSceneNodes[n]->getScale(), 1007 // JointChildSceneNodes[n]->getScale(),
1008 // TransitingBlend)); 1008 // TransitingBlend));
1009 } 1009 }
1010 } 1010 }
1011 1011
1012 if (CalculateAbsolutePositions) 1012 if (CalculateAbsolutePositions)
1013 { 1013 {
1014 //---slow--- 1014 //---slow---
1015 for (u32 n=0;n<JointChildSceneNodes.size();++n) 1015 for (u32 n=0;n<JointChildSceneNodes.size();++n)
1016 { 1016 {
1017 if (JointChildSceneNodes[n]->getParent()==this) 1017 if (JointChildSceneNodes[n]->getParent()==this)
1018 { 1018 {
1019 JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option 1019 JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option
1020 } 1020 }
1021 } 1021 }
1022 } 1022 }
1023 } 1023 }
1024#endif 1024#endif
1025} 1025}
1026 1026
1027/*! 1027/*!
1028*/ 1028*/
1029void CAnimatedMeshSceneNode::checkJoints() 1029void CAnimatedMeshSceneNode::checkJoints()
1030{ 1030{
1031#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ 1031#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
1032 return; 1032 return;
1033#else 1033#else
1034 1034
1035 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) 1035 if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
1036 return; 1036 return;
1037 1037
1038 if (!JointsUsed) 1038 if (!JointsUsed)
1039 { 1039 {
1040 for (u32 i=0; i<JointChildSceneNodes.size(); ++i) 1040 for (u32 i=0; i<JointChildSceneNodes.size(); ++i)
1041 removeChild(JointChildSceneNodes[i]); 1041 removeChild(JointChildSceneNodes[i]);
1042 JointChildSceneNodes.clear(); 1042 JointChildSceneNodes.clear();
1043 1043
1044 //Create joints for SkinnedMesh 1044 //Create joints for SkinnedMesh
1045 ((CSkinnedMesh*)Mesh)->addJoints(JointChildSceneNodes, this, SceneManager); 1045 ((CSkinnedMesh*)Mesh)->addJoints(JointChildSceneNodes, this, SceneManager);
1046 ((CSkinnedMesh*)Mesh)->recoverJointsFromMesh(JointChildSceneNodes); 1046 ((CSkinnedMesh*)Mesh)->recoverJointsFromMesh(JointChildSceneNodes);
1047 1047
1048 JointsUsed=true; 1048 JointsUsed=true;
1049 JointMode=EJUOR_READ; 1049 JointMode=EJUOR_READ;
1050 } 1050 }
1051#endif 1051#endif
1052} 1052}
1053 1053
1054/*! 1054/*!
1055*/ 1055*/
1056void CAnimatedMeshSceneNode::beginTransition() 1056void CAnimatedMeshSceneNode::beginTransition()
1057{ 1057{
1058 if (!JointsUsed) 1058 if (!JointsUsed)
1059 return; 1059 return;
1060 1060
1061 if (TransitionTime != 0) 1061 if (TransitionTime != 0)
1062 { 1062 {
1063 //Check the array is big enough 1063 //Check the array is big enough
1064 if (PretransitingSave.size()<JointChildSceneNodes.size()) 1064 if (PretransitingSave.size()<JointChildSceneNodes.size())
1065 { 1065 {
1066 for(u32 n=PretransitingSave.size(); n<JointChildSceneNodes.size(); ++n) 1066 for(u32 n=PretransitingSave.size(); n<JointChildSceneNodes.size(); ++n)
1067 PretransitingSave.push_back(core::matrix4()); 1067 PretransitingSave.push_back(core::matrix4());
1068 } 1068 }
1069 1069
1070 //Copy the position of joints 1070 //Copy the position of joints
1071 for (u32 n=0;n<JointChildSceneNodes.size();++n) 1071 for (u32 n=0;n<JointChildSceneNodes.size();++n)
1072 PretransitingSave[n]=JointChildSceneNodes[n]->getRelativeTransformation(); 1072 PretransitingSave[n]=JointChildSceneNodes[n]->getRelativeTransformation();
1073 1073
1074 Transiting = core::reciprocal((f32)TransitionTime); 1074 Transiting = core::reciprocal((f32)TransitionTime);
1075 } 1075 }
1076 TransitingBlend = 0.f; 1076 TransitingBlend = 0.f;
1077} 1077}
1078 1078
1079 1079
1080/*! 1080/*!
1081*/ 1081*/
1082ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) 1082ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
1083{ 1083{
1084 if (!newParent) 1084 if (!newParent)
1085 newParent = Parent; 1085 newParent = Parent;
1086 if (!newManager) 1086 if (!newManager)
1087 newManager = SceneManager; 1087 newManager = SceneManager;
1088 1088
1089 CAnimatedMeshSceneNode* newNode = 1089 CAnimatedMeshSceneNode* newNode =
1090 new CAnimatedMeshSceneNode(Mesh, NULL, newManager, ID, RelativeTranslation, 1090 new CAnimatedMeshSceneNode(Mesh, NULL, newManager, ID, RelativeTranslation,
1091 RelativeRotation, RelativeScale); 1091 RelativeRotation, RelativeScale);
1092 1092
1093 if (newParent) 1093 if (newParent)
1094 { 1094 {
1095 newNode->setParent(newParent); // not in constructor because virtual overload for updateAbsolutePosition won't be called 1095 newNode->setParent(newParent); // not in constructor because virtual overload for updateAbsolutePosition won't be called
1096 newNode->drop(); 1096 newNode->drop();
1097 } 1097 }
1098 1098
1099 newNode->cloneMembers(this, newManager); 1099 newNode->cloneMembers(this, newManager);
1100 1100
1101 newNode->Materials = Materials; 1101 newNode->Materials = Materials;
1102 newNode->Box = Box; 1102 newNode->Box = Box;
1103 newNode->Mesh = Mesh; 1103 newNode->Mesh = Mesh;
1104 newNode->StartFrame = StartFrame; 1104 newNode->StartFrame = StartFrame;
1105 newNode->EndFrame = EndFrame; 1105 newNode->EndFrame = EndFrame;
1106 newNode->FramesPerSecond = FramesPerSecond; 1106 newNode->FramesPerSecond = FramesPerSecond;
1107 newNode->CurrentFrameNr = CurrentFrameNr; 1107 newNode->CurrentFrameNr = CurrentFrameNr;
1108 newNode->JointMode = JointMode; 1108 newNode->JointMode = JointMode;
1109 newNode->JointsUsed = JointsUsed; 1109 newNode->JointsUsed = JointsUsed;
1110 newNode->TransitionTime = TransitionTime; 1110 newNode->TransitionTime = TransitionTime;
1111 newNode->Transiting = Transiting; 1111 newNode->Transiting = Transiting;
1112 newNode->TransitingBlend = TransitingBlend; 1112 newNode->TransitingBlend = TransitingBlend;
1113 newNode->Looping = Looping; 1113 newNode->Looping = Looping;
1114 newNode->ReadOnlyMaterials = ReadOnlyMaterials; 1114 newNode->ReadOnlyMaterials = ReadOnlyMaterials;
1115 newNode->LoopCallBack = LoopCallBack; 1115 newNode->LoopCallBack = LoopCallBack;
1116 newNode->PassCount = PassCount; 1116 newNode->PassCount = PassCount;
1117 newNode->Shadow = Shadow; 1117 newNode->Shadow = Shadow;
1118 newNode->Shadow->grab(); 1118 newNode->Shadow->grab();
1119 newNode->JointChildSceneNodes = JointChildSceneNodes; 1119 newNode->JointChildSceneNodes = JointChildSceneNodes;
1120 newNode->PretransitingSave = PretransitingSave; 1120 newNode->PretransitingSave = PretransitingSave;
1121 newNode->RenderFromIdentity = RenderFromIdentity; 1121 newNode->RenderFromIdentity = RenderFromIdentity;
1122 newNode->MD3Special = MD3Special; 1122 newNode->MD3Special = MD3Special;
1123 1123
1124 return newNode; 1124 return newNode;
1125} 1125}
1126 1126
1127 1127
1128} // end namespace scene 1128} // end namespace scene
1129} // end namespace irr 1129} // end namespace irr