diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CMD2MeshFileLoader.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CMD2MeshFileLoader.cpp | 364 |
1 files changed, 0 insertions, 364 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CMD2MeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CMD2MeshFileLoader.cpp deleted file mode 100644 index 79333ab..0000000 --- a/libraries/irrlicht-1.8/source/Irrlicht/CMD2MeshFileLoader.cpp +++ /dev/null | |||
@@ -1,364 +0,0 @@ | |||
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 "CMD2MeshFileLoader.h" | ||
9 | #include "CAnimatedMeshMD2.h" | ||
10 | #include "os.h" | ||
11 | |||
12 | namespace irr | ||
13 | { | ||
14 | namespace scene | ||
15 | { | ||
16 | |||
17 | |||
18 | // structs needed to load the md2-format | ||
19 | |||
20 | const s32 MD2_MAGIC_NUMBER = 844121161; | ||
21 | const s32 MD2_VERSION = 8; | ||
22 | const s32 MD2_MAX_VERTS = 2048; | ||
23 | |||
24 | // byte-align structures | ||
25 | #include "irrpack.h" | ||
26 | |||
27 | struct SMD2Header | ||
28 | { | ||
29 | s32 magic; // four character code "IDP2" | ||
30 | s32 version; // must be 8 | ||
31 | s32 skinWidth; // width of the texture | ||
32 | s32 skinHeight; // height of the texture | ||
33 | s32 frameSize; // size in bytes of an animation frame | ||
34 | s32 numSkins; // number of textures | ||
35 | s32 numVertices; // total number of vertices | ||
36 | s32 numTexcoords; // number of vertices with texture coords | ||
37 | s32 numTriangles; // number of triangles | ||
38 | s32 numGlCommands; // number of opengl commands (triangle strip or triangle fan) | ||
39 | s32 numFrames; // animation keyframe count | ||
40 | s32 offsetSkins; // offset in bytes to 64 character skin names | ||
41 | s32 offsetTexcoords; // offset in bytes to texture coordinate list | ||
42 | s32 offsetTriangles; // offset in bytes to triangle list | ||
43 | s32 offsetFrames; // offset in bytes to frame list | ||
44 | s32 offsetGlCommands;// offset in bytes to opengl commands | ||
45 | s32 offsetEnd; // offset in bytes to end of file | ||
46 | } PACK_STRUCT; | ||
47 | |||
48 | struct SMD2Vertex | ||
49 | { | ||
50 | u8 vertex[3]; // [0] = X, [1] = Z, [2] = Y | ||
51 | u8 lightNormalIndex; // index in the normal table | ||
52 | } PACK_STRUCT; | ||
53 | |||
54 | struct SMD2Frame | ||
55 | { | ||
56 | f32 scale[3]; // first scale the vertex position | ||
57 | f32 translate[3]; // then translate the position | ||
58 | c8 name[16]; // the name of the animation that this key belongs to | ||
59 | SMD2Vertex vertices[1]; // vertex 1 of SMD2Header.numVertices | ||
60 | } PACK_STRUCT; | ||
61 | |||
62 | struct SMD2Triangle | ||
63 | { | ||
64 | u16 vertexIndices[3]; | ||
65 | u16 textureIndices[3]; | ||
66 | } PACK_STRUCT; | ||
67 | |||
68 | struct SMD2TextureCoordinate | ||
69 | { | ||
70 | s16 s; | ||
71 | s16 t; | ||
72 | } PACK_STRUCT; | ||
73 | |||
74 | struct SMD2GLCommand | ||
75 | { | ||
76 | f32 s, t; | ||
77 | s32 vertexIndex; | ||
78 | } PACK_STRUCT; | ||
79 | |||
80 | // Default alignment | ||
81 | #include "irrunpack.h" | ||
82 | |||
83 | //! Constructor | ||
84 | CMD2MeshFileLoader::CMD2MeshFileLoader() | ||
85 | { | ||
86 | #ifdef _DEBUG | ||
87 | setDebugName("CMD2MeshFileLoader"); | ||
88 | #endif | ||
89 | } | ||
90 | |||
91 | |||
92 | //! returns true if the file maybe is able to be loaded by this class | ||
93 | //! based on the file extension (e.g. ".bsp") | ||
94 | bool CMD2MeshFileLoader::isALoadableFileExtension(const io::path& filename) const | ||
95 | { | ||
96 | return core::hasFileExtension ( filename, "md2" ); | ||
97 | } | ||
98 | |||
99 | |||
100 | //! creates/loads an animated mesh from the file. | ||
101 | //! \return Pointer to the created mesh. Returns 0 if loading failed. | ||
102 | //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). | ||
103 | //! See IReferenceCounted::drop() for more information. | ||
104 | IAnimatedMesh* CMD2MeshFileLoader::createMesh(io::IReadFile* file) | ||
105 | { | ||
106 | IAnimatedMesh* msh = new CAnimatedMeshMD2(); | ||
107 | if (msh) | ||
108 | { | ||
109 | if (loadFile(file, (CAnimatedMeshMD2*)msh) ) | ||
110 | return msh; | ||
111 | |||
112 | msh->drop(); | ||
113 | } | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | //! loads an md2 file | ||
119 | bool CMD2MeshFileLoader::loadFile(io::IReadFile* file, CAnimatedMeshMD2* mesh) | ||
120 | { | ||
121 | if (!file) | ||
122 | return false; | ||
123 | |||
124 | SMD2Header header; | ||
125 | |||
126 | file->read(&header, sizeof(SMD2Header)); | ||
127 | |||
128 | #ifdef __BIG_ENDIAN__ | ||
129 | header.magic = os::Byteswap::byteswap(header.magic); | ||
130 | header.version = os::Byteswap::byteswap(header.version); | ||
131 | header.skinWidth = os::Byteswap::byteswap(header.skinWidth); | ||
132 | header.skinHeight = os::Byteswap::byteswap(header.skinHeight); | ||
133 | header.frameSize = os::Byteswap::byteswap(header.frameSize); | ||
134 | header.numSkins = os::Byteswap::byteswap(header.numSkins); | ||
135 | header.numVertices = os::Byteswap::byteswap(header.numVertices); | ||
136 | header.numTexcoords = os::Byteswap::byteswap(header.numTexcoords); | ||
137 | header.numTriangles = os::Byteswap::byteswap(header.numTriangles); | ||
138 | header.numGlCommands = os::Byteswap::byteswap(header.numGlCommands); | ||
139 | header.numFrames = os::Byteswap::byteswap(header.numFrames); | ||
140 | header.offsetSkins = os::Byteswap::byteswap(header.offsetSkins); | ||
141 | header.offsetTexcoords = os::Byteswap::byteswap(header.offsetTexcoords); | ||
142 | header.offsetTriangles = os::Byteswap::byteswap(header.offsetTriangles); | ||
143 | header.offsetFrames = os::Byteswap::byteswap(header.offsetFrames); | ||
144 | header.offsetGlCommands = os::Byteswap::byteswap(header.offsetGlCommands); | ||
145 | header.offsetEnd = os::Byteswap::byteswap(header.offsetEnd); | ||
146 | #endif | ||
147 | |||
148 | if (header.magic != MD2_MAGIC_NUMBER || header.version != MD2_VERSION) | ||
149 | { | ||
150 | os::Printer::log("MD2 Loader: Wrong file header", file->getFileName(), ELL_WARNING); | ||
151 | return false; | ||
152 | } | ||
153 | |||
154 | // | ||
155 | // prepare mesh and allocate memory | ||
156 | // | ||
157 | |||
158 | mesh->FrameCount = header.numFrames; | ||
159 | |||
160 | // create keyframes | ||
161 | mesh->FrameTransforms.set_used(header.numFrames); | ||
162 | |||
163 | // create vertex arrays for each keyframe | ||
164 | if (mesh->FrameList) | ||
165 | delete [] mesh->FrameList; | ||
166 | mesh->FrameList = new core::array<CAnimatedMeshMD2::SMD2Vert>[header.numFrames]; | ||
167 | |||
168 | // allocate space in vertex arrays | ||
169 | s32 i; | ||
170 | for (i=0; i<header.numFrames; ++i) | ||
171 | mesh->FrameList[i].reallocate(header.numVertices); | ||
172 | |||
173 | // allocate interpolation buffer vertices | ||
174 | mesh->InterpolationBuffer->Vertices.set_used(header.numTriangles*3); | ||
175 | |||
176 | // populate triangles | ||
177 | mesh->InterpolationBuffer->Indices.reallocate(header.numTriangles*3); | ||
178 | const s32 count = header.numTriangles*3; | ||
179 | for (i=0; i<count; i+=3) | ||
180 | { | ||
181 | mesh->InterpolationBuffer->Indices.push_back(i); | ||
182 | mesh->InterpolationBuffer->Indices.push_back(i+1); | ||
183 | mesh->InterpolationBuffer->Indices.push_back(i+2); | ||
184 | } | ||
185 | |||
186 | // | ||
187 | // read texture coordinates | ||
188 | // | ||
189 | |||
190 | file->seek(header.offsetTexcoords); | ||
191 | SMD2TextureCoordinate* textureCoords = new SMD2TextureCoordinate[header.numTexcoords]; | ||
192 | |||
193 | if (!file->read(textureCoords, sizeof(SMD2TextureCoordinate)*header.numTexcoords)) | ||
194 | { | ||
195 | delete[] textureCoords; | ||
196 | os::Printer::log("MD2 Loader: Error reading TextureCoords.", file->getFileName(), ELL_ERROR); | ||
197 | return false; | ||
198 | } | ||
199 | |||
200 | #ifdef __BIG_ENDIAN__ | ||
201 | for (i=0; i<header.numTexcoords; ++i) | ||
202 | { | ||
203 | textureCoords[i].s = os::Byteswap::byteswap(textureCoords[i].s); | ||
204 | textureCoords[i].t = os::Byteswap::byteswap(textureCoords[i].t); | ||
205 | } | ||
206 | #endif | ||
207 | |||
208 | // read Triangles | ||
209 | |||
210 | file->seek(header.offsetTriangles); | ||
211 | |||
212 | SMD2Triangle *triangles = new SMD2Triangle[header.numTriangles]; | ||
213 | if (!file->read(triangles, header.numTriangles *sizeof(SMD2Triangle))) | ||
214 | { | ||
215 | delete[] triangles; | ||
216 | delete[] textureCoords; | ||
217 | |||
218 | os::Printer::log("MD2 Loader: Error reading triangles.", file->getFileName(), ELL_ERROR); | ||
219 | return false; | ||
220 | } | ||
221 | |||
222 | #ifdef __BIG_ENDIAN__ | ||
223 | for (i=0; i<header.numTriangles; ++i) | ||
224 | { | ||
225 | triangles[i].vertexIndices[0] = os::Byteswap::byteswap(triangles[i].vertexIndices[0]); | ||
226 | triangles[i].vertexIndices[1] = os::Byteswap::byteswap(triangles[i].vertexIndices[1]); | ||
227 | triangles[i].vertexIndices[2] = os::Byteswap::byteswap(triangles[i].vertexIndices[2]); | ||
228 | triangles[i].textureIndices[0] = os::Byteswap::byteswap(triangles[i].textureIndices[0]); | ||
229 | triangles[i].textureIndices[1] = os::Byteswap::byteswap(triangles[i].textureIndices[1]); | ||
230 | triangles[i].textureIndices[2] = os::Byteswap::byteswap(triangles[i].textureIndices[2]); | ||
231 | } | ||
232 | #endif | ||
233 | |||
234 | // read Vertices | ||
235 | |||
236 | u8 buffer[MD2_MAX_VERTS*4+128]; | ||
237 | SMD2Frame* frame = (SMD2Frame*)buffer; | ||
238 | |||
239 | file->seek(header.offsetFrames); | ||
240 | |||
241 | for (i = 0; i<header.numFrames; ++i) | ||
242 | { | ||
243 | // read vertices | ||
244 | |||
245 | file->read(frame, header.frameSize); | ||
246 | |||
247 | #ifdef __BIG_ENDIAN__ | ||
248 | frame->scale[0] = os::Byteswap::byteswap(frame->scale[0]); | ||
249 | frame->scale[1] = os::Byteswap::byteswap(frame->scale[1]); | ||
250 | frame->scale[2] = os::Byteswap::byteswap(frame->scale[2]); | ||
251 | frame->translate[0] = os::Byteswap::byteswap(frame->translate[0]); | ||
252 | frame->translate[1] = os::Byteswap::byteswap(frame->translate[1]); | ||
253 | frame->translate[2] = os::Byteswap::byteswap(frame->translate[2]); | ||
254 | #endif | ||
255 | // | ||
256 | // store frame data | ||
257 | // | ||
258 | |||
259 | CAnimatedMeshMD2::SAnimationData adata; | ||
260 | adata.begin = i; | ||
261 | adata.end = i; | ||
262 | adata.fps = 7; | ||
263 | |||
264 | // Add new named animation if necessary | ||
265 | if (frame->name[0]) | ||
266 | { | ||
267 | // get animation name | ||
268 | for (s32 s = 0; s < 16 && frame->name[s]!=0 && (frame->name[s] < '0' || frame->name[s] > '9'); ++s) | ||
269 | { | ||
270 | adata.name += frame->name[s]; | ||
271 | } | ||
272 | |||
273 | // Does this keyframe have the same animation name as the current animation? | ||
274 | if (!mesh->AnimationData.empty() && mesh->AnimationData[mesh->AnimationData.size()-1].name == adata.name) | ||
275 | { | ||
276 | // Increase the length of the animation | ||
277 | ++mesh->AnimationData[mesh->AnimationData.size() - 1].end; | ||
278 | } | ||
279 | else | ||
280 | { | ||
281 | // Add the new animation | ||
282 | mesh->AnimationData.push_back(adata); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | // save keyframe scale and translation | ||
287 | |||
288 | mesh->FrameTransforms[i].scale.X = frame->scale[0]; | ||
289 | mesh->FrameTransforms[i].scale.Z = frame->scale[1]; | ||
290 | mesh->FrameTransforms[i].scale.Y = frame->scale[2]; | ||
291 | mesh->FrameTransforms[i].translate.X = frame->translate[0]; | ||
292 | mesh->FrameTransforms[i].translate.Z = frame->translate[1]; | ||
293 | mesh->FrameTransforms[i].translate.Y = frame->translate[2]; | ||
294 | |||
295 | // add vertices | ||
296 | for (s32 j=0; j<header.numTriangles; ++j) | ||
297 | { | ||
298 | for (u32 ti=0; ti<3; ++ti) | ||
299 | { | ||
300 | CAnimatedMeshMD2::SMD2Vert v; | ||
301 | u32 num = triangles[j].vertexIndices[ti]; | ||
302 | v.Pos.X = frame->vertices[num].vertex[0]; | ||
303 | v.Pos.Z = frame->vertices[num].vertex[1]; | ||
304 | v.Pos.Y = frame->vertices[num].vertex[2]; | ||
305 | v.NormalIdx = frame->vertices[num].lightNormalIndex; | ||
306 | |||
307 | mesh->FrameList[i].push_back(v); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | // calculate bounding boxes | ||
312 | if (header.numVertices) | ||
313 | { | ||
314 | core::aabbox3d<f32> box; | ||
315 | core::vector3df pos; | ||
316 | pos.X = f32(mesh->FrameList[i] [0].Pos.X) * mesh->FrameTransforms[i].scale.X + mesh->FrameTransforms[i].translate.X; | ||
317 | pos.Y = f32(mesh->FrameList[i] [0].Pos.Y) * mesh->FrameTransforms[i].scale.Y + mesh->FrameTransforms[i].translate.Y; | ||
318 | pos.Z = f32(mesh->FrameList[i] [0].Pos.Z) * mesh->FrameTransforms[i].scale.Z + mesh->FrameTransforms[i].translate.Z; | ||
319 | |||
320 | box.reset(pos); | ||
321 | |||
322 | for (s32 j=1; j<header.numTriangles*3; ++j) | ||
323 | { | ||
324 | pos.X = f32(mesh->FrameList[i] [j].Pos.X) * mesh->FrameTransforms[i].scale.X + mesh->FrameTransforms[i].translate.X; | ||
325 | pos.Y = f32(mesh->FrameList[i] [j].Pos.Y) * mesh->FrameTransforms[i].scale.Y + mesh->FrameTransforms[i].translate.Y; | ||
326 | pos.Z = f32(mesh->FrameList[i] [j].Pos.Z) * mesh->FrameTransforms[i].scale.Z + mesh->FrameTransforms[i].translate.Z; | ||
327 | |||
328 | box.addInternalPoint(pos); | ||
329 | } | ||
330 | mesh->BoxList.push_back(box); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | // populate interpolation buffer with texture coordinates and colors | ||
335 | if (header.numFrames) | ||
336 | { | ||
337 | f32 dmaxs = 1.0f/(header.skinWidth); | ||
338 | f32 dmaxt = 1.0f/(header.skinHeight); | ||
339 | |||
340 | for (s32 t=0; t<header.numTriangles; ++t) | ||
341 | { | ||
342 | for (s32 n=0; n<3; ++n) | ||
343 | { | ||
344 | mesh->InterpolationBuffer->Vertices[t*3 + n].TCoords.X = (textureCoords[triangles[t].textureIndices[n]].s + 0.5f) * dmaxs; | ||
345 | mesh->InterpolationBuffer->Vertices[t*3 + n].TCoords.Y = (textureCoords[triangles[t].textureIndices[n]].t + 0.5f) * dmaxt; | ||
346 | mesh->InterpolationBuffer->Vertices[t*3 + n].Color = video::SColor(255,255,255,255); | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | // clean up | ||
352 | delete [] triangles; | ||
353 | delete [] textureCoords; | ||
354 | |||
355 | // init buffer with start frame. | ||
356 | mesh->getMesh(0); | ||
357 | return true; | ||
358 | } | ||
359 | |||
360 | } // end namespace scene | ||
361 | } // end namespace irr | ||
362 | |||
363 | |||
364 | #endif // _IRR_COMPILE_WITH_MD2_LOADER_ | ||