aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.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/CAnimatedMeshMD3.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 'libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.cpp936
1 files changed, 468 insertions, 468 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.cpp
index 0d3a091..d288d4b 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshMD3.cpp
@@ -1,468 +1,468 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten 1// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten
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 "IrrCompileConfig.h" 5#include "IrrCompileConfig.h"
6#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ 6#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
7 7
8#include "CAnimatedMeshMD3.h" 8#include "CAnimatedMeshMD3.h"
9#include "os.h" 9#include "os.h"
10 10
11namespace irr 11namespace irr
12{ 12{
13namespace scene 13namespace scene
14{ 14{
15 15
16 16
17// byte-align structures 17// byte-align structures
18#include "irrpack.h" 18#include "irrpack.h"
19 19
20//! General properties of a single animation frame. 20//! General properties of a single animation frame.
21struct SMD3Frame 21struct SMD3Frame
22{ 22{
23 f32 mins[3]; // bounding box per frame 23 f32 mins[3]; // bounding box per frame
24 f32 maxs[3]; 24 f32 maxs[3];
25 f32 position[3]; // position of bounding box 25 f32 position[3]; // position of bounding box
26 f32 radius; // radius of bounding sphere 26 f32 radius; // radius of bounding sphere
27 c8 creator[16]; // name of frame 27 c8 creator[16]; // name of frame
28} PACK_STRUCT; 28} PACK_STRUCT;
29 29
30 30
31//! An attachment point for another MD3 model. 31//! An attachment point for another MD3 model.
32struct SMD3Tag 32struct SMD3Tag
33{ 33{
34 c8 Name[64]; //name of 'tag' as it's usually called in the md3 files try to see it as a sub-mesh/seperate mesh-part. 34 c8 Name[64]; //name of 'tag' as it's usually called in the md3 files try to see it as a sub-mesh/seperate mesh-part.
35 f32 position[3]; //relative position of tag 35 f32 position[3]; //relative position of tag
36 f32 rotationMatrix[9]; //3x3 rotation direction of tag 36 f32 rotationMatrix[9]; //3x3 rotation direction of tag
37} PACK_STRUCT; 37} PACK_STRUCT;
38 38
39//!Shader 39//!Shader
40struct SMD3Shader 40struct SMD3Shader
41{ 41{
42 c8 name[64]; // name of shader 42 c8 name[64]; // name of shader
43 s32 shaderIndex; 43 s32 shaderIndex;
44} PACK_STRUCT; 44} PACK_STRUCT;
45 45
46// Default alignment 46// Default alignment
47#include "irrunpack.h" 47#include "irrunpack.h"
48 48
49 49
50//! Constructor 50//! Constructor
51CAnimatedMeshMD3::CAnimatedMeshMD3() 51CAnimatedMeshMD3::CAnimatedMeshMD3()
52:Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f)//, FramesPerSecond(25.f) 52:Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f)//, FramesPerSecond(25.f)
53{ 53{
54#ifdef _DEBUG 54#ifdef _DEBUG
55 setDebugName("CAnimatedMeshMD3"); 55 setDebugName("CAnimatedMeshMD3");
56#endif 56#endif
57 57
58 Mesh = new SMD3Mesh(); 58 Mesh = new SMD3Mesh();
59 MeshIPol = new SMesh(); 59 MeshIPol = new SMesh();
60 setInterpolationShift(0, 0); 60 setInterpolationShift(0, 0);
61} 61}
62 62
63 63
64//! Destructor 64//! Destructor
65CAnimatedMeshMD3::~CAnimatedMeshMD3() 65CAnimatedMeshMD3::~CAnimatedMeshMD3()
66{ 66{
67 if (Mesh) 67 if (Mesh)
68 Mesh->drop(); 68 Mesh->drop();
69 if (MeshIPol) 69 if (MeshIPol)
70 MeshIPol->drop(); 70 MeshIPol->drop();
71} 71}
72 72
73 73
74//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. 74//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
75u32 CAnimatedMeshMD3::getFrameCount() const 75u32 CAnimatedMeshMD3::getFrameCount() const
76{ 76{
77 return Mesh->MD3Header.numFrames << IPolShift; 77 return Mesh->MD3Header.numFrames << IPolShift;
78} 78}
79 79
80 80
81//! Rendering Hint 81//! Rendering Hint
82void CAnimatedMeshMD3::setInterpolationShift(u32 shift, u32 loopMode) 82void CAnimatedMeshMD3::setInterpolationShift(u32 shift, u32 loopMode)
83{ 83{
84 IPolShift = shift; 84 IPolShift = shift;
85 LoopMode = loopMode; 85 LoopMode = loopMode;
86} 86}
87 87
88 88
89//! returns amount of mesh buffers. 89//! returns amount of mesh buffers.
90u32 CAnimatedMeshMD3::getMeshBufferCount() const 90u32 CAnimatedMeshMD3::getMeshBufferCount() const
91{ 91{
92 return MeshIPol->getMeshBufferCount(); 92 return MeshIPol->getMeshBufferCount();
93} 93}
94 94
95 95
96//! returns pointer to a mesh buffer 96//! returns pointer to a mesh buffer
97IMeshBuffer* CAnimatedMeshMD3::getMeshBuffer(u32 nr) const 97IMeshBuffer* CAnimatedMeshMD3::getMeshBuffer(u32 nr) const
98{ 98{
99 return MeshIPol->getMeshBuffer(nr); 99 return MeshIPol->getMeshBuffer(nr);
100} 100}
101 101
102 102
103//! Returns pointer to a mesh buffer which fits a material 103//! Returns pointer to a mesh buffer which fits a material
104IMeshBuffer* CAnimatedMeshMD3::getMeshBuffer(const video::SMaterial &material) const 104IMeshBuffer* CAnimatedMeshMD3::getMeshBuffer(const video::SMaterial &material) const
105{ 105{
106 return MeshIPol->getMeshBuffer(material); 106 return MeshIPol->getMeshBuffer(material);
107} 107}
108 108
109 109
110void CAnimatedMeshMD3::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) 110void CAnimatedMeshMD3::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
111{ 111{
112 MeshIPol->setMaterialFlag(flag, newvalue); 112 MeshIPol->setMaterialFlag(flag, newvalue);
113} 113}
114 114
115 115
116//! set the hardware mapping hint, for driver 116//! set the hardware mapping hint, for driver
117void CAnimatedMeshMD3::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, 117void CAnimatedMeshMD3::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,
118 E_BUFFER_TYPE buffer) 118 E_BUFFER_TYPE buffer)
119{ 119{
120 MeshIPol->setHardwareMappingHint(newMappingHint, buffer); 120 MeshIPol->setHardwareMappingHint(newMappingHint, buffer);
121} 121}
122 122
123 123
124//! flags the meshbuffer as changed, reloads hardware buffers 124//! flags the meshbuffer as changed, reloads hardware buffers
125void CAnimatedMeshMD3::setDirty(E_BUFFER_TYPE buffer) 125void CAnimatedMeshMD3::setDirty(E_BUFFER_TYPE buffer)
126{ 126{
127 MeshIPol->setDirty(buffer); 127 MeshIPol->setDirty(buffer);
128} 128}
129 129
130 130
131//! set user axis aligned bounding box 131//! set user axis aligned bounding box
132void CAnimatedMeshMD3::setBoundingBox(const core::aabbox3df& box) 132void CAnimatedMeshMD3::setBoundingBox(const core::aabbox3df& box)
133{ 133{
134 MeshIPol->setBoundingBox(box); 134 MeshIPol->setBoundingBox(box);
135} 135}
136 136
137 137
138//! Returns the animated tag list based on a detail level. 0 is the lowest, 255 the highest detail. 138//! Returns the animated tag list based on a detail level. 0 is the lowest, 255 the highest detail.
139SMD3QuaternionTagList *CAnimatedMeshMD3::getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) 139SMD3QuaternionTagList *CAnimatedMeshMD3::getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
140{ 140{
141 if (0 == Mesh) 141 if (0 == Mesh)
142 return 0; 142 return 0;
143 143
144 getMesh(frame, detailLevel, startFrameLoop, endFrameLoop); 144 getMesh(frame, detailLevel, startFrameLoop, endFrameLoop);
145 return &TagListIPol; 145 return &TagListIPol;
146} 146}
147 147
148 148
149//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. 149//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail.
150IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) 150IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
151{ 151{
152 if (0 == Mesh) 152 if (0 == Mesh)
153 return 0; 153 return 0;
154 154
155 //! check if we have the mesh in our private cache 155 //! check if we have the mesh in our private cache
156 SCacheInfo candidate(frame, startFrameLoop, endFrameLoop); 156 SCacheInfo candidate(frame, startFrameLoop, endFrameLoop);
157 if (candidate == Current) 157 if (candidate == Current)
158 return MeshIPol; 158 return MeshIPol;
159 159
160 startFrameLoop = core::s32_max(0, startFrameLoop >> IPolShift); 160 startFrameLoop = core::s32_max(0, startFrameLoop >> IPolShift);
161 endFrameLoop = core::if_c_a_else_b(endFrameLoop < 0, Mesh->MD3Header.numFrames - 1, endFrameLoop >> IPolShift); 161 endFrameLoop = core::if_c_a_else_b(endFrameLoop < 0, Mesh->MD3Header.numFrames - 1, endFrameLoop >> IPolShift);
162 162
163 const u32 mask = 1 << IPolShift; 163 const u32 mask = 1 << IPolShift;
164 164
165 s32 frameA; 165 s32 frameA;
166 s32 frameB; 166 s32 frameB;
167 f32 iPol; 167 f32 iPol;
168 168
169 if (LoopMode) 169 if (LoopMode)
170 { 170 {
171 // correct frame to "pixel center" 171 // correct frame to "pixel center"
172 frame -= mask >> 1; 172 frame -= mask >> 1;
173 173
174 // interpolation 174 // interpolation
175 iPol = f32(frame & (mask - 1)) * core::reciprocal(f32(mask)); 175 iPol = f32(frame & (mask - 1)) * core::reciprocal(f32(mask));
176 176
177 // wrap anim 177 // wrap anim
178 frame >>= IPolShift; 178 frame >>= IPolShift;
179 frameA = core::if_c_a_else_b(frame < startFrameLoop, endFrameLoop, frame); 179 frameA = core::if_c_a_else_b(frame < startFrameLoop, endFrameLoop, frame);
180 frameB = core::if_c_a_else_b(frameA + 1 > endFrameLoop, startFrameLoop, frameA + 1); 180 frameB = core::if_c_a_else_b(frameA + 1 > endFrameLoop, startFrameLoop, frameA + 1);
181 } 181 }
182 else 182 else
183 { 183 {
184 // correct frame to "pixel center" 184 // correct frame to "pixel center"
185 frame -= mask >> 1; 185 frame -= mask >> 1;
186 186
187 iPol = f32(frame & (mask - 1)) * core::reciprocal(f32(mask)); 187 iPol = f32(frame & (mask - 1)) * core::reciprocal(f32(mask));
188 188
189 // clamp anim 189 // clamp anim
190 frame >>= IPolShift; 190 frame >>= IPolShift;
191 frameA = core::s32_clamp(frame, startFrameLoop, endFrameLoop); 191 frameA = core::s32_clamp(frame, startFrameLoop, endFrameLoop);
192 frameB = core::s32_min(frameA + 1, endFrameLoop); 192 frameB = core::s32_min(frameA + 1, endFrameLoop);
193 } 193 }
194 194
195 // build current vertex 195 // build current vertex
196 for (u32 i = 0; i!= Mesh->Buffer.size(); ++i) 196 for (u32 i = 0; i!= Mesh->Buffer.size(); ++i)
197 { 197 {
198 buildVertexArray(frameA, frameB, iPol, 198 buildVertexArray(frameA, frameB, iPol,
199 Mesh->Buffer[i], 199 Mesh->Buffer[i],
200 (SMeshBufferLightMap*) MeshIPol->getMeshBuffer(i)); 200 (SMeshBufferLightMap*) MeshIPol->getMeshBuffer(i));
201 } 201 }
202 MeshIPol->recalculateBoundingBox(); 202 MeshIPol->recalculateBoundingBox();
203 203
204 // build current tags 204 // build current tags
205 buildTagArray(frameA, frameB, iPol); 205 buildTagArray(frameA, frameB, iPol);
206 206
207 Current = candidate; 207 Current = candidate;
208 return MeshIPol; 208 return MeshIPol;
209} 209}
210 210
211 211
212//! create a Irrlicht MeshBuffer for a MD3 MeshBuffer 212//! create a Irrlicht MeshBuffer for a MD3 MeshBuffer
213IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source, 213IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source,
214 io::IFileSystem* fs, video::IVideoDriver * driver) 214 io::IFileSystem* fs, video::IVideoDriver * driver)
215{ 215{
216 SMeshBufferLightMap * dest = new SMeshBufferLightMap(); 216 SMeshBufferLightMap * dest = new SMeshBufferLightMap();
217 dest->Vertices.set_used(source->MeshHeader.numVertices); 217 dest->Vertices.set_used(source->MeshHeader.numVertices);
218 dest->Indices.set_used(source->Indices.size()); 218 dest->Indices.set_used(source->Indices.size());
219 219
220 u32 i; 220 u32 i;
221 221
222 // fill in static face info 222 // fill in static face info
223 for (i = 0; i < source->Indices.size(); i += 3) 223 for (i = 0; i < source->Indices.size(); i += 3)
224 { 224 {
225 dest->Indices[i + 0] = (u16) source->Indices[i + 0]; 225 dest->Indices[i + 0] = (u16) source->Indices[i + 0];
226 dest->Indices[i + 1] = (u16) source->Indices[i + 1]; 226 dest->Indices[i + 1] = (u16) source->Indices[i + 1];
227 dest->Indices[i + 2] = (u16) source->Indices[i + 2]; 227 dest->Indices[i + 2] = (u16) source->Indices[i + 2];
228 } 228 }
229 229
230 // fill in static vertex info 230 // fill in static vertex info
231 for (i = 0; i!= (u32)source->MeshHeader.numVertices; ++i) 231 for (i = 0; i!= (u32)source->MeshHeader.numVertices; ++i)
232 { 232 {
233 video::S3DVertex2TCoords &v = dest->Vertices[i]; 233 video::S3DVertex2TCoords &v = dest->Vertices[i];
234 v.Color = 0xFFFFFFFF; 234 v.Color = 0xFFFFFFFF;
235 v.TCoords.X = source->Tex[i].u; 235 v.TCoords.X = source->Tex[i].u;
236 v.TCoords.Y = source->Tex[i].v; 236 v.TCoords.Y = source->Tex[i].v;
237 v.TCoords2.X = 0.f; 237 v.TCoords2.X = 0.f;
238 v.TCoords2.Y = 0.f; 238 v.TCoords2.Y = 0.f;
239 } 239 }
240 240
241 // load static texture 241 // load static texture
242 u32 pos = 0; 242 u32 pos = 0;
243 quake3::tTexArray textureArray; 243 quake3::tTexArray textureArray;
244 quake3::getTextures(textureArray, source->Shader, pos, fs, driver); 244 quake3::getTextures(textureArray, source->Shader, pos, fs, driver);
245 dest->Material.MaterialType = video::EMT_SOLID; 245 dest->Material.MaterialType = video::EMT_SOLID;
246 dest->Material.setTexture(0, textureArray[0]); 246 dest->Material.setTexture(0, textureArray[0]);
247 dest->Material.Lighting = false; 247 dest->Material.Lighting = false;
248 248
249 return dest; 249 return dest;
250} 250}
251 251
252 252
253//! build final mesh's vertices from frames frameA and frameB with linear interpolation. 253//! build final mesh's vertices from frames frameA and frameB with linear interpolation.
254void CAnimatedMeshMD3::buildVertexArray(u32 frameA, u32 frameB, f32 interpolate, 254void CAnimatedMeshMD3::buildVertexArray(u32 frameA, u32 frameB, f32 interpolate,
255 const SMD3MeshBuffer* source, 255 const SMD3MeshBuffer* source,
256 SMeshBufferLightMap* dest) 256 SMeshBufferLightMap* dest)
257{ 257{
258 const u32 frameOffsetA = frameA * source->MeshHeader.numVertices; 258 const u32 frameOffsetA = frameA * source->MeshHeader.numVertices;
259 const u32 frameOffsetB = frameB * source->MeshHeader.numVertices; 259 const u32 frameOffsetB = frameB * source->MeshHeader.numVertices;
260 const f32 scale = (1.f/ 64.f); 260 const f32 scale = (1.f/ 64.f);
261 261
262 for (s32 i = 0; i != source->MeshHeader.numVertices; ++i) 262 for (s32 i = 0; i != source->MeshHeader.numVertices; ++i)
263 { 263 {
264 video::S3DVertex2TCoords &v = dest->Vertices [ i ]; 264 video::S3DVertex2TCoords &v = dest->Vertices [ i ];
265 265
266 const SMD3Vertex &vA = source->Vertices [ frameOffsetA + i ]; 266 const SMD3Vertex &vA = source->Vertices [ frameOffsetA + i ];
267 const SMD3Vertex &vB = source->Vertices [ frameOffsetB + i ]; 267 const SMD3Vertex &vB = source->Vertices [ frameOffsetB + i ];
268 268
269 // position 269 // position
270 v.Pos.X = scale * (vA.position[0] + interpolate * (vB.position[0] - vA.position[0])); 270 v.Pos.X = scale * (vA.position[0] + interpolate * (vB.position[0] - vA.position[0]));
271 v.Pos.Y = scale * (vA.position[2] + interpolate * (vB.position[2] - vA.position[2])); 271 v.Pos.Y = scale * (vA.position[2] + interpolate * (vB.position[2] - vA.position[2]));
272 v.Pos.Z = scale * (vA.position[1] + interpolate * (vB.position[1] - vA.position[1])); 272 v.Pos.Z = scale * (vA.position[1] + interpolate * (vB.position[1] - vA.position[1]));
273 273
274 // normal 274 // normal
275 const core::vector3df nA(quake3::getMD3Normal(vA.normal[0], vA.normal[1])); 275 const core::vector3df nA(quake3::getMD3Normal(vA.normal[0], vA.normal[1]));
276 const core::vector3df nB(quake3::getMD3Normal(vB.normal[0], vB.normal[1])); 276 const core::vector3df nB(quake3::getMD3Normal(vB.normal[0], vB.normal[1]));
277 277
278 v.Normal.X = nA.X + interpolate * (nB.X - nA.X); 278 v.Normal.X = nA.X + interpolate * (nB.X - nA.X);
279 v.Normal.Y = nA.Z + interpolate * (nB.Z - nA.Z); 279 v.Normal.Y = nA.Z + interpolate * (nB.Z - nA.Z);
280 v.Normal.Z = nA.Y + interpolate * (nB.Y - nA.Y); 280 v.Normal.Z = nA.Y + interpolate * (nB.Y - nA.Y);
281 } 281 }
282 282
283 dest->recalculateBoundingBox(); 283 dest->recalculateBoundingBox();
284} 284}
285 285
286 286
287//! build final mesh's tag from frames frameA and frameB with linear interpolation. 287//! build final mesh's tag from frames frameA and frameB with linear interpolation.
288void CAnimatedMeshMD3::buildTagArray(u32 frameA, u32 frameB, f32 interpolate) 288void CAnimatedMeshMD3::buildTagArray(u32 frameA, u32 frameB, f32 interpolate)
289{ 289{
290 const u32 frameOffsetA = frameA * Mesh->MD3Header.numTags; 290 const u32 frameOffsetA = frameA * Mesh->MD3Header.numTags;
291 const u32 frameOffsetB = frameB * Mesh->MD3Header.numTags; 291 const u32 frameOffsetB = frameB * Mesh->MD3Header.numTags;
292 292
293 for (s32 i = 0; i != Mesh->MD3Header.numTags; ++i) 293 for (s32 i = 0; i != Mesh->MD3Header.numTags; ++i)
294 { 294 {
295 SMD3QuaternionTag &d = TagListIPol [ i ]; 295 SMD3QuaternionTag &d = TagListIPol [ i ];
296 296
297 const SMD3QuaternionTag &qA = Mesh->TagList[ frameOffsetA + i]; 297 const SMD3QuaternionTag &qA = Mesh->TagList[ frameOffsetA + i];
298 const SMD3QuaternionTag &qB = Mesh->TagList[ frameOffsetB + i]; 298 const SMD3QuaternionTag &qB = Mesh->TagList[ frameOffsetB + i];
299 299
300 // rotation 300 // rotation
301 d.rotation.slerp(qA.rotation, qB.rotation, interpolate); 301 d.rotation.slerp(qA.rotation, qB.rotation, interpolate);
302 302
303 // position 303 // position
304 d.position.X = qA.position.X + interpolate * (qB.position.X - qA.position.X); 304 d.position.X = qA.position.X + interpolate * (qB.position.X - qA.position.X);
305 d.position.Y = qA.position.Y + interpolate * (qB.position.Y - qA.position.Y); 305 d.position.Y = qA.position.Y + interpolate * (qB.position.Y - qA.position.Y);
306 d.position.Z = qA.position.Z + interpolate * (qB.position.Z - qA.position.Z); 306 d.position.Z = qA.position.Z + interpolate * (qB.position.Z - qA.position.Z);
307 } 307 }
308} 308}
309 309
310 310
311/*! 311/*!
312 loads a model 312 loads a model
313*/ 313*/
314bool CAnimatedMeshMD3::loadModelFile(u32 modelIndex, io::IReadFile* file, 314bool CAnimatedMeshMD3::loadModelFile(u32 modelIndex, io::IReadFile* file,
315 io::IFileSystem* fs, video::IVideoDriver* driver) 315 io::IFileSystem* fs, video::IVideoDriver* driver)
316{ 316{
317 if (!file) 317 if (!file)
318 return false; 318 return false;
319 319
320 //! Check MD3Header 320 //! Check MD3Header
321 { 321 {
322 file->read(&Mesh->MD3Header, sizeof(SMD3Header)); 322 file->read(&Mesh->MD3Header, sizeof(SMD3Header));
323 323
324 if (strncmp("IDP3", Mesh->MD3Header.headerID, 4)) 324 if (strncmp("IDP3", Mesh->MD3Header.headerID, 4))
325 { 325 {
326 os::Printer::log("MD3 Loader: invalid header"); 326 os::Printer::log("MD3 Loader: invalid header");
327 return false; 327 return false;
328 } 328 }
329 } 329 }
330 330
331 //! store model name 331 //! store model name
332 Mesh->Name = file->getFileName(); 332 Mesh->Name = file->getFileName();
333 333
334 u32 i; 334 u32 i;
335 335
336 //! Frame Data (ignore) 336 //! Frame Data (ignore)
337#if 0 337#if 0
338 SMD3Frame frameImport; 338 SMD3Frame frameImport;
339 file->seek(Mesh->MD3Header.frameStart); 339 file->seek(Mesh->MD3Header.frameStart);
340 for (i = 0; i != Mesh->MD3Header.numFrames; ++i) 340 for (i = 0; i != Mesh->MD3Header.numFrames; ++i)
341 { 341 {
342 file->read(&frameImport, sizeof(frameImport)); 342 file->read(&frameImport, sizeof(frameImport));
343 } 343 }
344#endif 344#endif
345 345
346 //! Tag Data 346 //! Tag Data
347 const u32 totalTags = Mesh->MD3Header.numTags * Mesh->MD3Header.numFrames; 347 const u32 totalTags = Mesh->MD3Header.numTags * Mesh->MD3Header.numFrames;
348 348
349 SMD3Tag import; 349 SMD3Tag import;
350 350
351 file->seek(Mesh->MD3Header.tagStart); 351 file->seek(Mesh->MD3Header.tagStart);
352 Mesh->TagList.set_used(totalTags); 352 Mesh->TagList.set_used(totalTags);
353 for (i = 0; i != totalTags; ++i) 353 for (i = 0; i != totalTags; ++i)
354 { 354 {
355 file->read(&import, sizeof(import)); 355 file->read(&import, sizeof(import));
356 356
357 SMD3QuaternionTag &exp = Mesh->TagList[i]; 357 SMD3QuaternionTag &exp = Mesh->TagList[i];
358 358
359 //! tag name 359 //! tag name
360 exp.Name = import.Name; 360 exp.Name = import.Name;
361 361
362 //! position 362 //! position
363 exp.position.X = import.position[0]; 363 exp.position.X = import.position[0];
364 exp.position.Y = import.position[2]; 364 exp.position.Y = import.position[2];
365 exp.position.Z = import.position[1]; 365 exp.position.Z = import.position[1];
366 366
367 //! construct quaternion from a RH 3x3 Matrix 367 //! construct quaternion from a RH 3x3 Matrix
368 exp.rotation.set(import.rotationMatrix[7], 368 exp.rotation.set(import.rotationMatrix[7],
369 0.f, 369 0.f,
370 -import.rotationMatrix[6], 370 -import.rotationMatrix[6],
371 1 + import.rotationMatrix[8]); 371 1 + import.rotationMatrix[8]);
372 exp.rotation.normalize(); 372 exp.rotation.normalize();
373 } 373 }
374 374
375 //! Meshes 375 //! Meshes
376 u32 offset = Mesh->MD3Header.tagEnd; 376 u32 offset = Mesh->MD3Header.tagEnd;
377 377
378 for (i = 0; i != (u32)Mesh->MD3Header.numMeshes; ++i) 378 for (i = 0; i != (u32)Mesh->MD3Header.numMeshes; ++i)
379 { 379 {
380 //! construct a new mesh buffer 380 //! construct a new mesh buffer
381 SMD3MeshBuffer * buf = new SMD3MeshBuffer(); 381 SMD3MeshBuffer * buf = new SMD3MeshBuffer();
382 382
383 // !read mesh header info 383 // !read mesh header info
384 SMD3MeshHeader &meshHeader = buf->MeshHeader; 384 SMD3MeshHeader &meshHeader = buf->MeshHeader;
385 385
386 //! read mesh info 386 //! read mesh info
387 file->seek(offset); 387 file->seek(offset);
388 file->read(&meshHeader, sizeof(SMD3MeshHeader)); 388 file->read(&meshHeader, sizeof(SMD3MeshHeader));
389 389
390 //! prepare memory 390 //! prepare memory
391 buf->Vertices.set_used(meshHeader.numVertices * Mesh->MD3Header.numFrames); 391 buf->Vertices.set_used(meshHeader.numVertices * Mesh->MD3Header.numFrames);
392 buf->Indices.set_used(meshHeader.numTriangles * 3); 392 buf->Indices.set_used(meshHeader.numTriangles * 3);
393 buf->Tex.set_used(meshHeader.numVertices); 393 buf->Tex.set_used(meshHeader.numVertices);
394 394
395 //! read skins (shaders). should be 1 per meshbuffer 395 //! read skins (shaders). should be 1 per meshbuffer
396 SMD3Shader skin; 396 SMD3Shader skin;
397 file->seek(offset + buf->MeshHeader.offset_shaders); 397 file->seek(offset + buf->MeshHeader.offset_shaders);
398 for (s32 g = 0; g != buf->MeshHeader.numShader; ++g) 398 for (s32 g = 0; g != buf->MeshHeader.numShader; ++g)
399 { 399 {
400 file->read(&skin, sizeof(skin)); 400 file->read(&skin, sizeof(skin));
401 401
402 io::path name; 402 io::path name;
403 cutFilenameExtension(name, skin.name); 403 cutFilenameExtension(name, skin.name);
404 name.replace('\\', '/'); 404 name.replace('\\', '/');
405 buf->Shader = name; 405 buf->Shader = name;
406 } 406 }
407 407
408 //! read texture coordinates 408 //! read texture coordinates
409 file->seek(offset + buf->MeshHeader.offset_st); 409 file->seek(offset + buf->MeshHeader.offset_st);
410 file->read(buf->Tex.pointer(), buf->MeshHeader.numVertices * sizeof(SMD3TexCoord)); 410 file->read(buf->Tex.pointer(), buf->MeshHeader.numVertices * sizeof(SMD3TexCoord));
411 411
412 //! read vertices 412 //! read vertices
413 file->seek(offset + meshHeader.vertexStart); 413 file->seek(offset + meshHeader.vertexStart);
414 file->read(buf->Vertices.pointer(), Mesh->MD3Header.numFrames * meshHeader.numVertices * sizeof(SMD3Vertex)); 414 file->read(buf->Vertices.pointer(), Mesh->MD3Header.numFrames * meshHeader.numVertices * sizeof(SMD3Vertex));
415 415
416 //! read indices 416 //! read indices
417 file->seek(offset + meshHeader.offset_triangles); 417 file->seek(offset + meshHeader.offset_triangles);
418 file->read(buf->Indices.pointer(), meshHeader.numTriangles * sizeof(SMD3Face)); 418 file->read(buf->Indices.pointer(), meshHeader.numTriangles * sizeof(SMD3Face));
419 419
420 //! store meshBuffer 420 //! store meshBuffer
421 Mesh->Buffer.push_back(buf); 421 Mesh->Buffer.push_back(buf);
422 422
423 offset += meshHeader.offset_end; 423 offset += meshHeader.offset_end;
424 } 424 }
425 425
426 // Init Mesh Interpolation 426 // Init Mesh Interpolation
427 for (i = 0; i != Mesh->Buffer.size(); ++i) 427 for (i = 0; i != Mesh->Buffer.size(); ++i)
428 { 428 {
429 IMeshBuffer * buffer = createMeshBuffer(Mesh->Buffer[i], fs, driver); 429 IMeshBuffer * buffer = createMeshBuffer(Mesh->Buffer[i], fs, driver);
430 MeshIPol->addMeshBuffer(buffer); 430 MeshIPol->addMeshBuffer(buffer);
431 buffer->drop(); 431 buffer->drop();
432 } 432 }
433 MeshIPol->recalculateBoundingBox(); 433 MeshIPol->recalculateBoundingBox();
434 434
435 // Init Tag Interpolation 435 // Init Tag Interpolation
436 for (i = 0; i != (u32)Mesh->MD3Header.numTags; ++i) 436 for (i = 0; i != (u32)Mesh->MD3Header.numTags; ++i)
437 { 437 {
438 TagListIPol.push_back(Mesh->TagList[i]); 438 TagListIPol.push_back(Mesh->TagList[i]);
439 } 439 }
440 440
441 return true; 441 return true;
442} 442}
443 443
444 444
445SMD3Mesh * CAnimatedMeshMD3::getOriginalMesh() 445SMD3Mesh * CAnimatedMeshMD3::getOriginalMesh()
446{ 446{
447 return Mesh; 447 return Mesh;
448} 448}
449 449
450 450
451//! Returns an axis aligned bounding box 451//! Returns an axis aligned bounding box
452const core::aabbox3d<f32>& CAnimatedMeshMD3::getBoundingBox() const 452const core::aabbox3d<f32>& CAnimatedMeshMD3::getBoundingBox() const
453{ 453{
454 return MeshIPol->BoundingBox; 454 return MeshIPol->BoundingBox;
455} 455}
456 456
457 457
458//! Returns the type of the animated mesh. 458//! Returns the type of the animated mesh.
459E_ANIMATED_MESH_TYPE CAnimatedMeshMD3::getMeshType() const 459E_ANIMATED_MESH_TYPE CAnimatedMeshMD3::getMeshType() const
460{ 460{
461 return EAMT_MD3; 461 return EAMT_MD3;
462} 462}
463 463
464 464
465} // end namespace scene 465} // end namespace scene
466} // end namespace irr 466} // end namespace irr
467 467
468#endif // _IRR_COMPILE_WITH_MD3_LOADER_ 468#endif // _IRR_COMPILE_WITH_MD3_LOADER_