aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CMS3DMeshFileLoader.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/CMS3DMeshFileLoader.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/CMS3DMeshFileLoader.cpp1636
1 files changed, 818 insertions, 818 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CMS3DMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CMS3DMeshFileLoader.cpp
index 9a88d49..af06188 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CMS3DMeshFileLoader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CMS3DMeshFileLoader.cpp
@@ -1,818 +1,818 @@
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 "IrrCompileConfig.h" 5#include "IrrCompileConfig.h"
6#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ 6#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
7 7
8#include "IReadFile.h" 8#include "IReadFile.h"
9#include "os.h" 9#include "os.h"
10#include "CMS3DMeshFileLoader.h" 10#include "CMS3DMeshFileLoader.h"
11#include "CSkinnedMesh.h" 11#include "CSkinnedMesh.h"
12 12
13 13
14namespace irr 14namespace irr
15{ 15{
16namespace scene 16namespace scene
17{ 17{
18 18
19#ifdef _DEBUG 19#ifdef _DEBUG
20#define _IRR_DEBUG_MS3D_LOADER_ 20#define _IRR_DEBUG_MS3D_LOADER_
21#endif 21#endif
22 22
23// byte-align structures 23// byte-align structures
24#include "irrpack.h" 24#include "irrpack.h"
25 25
26namespace { 26namespace {
27// File header 27// File header
28struct MS3DHeader 28struct MS3DHeader
29{ 29{
30 char ID[10]; 30 char ID[10];
31 int Version; 31 int Version;
32} PACK_STRUCT; 32} PACK_STRUCT;
33 33
34// Vertex information 34// Vertex information
35struct MS3DVertex 35struct MS3DVertex
36{ 36{
37 u8 Flags; 37 u8 Flags;
38 float Vertex[3]; 38 float Vertex[3];
39 char BoneID; 39 char BoneID;
40 u8 RefCount; 40 u8 RefCount;
41} PACK_STRUCT; 41} PACK_STRUCT;
42 42
43// Triangle information 43// Triangle information
44struct MS3DTriangle 44struct MS3DTriangle
45{ 45{
46 u16 Flags; 46 u16 Flags;
47 u16 VertexIndices[3]; 47 u16 VertexIndices[3];
48 float VertexNormals[3][3]; 48 float VertexNormals[3][3];
49 float S[3], T[3]; 49 float S[3], T[3];
50 u8 SmoothingGroup; 50 u8 SmoothingGroup;
51 u8 GroupIndex; 51 u8 GroupIndex;
52} PACK_STRUCT; 52} PACK_STRUCT;
53 53
54// Material information 54// Material information
55struct MS3DMaterial 55struct MS3DMaterial
56{ 56{
57 char Name[32]; 57 char Name[32];
58 float Ambient[4]; 58 float Ambient[4];
59 float Diffuse[4]; 59 float Diffuse[4];
60 float Specular[4]; 60 float Specular[4];
61 float Emissive[4]; 61 float Emissive[4];
62 float Shininess; // 0.0f - 128.0f 62 float Shininess; // 0.0f - 128.0f
63 float Transparency; // 0.0f - 1.0f 63 float Transparency; // 0.0f - 1.0f
64 u8 Mode; // 0, 1, 2 is unused now 64 u8 Mode; // 0, 1, 2 is unused now
65 char Texture[128]; 65 char Texture[128];
66 char Alphamap[128]; 66 char Alphamap[128];
67} PACK_STRUCT; 67} PACK_STRUCT;
68 68
69// Joint information 69// Joint information
70struct MS3DJoint 70struct MS3DJoint
71{ 71{
72 u8 Flags; 72 u8 Flags;
73 char Name[32]; 73 char Name[32];
74 char ParentName[32]; 74 char ParentName[32];
75 float Rotation[3]; 75 float Rotation[3];
76 float Translation[3]; 76 float Translation[3];
77 u16 NumRotationKeyframes; 77 u16 NumRotationKeyframes;
78 u16 NumTranslationKeyframes; 78 u16 NumTranslationKeyframes;
79} PACK_STRUCT; 79} PACK_STRUCT;
80 80
81// Keyframe data 81// Keyframe data
82struct MS3DKeyframe 82struct MS3DKeyframe
83{ 83{
84 float Time; 84 float Time;
85 float Parameter[3]; 85 float Parameter[3];
86} PACK_STRUCT; 86} PACK_STRUCT;
87 87
88// vertex weights in 1.8.x 88// vertex weights in 1.8.x
89struct MS3DVertexWeights 89struct MS3DVertexWeights
90{ 90{
91 char boneIds[3]; 91 char boneIds[3];
92 u8 weights[3]; 92 u8 weights[3];
93} PACK_STRUCT; 93} PACK_STRUCT;
94 94
95} // end namespace 95} // end namespace
96 96
97// Default alignment 97// Default alignment
98#include "irrunpack.h" 98#include "irrunpack.h"
99 99
100struct SGroup 100struct SGroup
101{ 101{
102 core::stringc Name; 102 core::stringc Name;
103 core::array<u16> VertexIds; 103 core::array<u16> VertexIds;
104 u16 MaterialIdx; 104 u16 MaterialIdx;
105}; 105};
106 106
107//! Constructor 107//! Constructor
108CMS3DMeshFileLoader::CMS3DMeshFileLoader(video::IVideoDriver *driver) 108CMS3DMeshFileLoader::CMS3DMeshFileLoader(video::IVideoDriver *driver)
109: Driver(driver), AnimatedMesh(0) 109: Driver(driver), AnimatedMesh(0)
110{ 110{
111 #ifdef _DEBUG 111 #ifdef _DEBUG
112 setDebugName("CMS3DMeshFileLoader"); 112 setDebugName("CMS3DMeshFileLoader");
113 #endif 113 #endif
114} 114}
115 115
116 116
117//! returns true if the file maybe is able to be loaded by this class 117//! returns true if the file maybe is able to be loaded by this class
118//! based on the file extension (e.g. ".bsp") 118//! based on the file extension (e.g. ".bsp")
119bool CMS3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 119bool CMS3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
120{ 120{
121 return core::hasFileExtension ( filename, "ms3d" ); 121 return core::hasFileExtension ( filename, "ms3d" );
122} 122}
123 123
124 124
125//! creates/loads an animated mesh from the file. 125//! creates/loads an animated mesh from the file.
126//! \return Pointer to the created mesh. Returns 0 if loading failed. 126//! \return Pointer to the created mesh. Returns 0 if loading failed.
127//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). 127//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
128//! See IReferenceCounted::drop() for more information. 128//! See IReferenceCounted::drop() for more information.
129IAnimatedMesh* CMS3DMeshFileLoader::createMesh(io::IReadFile* file) 129IAnimatedMesh* CMS3DMeshFileLoader::createMesh(io::IReadFile* file)
130{ 130{
131 if (!file) 131 if (!file)
132 return 0; 132 return 0;
133 133
134 AnimatedMesh = new CSkinnedMesh(); 134 AnimatedMesh = new CSkinnedMesh();
135 135
136 if ( load(file) ) 136 if ( load(file) )
137 { 137 {
138 AnimatedMesh->finalize(); 138 AnimatedMesh->finalize();
139 } 139 }
140 else 140 else
141 { 141 {
142 AnimatedMesh->drop(); 142 AnimatedMesh->drop();
143 AnimatedMesh = 0; 143 AnimatedMesh = 0;
144 } 144 }
145 145
146 return AnimatedMesh; 146 return AnimatedMesh;
147} 147}
148 148
149 149
150//! loads a milkshape file 150//! loads a milkshape file
151bool CMS3DMeshFileLoader::load(io::IReadFile* file) 151bool CMS3DMeshFileLoader::load(io::IReadFile* file)
152{ 152{
153 if (!file) 153 if (!file)
154 return false; 154 return false;
155 155
156 // find file size 156 // find file size
157 const long fileSize = file->getSize(); 157 const long fileSize = file->getSize();
158 158
159 // read whole file 159 // read whole file
160 160
161 u8* buffer = new u8[fileSize]; 161 u8* buffer = new u8[fileSize];
162 s32 read = file->read(buffer, fileSize); 162 s32 read = file->read(buffer, fileSize);
163 if (read != fileSize) 163 if (read != fileSize)
164 { 164 {
165 delete [] buffer; 165 delete [] buffer;
166 os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR); 166 os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR);
167 return false; 167 return false;
168 } 168 }
169 169
170 // read header 170 // read header
171 171
172 const u8 *pPtr = (u8*)((void*)buffer); 172 const u8 *pPtr = (u8*)((void*)buffer);
173 MS3DHeader *pHeader = (MS3DHeader*)pPtr; 173 MS3DHeader *pHeader = (MS3DHeader*)pPtr;
174 pPtr += sizeof(MS3DHeader); 174 pPtr += sizeof(MS3DHeader);
175 175
176 if ( strncmp( pHeader->ID, "MS3D000000", 10 ) != 0 ) 176 if ( strncmp( pHeader->ID, "MS3D000000", 10 ) != 0 )
177 { 177 {
178 delete [] buffer; 178 delete [] buffer;
179 os::Printer::log("Not a valid Milkshape3D Model File. Loading failed", file->getFileName(), ELL_ERROR); 179 os::Printer::log("Not a valid Milkshape3D Model File. Loading failed", file->getFileName(), ELL_ERROR);
180 return false; 180 return false;
181 } 181 }
182 182
183#ifdef __BIG_ENDIAN__ 183#ifdef __BIG_ENDIAN__
184 pHeader->Version = os::Byteswap::byteswap(pHeader->Version); 184 pHeader->Version = os::Byteswap::byteswap(pHeader->Version);
185#endif 185#endif
186 if ( pHeader->Version < 3 || pHeader->Version > 4 ) 186 if ( pHeader->Version < 3 || pHeader->Version > 4 )
187 { 187 {
188 delete [] buffer; 188 delete [] buffer;
189 os::Printer::log("Only Milkshape3D version 3 and 4 (1.3 to 1.8) is supported. Loading failed", file->getFileName(), ELL_ERROR); 189 os::Printer::log("Only Milkshape3D version 3 and 4 (1.3 to 1.8) is supported. Loading failed", file->getFileName(), ELL_ERROR);
190 return false; 190 return false;
191 } 191 }
192#ifdef _IRR_DEBUG_MS3D_LOADER_ 192#ifdef _IRR_DEBUG_MS3D_LOADER_
193 os::Printer::log("Loaded header version", core::stringc(pHeader->Version).c_str()); 193 os::Printer::log("Loaded header version", core::stringc(pHeader->Version).c_str());
194#endif 194#endif
195 195
196 // get pointers to data 196 // get pointers to data
197 197
198 // vertices 198 // vertices
199 u16 numVertices = *(u16*)pPtr; 199 u16 numVertices = *(u16*)pPtr;
200#ifdef __BIG_ENDIAN__ 200#ifdef __BIG_ENDIAN__
201 numVertices = os::Byteswap::byteswap(numVertices); 201 numVertices = os::Byteswap::byteswap(numVertices);
202#endif 202#endif
203#ifdef _IRR_DEBUG_MS3D_LOADER_ 203#ifdef _IRR_DEBUG_MS3D_LOADER_
204 os::Printer::log("Load vertices", core::stringc(numVertices).c_str()); 204 os::Printer::log("Load vertices", core::stringc(numVertices).c_str());
205#endif 205#endif
206 pPtr += sizeof(u16); 206 pPtr += sizeof(u16);
207 MS3DVertex *vertices = (MS3DVertex*)pPtr; 207 MS3DVertex *vertices = (MS3DVertex*)pPtr;
208 pPtr += sizeof(MS3DVertex) * numVertices; 208 pPtr += sizeof(MS3DVertex) * numVertices;
209 if (pPtr > buffer+fileSize) 209 if (pPtr > buffer+fileSize)
210 { 210 {
211 delete [] buffer; 211 delete [] buffer;
212 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 212 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
213 return false; 213 return false;
214 } 214 }
215 for (u16 tmp=0; tmp<numVertices; ++tmp) 215 for (u16 tmp=0; tmp<numVertices; ++tmp)
216 { 216 {
217#ifdef __BIG_ENDIAN__ 217#ifdef __BIG_ENDIAN__
218 vertices[tmp].Vertex[0] = os::Byteswap::byteswap(vertices[tmp].Vertex[0]); 218 vertices[tmp].Vertex[0] = os::Byteswap::byteswap(vertices[tmp].Vertex[0]);
219 vertices[tmp].Vertex[1] = os::Byteswap::byteswap(vertices[tmp].Vertex[1]); 219 vertices[tmp].Vertex[1] = os::Byteswap::byteswap(vertices[tmp].Vertex[1]);
220 vertices[tmp].Vertex[2] = -os::Byteswap::byteswap(vertices[tmp].Vertex[2]); 220 vertices[tmp].Vertex[2] = -os::Byteswap::byteswap(vertices[tmp].Vertex[2]);
221#else 221#else
222 vertices[tmp].Vertex[2] = -vertices[tmp].Vertex[2]; 222 vertices[tmp].Vertex[2] = -vertices[tmp].Vertex[2];
223#endif 223#endif
224 } 224 }
225 225
226 // triangles 226 // triangles
227 u16 numTriangles = *(u16*)pPtr; 227 u16 numTriangles = *(u16*)pPtr;
228#ifdef __BIG_ENDIAN__ 228#ifdef __BIG_ENDIAN__
229 numTriangles = os::Byteswap::byteswap(numTriangles); 229 numTriangles = os::Byteswap::byteswap(numTriangles);
230#endif 230#endif
231#ifdef _IRR_DEBUG_MS3D_LOADER_ 231#ifdef _IRR_DEBUG_MS3D_LOADER_
232 os::Printer::log("Load Triangles", core::stringc(numTriangles).c_str()); 232 os::Printer::log("Load Triangles", core::stringc(numTriangles).c_str());
233#endif 233#endif
234 pPtr += sizeof(u16); 234 pPtr += sizeof(u16);
235 MS3DTriangle *triangles = (MS3DTriangle*)pPtr; 235 MS3DTriangle *triangles = (MS3DTriangle*)pPtr;
236 pPtr += sizeof(MS3DTriangle) * numTriangles; 236 pPtr += sizeof(MS3DTriangle) * numTriangles;
237 if (pPtr > buffer+fileSize) 237 if (pPtr > buffer+fileSize)
238 { 238 {
239 delete [] buffer; 239 delete [] buffer;
240 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 240 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
241 return false; 241 return false;
242 } 242 }
243 for (u16 tmp=0; tmp<numTriangles; ++tmp) 243 for (u16 tmp=0; tmp<numTriangles; ++tmp)
244 { 244 {
245#ifdef __BIG_ENDIAN__ 245#ifdef __BIG_ENDIAN__
246 triangles[tmp].Flags = os::Byteswap::byteswap(triangles[tmp].Flags); 246 triangles[tmp].Flags = os::Byteswap::byteswap(triangles[tmp].Flags);
247 for (u16 j=0; j<3; ++j) 247 for (u16 j=0; j<3; ++j)
248 { 248 {
249 triangles[tmp].VertexIndices[j] = os::Byteswap::byteswap(triangles[tmp].VertexIndices[j]); 249 triangles[tmp].VertexIndices[j] = os::Byteswap::byteswap(triangles[tmp].VertexIndices[j]);
250 triangles[tmp].VertexNormals[j][0] = os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][0]); 250 triangles[tmp].VertexNormals[j][0] = os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][0]);
251 triangles[tmp].VertexNormals[j][1] = os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][1]); 251 triangles[tmp].VertexNormals[j][1] = os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][1]);
252 triangles[tmp].VertexNormals[j][2] = -os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][2]); 252 triangles[tmp].VertexNormals[j][2] = -os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][2]);
253 triangles[tmp].S[j] = os::Byteswap::byteswap(triangles[tmp].S[j]); 253 triangles[tmp].S[j] = os::Byteswap::byteswap(triangles[tmp].S[j]);
254 triangles[tmp].T[j] = os::Byteswap::byteswap(triangles[tmp].T[j]); 254 triangles[tmp].T[j] = os::Byteswap::byteswap(triangles[tmp].T[j]);
255 } 255 }
256#else 256#else
257 triangles[tmp].VertexNormals[0][2] = -triangles[tmp].VertexNormals[0][2]; 257 triangles[tmp].VertexNormals[0][2] = -triangles[tmp].VertexNormals[0][2];
258 triangles[tmp].VertexNormals[1][2] = -triangles[tmp].VertexNormals[1][2]; 258 triangles[tmp].VertexNormals[1][2] = -triangles[tmp].VertexNormals[1][2];
259 triangles[tmp].VertexNormals[2][2] = -triangles[tmp].VertexNormals[2][2]; 259 triangles[tmp].VertexNormals[2][2] = -triangles[tmp].VertexNormals[2][2];
260#endif 260#endif
261 } 261 }
262 262
263 // groups 263 // groups
264 u16 numGroups = *(u16*)pPtr; 264 u16 numGroups = *(u16*)pPtr;
265#ifdef __BIG_ENDIAN__ 265#ifdef __BIG_ENDIAN__
266 numGroups = os::Byteswap::byteswap(numGroups); 266 numGroups = os::Byteswap::byteswap(numGroups);
267#endif 267#endif
268#ifdef _IRR_DEBUG_MS3D_LOADER_ 268#ifdef _IRR_DEBUG_MS3D_LOADER_
269 os::Printer::log("Load Groups", core::stringc(numGroups).c_str()); 269 os::Printer::log("Load Groups", core::stringc(numGroups).c_str());
270#endif 270#endif
271 pPtr += sizeof(u16); 271 pPtr += sizeof(u16);
272 272
273 core::array<SGroup> groups; 273 core::array<SGroup> groups;
274 groups.reallocate(numGroups); 274 groups.reallocate(numGroups);
275 275
276 //store groups 276 //store groups
277 u32 i; 277 u32 i;
278 for (i=0; i<numGroups; ++i) 278 for (i=0; i<numGroups; ++i)
279 { 279 {
280 groups.push_back(SGroup()); 280 groups.push_back(SGroup());
281 SGroup& grp = groups.getLast(); 281 SGroup& grp = groups.getLast();
282 282
283 // The byte flag is before the name, so add 1 283 // The byte flag is before the name, so add 1
284 grp.Name = ((const c8*) pPtr) + 1; 284 grp.Name = ((const c8*) pPtr) + 1;
285 285
286 pPtr += 33; // name and 1 byte flags 286 pPtr += 33; // name and 1 byte flags
287 u16 triangleCount = *(u16*)pPtr; 287 u16 triangleCount = *(u16*)pPtr;
288#ifdef __BIG_ENDIAN__ 288#ifdef __BIG_ENDIAN__
289 triangleCount = os::Byteswap::byteswap(triangleCount); 289 triangleCount = os::Byteswap::byteswap(triangleCount);
290#endif 290#endif
291 pPtr += sizeof(u16); 291 pPtr += sizeof(u16);
292 grp.VertexIds.reallocate(triangleCount); 292 grp.VertexIds.reallocate(triangleCount);
293 293
294 //pPtr += sizeof(u16) * triangleCount; // triangle indices 294 //pPtr += sizeof(u16) * triangleCount; // triangle indices
295 for (u16 j=0; j<triangleCount; ++j) 295 for (u16 j=0; j<triangleCount; ++j)
296 { 296 {
297#ifdef __BIG_ENDIAN__ 297#ifdef __BIG_ENDIAN__
298 grp.VertexIds.push_back(os::Byteswap::byteswap(*(u16*)pPtr)); 298 grp.VertexIds.push_back(os::Byteswap::byteswap(*(u16*)pPtr));
299#else 299#else
300 grp.VertexIds.push_back(*(u16*)pPtr); 300 grp.VertexIds.push_back(*(u16*)pPtr);
301#endif 301#endif
302 pPtr += sizeof (u16); 302 pPtr += sizeof (u16);
303 } 303 }
304 304
305 grp.MaterialIdx = *(u8*)pPtr; 305 grp.MaterialIdx = *(u8*)pPtr;
306 if (grp.MaterialIdx == 255) 306 if (grp.MaterialIdx == 255)
307 grp.MaterialIdx = 0; 307 grp.MaterialIdx = 0;
308 308
309 pPtr += sizeof(c8); // material index 309 pPtr += sizeof(c8); // material index
310 if (pPtr > buffer+fileSize) 310 if (pPtr > buffer+fileSize)
311 { 311 {
312 delete [] buffer; 312 delete [] buffer;
313 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 313 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
314 return false; 314 return false;
315 } 315 }
316 } 316 }
317 317
318 // load materials 318 // load materials
319 u16 numMaterials = *(u16*)pPtr; 319 u16 numMaterials = *(u16*)pPtr;
320#ifdef __BIG_ENDIAN__ 320#ifdef __BIG_ENDIAN__
321 numMaterials = os::Byteswap::byteswap(numMaterials); 321 numMaterials = os::Byteswap::byteswap(numMaterials);
322#endif 322#endif
323#ifdef _IRR_DEBUG_MS3D_LOADER_ 323#ifdef _IRR_DEBUG_MS3D_LOADER_
324 os::Printer::log("Load Materials", core::stringc(numMaterials).c_str()); 324 os::Printer::log("Load Materials", core::stringc(numMaterials).c_str());
325#endif 325#endif
326 pPtr += sizeof(u16); 326 pPtr += sizeof(u16);
327 327
328 if(numMaterials == 0) 328 if(numMaterials == 0)
329 { 329 {
330 // if there are no materials, add at least one buffer 330 // if there are no materials, add at least one buffer
331 AnimatedMesh->addMeshBuffer(); 331 AnimatedMesh->addMeshBuffer();
332 } 332 }
333 333
334 for (i=0; i<numMaterials; ++i) 334 for (i=0; i<numMaterials; ++i)
335 { 335 {
336 MS3DMaterial *material = (MS3DMaterial*)pPtr; 336 MS3DMaterial *material = (MS3DMaterial*)pPtr;
337#ifdef __BIG_ENDIAN__ 337#ifdef __BIG_ENDIAN__
338 for (u16 j=0; j<4; ++j) 338 for (u16 j=0; j<4; ++j)
339 material->Ambient[j] = os::Byteswap::byteswap(material->Ambient[j]); 339 material->Ambient[j] = os::Byteswap::byteswap(material->Ambient[j]);
340 for (u16 j=0; j<4; ++j) 340 for (u16 j=0; j<4; ++j)
341 material->Diffuse[j] = os::Byteswap::byteswap(material->Diffuse[j]); 341 material->Diffuse[j] = os::Byteswap::byteswap(material->Diffuse[j]);
342 for (u16 j=0; j<4; ++j) 342 for (u16 j=0; j<4; ++j)
343 material->Specular[j] = os::Byteswap::byteswap(material->Specular[j]); 343 material->Specular[j] = os::Byteswap::byteswap(material->Specular[j]);
344 for (u16 j=0; j<4; ++j) 344 for (u16 j=0; j<4; ++j)
345 material->Emissive[j] = os::Byteswap::byteswap(material->Emissive[j]); 345 material->Emissive[j] = os::Byteswap::byteswap(material->Emissive[j]);
346 material->Shininess = os::Byteswap::byteswap(material->Shininess); 346 material->Shininess = os::Byteswap::byteswap(material->Shininess);
347 material->Transparency = os::Byteswap::byteswap(material->Transparency); 347 material->Transparency = os::Byteswap::byteswap(material->Transparency);
348#endif 348#endif
349 pPtr += sizeof(MS3DMaterial); 349 pPtr += sizeof(MS3DMaterial);
350 if (pPtr > buffer+fileSize) 350 if (pPtr > buffer+fileSize)
351 { 351 {
352 delete [] buffer; 352 delete [] buffer;
353 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 353 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
354 return false; 354 return false;
355 } 355 }
356 356
357 scene::SSkinMeshBuffer *tmpBuffer = AnimatedMesh->addMeshBuffer(); 357 scene::SSkinMeshBuffer *tmpBuffer = AnimatedMesh->addMeshBuffer();
358 358
359 tmpBuffer->Material.MaterialType = video::EMT_SOLID; 359 tmpBuffer->Material.MaterialType = video::EMT_SOLID;
360 360
361 tmpBuffer->Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor (); 361 tmpBuffer->Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor ();
362 tmpBuffer->Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor (); 362 tmpBuffer->Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor ();
363 tmpBuffer->Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor (); 363 tmpBuffer->Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor ();
364 tmpBuffer->Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor (); 364 tmpBuffer->Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor ();
365 tmpBuffer->Material.Shininess = material->Shininess; 365 tmpBuffer->Material.Shininess = material->Shininess;
366 366
367 core::stringc TexturePath(material->Texture); 367 core::stringc TexturePath(material->Texture);
368 if (TexturePath.trim()!="") 368 if (TexturePath.trim()!="")
369 { 369 {
370 TexturePath=stripPathFromString(file->getFileName(),true) + stripPathFromString(TexturePath,false); 370 TexturePath=stripPathFromString(file->getFileName(),true) + stripPathFromString(TexturePath,false);
371 tmpBuffer->Material.setTexture(0, Driver->getTexture(TexturePath)); 371 tmpBuffer->Material.setTexture(0, Driver->getTexture(TexturePath));
372 } 372 }
373 373
374 core::stringc AlphamapPath=(const c8*)material->Alphamap; 374 core::stringc AlphamapPath=(const c8*)material->Alphamap;
375 if (AlphamapPath.trim()!="") 375 if (AlphamapPath.trim()!="")
376 { 376 {
377 AlphamapPath=stripPathFromString(file->getFileName(),true) + stripPathFromString(AlphamapPath,false); 377 AlphamapPath=stripPathFromString(file->getFileName(),true) + stripPathFromString(AlphamapPath,false);
378 tmpBuffer->Material.setTexture(2, Driver->getTexture(AlphamapPath)); 378 tmpBuffer->Material.setTexture(2, Driver->getTexture(AlphamapPath));
379 } 379 }
380 } 380 }
381 381
382 // animation time 382 // animation time
383 f32 framesPerSecond = *(float*)pPtr; 383 f32 framesPerSecond = *(float*)pPtr;
384#ifdef __BIG_ENDIAN__ 384#ifdef __BIG_ENDIAN__
385 framesPerSecond = os::Byteswap::byteswap(framesPerSecond); 385 framesPerSecond = os::Byteswap::byteswap(framesPerSecond);
386#endif 386#endif
387#ifdef _IRR_DEBUG_MS3D_LOADER_ 387#ifdef _IRR_DEBUG_MS3D_LOADER_
388 os::Printer::log("FPS", core::stringc(framesPerSecond).c_str()); 388 os::Printer::log("FPS", core::stringc(framesPerSecond).c_str());
389#endif 389#endif
390 pPtr += sizeof(float) * 2; // fps and current time 390 pPtr += sizeof(float) * 2; // fps and current time
391 391
392 if (framesPerSecond<1.f) 392 if (framesPerSecond<1.f)
393 framesPerSecond=1.f; 393 framesPerSecond=1.f;
394 AnimatedMesh->setAnimationSpeed(framesPerSecond); 394 AnimatedMesh->setAnimationSpeed(framesPerSecond);
395 395
396// ignore, calculated inside SkinnedMesh 396// ignore, calculated inside SkinnedMesh
397// s32 frameCount = *(int*)pPtr; 397// s32 frameCount = *(int*)pPtr;
398#ifdef __BIG_ENDIAN__ 398#ifdef __BIG_ENDIAN__
399// frameCount = os::Byteswap::byteswap(frameCount); 399// frameCount = os::Byteswap::byteswap(frameCount);
400#endif 400#endif
401 pPtr += sizeof(int); 401 pPtr += sizeof(int);
402 402
403 u16 jointCount = *(u16*)pPtr; 403 u16 jointCount = *(u16*)pPtr;
404#ifdef __BIG_ENDIAN__ 404#ifdef __BIG_ENDIAN__
405 jointCount = os::Byteswap::byteswap(jointCount); 405 jointCount = os::Byteswap::byteswap(jointCount);
406#endif 406#endif
407#ifdef _IRR_DEBUG_MS3D_LOADER_ 407#ifdef _IRR_DEBUG_MS3D_LOADER_
408 os::Printer::log("Joints", core::stringc(jointCount).c_str()); 408 os::Printer::log("Joints", core::stringc(jointCount).c_str());
409#endif 409#endif
410 pPtr += sizeof(u16); 410 pPtr += sizeof(u16);
411 if (pPtr > buffer+fileSize) 411 if (pPtr > buffer+fileSize)
412 { 412 {
413 delete [] buffer; 413 delete [] buffer;
414 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 414 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
415 return false; 415 return false;
416 } 416 }
417 417
418 core::array<core::stringc> parentNames; 418 core::array<core::stringc> parentNames;
419 parentNames.reallocate(jointCount); 419 parentNames.reallocate(jointCount);
420 420
421 // load joints 421 // load joints
422 for (i=0; i<jointCount; ++i) 422 for (i=0; i<jointCount; ++i)
423 { 423 {
424 u32 j; 424 u32 j;
425 MS3DJoint *pJoint = (MS3DJoint*)pPtr; 425 MS3DJoint *pJoint = (MS3DJoint*)pPtr;
426#ifdef __BIG_ENDIAN__ 426#ifdef __BIG_ENDIAN__
427 for (j=0; j<3; ++j) 427 for (j=0; j<3; ++j)
428 pJoint->Rotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]); 428 pJoint->Rotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]);
429 for (j=0; j<3; ++j) 429 for (j=0; j<3; ++j)
430 pJoint->Translation[j] = os::Byteswap::byteswap(pJoint->Translation[j]); 430 pJoint->Translation[j] = os::Byteswap::byteswap(pJoint->Translation[j]);
431 pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes); 431 pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes);
432 pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes); 432 pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes);
433#endif 433#endif
434 pPtr += sizeof(MS3DJoint); 434 pPtr += sizeof(MS3DJoint);
435 if (pPtr > buffer+fileSize) 435 if (pPtr > buffer+fileSize)
436 { 436 {
437 delete [] buffer; 437 delete [] buffer;
438 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 438 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
439 return false; 439 return false;
440 } 440 }
441 441
442 ISkinnedMesh::SJoint *jnt = AnimatedMesh->addJoint(); 442 ISkinnedMesh::SJoint *jnt = AnimatedMesh->addJoint();
443 443
444 jnt->Name = pJoint->Name; 444 jnt->Name = pJoint->Name;
445#ifdef _IRR_DEBUG_MS3D_LOADER_ 445#ifdef _IRR_DEBUG_MS3D_LOADER_
446 os::Printer::log("Joint", jnt->Name.c_str()); 446 os::Printer::log("Joint", jnt->Name.c_str());
447 os::Printer::log("Rotation keyframes", core::stringc(pJoint->NumRotationKeyframes).c_str()); 447 os::Printer::log("Rotation keyframes", core::stringc(pJoint->NumRotationKeyframes).c_str());
448 os::Printer::log("Translation keyframes", core::stringc(pJoint->NumTranslationKeyframes).c_str()); 448 os::Printer::log("Translation keyframes", core::stringc(pJoint->NumTranslationKeyframes).c_str());
449#endif 449#endif
450 jnt->LocalMatrix.makeIdentity(); 450 jnt->LocalMatrix.makeIdentity();
451 jnt->LocalMatrix.setRotationRadians( 451 jnt->LocalMatrix.setRotationRadians(
452 core::vector3df(pJoint->Rotation[0], pJoint->Rotation[1], pJoint->Rotation[2]) ); 452 core::vector3df(pJoint->Rotation[0], pJoint->Rotation[1], pJoint->Rotation[2]) );
453 // convert right-handed to left-handed 453 // convert right-handed to left-handed
454 jnt->LocalMatrix[2]=-jnt->LocalMatrix[2]; 454 jnt->LocalMatrix[2]=-jnt->LocalMatrix[2];
455 jnt->LocalMatrix[6]=-jnt->LocalMatrix[6]; 455 jnt->LocalMatrix[6]=-jnt->LocalMatrix[6];
456 jnt->LocalMatrix[8]=-jnt->LocalMatrix[8]; 456 jnt->LocalMatrix[8]=-jnt->LocalMatrix[8];
457 jnt->LocalMatrix[9]=-jnt->LocalMatrix[9]; 457 jnt->LocalMatrix[9]=-jnt->LocalMatrix[9];
458 458
459 jnt->LocalMatrix.setTranslation( 459 jnt->LocalMatrix.setTranslation(
460 core::vector3df(pJoint->Translation[0], pJoint->Translation[1], -pJoint->Translation[2]) ); 460 core::vector3df(pJoint->Translation[0], pJoint->Translation[1], -pJoint->Translation[2]) );
461 jnt->Animatedposition.set(jnt->LocalMatrix.getTranslation()); 461 jnt->Animatedposition.set(jnt->LocalMatrix.getTranslation());
462 jnt->Animatedrotation.set(jnt->LocalMatrix.getRotationDegrees()); 462 jnt->Animatedrotation.set(jnt->LocalMatrix.getRotationDegrees());
463 463
464 parentNames.push_back( (c8*)pJoint->ParentName ); 464 parentNames.push_back( (c8*)pJoint->ParentName );
465 465
466 /*if (pJoint->NumRotationKeyframes || 466 /*if (pJoint->NumRotationKeyframes ||
467 pJoint->NumTranslationKeyframes) 467 pJoint->NumTranslationKeyframes)
468 HasAnimation = true; 468 HasAnimation = true;
469 */ 469 */
470 470
471 // get rotation keyframes 471 // get rotation keyframes
472 const u16 numRotationKeyframes = pJoint->NumRotationKeyframes; 472 const u16 numRotationKeyframes = pJoint->NumRotationKeyframes;
473 for (j=0; j < numRotationKeyframes; ++j) 473 for (j=0; j < numRotationKeyframes; ++j)
474 { 474 {
475 MS3DKeyframe* kf = (MS3DKeyframe*)pPtr; 475 MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
476#ifdef __BIG_ENDIAN__ 476#ifdef __BIG_ENDIAN__
477 kf->Time = os::Byteswap::byteswap(kf->Time); 477 kf->Time = os::Byteswap::byteswap(kf->Time);
478 for (u32 l=0; l<3; ++l) 478 for (u32 l=0; l<3; ++l)
479 kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]); 479 kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
480#endif 480#endif
481 pPtr += sizeof(MS3DKeyframe); 481 pPtr += sizeof(MS3DKeyframe);
482 if (pPtr > buffer+fileSize) 482 if (pPtr > buffer+fileSize)
483 { 483 {
484 delete [] buffer; 484 delete [] buffer;
485 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 485 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
486 return false; 486 return false;
487 } 487 }
488 488
489 ISkinnedMesh::SRotationKey *k=AnimatedMesh->addRotationKey(jnt); 489 ISkinnedMesh::SRotationKey *k=AnimatedMesh->addRotationKey(jnt);
490 k->frame = kf->Time * framesPerSecond-1; 490 k->frame = kf->Time * framesPerSecond-1;
491 491
492 core::matrix4 tmpMatrix; 492 core::matrix4 tmpMatrix;
493 493
494 tmpMatrix.setRotationRadians( 494 tmpMatrix.setRotationRadians(
495 core::vector3df(kf->Parameter[0], kf->Parameter[1], kf->Parameter[2]) ); 495 core::vector3df(kf->Parameter[0], kf->Parameter[1], kf->Parameter[2]) );
496 // convert right-handed to left-handed 496 // convert right-handed to left-handed
497 tmpMatrix[2]=-tmpMatrix[2]; 497 tmpMatrix[2]=-tmpMatrix[2];
498 tmpMatrix[6]=-tmpMatrix[6]; 498 tmpMatrix[6]=-tmpMatrix[6];
499 tmpMatrix[8]=-tmpMatrix[8]; 499 tmpMatrix[8]=-tmpMatrix[8];
500 tmpMatrix[9]=-tmpMatrix[9]; 500 tmpMatrix[9]=-tmpMatrix[9];
501 501
502 tmpMatrix=jnt->LocalMatrix*tmpMatrix; 502 tmpMatrix=jnt->LocalMatrix*tmpMatrix;
503 503
504 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from tmpMatrix to tmpMatrix.getTransposed() for downward compatibility. 504 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from tmpMatrix to tmpMatrix.getTransposed() for downward compatibility.
505 // Not tested so far if this was correct or wrong before quaternion fix! 505 // Not tested so far if this was correct or wrong before quaternion fix!
506 k->rotation = core::quaternion(tmpMatrix.getTransposed()); 506 k->rotation = core::quaternion(tmpMatrix.getTransposed());
507 } 507 }
508 508
509 // get translation keyframes 509 // get translation keyframes
510 const u16 numTranslationKeyframes = pJoint->NumTranslationKeyframes; 510 const u16 numTranslationKeyframes = pJoint->NumTranslationKeyframes;
511 for (j=0; j<numTranslationKeyframes; ++j) 511 for (j=0; j<numTranslationKeyframes; ++j)
512 { 512 {
513 MS3DKeyframe* kf = (MS3DKeyframe*)pPtr; 513 MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
514#ifdef __BIG_ENDIAN__ 514#ifdef __BIG_ENDIAN__
515 kf->Time = os::Byteswap::byteswap(kf->Time); 515 kf->Time = os::Byteswap::byteswap(kf->Time);
516 for (u32 l=0; l<3; ++l) 516 for (u32 l=0; l<3; ++l)
517 kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]); 517 kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
518#endif 518#endif
519 pPtr += sizeof(MS3DKeyframe); 519 pPtr += sizeof(MS3DKeyframe);
520 if (pPtr > buffer+fileSize) 520 if (pPtr > buffer+fileSize)
521 { 521 {
522 delete [] buffer; 522 delete [] buffer;
523 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 523 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
524 return false; 524 return false;
525 } 525 }
526 526
527 ISkinnedMesh::SPositionKey *k=AnimatedMesh->addPositionKey(jnt); 527 ISkinnedMesh::SPositionKey *k=AnimatedMesh->addPositionKey(jnt);
528 k->frame = kf->Time * framesPerSecond-1; 528 k->frame = kf->Time * framesPerSecond-1;
529 529
530 k->position = core::vector3df 530 k->position = core::vector3df
531 (kf->Parameter[0]+pJoint->Translation[0], 531 (kf->Parameter[0]+pJoint->Translation[0],
532 kf->Parameter[1]+pJoint->Translation[1], 532 kf->Parameter[1]+pJoint->Translation[1],
533 -kf->Parameter[2]-pJoint->Translation[2]); 533 -kf->Parameter[2]-pJoint->Translation[2]);
534 } 534 }
535 } 535 }
536 536
537 core::array<MS3DVertexWeights> vertexWeights; 537 core::array<MS3DVertexWeights> vertexWeights;
538 f32 weightFactor=0; 538 f32 weightFactor=0;
539 539
540 if (jointCount && (pHeader->Version == 4) && (pPtr < buffer+fileSize)) 540 if (jointCount && (pHeader->Version == 4) && (pPtr < buffer+fileSize))
541 { 541 {
542 s32 subVersion = *(s32*)pPtr; // comment subVersion, always 1 542 s32 subVersion = *(s32*)pPtr; // comment subVersion, always 1
543#ifdef __BIG_ENDIAN__ 543#ifdef __BIG_ENDIAN__
544 subVersion = os::Byteswap::byteswap(subVersion); 544 subVersion = os::Byteswap::byteswap(subVersion);
545#endif 545#endif
546 pPtr += sizeof(s32); 546 pPtr += sizeof(s32);
547 547
548 for (u32 j=0; j<4; ++j) // four comment groups 548 for (u32 j=0; j<4; ++j) // four comment groups
549 { 549 {
550#ifdef _IRR_DEBUG_MS3D_LOADER_ 550#ifdef _IRR_DEBUG_MS3D_LOADER_
551 os::Printer::log("Skipping comment group", core::stringc(j+1).c_str()); 551 os::Printer::log("Skipping comment group", core::stringc(j+1).c_str());
552#endif 552#endif
553 u32 numComments = *(u32*)pPtr; 553 u32 numComments = *(u32*)pPtr;
554#ifdef __BIG_ENDIAN__ 554#ifdef __BIG_ENDIAN__
555 numComments = os::Byteswap::byteswap(numComments); 555 numComments = os::Byteswap::byteswap(numComments);
556#endif 556#endif
557 pPtr += sizeof(u32); 557 pPtr += sizeof(u32);
558 for (i=0; i<numComments; ++i) 558 for (i=0; i<numComments; ++i)
559 { 559 {
560 // according to scorpiomidget this field does 560 // according to scorpiomidget this field does
561 // not exist for model comments. So avoid to 561 // not exist for model comments. So avoid to
562 // read it 562 // read it
563 if (j!=3) 563 if (j!=3)
564 pPtr += sizeof(s32); // index 564 pPtr += sizeof(s32); // index
565 s32 commentLength = *(s32*)pPtr; 565 s32 commentLength = *(s32*)pPtr;
566#ifdef __BIG_ENDIAN__ 566#ifdef __BIG_ENDIAN__
567 commentLength = os::Byteswap::byteswap(commentLength); 567 commentLength = os::Byteswap::byteswap(commentLength);
568#endif 568#endif
569 pPtr += sizeof(s32); 569 pPtr += sizeof(s32);
570 pPtr += commentLength; 570 pPtr += commentLength;
571 } 571 }
572 572
573 if (pPtr > buffer+fileSize) 573 if (pPtr > buffer+fileSize)
574 { 574 {
575 delete [] buffer; 575 delete [] buffer;
576 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 576 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
577 return false; 577 return false;
578 } 578 }
579 } 579 }
580 580
581 if (pPtr < buffer+fileSize) 581 if (pPtr < buffer+fileSize)
582 { 582 {
583 subVersion = *(s32*)pPtr; // vertex subVersion, 1 or 2 583 subVersion = *(s32*)pPtr; // vertex subVersion, 1 or 2
584#ifdef __BIG_ENDIAN__ 584#ifdef __BIG_ENDIAN__
585 subVersion = os::Byteswap::byteswap(subVersion); 585 subVersion = os::Byteswap::byteswap(subVersion);
586#endif 586#endif
587 if (subVersion==1) 587 if (subVersion==1)
588 weightFactor=1.f/255.f; 588 weightFactor=1.f/255.f;
589 else 589 else
590 weightFactor=1.f/100.f; 590 weightFactor=1.f/100.f;
591 pPtr += sizeof(s32); 591 pPtr += sizeof(s32);
592 592
593#ifdef _IRR_DEBUG_MS3D_LOADER_ 593#ifdef _IRR_DEBUG_MS3D_LOADER_
594 os::Printer::log("Reading vertex weights"); 594 os::Printer::log("Reading vertex weights");
595#endif 595#endif
596 // read vertex weights, ignoring data 'extra' from 1.8.2 596 // read vertex weights, ignoring data 'extra' from 1.8.2
597 vertexWeights.reallocate(numVertices); 597 vertexWeights.reallocate(numVertices);
598 const char offset = (subVersion==1)?6:10; 598 const char offset = (subVersion==1)?6:10;
599 for (i=0; i<numVertices; ++i) 599 for (i=0; i<numVertices; ++i)
600 { 600 {
601 vertexWeights.push_back(*(MS3DVertexWeights*)pPtr); 601 vertexWeights.push_back(*(MS3DVertexWeights*)pPtr);
602 pPtr += offset; 602 pPtr += offset;
603 } 603 }
604 604
605 if (pPtr > buffer+fileSize) 605 if (pPtr > buffer+fileSize)
606 { 606 {
607 delete [] buffer; 607 delete [] buffer;
608 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); 608 os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
609 return false; 609 return false;
610 } 610 }
611 } 611 }
612 612
613 if (pPtr < buffer+fileSize) 613 if (pPtr < buffer+fileSize)
614 { 614 {
615 subVersion = *(s32*)pPtr; // joint subVersion, 1 or 2 615 subVersion = *(s32*)pPtr; // joint subVersion, 1 or 2
616#ifdef __BIG_ENDIAN__ 616#ifdef __BIG_ENDIAN__
617 subVersion = os::Byteswap::byteswap(subVersion); 617 subVersion = os::Byteswap::byteswap(subVersion);
618#endif 618#endif
619 pPtr += sizeof(s32); 619 pPtr += sizeof(s32);
620 // skip joint colors 620 // skip joint colors
621#ifdef _IRR_DEBUG_MS3D_LOADER_ 621#ifdef _IRR_DEBUG_MS3D_LOADER_
622 os::Printer::log("Skip joint color"); 622 os::Printer::log("Skip joint color");
623#endif 623#endif
624 pPtr += 3*sizeof(float)*jointCount; 624 pPtr += 3*sizeof(float)*jointCount;
625 625
626 if (pPtr > buffer+fileSize) 626 if (pPtr > buffer+fileSize)
627 { 627 {
628 delete [] buffer; 628 delete [] buffer;
629 os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR); 629 os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR);
630 return false; 630 return false;
631 } 631 }
632 } 632 }
633 633
634 if (pPtr < buffer+fileSize) 634 if (pPtr < buffer+fileSize)
635 { 635 {
636 subVersion = *(s32*)pPtr; // model subVersion, 1 or 2 636 subVersion = *(s32*)pPtr; // model subVersion, 1 or 2
637#ifdef __BIG_ENDIAN__ 637#ifdef __BIG_ENDIAN__
638 subVersion = os::Byteswap::byteswap(subVersion); 638 subVersion = os::Byteswap::byteswap(subVersion);
639#endif 639#endif
640 pPtr += sizeof(s32); 640 pPtr += sizeof(s32);
641#ifdef _IRR_DEBUG_MS3D_LOADER_ 641#ifdef _IRR_DEBUG_MS3D_LOADER_
642 os::Printer::log("Skip model extra information"); 642 os::Printer::log("Skip model extra information");
643#endif 643#endif
644 // now the model extra information would follow 644 // now the model extra information would follow
645 // we also skip this for now 645 // we also skip this for now
646 } 646 }
647 } 647 }
648 648
649 //find parent of every joint 649 //find parent of every joint
650 for (u32 jointnum=0; jointnum<AnimatedMesh->getAllJoints().size(); ++jointnum) 650 for (u32 jointnum=0; jointnum<AnimatedMesh->getAllJoints().size(); ++jointnum)
651 { 651 {
652 for (u32 j2=0; j2<AnimatedMesh->getAllJoints().size(); ++j2) 652 for (u32 j2=0; j2<AnimatedMesh->getAllJoints().size(); ++j2)
653 { 653 {
654 if (jointnum != j2 && parentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name ) 654 if (jointnum != j2 && parentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name )
655 { 655 {
656 AnimatedMesh->getAllJoints()[j2]->Children.push_back(AnimatedMesh->getAllJoints()[jointnum]); 656 AnimatedMesh->getAllJoints()[j2]->Children.push_back(AnimatedMesh->getAllJoints()[jointnum]);
657 break; 657 break;
658 } 658 }
659 } 659 }
660 } 660 }
661 661
662 // create vertices and indices, attach them to the joints. 662 // create vertices and indices, attach them to the joints.
663 video::S3DVertex v; 663 video::S3DVertex v;
664 core::array<video::S3DVertex> *Vertices; 664 core::array<video::S3DVertex> *Vertices;
665 core::array<u16> Indices; 665 core::array<u16> Indices;
666 666
667 for (i=0; i<numTriangles; ++i) 667 for (i=0; i<numTriangles; ++i)
668 { 668 {
669 u32 tmp = groups[triangles[i].GroupIndex].MaterialIdx; 669 u32 tmp = groups[triangles[i].GroupIndex].MaterialIdx;
670 Vertices = &AnimatedMesh->getMeshBuffers()[tmp]->Vertices_Standard; 670 Vertices = &AnimatedMesh->getMeshBuffers()[tmp]->Vertices_Standard;
671 671
672 for (s32 j = 2; j!=-1; --j) 672 for (s32 j = 2; j!=-1; --j)
673 { 673 {
674 const u32 vertidx = triangles[i].VertexIndices[j]; 674 const u32 vertidx = triangles[i].VertexIndices[j];
675 675
676 v.TCoords.X = triangles[i].S[j]; 676 v.TCoords.X = triangles[i].S[j];
677 v.TCoords.Y = triangles[i].T[j]; 677 v.TCoords.Y = triangles[i].T[j];
678 678
679 v.Normal.X = triangles[i].VertexNormals[j][0]; 679 v.Normal.X = triangles[i].VertexNormals[j][0];
680 v.Normal.Y = triangles[i].VertexNormals[j][1]; 680 v.Normal.Y = triangles[i].VertexNormals[j][1];
681 v.Normal.Z = triangles[i].VertexNormals[j][2]; 681 v.Normal.Z = triangles[i].VertexNormals[j][2];
682 682
683 if(triangles[i].GroupIndex < groups.size() && 683 if(triangles[i].GroupIndex < groups.size() &&
684 groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size()) 684 groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size())
685 v.Color = AnimatedMesh->getMeshBuffers()[groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor; 685 v.Color = AnimatedMesh->getMeshBuffers()[groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor;
686 else 686 else
687 v.Color.set(255,255,255,255); 687 v.Color.set(255,255,255,255);
688 688
689 v.Pos.X = vertices[vertidx].Vertex[0]; 689 v.Pos.X = vertices[vertidx].Vertex[0];
690 v.Pos.Y = vertices[vertidx].Vertex[1]; 690 v.Pos.Y = vertices[vertidx].Vertex[1];
691 v.Pos.Z = vertices[vertidx].Vertex[2]; 691 v.Pos.Z = vertices[vertidx].Vertex[2];
692 692
693 // check if we already have this vertex in our vertex array 693 // check if we already have this vertex in our vertex array
694 s32 index = -1; 694 s32 index = -1;
695 for (u32 iV = 0; iV < Vertices->size(); ++iV) 695 for (u32 iV = 0; iV < Vertices->size(); ++iV)
696 { 696 {
697 if (v == (*Vertices)[iV]) 697 if (v == (*Vertices)[iV])
698 { 698 {
699 index = (s32)iV; 699 index = (s32)iV;
700 break; 700 break;
701 } 701 }
702 } 702 }
703 703
704 if (index == -1) 704 if (index == -1)
705 { 705 {
706 index = Vertices->size(); 706 index = Vertices->size();
707 const u32 matidx = groups[triangles[i].GroupIndex].MaterialIdx; 707 const u32 matidx = groups[triangles[i].GroupIndex].MaterialIdx;
708 if (vertexWeights.size()==0) 708 if (vertexWeights.size()==0)
709 { 709 {
710 const s32 boneid = vertices[vertidx].BoneID; 710 const s32 boneid = vertices[vertidx].BoneID;
711 if ((u32)boneid < AnimatedMesh->getAllJoints().size()) 711 if ((u32)boneid < AnimatedMesh->getAllJoints().size())
712 { 712 {
713 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); 713 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
714 w->buffer_id = matidx; 714 w->buffer_id = matidx;
715 w->strength = 1.0f; 715 w->strength = 1.0f;
716 w->vertex_id = index; 716 w->vertex_id = index;
717 } 717 }
718 } 718 }
719 else if (jointCount) // new weights from 1.8.x 719 else if (jointCount) // new weights from 1.8.x
720 { 720 {
721 f32 sum = 1.0f; 721 f32 sum = 1.0f;
722 s32 boneid = vertices[vertidx].BoneID; 722 s32 boneid = vertices[vertidx].BoneID;
723 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[0] != 0)) 723 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[0] != 0))
724 { 724 {
725 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); 725 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
726 w->buffer_id = matidx; 726 w->buffer_id = matidx;
727 sum -= (w->strength = vertexWeights[vertidx].weights[0]*weightFactor); 727 sum -= (w->strength = vertexWeights[vertidx].weights[0]*weightFactor);
728 w->vertex_id = index; 728 w->vertex_id = index;
729 } 729 }
730 boneid = vertexWeights[vertidx].boneIds[0]; 730 boneid = vertexWeights[vertidx].boneIds[0];
731 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[1] != 0)) 731 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[1] != 0))
732 { 732 {
733 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); 733 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
734 w->buffer_id = matidx; 734 w->buffer_id = matidx;
735 sum -= (w->strength = vertexWeights[vertidx].weights[1]*weightFactor); 735 sum -= (w->strength = vertexWeights[vertidx].weights[1]*weightFactor);
736 w->vertex_id = index; 736 w->vertex_id = index;
737 } 737 }
738 boneid = vertexWeights[vertidx].boneIds[1]; 738 boneid = vertexWeights[vertidx].boneIds[1];
739 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[2] != 0)) 739 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[2] != 0))
740 { 740 {
741 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); 741 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
742 w->buffer_id = matidx; 742 w->buffer_id = matidx;
743 sum -= (w->strength = vertexWeights[vertidx].weights[2]*weightFactor); 743 sum -= (w->strength = vertexWeights[vertidx].weights[2]*weightFactor);
744 w->vertex_id = index; 744 w->vertex_id = index;
745 } 745 }
746 boneid = vertexWeights[vertidx].boneIds[2]; 746 boneid = vertexWeights[vertidx].boneIds[2];
747 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (sum > 0.f)) 747 if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (sum > 0.f))
748 { 748 {
749 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); 749 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
750 w->buffer_id = matidx; 750 w->buffer_id = matidx;
751 w->strength = sum; 751 w->strength = sum;
752 w->vertex_id = index; 752 w->vertex_id = index;
753 } 753 }
754 // fallback, if no bone chosen. Seems to be an error in the specs 754 // fallback, if no bone chosen. Seems to be an error in the specs
755 boneid = vertices[vertidx].BoneID; 755 boneid = vertices[vertidx].BoneID;
756 if ((sum == 1.f) && ((u32)boneid < AnimatedMesh->getAllJoints().size())) 756 if ((sum == 1.f) && ((u32)boneid < AnimatedMesh->getAllJoints().size()))
757 { 757 {
758 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); 758 ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]);
759 w->buffer_id = matidx; 759 w->buffer_id = matidx;
760 w->strength = 1.f; 760 w->strength = 1.f;
761 w->vertex_id = index; 761 w->vertex_id = index;
762 } 762 }
763 } 763 }
764 764
765 Vertices->push_back(v); 765 Vertices->push_back(v);
766 } 766 }
767 Indices.push_back(index); 767 Indices.push_back(index);
768 } 768 }
769 } 769 }
770 770
771 //create groups 771 //create groups
772 s32 iIndex = -1; 772 s32 iIndex = -1;
773 for (i=0; i<groups.size(); ++i) 773 for (i=0; i<groups.size(); ++i)
774 { 774 {
775 SGroup& grp = groups[i]; 775 SGroup& grp = groups[i];
776 776
777 if (grp.MaterialIdx >= AnimatedMesh->getMeshBuffers().size()) 777 if (grp.MaterialIdx >= AnimatedMesh->getMeshBuffers().size())
778 grp.MaterialIdx = 0; 778 grp.MaterialIdx = 0;
779 779
780 core::array<u16>& indices = AnimatedMesh->getMeshBuffers()[grp.MaterialIdx]->Indices; 780 core::array<u16>& indices = AnimatedMesh->getMeshBuffers()[grp.MaterialIdx]->Indices;
781 781
782 for (u32 k=0; k < grp.VertexIds.size(); ++k) 782 for (u32 k=0; k < grp.VertexIds.size(); ++k)
783 for (u32 l=0; l<3; ++l) 783 for (u32 l=0; l<3; ++l)
784 indices.push_back(Indices[++iIndex]); 784 indices.push_back(Indices[++iIndex]);
785 } 785 }
786 786
787 delete [] buffer; 787 delete [] buffer;
788 788
789 return true; 789 return true;
790} 790}
791 791
792 792
793core::stringc CMS3DMeshFileLoader::stripPathFromString(const core::stringc& inString, bool returnPath) const 793core::stringc CMS3DMeshFileLoader::stripPathFromString(const core::stringc& inString, bool returnPath) const
794{ 794{
795 s32 slashIndex=inString.findLast('/'); // forward slash 795 s32 slashIndex=inString.findLast('/'); // forward slash
796 s32 backSlash=inString.findLast('\\'); // back slash 796 s32 backSlash=inString.findLast('\\'); // back slash
797 797
798 if (backSlash>slashIndex) slashIndex=backSlash; 798 if (backSlash>slashIndex) slashIndex=backSlash;
799 799
800 if (slashIndex==-1)//no slashes found 800 if (slashIndex==-1)//no slashes found
801 { 801 {
802 if (returnPath) 802 if (returnPath)
803 return core::stringc(); //no path to return 803 return core::stringc(); //no path to return
804 else 804 else
805 return inString; 805 return inString;
806 } 806 }
807 807
808 if (returnPath) 808 if (returnPath)
809 return inString.subString(0, slashIndex + 1); 809 return inString.subString(0, slashIndex + 1);
810 else 810 else
811 return inString.subString(slashIndex+1, inString.size() - (slashIndex+1)); 811 return inString.subString(slashIndex+1, inString.size() - (slashIndex+1));
812} 812}
813 813
814 814
815} // end namespace scene 815} // end namespace scene
816} // end namespace irr 816} // end namespace irr
817 817
818#endif 818#endif