aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp457
1 files changed, 457 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp
new file mode 100644
index 0000000..3c4f55c
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp
@@ -0,0 +1,457 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "IrrCompileConfig.h"
6#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
7
8#include "CAnimatedMeshMD2.h"
9#include "SColor.h"
10#include "irrMath.h"
11
12namespace irr
13{
14namespace scene
15{
16
17const s32 MD2_FRAME_SHIFT = 2;
18const f32 MD2_FRAME_SHIFT_RECIPROCAL = 1.f / (1 << MD2_FRAME_SHIFT);
19
20const s32 Q2_VERTEX_NORMAL_TABLE_SIZE = 162;
21
22static const f32 Q2_VERTEX_NORMAL_TABLE[Q2_VERTEX_NORMAL_TABLE_SIZE][3] = {
23 {-0.525731f, 0.000000f, 0.850651f},
24 {-0.442863f, 0.238856f, 0.864188f},
25 {-0.295242f, 0.000000f, 0.955423f},
26 {-0.309017f, 0.500000f, 0.809017f},
27 {-0.162460f, 0.262866f, 0.951056f},
28 {0.000000f, 0.000000f, 1.000000f},
29 {0.000000f, 0.850651f, 0.525731f},
30 {-0.147621f, 0.716567f, 0.681718f},
31 {0.147621f, 0.716567f, 0.681718f},
32 {0.000000f, 0.525731f, 0.850651f},
33 {0.309017f, 0.500000f, 0.809017f},
34 {0.525731f, 0.000000f, 0.850651f},
35 {0.295242f, 0.000000f, 0.955423f},
36 {0.442863f, 0.238856f, 0.864188f},
37 {0.162460f, 0.262866f, 0.951056f},
38 {-0.681718f, 0.147621f, 0.716567f},
39 {-0.809017f, 0.309017f, 0.500000f},
40 {-0.587785f, 0.425325f, 0.688191f},
41 {-0.850651f, 0.525731f, 0.000000f},
42 {-0.864188f, 0.442863f, 0.238856f},
43 {-0.716567f, 0.681718f, 0.147621f},
44 {-0.688191f, 0.587785f, 0.425325f},
45 {-0.500000f, 0.809017f, 0.309017f},
46 {-0.238856f, 0.864188f, 0.442863f},
47 {-0.425325f, 0.688191f, 0.587785f},
48 {-0.716567f, 0.681718f, -0.147621f},
49 {-0.500000f, 0.809017f, -0.309017f},
50 {-0.525731f, 0.850651f, 0.000000f},
51 {0.000000f, 0.850651f, -0.525731f},
52 {-0.238856f, 0.864188f, -0.442863f},
53 {0.000000f, 0.955423f, -0.295242f},
54 {-0.262866f, 0.951056f, -0.162460f},
55 {0.000000f, 1.000000f, 0.000000f},
56 {0.000000f, 0.955423f, 0.295242f},
57 {-0.262866f, 0.951056f, 0.162460f},
58 {0.238856f, 0.864188f, 0.442863f},
59 {0.262866f, 0.951056f, 0.162460f},
60 {0.500000f, 0.809017f, 0.309017f},
61 {0.238856f, 0.864188f, -0.442863f},
62 {0.262866f, 0.951056f, -0.162460f},
63 {0.500000f, 0.809017f, -0.309017f},
64 {0.850651f, 0.525731f, 0.000000f},
65 {0.716567f, 0.681718f, 0.147621f},
66 {0.716567f, 0.681718f, -0.147621f},
67 {0.525731f, 0.850651f, 0.000000f},
68 {0.425325f, 0.688191f, 0.587785f},
69 {0.864188f, 0.442863f, 0.238856f},
70 {0.688191f, 0.587785f, 0.425325f},
71 {0.809017f, 0.309017f, 0.500000f},
72 {0.681718f, 0.147621f, 0.716567f},
73 {0.587785f, 0.425325f, 0.688191f},
74 {0.955423f, 0.295242f, 0.000000f},
75 {1.000000f, 0.000000f, 0.000000f},
76 {0.951056f, 0.162460f, 0.262866f},
77 {0.850651f, -0.525731f, 0.000000f},
78 {0.955423f, -0.295242f, 0.000000f},
79 {0.864188f, -0.442863f, 0.238856f},
80 {0.951056f, -0.162460f, 0.262866f},
81 {0.809017f, -0.309017f, 0.500000f},
82 {0.681718f, -0.147621f, 0.716567f},
83 {0.850651f, 0.000000f, 0.525731f},
84 {0.864188f, 0.442863f, -0.238856f},
85 {0.809017f, 0.309017f, -0.500000f},
86 {0.951056f, 0.162460f, -0.262866f},
87 {0.525731f, 0.000000f, -0.850651f},
88 {0.681718f, 0.147621f, -0.716567f},
89 {0.681718f, -0.147621f, -0.716567f},
90 {0.850651f, 0.000000f, -0.525731f},
91 {0.809017f, -0.309017f, -0.500000f},
92 {0.864188f, -0.442863f, -0.238856f},
93 {0.951056f, -0.162460f, -0.262866f},
94 {0.147621f, 0.716567f, -0.681718f},
95 {0.309017f, 0.500000f, -0.809017f},
96 {0.425325f, 0.688191f, -0.587785f},
97 {0.442863f, 0.238856f, -0.864188f},
98 {0.587785f, 0.425325f, -0.688191f},
99 {0.688191f, 0.587785f, -0.425325f},
100 {-0.147621f, 0.716567f, -0.681718f},
101 {-0.309017f, 0.500000f, -0.809017f},
102 {0.000000f, 0.525731f, -0.850651f},
103 {-0.525731f, 0.000000f, -0.850651f},
104 {-0.442863f, 0.238856f, -0.864188f},
105 {-0.295242f, 0.000000f, -0.955423f},
106 {-0.162460f, 0.262866f, -0.951056f},
107 {0.000000f, 0.000000f, -1.000000f},
108 {0.295242f, 0.000000f, -0.955423f},
109 {0.162460f, 0.262866f, -0.951056f},
110 {-0.442863f, -0.238856f, -0.864188f},
111 {-0.309017f, -0.500000f, -0.809017f},
112 {-0.162460f, -0.262866f, -0.951056f},
113 {0.000000f, -0.850651f, -0.525731f},
114 {-0.147621f, -0.716567f, -0.681718f},
115 {0.147621f, -0.716567f, -0.681718f},
116 {0.000000f, -0.525731f, -0.850651f},
117 {0.309017f, -0.500000f, -0.809017f},
118 {0.442863f, -0.238856f, -0.864188f},
119 {0.162460f, -0.262866f, -0.951056f},
120 {0.238856f, -0.864188f, -0.442863f},
121 {0.500000f, -0.809017f, -0.309017f},
122 {0.425325f, -0.688191f, -0.587785f},
123 {0.716567f, -0.681718f, -0.147621f},
124 {0.688191f, -0.587785f, -0.425325f},
125 {0.587785f, -0.425325f, -0.688191f},
126 {0.000000f, -0.955423f, -0.295242f},
127 {0.000000f, -1.000000f, 0.000000f},
128 {0.262866f, -0.951056f, -0.162460f},
129 {0.000000f, -0.850651f, 0.525731f},
130 {0.000000f, -0.955423f, 0.295242f},
131 {0.238856f, -0.864188f, 0.442863f},
132 {0.262866f, -0.951056f, 0.162460f},
133 {0.500000f, -0.809017f, 0.309017f},
134 {0.716567f, -0.681718f, 0.147621f},
135 {0.525731f, -0.850651f, 0.000000f},
136 {-0.238856f, -0.864188f, -0.442863f},
137 {-0.500000f, -0.809017f, -0.309017f},
138 {-0.262866f, -0.951056f, -0.162460f},
139 {-0.850651f, -0.525731f, 0.000000f},
140 {-0.716567f, -0.681718f, -0.147621f},
141 {-0.716567f, -0.681718f, 0.147621f},
142 {-0.525731f, -0.850651f, 0.000000f},
143 {-0.500000f, -0.809017f, 0.309017f},
144 {-0.238856f, -0.864188f, 0.442863f},
145 {-0.262866f, -0.951056f, 0.162460f},
146 {-0.864188f, -0.442863f, 0.238856f},
147 {-0.809017f, -0.309017f, 0.500000f},
148 {-0.688191f, -0.587785f, 0.425325f},
149 {-0.681718f, -0.147621f, 0.716567f},
150 {-0.442863f, -0.238856f, 0.864188f},
151 {-0.587785f, -0.425325f, 0.688191f},
152 {-0.309017f, -0.500000f, 0.809017f},
153 {-0.147621f, -0.716567f, 0.681718f},
154 {-0.425325f, -0.688191f, 0.587785f},
155 {-0.162460f, -0.262866f, 0.951056f},
156 {0.442863f, -0.238856f, 0.864188f},
157 {0.162460f, -0.262866f, 0.951056f},
158 {0.309017f, -0.500000f, 0.809017f},
159 {0.147621f, -0.716567f, 0.681718f},
160 {0.000000f, -0.525731f, 0.850651f},
161 {0.425325f, -0.688191f, 0.587785f},
162 {0.587785f, -0.425325f, 0.688191f},
163 {0.688191f, -0.587785f, 0.425325f},
164 {-0.955423f, 0.295242f, 0.000000f},
165 {-0.951056f, 0.162460f, 0.262866f},
166 {-1.000000f, 0.000000f, 0.000000f},
167 {-0.850651f, 0.000000f, 0.525731f},
168 {-0.955423f, -0.295242f, 0.000000f},
169 {-0.951056f, -0.162460f, 0.262866f},
170 {-0.864188f, 0.442863f, -0.238856f},
171 {-0.951056f, 0.162460f, -0.262866f},
172 {-0.809017f, 0.309017f, -0.500000f},
173 {-0.864188f, -0.442863f, -0.238856f},
174 {-0.951056f, -0.162460f, -0.262866f},
175 {-0.809017f, -0.309017f, -0.500000f},
176 {-0.681718f, 0.147621f, -0.716567f},
177 {-0.681718f, -0.147621f, -0.716567f},
178 {-0.850651f, 0.000000f, -0.525731f},
179 {-0.688191f, 0.587785f, -0.425325f},
180 {-0.587785f, 0.425325f, -0.688191f},
181 {-0.425325f, 0.688191f, -0.587785f},
182 {-0.425325f, -0.688191f, -0.587785f},
183 {-0.587785f, -0.425325f, -0.688191f},
184 {-0.688191f, -0.587785f, -0.425325f},
185 };
186
187struct SMD2AnimationType
188{
189 s32 begin;
190 s32 end;
191 s32 fps;
192};
193
194static const SMD2AnimationType MD2AnimationTypeList[21] =
195{
196 { 0, 39, 9}, // STAND
197 { 40, 45, 10}, // RUN
198 { 46, 53, 10}, // ATTACK
199 { 54, 57, 7}, // PAIN_A
200 { 58, 61, 7}, // PAIN_B
201 { 62, 65, 7}, // PAIN_C
202 { 66, 71, 7}, // JUMP
203 { 72, 83, 7}, // FLIP
204 { 84, 94, 7}, // SALUTE
205 { 95, 111, 10}, // FALLBACK
206 {112, 122, 7}, // WAVE
207 {123, 134, 6}, // POINT
208 {135, 153, 10}, // CROUCH_STAND
209 {154, 159, 7}, // CROUCH_WALK
210 {160, 168, 10}, // CROUCH_ATTACK
211 {169, 172, 7}, // CROUCH_PAIN
212 {173, 177, 5}, // CROUCH_DEATH
213 {178, 183, 7}, // DEATH_FALLBACK
214 {184, 189, 7}, // DEATH_FALLFORWARD
215 {190, 197, 7}, // DEATH_FALLBACKSLOW
216 {198, 198, 5}, // BOOM
217};
218
219
220//! constructor
221CAnimatedMeshMD2::CAnimatedMeshMD2()
222 : InterpolationBuffer(0), FrameList(0), FrameCount(0), FramesPerSecond((f32)(MD2AnimationTypeList[0].fps << MD2_FRAME_SHIFT))
223{
224 #ifdef _DEBUG
225 IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh");
226 IMesh::setDebugName("CAnimatedMeshMD2 IMesh");
227 #endif
228 InterpolationBuffer = new SMeshBuffer;
229}
230
231
232//! destructor
233CAnimatedMeshMD2::~CAnimatedMeshMD2()
234{
235 delete [] FrameList;
236 if (InterpolationBuffer)
237 InterpolationBuffer->drop();
238}
239
240
241//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
242u32 CAnimatedMeshMD2::getFrameCount() const
243{
244 return FrameCount<<MD2_FRAME_SHIFT;
245}
246
247
248//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
249IMesh* CAnimatedMeshMD2::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
250{
251 if ((u32)frame > getFrameCount())
252 frame = (frame % getFrameCount());
253
254 if (startFrameLoop == -1 && endFrameLoop == -1)
255 {
256 startFrameLoop = 0;
257 endFrameLoop = getFrameCount();
258 }
259
260 updateInterpolationBuffer(frame, startFrameLoop, endFrameLoop);
261 return this;
262}
263
264
265//! returns amount of mesh buffers. MD2 meshes only have one buffer
266u32 CAnimatedMeshMD2::getMeshBufferCount() const
267{
268 return 1;
269}
270
271
272//! returns pointer to a mesh buffer
273IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(u32 nr) const
274{
275 if (nr == 0)
276 return InterpolationBuffer;
277 else
278 return 0;
279}
280
281
282//! Returns pointer to a mesh buffer which fits a material
283IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const
284{
285 if (InterpolationBuffer->Material == material)
286 return InterpolationBuffer;
287 else
288 return 0;
289}
290
291
292// updates the interpolation buffer
293void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop, s32 endFrameLoop)
294{
295 u32 firstFrame, secondFrame;
296 f32 div;
297
298 // TA: resolve missing ipol in loop between end-start
299
300 if (endFrameLoop - startFrameLoop == 0)
301 {
302 firstFrame = frame>>MD2_FRAME_SHIFT;
303 secondFrame = frame>>MD2_FRAME_SHIFT;
304 div = 1.0f;
305 }
306 else
307 {
308 // key frames
309 u32 s = startFrameLoop >> MD2_FRAME_SHIFT;
310 u32 e = endFrameLoop >> MD2_FRAME_SHIFT;
311
312 firstFrame = frame >> MD2_FRAME_SHIFT;
313 secondFrame = core::if_c_a_else_b(firstFrame + 1 > e, s, firstFrame + 1);
314
315 firstFrame = core::s32_min(FrameCount - 1, firstFrame);
316 secondFrame = core::s32_min(FrameCount - 1, secondFrame);
317
318 //div = (frame % (1<<MD2_FRAME_SHIFT)) / (f32)(1<<MD2_FRAME_SHIFT);
319 frame &= (1<<MD2_FRAME_SHIFT) - 1;
320 div = frame * MD2_FRAME_SHIFT_RECIPROCAL;
321 }
322
323 video::S3DVertex* target = static_cast<video::S3DVertex*>(InterpolationBuffer->getVertices());
324 SMD2Vert* first = FrameList[firstFrame].pointer();
325 SMD2Vert* second = FrameList[secondFrame].pointer();
326
327 // interpolate both frames
328 const u32 count = FrameList[firstFrame].size();
329 for (u32 i=0; i<count; ++i)
330 {
331 const core::vector3df one = core::vector3df(f32(first->Pos.X) * FrameTransforms[firstFrame].scale.X + FrameTransforms[firstFrame].translate.X,
332 f32(first->Pos.Y) * FrameTransforms[firstFrame].scale.Y + FrameTransforms[firstFrame].translate.Y,
333 f32(first->Pos.Z) * FrameTransforms[firstFrame].scale.Z + FrameTransforms[firstFrame].translate.Z);
334 const core::vector3df two = core::vector3df(f32(second->Pos.X) * FrameTransforms[secondFrame].scale.X + FrameTransforms[secondFrame].translate.X,
335 f32(second->Pos.Y) * FrameTransforms[secondFrame].scale.Y + FrameTransforms[secondFrame].translate.Y,
336 f32(second->Pos.Z) * FrameTransforms[secondFrame].scale.Z + FrameTransforms[secondFrame].translate.Z);
337 target->Pos = two.getInterpolated(one, div);
338 const core::vector3df n1(
339 Q2_VERTEX_NORMAL_TABLE[first->NormalIdx][0],
340 Q2_VERTEX_NORMAL_TABLE[first->NormalIdx][2],
341 Q2_VERTEX_NORMAL_TABLE[first->NormalIdx][1]);
342 const core::vector3df n2(
343 Q2_VERTEX_NORMAL_TABLE[second->NormalIdx][0],
344 Q2_VERTEX_NORMAL_TABLE[second->NormalIdx][2],
345 Q2_VERTEX_NORMAL_TABLE[second->NormalIdx][1]);
346 target->Normal = n2.getInterpolated(n1, div);
347 ++target;
348 ++first;
349 ++second;
350 }
351
352 //update bounding box
353 InterpolationBuffer->setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div));
354 InterpolationBuffer->setDirty();
355}
356
357
358//! sets a flag of all contained materials to a new value
359void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
360{
361 InterpolationBuffer->Material.setFlag(flag, newvalue);
362}
363
364
365//! set the hardware mapping hint, for driver
366void CAnimatedMeshMD2::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,
367 E_BUFFER_TYPE buffer)
368{
369 InterpolationBuffer->setHardwareMappingHint(newMappingHint, buffer);
370}
371
372
373//! flags the meshbuffer as changed, reloads hardware buffers
374void CAnimatedMeshMD2::setDirty(E_BUFFER_TYPE buffer)
375{
376 InterpolationBuffer->setDirty(buffer);
377}
378
379
380//! returns an axis aligned bounding box
381const core::aabbox3d<f32>& CAnimatedMeshMD2::getBoundingBox() const
382{
383 return InterpolationBuffer->BoundingBox;
384}
385
386
387//! set user axis aligned bounding box
388void CAnimatedMeshMD2::setBoundingBox(const core::aabbox3df& box)
389{
390 InterpolationBuffer->BoundingBox = box;
391}
392
393
394//! Returns the type of the animated mesh.
395E_ANIMATED_MESH_TYPE CAnimatedMeshMD2::getMeshType() const
396{
397 return EAMT_MD2;
398}
399
400
401//! Returns frame loop data for a special MD2 animation type.
402void CAnimatedMeshMD2::getFrameLoop(EMD2_ANIMATION_TYPE l,
403 s32& outBegin, s32& outEnd, s32& outFPS) const
404{
405 if (l < 0 || l >= EMAT_COUNT)
406 return;
407
408 outBegin = MD2AnimationTypeList[l].begin << MD2_FRAME_SHIFT;
409 outEnd = MD2AnimationTypeList[l].end << MD2_FRAME_SHIFT;
410
411 // correct to anim between last->first frame
412 outEnd += MD2_FRAME_SHIFT == 0 ? 1 : (1 << MD2_FRAME_SHIFT) - 1;
413 outFPS = MD2AnimationTypeList[l].fps << MD2_FRAME_SHIFT;
414}
415
416
417//! Returns frame loop data for a special MD2 animation type.
418bool CAnimatedMeshMD2::getFrameLoop(const c8* name,
419 s32& outBegin, s32&outEnd, s32& outFPS) const
420{
421 for (u32 i=0; i < AnimationData.size(); ++i)
422 {
423 if (AnimationData[i].name == name)
424 {
425 outBegin = AnimationData[i].begin << MD2_FRAME_SHIFT;
426 outEnd = AnimationData[i].end << MD2_FRAME_SHIFT;
427 outEnd += MD2_FRAME_SHIFT == 0 ? 1 : (1 << MD2_FRAME_SHIFT) - 1;
428 outFPS = AnimationData[i].fps << MD2_FRAME_SHIFT;
429 return true;
430 }
431 }
432
433 return false;
434}
435
436
437//! Returns amount of md2 animations in this file.
438s32 CAnimatedMeshMD2::getAnimationCount() const
439{
440 return AnimationData.size();
441}
442
443
444//! Returns name of md2 animation.
445const c8* CAnimatedMeshMD2::getAnimationName(s32 nr) const
446{
447 if ((u32)nr >= AnimationData.size())
448 return 0;
449
450 return AnimationData[nr].name.c_str();
451}
452
453
454} // end namespace scene
455} // end namespace irr
456
457#endif // _IRR_COMPILE_WITH_MD2_LOADER_