aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp2210
1 files changed, 1105 insertions, 1105 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp
index 3d8769e..399e342 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp
@@ -1,1105 +1,1105 @@
1// Copyright (C) 2006-2012 Luke Hoschke 1// Copyright (C) 2006-2012 Luke Hoschke
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// B3D Mesh loader 5// B3D Mesh loader
6// File format designed by Mark Sibly for the Blitz3D engine and has been 6// File format designed by Mark Sibly for the Blitz3D engine and has been
7// declared public domain 7// declared public domain
8 8
9#include "IrrCompileConfig.h" 9#include "IrrCompileConfig.h"
10#ifdef _IRR_COMPILE_WITH_B3D_LOADER_ 10#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
11 11
12#include "CB3DMeshFileLoader.h" 12#include "CB3DMeshFileLoader.h"
13 13
14#include "IVideoDriver.h" 14#include "IVideoDriver.h"
15#include "IFileSystem.h" 15#include "IFileSystem.h"
16#include "os.h" 16#include "os.h"
17 17
18#ifdef _DEBUG 18#ifdef _DEBUG
19#define _B3D_READER_DEBUG 19#define _B3D_READER_DEBUG
20#endif 20#endif
21 21
22namespace irr 22namespace irr
23{ 23{
24namespace scene 24namespace scene
25{ 25{
26 26
27//! Constructor 27//! Constructor
28CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr) 28CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr)
29: SceneManager(smgr), AnimatedMesh(0), B3DFile(0), NormalsInFile(false), 29: SceneManager(smgr), AnimatedMesh(0), B3DFile(0), NormalsInFile(false),
30 HasVertexColors(false), ShowWarning(true) 30 HasVertexColors(false), ShowWarning(true)
31{ 31{
32 #ifdef _DEBUG 32 #ifdef _DEBUG
33 setDebugName("CB3DMeshFileLoader"); 33 setDebugName("CB3DMeshFileLoader");
34 #endif 34 #endif
35} 35}
36 36
37 37
38//! returns true if the file maybe is able to be loaded by this class 38//! returns true if the file maybe is able to be loaded by this class
39//! based on the file extension (e.g. ".bsp") 39//! based on the file extension (e.g. ".bsp")
40bool CB3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 40bool CB3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
41{ 41{
42 return core::hasFileExtension ( filename, "b3d" ); 42 return core::hasFileExtension ( filename, "b3d" );
43} 43}
44 44
45 45
46//! creates/loads an animated mesh from the file. 46//! creates/loads an animated mesh from the file.
47//! \return Pointer to the created mesh. Returns 0 if loading failed. 47//! \return Pointer to the created mesh. Returns 0 if loading failed.
48//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). 48//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
49//! See IReferenceCounted::drop() for more information. 49//! See IReferenceCounted::drop() for more information.
50IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f) 50IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f)
51{ 51{
52 if (!f) 52 if (!f)
53 return 0; 53 return 0;
54 54
55 B3DFile = f; 55 B3DFile = f;
56 AnimatedMesh = new scene::CSkinnedMesh(); 56 AnimatedMesh = new scene::CSkinnedMesh();
57 ShowWarning = true; // If true a warning is issued if too many textures are used 57 ShowWarning = true; // If true a warning is issued if too many textures are used
58 VerticesStart=0; 58 VerticesStart=0;
59 59
60 if ( load() ) 60 if ( load() )
61 { 61 {
62 AnimatedMesh->finalize(); 62 AnimatedMesh->finalize();
63 } 63 }
64 else 64 else
65 { 65 {
66 AnimatedMesh->drop(); 66 AnimatedMesh->drop();
67 AnimatedMesh = 0; 67 AnimatedMesh = 0;
68 } 68 }
69 69
70 return AnimatedMesh; 70 return AnimatedMesh;
71} 71}
72 72
73 73
74bool CB3DMeshFileLoader::load() 74bool CB3DMeshFileLoader::load()
75{ 75{
76 B3dStack.clear(); 76 B3dStack.clear();
77 77
78 NormalsInFile=false; 78 NormalsInFile=false;
79 HasVertexColors=false; 79 HasVertexColors=false;
80 80
81 //------ Get header ------ 81 //------ Get header ------
82 82
83 SB3dChunkHeader header; 83 SB3dChunkHeader header;
84 B3DFile->read(&header, sizeof(header)); 84 B3DFile->read(&header, sizeof(header));
85#ifdef __BIG_ENDIAN__ 85#ifdef __BIG_ENDIAN__
86 header.size = os::Byteswap::byteswap(header.size); 86 header.size = os::Byteswap::byteswap(header.size);
87#endif 87#endif
88 88
89 if ( strncmp( header.name, "BB3D", 4 ) != 0 ) 89 if ( strncmp( header.name, "BB3D", 4 ) != 0 )
90 { 90 {
91 os::Printer::log("File is not a b3d file. Loading failed (No header found)", B3DFile->getFileName(), ELL_ERROR); 91 os::Printer::log("File is not a b3d file. Loading failed (No header found)", B3DFile->getFileName(), ELL_ERROR);
92 return false; 92 return false;
93 } 93 }
94 94
95 // Add main chunk... 95 // Add main chunk...
96 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); 96 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8));
97 97
98 // Get file version, but ignore it, as it's not important with b3d files... 98 // Get file version, but ignore it, as it's not important with b3d files...
99 s32 fileVersion; 99 s32 fileVersion;
100 B3DFile->read(&fileVersion, sizeof(fileVersion)); 100 B3DFile->read(&fileVersion, sizeof(fileVersion));
101#ifdef __BIG_ENDIAN__ 101#ifdef __BIG_ENDIAN__
102 fileVersion = os::Byteswap::byteswap(fileVersion); 102 fileVersion = os::Byteswap::byteswap(fileVersion);
103#endif 103#endif
104 104
105 //------ Read main chunk ------ 105 //------ Read main chunk ------
106 106
107 while ( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos() ) 107 while ( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos() )
108 { 108 {
109 B3DFile->read(&header, sizeof(header)); 109 B3DFile->read(&header, sizeof(header));
110#ifdef __BIG_ENDIAN__ 110#ifdef __BIG_ENDIAN__
111 header.size = os::Byteswap::byteswap(header.size); 111 header.size = os::Byteswap::byteswap(header.size);
112#endif 112#endif
113 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); 113 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8));
114 114
115 if ( strncmp( B3dStack.getLast().name, "TEXS", 4 ) == 0 ) 115 if ( strncmp( B3dStack.getLast().name, "TEXS", 4 ) == 0 )
116 { 116 {
117 if (!readChunkTEXS()) 117 if (!readChunkTEXS())
118 return false; 118 return false;
119 } 119 }
120 else if ( strncmp( B3dStack.getLast().name, "BRUS", 4 ) == 0 ) 120 else if ( strncmp( B3dStack.getLast().name, "BRUS", 4 ) == 0 )
121 { 121 {
122 if (!readChunkBRUS()) 122 if (!readChunkBRUS())
123 return false; 123 return false;
124 } 124 }
125 else if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) 125 else if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 )
126 { 126 {
127 if (!readChunkNODE((CSkinnedMesh::SJoint*)0) ) 127 if (!readChunkNODE((CSkinnedMesh::SJoint*)0) )
128 return false; 128 return false;
129 } 129 }
130 else 130 else
131 { 131 {
132 os::Printer::log("Unknown chunk found in mesh base - skipping"); 132 os::Printer::log("Unknown chunk found in mesh base - skipping");
133 B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); 133 B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length);
134 B3dStack.erase(B3dStack.size()-1); 134 B3dStack.erase(B3dStack.size()-1);
135 } 135 }
136 } 136 }
137 137
138 B3dStack.clear(); 138 B3dStack.clear();
139 139
140 BaseVertices.clear(); 140 BaseVertices.clear();
141 AnimatedVertices_VertexID.clear(); 141 AnimatedVertices_VertexID.clear();
142 AnimatedVertices_BufferID.clear(); 142 AnimatedVertices_BufferID.clear();
143 143
144 Materials.clear(); 144 Materials.clear();
145 Textures.clear(); 145 Textures.clear();
146 146
147 return true; 147 return true;
148} 148}
149 149
150 150
151bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) 151bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint)
152{ 152{
153 CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint); 153 CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint);
154 readString(joint->Name); 154 readString(joint->Name);
155 155
156#ifdef _B3D_READER_DEBUG 156#ifdef _B3D_READER_DEBUG
157 core::stringc logStr; 157 core::stringc logStr;
158 for ( u32 i=1; i < B3dStack.size(); ++i ) 158 for ( u32 i=1; i < B3dStack.size(); ++i )
159 logStr += "-"; 159 logStr += "-";
160 logStr += "read ChunkNODE"; 160 logStr += "read ChunkNODE";
161 os::Printer::log(logStr.c_str(), joint->Name.c_str()); 161 os::Printer::log(logStr.c_str(), joint->Name.c_str());
162#endif 162#endif
163 163
164 f32 position[3], scale[3], rotation[4]; 164 f32 position[3], scale[3], rotation[4];
165 165
166 readFloats(position, 3); 166 readFloats(position, 3);
167 readFloats(scale, 3); 167 readFloats(scale, 3);
168 readFloats(rotation, 4); 168 readFloats(rotation, 4);
169 169
170 joint->Animatedposition = core::vector3df(position[0],position[1],position[2]) ; 170 joint->Animatedposition = core::vector3df(position[0],position[1],position[2]) ;
171 joint->Animatedscale = core::vector3df(scale[0],scale[1],scale[2]); 171 joint->Animatedscale = core::vector3df(scale[0],scale[1],scale[2]);
172 joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]); 172 joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]);
173 173
174 //Build LocalMatrix: 174 //Build LocalMatrix:
175 175
176 core::matrix4 positionMatrix; 176 core::matrix4 positionMatrix;
177 positionMatrix.setTranslation( joint->Animatedposition ); 177 positionMatrix.setTranslation( joint->Animatedposition );
178 core::matrix4 scaleMatrix; 178 core::matrix4 scaleMatrix;
179 scaleMatrix.setScale( joint->Animatedscale ); 179 scaleMatrix.setScale( joint->Animatedscale );
180 core::matrix4 rotationMatrix; 180 core::matrix4 rotationMatrix;
181 joint->Animatedrotation.getMatrix_transposed(rotationMatrix); 181 joint->Animatedrotation.getMatrix_transposed(rotationMatrix);
182 182
183 joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix; 183 joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix;
184 184
185 if (inJoint) 185 if (inJoint)
186 joint->GlobalMatrix = inJoint->GlobalMatrix * joint->LocalMatrix; 186 joint->GlobalMatrix = inJoint->GlobalMatrix * joint->LocalMatrix;
187 else 187 else
188 joint->GlobalMatrix = joint->LocalMatrix; 188 joint->GlobalMatrix = joint->LocalMatrix;
189 189
190 while(B3dStack.getLast().startposition + B3dStack.getLast().length > B3DFile->getPos()) // this chunk repeats 190 while(B3dStack.getLast().startposition + B3dStack.getLast().length > B3DFile->getPos()) // this chunk repeats
191 { 191 {
192 SB3dChunkHeader header; 192 SB3dChunkHeader header;
193 B3DFile->read(&header, sizeof(header)); 193 B3DFile->read(&header, sizeof(header));
194#ifdef __BIG_ENDIAN__ 194#ifdef __BIG_ENDIAN__
195 header.size = os::Byteswap::byteswap(header.size); 195 header.size = os::Byteswap::byteswap(header.size);
196#endif 196#endif
197 197
198 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); 198 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8));
199 199
200 if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) 200 if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 )
201 { 201 {
202 if (!readChunkNODE(joint)) 202 if (!readChunkNODE(joint))
203 return false; 203 return false;
204 } 204 }
205 else if ( strncmp( B3dStack.getLast().name, "MESH", 4 ) == 0 ) 205 else if ( strncmp( B3dStack.getLast().name, "MESH", 4 ) == 0 )
206 { 206 {
207 VerticesStart=BaseVertices.size(); 207 VerticesStart=BaseVertices.size();
208 if (!readChunkMESH(joint)) 208 if (!readChunkMESH(joint))
209 return false; 209 return false;
210 } 210 }
211 else if ( strncmp( B3dStack.getLast().name, "BONE", 4 ) == 0 ) 211 else if ( strncmp( B3dStack.getLast().name, "BONE", 4 ) == 0 )
212 { 212 {
213 if (!readChunkBONE(joint)) 213 if (!readChunkBONE(joint))
214 return false; 214 return false;
215 } 215 }
216 else if ( strncmp( B3dStack.getLast().name, "KEYS", 4 ) == 0 ) 216 else if ( strncmp( B3dStack.getLast().name, "KEYS", 4 ) == 0 )
217 { 217 {
218 if(!readChunkKEYS(joint)) 218 if(!readChunkKEYS(joint))
219 return false; 219 return false;
220 } 220 }
221 else if ( strncmp( B3dStack.getLast().name, "ANIM", 4 ) == 0 ) 221 else if ( strncmp( B3dStack.getLast().name, "ANIM", 4 ) == 0 )
222 { 222 {
223 if (!readChunkANIM()) 223 if (!readChunkANIM())
224 return false; 224 return false;
225 } 225 }
226 else 226 else
227 { 227 {
228 os::Printer::log("Unknown chunk found in node chunk - skipping"); 228 os::Printer::log("Unknown chunk found in node chunk - skipping");
229 B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); 229 B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length);
230 B3dStack.erase(B3dStack.size()-1); 230 B3dStack.erase(B3dStack.size()-1);
231 } 231 }
232 } 232 }
233 233
234 B3dStack.erase(B3dStack.size()-1); 234 B3dStack.erase(B3dStack.size()-1);
235 235
236 return true; 236 return true;
237} 237}
238 238
239 239
240bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) 240bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint)
241{ 241{
242#ifdef _B3D_READER_DEBUG 242#ifdef _B3D_READER_DEBUG
243 core::stringc logStr; 243 core::stringc logStr;
244 for ( u32 i=1; i < B3dStack.size(); ++i ) 244 for ( u32 i=1; i < B3dStack.size(); ++i )
245 logStr += "-"; 245 logStr += "-";
246 logStr += "read ChunkMESH"; 246 logStr += "read ChunkMESH";
247 os::Printer::log(logStr.c_str()); 247 os::Printer::log(logStr.c_str());
248#endif 248#endif
249 249
250 s32 brushID; 250 s32 brushID;
251 B3DFile->read(&brushID, sizeof(brushID)); 251 B3DFile->read(&brushID, sizeof(brushID));
252#ifdef __BIG_ENDIAN__ 252#ifdef __BIG_ENDIAN__
253 brushID = os::Byteswap::byteswap(brushID); 253 brushID = os::Byteswap::byteswap(brushID);
254#endif 254#endif
255 255
256 NormalsInFile=false; 256 NormalsInFile=false;
257 HasVertexColors=false; 257 HasVertexColors=false;
258 258
259 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats 259 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats
260 { 260 {
261 SB3dChunkHeader header; 261 SB3dChunkHeader header;
262 B3DFile->read(&header, sizeof(header)); 262 B3DFile->read(&header, sizeof(header));
263#ifdef __BIG_ENDIAN__ 263#ifdef __BIG_ENDIAN__
264 header.size = os::Byteswap::byteswap(header.size); 264 header.size = os::Byteswap::byteswap(header.size);
265#endif 265#endif
266 266
267 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); 267 B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8));
268 268
269 if ( strncmp( B3dStack.getLast().name, "VRTS", 4 ) == 0 ) 269 if ( strncmp( B3dStack.getLast().name, "VRTS", 4 ) == 0 )
270 { 270 {
271 if (!readChunkVRTS(inJoint)) 271 if (!readChunkVRTS(inJoint))
272 return false; 272 return false;
273 } 273 }
274 else if ( strncmp( B3dStack.getLast().name, "TRIS", 4 ) == 0 ) 274 else if ( strncmp( B3dStack.getLast().name, "TRIS", 4 ) == 0 )
275 { 275 {
276 scene::SSkinMeshBuffer *meshBuffer = AnimatedMesh->addMeshBuffer(); 276 scene::SSkinMeshBuffer *meshBuffer = AnimatedMesh->addMeshBuffer();
277 277
278 if (brushID!=-1) 278 if (brushID!=-1)
279 { 279 {
280 loadTextures(Materials[brushID]); 280 loadTextures(Materials[brushID]);
281 meshBuffer->Material=Materials[brushID].Material; 281 meshBuffer->Material=Materials[brushID].Material;
282 } 282 }
283 283
284 if(readChunkTRIS(meshBuffer,AnimatedMesh->getMeshBuffers().size()-1, VerticesStart)==false) 284 if(readChunkTRIS(meshBuffer,AnimatedMesh->getMeshBuffers().size()-1, VerticesStart)==false)
285 return false; 285 return false;
286 286
287 if (!NormalsInFile) 287 if (!NormalsInFile)
288 { 288 {
289 s32 i; 289 s32 i;
290 290
291 for ( i=0; i<(s32)meshBuffer->Indices.size(); i+=3) 291 for ( i=0; i<(s32)meshBuffer->Indices.size(); i+=3)
292 { 292 {
293 core::plane3df p(meshBuffer->getVertex(meshBuffer->Indices[i+0])->Pos, 293 core::plane3df p(meshBuffer->getVertex(meshBuffer->Indices[i+0])->Pos,
294 meshBuffer->getVertex(meshBuffer->Indices[i+1])->Pos, 294 meshBuffer->getVertex(meshBuffer->Indices[i+1])->Pos,
295 meshBuffer->getVertex(meshBuffer->Indices[i+2])->Pos); 295 meshBuffer->getVertex(meshBuffer->Indices[i+2])->Pos);
296 296
297 meshBuffer->getVertex(meshBuffer->Indices[i+0])->Normal += p.Normal; 297 meshBuffer->getVertex(meshBuffer->Indices[i+0])->Normal += p.Normal;
298 meshBuffer->getVertex(meshBuffer->Indices[i+1])->Normal += p.Normal; 298 meshBuffer->getVertex(meshBuffer->Indices[i+1])->Normal += p.Normal;
299 meshBuffer->getVertex(meshBuffer->Indices[i+2])->Normal += p.Normal; 299 meshBuffer->getVertex(meshBuffer->Indices[i+2])->Normal += p.Normal;
300 } 300 }
301 301
302 for ( i = 0; i<(s32)meshBuffer->getVertexCount(); ++i ) 302 for ( i = 0; i<(s32)meshBuffer->getVertexCount(); ++i )
303 { 303 {
304 meshBuffer->getVertex(i)->Normal.normalize(); 304 meshBuffer->getVertex(i)->Normal.normalize();
305 BaseVertices[VerticesStart+i].Normal=meshBuffer->getVertex(i)->Normal; 305 BaseVertices[VerticesStart+i].Normal=meshBuffer->getVertex(i)->Normal;
306 } 306 }
307 } 307 }
308 } 308 }
309 else 309 else
310 { 310 {
311 os::Printer::log("Unknown chunk found in mesh - skipping"); 311 os::Printer::log("Unknown chunk found in mesh - skipping");
312 B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); 312 B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length);
313 B3dStack.erase(B3dStack.size()-1); 313 B3dStack.erase(B3dStack.size()-1);
314 } 314 }
315 } 315 }
316 316
317 B3dStack.erase(B3dStack.size()-1); 317 B3dStack.erase(B3dStack.size()-1);
318 318
319 return true; 319 return true;
320} 320}
321 321
322 322
323/* 323/*
324VRTS: 324VRTS:
325 int flags ;1=normal values present, 2=rgba values present 325 int flags ;1=normal values present, 2=rgba values present
326 int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 326 int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8
327 but we only support 3 327 but we only support 3
328 int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 328 int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4
329 { 329 {
330 float x,y,z ;always present 330 float x,y,z ;always present
331 float nx,ny,nz ;vertex normal: present if (flags&1) 331 float nx,ny,nz ;vertex normal: present if (flags&1)
332 float red,green,blue,alpha ;vertex color: present if (flags&2) 332 float red,green,blue,alpha ;vertex color: present if (flags&2)
333 float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords 333 float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords
334 } 334 }
335*/ 335*/
336bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint) 336bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint)
337{ 337{
338#ifdef _B3D_READER_DEBUG 338#ifdef _B3D_READER_DEBUG
339 core::stringc logStr; 339 core::stringc logStr;
340 for ( u32 i=1; i < B3dStack.size(); ++i ) 340 for ( u32 i=1; i < B3dStack.size(); ++i )
341 logStr += "-"; 341 logStr += "-";
342 logStr += "ChunkVRTS"; 342 logStr += "ChunkVRTS";
343 os::Printer::log(logStr.c_str()); 343 os::Printer::log(logStr.c_str());
344#endif 344#endif
345 345
346 const s32 max_tex_coords = 3; 346 const s32 max_tex_coords = 3;
347 s32 flags, tex_coord_sets, tex_coord_set_size; 347 s32 flags, tex_coord_sets, tex_coord_set_size;
348 348
349 B3DFile->read(&flags, sizeof(flags)); 349 B3DFile->read(&flags, sizeof(flags));
350 B3DFile->read(&tex_coord_sets, sizeof(tex_coord_sets)); 350 B3DFile->read(&tex_coord_sets, sizeof(tex_coord_sets));
351 B3DFile->read(&tex_coord_set_size, sizeof(tex_coord_set_size)); 351 B3DFile->read(&tex_coord_set_size, sizeof(tex_coord_set_size));
352#ifdef __BIG_ENDIAN__ 352#ifdef __BIG_ENDIAN__
353 flags = os::Byteswap::byteswap(flags); 353 flags = os::Byteswap::byteswap(flags);
354 tex_coord_sets = os::Byteswap::byteswap(tex_coord_sets); 354 tex_coord_sets = os::Byteswap::byteswap(tex_coord_sets);
355 tex_coord_set_size = os::Byteswap::byteswap(tex_coord_set_size); 355 tex_coord_set_size = os::Byteswap::byteswap(tex_coord_set_size);
356#endif 356#endif
357 357
358 if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong 358 if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong
359 { 359 {
360 os::Printer::log("tex_coord_sets or tex_coord_set_size too big", B3DFile->getFileName(), ELL_ERROR); 360 os::Printer::log("tex_coord_sets or tex_coord_set_size too big", B3DFile->getFileName(), ELL_ERROR);
361 return false; 361 return false;
362 } 362 }
363 363
364 //------ Allocate Memory, for speed -----------// 364 //------ Allocate Memory, for speed -----------//
365 365
366 s32 numberOfReads = 3; 366 s32 numberOfReads = 3;
367 367
368 if (flags & 1) 368 if (flags & 1)
369 { 369 {
370 NormalsInFile = true; 370 NormalsInFile = true;
371 numberOfReads += 3; 371 numberOfReads += 3;
372 } 372 }
373 if (flags & 2) 373 if (flags & 2)
374 { 374 {
375 numberOfReads += 4; 375 numberOfReads += 4;
376 HasVertexColors=true; 376 HasVertexColors=true;
377 } 377 }
378 378
379 numberOfReads += tex_coord_sets*tex_coord_set_size; 379 numberOfReads += tex_coord_sets*tex_coord_set_size;
380 380
381 const s32 memoryNeeded = (B3dStack.getLast().length / sizeof(f32)) / numberOfReads; 381 const s32 memoryNeeded = (B3dStack.getLast().length / sizeof(f32)) / numberOfReads;
382 382
383 BaseVertices.reallocate(memoryNeeded + BaseVertices.size() + 1); 383 BaseVertices.reallocate(memoryNeeded + BaseVertices.size() + 1);
384 AnimatedVertices_VertexID.reallocate(memoryNeeded + AnimatedVertices_VertexID.size() + 1); 384 AnimatedVertices_VertexID.reallocate(memoryNeeded + AnimatedVertices_VertexID.size() + 1);
385 385
386 //--------------------------------------------// 386 //--------------------------------------------//
387 387
388 while( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats 388 while( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats
389 { 389 {
390 f32 position[3]; 390 f32 position[3];
391 f32 normal[3]={0.f, 0.f, 0.f}; 391 f32 normal[3]={0.f, 0.f, 0.f};
392 f32 color[4]={1.0f, 1.0f, 1.0f, 1.0f}; 392 f32 color[4]={1.0f, 1.0f, 1.0f, 1.0f};
393 f32 tex_coords[max_tex_coords][4]; 393 f32 tex_coords[max_tex_coords][4];
394 394
395 readFloats(position, 3); 395 readFloats(position, 3);
396 396
397 if (flags & 1) 397 if (flags & 1)
398 readFloats(normal, 3); 398 readFloats(normal, 3);
399 if (flags & 2) 399 if (flags & 2)
400 readFloats(color, 4); 400 readFloats(color, 4);
401 401
402 for (s32 i=0; i<tex_coord_sets; ++i) 402 for (s32 i=0; i<tex_coord_sets; ++i)
403 readFloats(tex_coords[i], tex_coord_set_size); 403 readFloats(tex_coords[i], tex_coord_set_size);
404 404
405 f32 tu=0.0f, tv=0.0f; 405 f32 tu=0.0f, tv=0.0f;
406 if (tex_coord_sets >= 1 && tex_coord_set_size >= 2) 406 if (tex_coord_sets >= 1 && tex_coord_set_size >= 2)
407 { 407 {
408 tu=tex_coords[0][0]; 408 tu=tex_coords[0][0];
409 tv=tex_coords[0][1]; 409 tv=tex_coords[0][1];
410 } 410 }
411 411
412 f32 tu2=0.0f, tv2=0.0f; 412 f32 tu2=0.0f, tv2=0.0f;
413 if (tex_coord_sets>1 && tex_coord_set_size>1) 413 if (tex_coord_sets>1 && tex_coord_set_size>1)
414 { 414 {
415 tu2=tex_coords[1][0]; 415 tu2=tex_coords[1][0];
416 tv2=tex_coords[1][1]; 416 tv2=tex_coords[1][1];
417 } 417 }
418 418
419 // Create Vertex... 419 // Create Vertex...
420 video::S3DVertex2TCoords Vertex(position[0], position[1], position[2], 420 video::S3DVertex2TCoords Vertex(position[0], position[1], position[2],
421 normal[0], normal[1], normal[2], 421 normal[0], normal[1], normal[2],
422 video::SColorf(color[0], color[1], color[2], color[3]).toSColor(), 422 video::SColorf(color[0], color[1], color[2], color[3]).toSColor(),
423 tu, tv, tu2, tv2); 423 tu, tv, tu2, tv2);
424 424
425 // Transform the Vertex position by nested node... 425 // Transform the Vertex position by nested node...
426 inJoint->GlobalMatrix.transformVect(Vertex.Pos); 426 inJoint->GlobalMatrix.transformVect(Vertex.Pos);
427 inJoint->GlobalMatrix.rotateVect(Vertex.Normal); 427 inJoint->GlobalMatrix.rotateVect(Vertex.Normal);
428 428
429 //Add it... 429 //Add it...
430 BaseVertices.push_back(Vertex); 430 BaseVertices.push_back(Vertex);
431 431
432 AnimatedVertices_VertexID.push_back(-1); 432 AnimatedVertices_VertexID.push_back(-1);
433 AnimatedVertices_BufferID.push_back(-1); 433 AnimatedVertices_BufferID.push_back(-1);
434 } 434 }
435 435
436 B3dStack.erase(B3dStack.size()-1); 436 B3dStack.erase(B3dStack.size()-1);
437 437
438 return true; 438 return true;
439} 439}
440 440
441 441
442bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 meshBufferID, s32 vertices_Start) 442bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 meshBufferID, s32 vertices_Start)
443{ 443{
444#ifdef _B3D_READER_DEBUG 444#ifdef _B3D_READER_DEBUG
445 core::stringc logStr; 445 core::stringc logStr;
446 for ( u32 i=1; i < B3dStack.size(); ++i ) 446 for ( u32 i=1; i < B3dStack.size(); ++i )
447 logStr += "-"; 447 logStr += "-";
448 logStr += "ChunkTRIS"; 448 logStr += "ChunkTRIS";
449 os::Printer::log(logStr.c_str()); 449 os::Printer::log(logStr.c_str());
450#endif 450#endif
451 451
452 bool showVertexWarning=false; 452 bool showVertexWarning=false;
453 453
454 s32 triangle_brush_id; // Note: Irrlicht can't have different brushes for each triangle (using a workaround) 454 s32 triangle_brush_id; // Note: Irrlicht can't have different brushes for each triangle (using a workaround)
455 B3DFile->read(&triangle_brush_id, sizeof(triangle_brush_id)); 455 B3DFile->read(&triangle_brush_id, sizeof(triangle_brush_id));
456#ifdef __BIG_ENDIAN__ 456#ifdef __BIG_ENDIAN__
457 triangle_brush_id = os::Byteswap::byteswap(triangle_brush_id); 457 triangle_brush_id = os::Byteswap::byteswap(triangle_brush_id);
458#endif 458#endif
459 459
460 SB3dMaterial *B3dMaterial; 460 SB3dMaterial *B3dMaterial;
461 461
462 if (triangle_brush_id != -1) 462 if (triangle_brush_id != -1)
463 { 463 {
464 loadTextures(Materials[triangle_brush_id]); 464 loadTextures(Materials[triangle_brush_id]);
465 B3dMaterial = &Materials[triangle_brush_id]; 465 B3dMaterial = &Materials[triangle_brush_id];
466 meshBuffer->Material = B3dMaterial->Material; 466 meshBuffer->Material = B3dMaterial->Material;
467 } 467 }
468 else 468 else
469 B3dMaterial = 0; 469 B3dMaterial = 0;
470 470
471 const s32 memoryNeeded = B3dStack.getLast().length / sizeof(s32); 471 const s32 memoryNeeded = B3dStack.getLast().length / sizeof(s32);
472 meshBuffer->Indices.reallocate(memoryNeeded + meshBuffer->Indices.size() + 1); 472 meshBuffer->Indices.reallocate(memoryNeeded + meshBuffer->Indices.size() + 1);
473 473
474 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats 474 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats
475 { 475 {
476 s32 vertex_id[3]; 476 s32 vertex_id[3];
477 477
478 B3DFile->read(vertex_id, 3*sizeof(s32)); 478 B3DFile->read(vertex_id, 3*sizeof(s32));
479#ifdef __BIG_ENDIAN__ 479#ifdef __BIG_ENDIAN__
480 vertex_id[0] = os::Byteswap::byteswap(vertex_id[0]); 480 vertex_id[0] = os::Byteswap::byteswap(vertex_id[0]);
481 vertex_id[1] = os::Byteswap::byteswap(vertex_id[1]); 481 vertex_id[1] = os::Byteswap::byteswap(vertex_id[1]);
482 vertex_id[2] = os::Byteswap::byteswap(vertex_id[2]); 482 vertex_id[2] = os::Byteswap::byteswap(vertex_id[2]);
483#endif 483#endif
484 484
485 //Make Ids global: 485 //Make Ids global:
486 vertex_id[0] += vertices_Start; 486 vertex_id[0] += vertices_Start;
487 vertex_id[1] += vertices_Start; 487 vertex_id[1] += vertices_Start;
488 vertex_id[2] += vertices_Start; 488 vertex_id[2] += vertices_Start;
489 489
490 for(s32 i=0; i<3; ++i) 490 for(s32 i=0; i<3; ++i)
491 { 491 {
492 if ((u32)vertex_id[i] >= AnimatedVertices_VertexID.size()) 492 if ((u32)vertex_id[i] >= AnimatedVertices_VertexID.size())
493 { 493 {
494 os::Printer::log("Illegal vertex index found", B3DFile->getFileName(), ELL_ERROR); 494 os::Printer::log("Illegal vertex index found", B3DFile->getFileName(), ELL_ERROR);
495 return false; 495 return false;
496 } 496 }
497 497
498 if (AnimatedVertices_VertexID[ vertex_id[i] ] != -1) 498 if (AnimatedVertices_VertexID[ vertex_id[i] ] != -1)
499 { 499 {
500 if ( AnimatedVertices_BufferID[ vertex_id[i] ] != (s32)meshBufferID ) //If this vertex is linked in a different meshbuffer 500 if ( AnimatedVertices_BufferID[ vertex_id[i] ] != (s32)meshBufferID ) //If this vertex is linked in a different meshbuffer
501 { 501 {
502 AnimatedVertices_VertexID[ vertex_id[i] ] = -1; 502 AnimatedVertices_VertexID[ vertex_id[i] ] = -1;
503 AnimatedVertices_BufferID[ vertex_id[i] ] = -1; 503 AnimatedVertices_BufferID[ vertex_id[i] ] = -1;
504 showVertexWarning=true; 504 showVertexWarning=true;
505 } 505 }
506 } 506 }
507 if (AnimatedVertices_VertexID[ vertex_id[i] ] == -1) //If this vertex is not in the meshbuffer 507 if (AnimatedVertices_VertexID[ vertex_id[i] ] == -1) //If this vertex is not in the meshbuffer
508 { 508 {
509 //Check for lightmapping: 509 //Check for lightmapping:
510 if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2df(0.f,0.f)) 510 if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2df(0.f,0.f))
511 meshBuffer->convertTo2TCoords(); //Will only affect the meshbuffer the first time this is called 511 meshBuffer->convertTo2TCoords(); //Will only affect the meshbuffer the first time this is called
512 512
513 //Add the vertex to the meshbuffer: 513 //Add the vertex to the meshbuffer:
514 if (meshBuffer->VertexType == video::EVT_STANDARD) 514 if (meshBuffer->VertexType == video::EVT_STANDARD)
515 meshBuffer->Vertices_Standard.push_back( BaseVertices[ vertex_id[i] ] ); 515 meshBuffer->Vertices_Standard.push_back( BaseVertices[ vertex_id[i] ] );
516 else 516 else
517 meshBuffer->Vertices_2TCoords.push_back(BaseVertices[ vertex_id[i] ] ); 517 meshBuffer->Vertices_2TCoords.push_back(BaseVertices[ vertex_id[i] ] );
518 518
519 //create vertex id to meshbuffer index link: 519 //create vertex id to meshbuffer index link:
520 AnimatedVertices_VertexID[ vertex_id[i] ] = meshBuffer->getVertexCount()-1; 520 AnimatedVertices_VertexID[ vertex_id[i] ] = meshBuffer->getVertexCount()-1;
521 AnimatedVertices_BufferID[ vertex_id[i] ] = meshBufferID; 521 AnimatedVertices_BufferID[ vertex_id[i] ] = meshBufferID;
522 522
523 if (B3dMaterial) 523 if (B3dMaterial)
524 { 524 {
525 // Apply Material/Color/etc... 525 // Apply Material/Color/etc...
526 video::S3DVertex *Vertex=meshBuffer->getVertex(meshBuffer->getVertexCount()-1); 526 video::S3DVertex *Vertex=meshBuffer->getVertex(meshBuffer->getVertexCount()-1);
527 527
528 if (!HasVertexColors) 528 if (!HasVertexColors)
529 Vertex->Color=B3dMaterial->Material.DiffuseColor; 529 Vertex->Color=B3dMaterial->Material.DiffuseColor;
530 else if (Vertex->Color.getAlpha() == 255) 530 else if (Vertex->Color.getAlpha() == 255)
531 Vertex->Color.setAlpha( (s32)(B3dMaterial->alpha * 255.0f) ); 531 Vertex->Color.setAlpha( (s32)(B3dMaterial->alpha * 255.0f) );
532 532
533 // Use texture's scale 533 // Use texture's scale
534 if (B3dMaterial->Textures[0]) 534 if (B3dMaterial->Textures[0])
535 { 535 {
536 Vertex->TCoords.X *= B3dMaterial->Textures[0]->Xscale; 536 Vertex->TCoords.X *= B3dMaterial->Textures[0]->Xscale;
537 Vertex->TCoords.Y *= B3dMaterial->Textures[0]->Yscale; 537 Vertex->TCoords.Y *= B3dMaterial->Textures[0]->Yscale;
538 } 538 }
539 /* 539 /*
540 if (B3dMaterial->Textures[1]) 540 if (B3dMaterial->Textures[1])
541 { 541 {
542 Vertex->TCoords2.X *=B3dMaterial->Textures[1]->Xscale; 542 Vertex->TCoords2.X *=B3dMaterial->Textures[1]->Xscale;
543 Vertex->TCoords2.Y *=B3dMaterial->Textures[1]->Yscale; 543 Vertex->TCoords2.Y *=B3dMaterial->Textures[1]->Yscale;
544 } 544 }
545 */ 545 */
546 } 546 }
547 } 547 }
548 } 548 }
549 549
550 meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[0] ] ); 550 meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[0] ] );
551 meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[1] ] ); 551 meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[1] ] );
552 meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[2] ] ); 552 meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[2] ] );
553 } 553 }
554 554
555 B3dStack.erase(B3dStack.size()-1); 555 B3dStack.erase(B3dStack.size()-1);
556 556
557 if (showVertexWarning) 557 if (showVertexWarning)
558 os::Printer::log("B3dMeshLoader: Warning, different meshbuffers linking to the same vertex, this will cause problems with animated meshes"); 558 os::Printer::log("B3dMeshLoader: Warning, different meshbuffers linking to the same vertex, this will cause problems with animated meshes");
559 559
560 return true; 560 return true;
561} 561}
562 562
563 563
564bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint) 564bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint)
565{ 565{
566#ifdef _B3D_READER_DEBUG 566#ifdef _B3D_READER_DEBUG
567 core::stringc logStr; 567 core::stringc logStr;
568 for ( u32 i=1; i < B3dStack.size(); ++i ) 568 for ( u32 i=1; i < B3dStack.size(); ++i )
569 logStr += "-"; 569 logStr += "-";
570 logStr += "read ChunkBONE"; 570 logStr += "read ChunkBONE";
571 os::Printer::log(logStr.c_str()); 571 os::Printer::log(logStr.c_str());
572#endif 572#endif
573 573
574 if (B3dStack.getLast().length > 8) 574 if (B3dStack.getLast().length > 8)
575 { 575 {
576 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats 576 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats
577 { 577 {
578 u32 globalVertexID; 578 u32 globalVertexID;
579 f32 strength; 579 f32 strength;
580 B3DFile->read(&globalVertexID, sizeof(globalVertexID)); 580 B3DFile->read(&globalVertexID, sizeof(globalVertexID));
581 B3DFile->read(&strength, sizeof(strength)); 581 B3DFile->read(&strength, sizeof(strength));
582#ifdef __BIG_ENDIAN__ 582#ifdef __BIG_ENDIAN__
583 globalVertexID = os::Byteswap::byteswap(globalVertexID); 583 globalVertexID = os::Byteswap::byteswap(globalVertexID);
584 strength = os::Byteswap::byteswap(strength); 584 strength = os::Byteswap::byteswap(strength);
585#endif 585#endif
586 globalVertexID += VerticesStart; 586 globalVertexID += VerticesStart;
587 587
588 if (AnimatedVertices_VertexID[globalVertexID]==-1) 588 if (AnimatedVertices_VertexID[globalVertexID]==-1)
589 { 589 {
590 os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)"); 590 os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)");
591 } 591 }
592 else if (strength >0) 592 else if (strength >0)
593 { 593 {
594 CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(inJoint); 594 CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(inJoint);
595 weight->strength=strength; 595 weight->strength=strength;
596 //Find the meshbuffer and Vertex index from the Global Vertex ID: 596 //Find the meshbuffer and Vertex index from the Global Vertex ID:
597 weight->vertex_id = AnimatedVertices_VertexID[globalVertexID]; 597 weight->vertex_id = AnimatedVertices_VertexID[globalVertexID];
598 weight->buffer_id = AnimatedVertices_BufferID[globalVertexID]; 598 weight->buffer_id = AnimatedVertices_BufferID[globalVertexID];
599 } 599 }
600 } 600 }
601 } 601 }
602 602
603 B3dStack.erase(B3dStack.size()-1); 603 B3dStack.erase(B3dStack.size()-1);
604 return true; 604 return true;
605} 605}
606 606
607 607
608bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint) 608bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint)
609{ 609{
610#ifdef _B3D_READER_DEBUG 610#ifdef _B3D_READER_DEBUG
611 // Only print first, that's just too much output otherwise 611 // Only print first, that's just too much output otherwise
612 if ( !inJoint || (inJoint->PositionKeys.empty() && inJoint->ScaleKeys.empty() && inJoint->RotationKeys.empty()) ) 612 if ( !inJoint || (inJoint->PositionKeys.empty() && inJoint->ScaleKeys.empty() && inJoint->RotationKeys.empty()) )
613 { 613 {
614 core::stringc logStr; 614 core::stringc logStr;
615 for ( u32 i=1; i < B3dStack.size(); ++i ) 615 for ( u32 i=1; i < B3dStack.size(); ++i )
616 logStr += "-"; 616 logStr += "-";
617 logStr += "read ChunkKEYS"; 617 logStr += "read ChunkKEYS";
618 os::Printer::log(logStr.c_str()); 618 os::Printer::log(logStr.c_str());
619 } 619 }
620#endif 620#endif
621 621
622 s32 flags; 622 s32 flags;
623 B3DFile->read(&flags, sizeof(flags)); 623 B3DFile->read(&flags, sizeof(flags));
624#ifdef __BIG_ENDIAN__ 624#ifdef __BIG_ENDIAN__
625 flags = os::Byteswap::byteswap(flags); 625 flags = os::Byteswap::byteswap(flags);
626#endif 626#endif
627 627
628 CSkinnedMesh::SPositionKey *oldPosKey=0; 628 CSkinnedMesh::SPositionKey *oldPosKey=0;
629 core::vector3df oldPos[2]; 629 core::vector3df oldPos[2];
630 CSkinnedMesh::SScaleKey *oldScaleKey=0; 630 CSkinnedMesh::SScaleKey *oldScaleKey=0;
631 core::vector3df oldScale[2]; 631 core::vector3df oldScale[2];
632 CSkinnedMesh::SRotationKey *oldRotKey=0; 632 CSkinnedMesh::SRotationKey *oldRotKey=0;
633 core::quaternion oldRot[2]; 633 core::quaternion oldRot[2];
634 bool isFirst[3]={true,true,true}; 634 bool isFirst[3]={true,true,true};
635 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats 635 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats
636 { 636 {
637 s32 frame; 637 s32 frame;
638 638
639 B3DFile->read(&frame, sizeof(frame)); 639 B3DFile->read(&frame, sizeof(frame));
640 #ifdef __BIG_ENDIAN__ 640 #ifdef __BIG_ENDIAN__
641 frame = os::Byteswap::byteswap(frame); 641 frame = os::Byteswap::byteswap(frame);
642 #endif 642 #endif
643 643
644 // Add key frames, frames in Irrlicht are zero-based 644 // Add key frames, frames in Irrlicht are zero-based
645 f32 data[4]; 645 f32 data[4];
646 if (flags & 1) 646 if (flags & 1)
647 { 647 {
648 readFloats(data, 3); 648 readFloats(data, 3);
649 if ((oldPosKey!=0) && (oldPos[0]==oldPos[1])) 649 if ((oldPosKey!=0) && (oldPos[0]==oldPos[1]))
650 { 650 {
651 const core::vector3df pos(data[0], data[1], data[2]); 651 const core::vector3df pos(data[0], data[1], data[2]);
652 if (oldPos[1]==pos) 652 if (oldPos[1]==pos)
653 oldPosKey->frame = (f32)frame-1; 653 oldPosKey->frame = (f32)frame-1;
654 else 654 else
655 { 655 {
656 oldPos[0]=oldPos[1]; 656 oldPos[0]=oldPos[1];
657 oldPosKey=AnimatedMesh->addPositionKey(inJoint); 657 oldPosKey=AnimatedMesh->addPositionKey(inJoint);
658 oldPosKey->frame = (f32)frame-1; 658 oldPosKey->frame = (f32)frame-1;
659 oldPos[1].set(oldPosKey->position.set(pos)); 659 oldPos[1].set(oldPosKey->position.set(pos));
660 } 660 }
661 } 661 }
662 else if (oldPosKey==0 && isFirst[0]) 662 else if (oldPosKey==0 && isFirst[0])
663 { 663 {
664 oldPosKey=AnimatedMesh->addPositionKey(inJoint); 664 oldPosKey=AnimatedMesh->addPositionKey(inJoint);
665 oldPosKey->frame = (f32)frame-1; 665 oldPosKey->frame = (f32)frame-1;
666 oldPos[0].set(oldPosKey->position.set(data[0], data[1], data[2])); 666 oldPos[0].set(oldPosKey->position.set(data[0], data[1], data[2]));
667 oldPosKey=0; 667 oldPosKey=0;
668 isFirst[0]=false; 668 isFirst[0]=false;
669 } 669 }
670 else 670 else
671 { 671 {
672 if (oldPosKey!=0) 672 if (oldPosKey!=0)
673 oldPos[0]=oldPos[1]; 673 oldPos[0]=oldPos[1];
674 oldPosKey=AnimatedMesh->addPositionKey(inJoint); 674 oldPosKey=AnimatedMesh->addPositionKey(inJoint);
675 oldPosKey->frame = (f32)frame-1; 675 oldPosKey->frame = (f32)frame-1;
676 oldPos[1].set(oldPosKey->position.set(data[0], data[1], data[2])); 676 oldPos[1].set(oldPosKey->position.set(data[0], data[1], data[2]));
677 } 677 }
678 } 678 }
679 if (flags & 2) 679 if (flags & 2)
680 { 680 {
681 readFloats(data, 3); 681 readFloats(data, 3);
682 if ((oldScaleKey!=0) && (oldScale[0]==oldScale[1])) 682 if ((oldScaleKey!=0) && (oldScale[0]==oldScale[1]))
683 { 683 {
684 const core::vector3df scale(data[0], data[1], data[2]); 684 const core::vector3df scale(data[0], data[1], data[2]);
685 if (oldScale[1]==scale) 685 if (oldScale[1]==scale)
686 oldScaleKey->frame = (f32)frame-1; 686 oldScaleKey->frame = (f32)frame-1;
687 else 687 else
688 { 688 {
689 oldScale[0]=oldScale[1]; 689 oldScale[0]=oldScale[1];
690 oldScaleKey=AnimatedMesh->addScaleKey(inJoint); 690 oldScaleKey=AnimatedMesh->addScaleKey(inJoint);
691 oldScaleKey->frame = (f32)frame-1; 691 oldScaleKey->frame = (f32)frame-1;
692 oldScale[1].set(oldScaleKey->scale.set(scale)); 692 oldScale[1].set(oldScaleKey->scale.set(scale));
693 } 693 }
694 } 694 }
695 else if (oldScaleKey==0 && isFirst[1]) 695 else if (oldScaleKey==0 && isFirst[1])
696 { 696 {
697 oldScaleKey=AnimatedMesh->addScaleKey(inJoint); 697 oldScaleKey=AnimatedMesh->addScaleKey(inJoint);
698 oldScaleKey->frame = (f32)frame-1; 698 oldScaleKey->frame = (f32)frame-1;
699 oldScale[0].set(oldScaleKey->scale.set(data[0], data[1], data[2])); 699 oldScale[0].set(oldScaleKey->scale.set(data[0], data[1], data[2]));
700 oldScaleKey=0; 700 oldScaleKey=0;
701 isFirst[1]=false; 701 isFirst[1]=false;
702 } 702 }
703 else 703 else
704 { 704 {
705 if (oldScaleKey!=0) 705 if (oldScaleKey!=0)
706 oldScale[0]=oldScale[1]; 706 oldScale[0]=oldScale[1];
707 oldScaleKey=AnimatedMesh->addScaleKey(inJoint); 707 oldScaleKey=AnimatedMesh->addScaleKey(inJoint);
708 oldScaleKey->frame = (f32)frame-1; 708 oldScaleKey->frame = (f32)frame-1;
709 oldScale[1].set(oldScaleKey->scale.set(data[0], data[1], data[2])); 709 oldScale[1].set(oldScaleKey->scale.set(data[0], data[1], data[2]));
710 } 710 }
711 } 711 }
712 if (flags & 4) 712 if (flags & 4)
713 { 713 {
714 readFloats(data, 4); 714 readFloats(data, 4);
715 if ((oldRotKey!=0) && (oldRot[0]==oldRot[1])) 715 if ((oldRotKey!=0) && (oldRot[0]==oldRot[1]))
716 { 716 {
717 // meant to be in this order since b3d stores W first 717 // meant to be in this order since b3d stores W first
718 const core::quaternion rot(data[1], data[2], data[3], data[0]); 718 const core::quaternion rot(data[1], data[2], data[3], data[0]);
719 if (oldRot[1]==rot) 719 if (oldRot[1]==rot)
720 oldRotKey->frame = (f32)frame-1; 720 oldRotKey->frame = (f32)frame-1;
721 else 721 else
722 { 722 {
723 oldRot[0]=oldRot[1]; 723 oldRot[0]=oldRot[1];
724 oldRotKey=AnimatedMesh->addRotationKey(inJoint); 724 oldRotKey=AnimatedMesh->addRotationKey(inJoint);
725 oldRotKey->frame = (f32)frame-1; 725 oldRotKey->frame = (f32)frame-1;
726 oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); 726 oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0]));
727 } 727 }
728 } 728 }
729 else if (oldRotKey==0 && isFirst[2]) 729 else if (oldRotKey==0 && isFirst[2])
730 { 730 {
731 oldRotKey=AnimatedMesh->addRotationKey(inJoint); 731 oldRotKey=AnimatedMesh->addRotationKey(inJoint);
732 oldRotKey->frame = (f32)frame-1; 732 oldRotKey->frame = (f32)frame-1;
733 // meant to be in this order since b3d stores W first 733 // meant to be in this order since b3d stores W first
734 oldRot[0].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); 734 oldRot[0].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0]));
735 oldRotKey=0; 735 oldRotKey=0;
736 isFirst[2]=false; 736 isFirst[2]=false;
737 } 737 }
738 else 738 else
739 { 739 {
740 if (oldRotKey!=0) 740 if (oldRotKey!=0)
741 oldRot[0]=oldRot[1]; 741 oldRot[0]=oldRot[1];
742 oldRotKey=AnimatedMesh->addRotationKey(inJoint); 742 oldRotKey=AnimatedMesh->addRotationKey(inJoint);
743 oldRotKey->frame = (f32)frame-1; 743 oldRotKey->frame = (f32)frame-1;
744 // meant to be in this order since b3d stores W first 744 // meant to be in this order since b3d stores W first
745 oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); 745 oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0]));
746 } 746 }
747 } 747 }
748 } 748 }
749 749
750 B3dStack.erase(B3dStack.size()-1); 750 B3dStack.erase(B3dStack.size()-1);
751 return true; 751 return true;
752} 752}
753 753
754 754
755bool CB3DMeshFileLoader::readChunkANIM() 755bool CB3DMeshFileLoader::readChunkANIM()
756{ 756{
757#ifdef _B3D_READER_DEBUG 757#ifdef _B3D_READER_DEBUG
758 core::stringc logStr; 758 core::stringc logStr;
759 for ( u32 i=1; i < B3dStack.size(); ++i ) 759 for ( u32 i=1; i < B3dStack.size(); ++i )
760 logStr += "-"; 760 logStr += "-";
761 logStr += "read ChunkANIM"; 761 logStr += "read ChunkANIM";
762 os::Printer::log(logStr.c_str()); 762 os::Printer::log(logStr.c_str());
763#endif 763#endif
764 764
765 s32 animFlags; //not stored\used 765 s32 animFlags; //not stored\used
766 s32 animFrames;//not stored\used 766 s32 animFrames;//not stored\used
767 f32 animFPS; //not stored\used 767 f32 animFPS; //not stored\used
768 768
769 B3DFile->read(&animFlags, sizeof(s32)); 769 B3DFile->read(&animFlags, sizeof(s32));
770 B3DFile->read(&animFrames, sizeof(s32)); 770 B3DFile->read(&animFrames, sizeof(s32));
771 readFloats(&animFPS, 1); 771 readFloats(&animFPS, 1);
772 if (animFPS>0.f) 772 if (animFPS>0.f)
773 AnimatedMesh->setAnimationSpeed(animFPS); 773 AnimatedMesh->setAnimationSpeed(animFPS);
774 os::Printer::log("FPS", io::path((double)animFPS), ELL_DEBUG); 774 os::Printer::log("FPS", io::path((double)animFPS), ELL_DEBUG);
775 775
776 #ifdef __BIG_ENDIAN__ 776 #ifdef __BIG_ENDIAN__
777 animFlags = os::Byteswap::byteswap(animFlags); 777 animFlags = os::Byteswap::byteswap(animFlags);
778 animFrames = os::Byteswap::byteswap(animFrames); 778 animFrames = os::Byteswap::byteswap(animFrames);
779 #endif 779 #endif
780 780
781 B3dStack.erase(B3dStack.size()-1); 781 B3dStack.erase(B3dStack.size()-1);
782 return true; 782 return true;
783} 783}
784 784
785 785
786bool CB3DMeshFileLoader::readChunkTEXS() 786bool CB3DMeshFileLoader::readChunkTEXS()
787{ 787{
788#ifdef _B3D_READER_DEBUG 788#ifdef _B3D_READER_DEBUG
789 core::stringc logStr; 789 core::stringc logStr;
790 for ( u32 i=1; i < B3dStack.size(); ++i ) 790 for ( u32 i=1; i < B3dStack.size(); ++i )
791 logStr += "-"; 791 logStr += "-";
792 logStr += "read ChunkTEXS"; 792 logStr += "read ChunkTEXS";
793 os::Printer::log(logStr.c_str()); 793 os::Printer::log(logStr.c_str());
794#endif 794#endif
795 795
796 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats 796 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats
797 { 797 {
798 Textures.push_back(SB3dTexture()); 798 Textures.push_back(SB3dTexture());
799 SB3dTexture& B3dTexture = Textures.getLast(); 799 SB3dTexture& B3dTexture = Textures.getLast();
800 800
801 readString(B3dTexture.TextureName); 801 readString(B3dTexture.TextureName);
802 B3dTexture.TextureName.replace('\\','/'); 802 B3dTexture.TextureName.replace('\\','/');
803#ifdef _B3D_READER_DEBUG 803#ifdef _B3D_READER_DEBUG
804 os::Printer::log("read Texture", B3dTexture.TextureName.c_str()); 804 os::Printer::log("read Texture", B3dTexture.TextureName.c_str());
805#endif 805#endif
806 806
807 B3DFile->read(&B3dTexture.Flags, sizeof(s32)); 807 B3DFile->read(&B3dTexture.Flags, sizeof(s32));
808 B3DFile->read(&B3dTexture.Blend, sizeof(s32)); 808 B3DFile->read(&B3dTexture.Blend, sizeof(s32));
809#ifdef __BIG_ENDIAN__ 809#ifdef __BIG_ENDIAN__
810 B3dTexture.Flags = os::Byteswap::byteswap(B3dTexture.Flags); 810 B3dTexture.Flags = os::Byteswap::byteswap(B3dTexture.Flags);
811 B3dTexture.Blend = os::Byteswap::byteswap(B3dTexture.Blend); 811 B3dTexture.Blend = os::Byteswap::byteswap(B3dTexture.Blend);
812#endif 812#endif
813#ifdef _B3D_READER_DEBUG 813#ifdef _B3D_READER_DEBUG
814 os::Printer::log("Flags", core::stringc(B3dTexture.Flags).c_str()); 814 os::Printer::log("Flags", core::stringc(B3dTexture.Flags).c_str());
815 os::Printer::log("Blend", core::stringc(B3dTexture.Blend).c_str()); 815 os::Printer::log("Blend", core::stringc(B3dTexture.Blend).c_str());
816#endif 816#endif
817 readFloats(&B3dTexture.Xpos, 1); 817 readFloats(&B3dTexture.Xpos, 1);
818 readFloats(&B3dTexture.Ypos, 1); 818 readFloats(&B3dTexture.Ypos, 1);
819 readFloats(&B3dTexture.Xscale, 1); 819 readFloats(&B3dTexture.Xscale, 1);
820 readFloats(&B3dTexture.Yscale, 1); 820 readFloats(&B3dTexture.Yscale, 1);
821 readFloats(&B3dTexture.Angle, 1); 821 readFloats(&B3dTexture.Angle, 1);
822 } 822 }
823 823
824 B3dStack.erase(B3dStack.size()-1); 824 B3dStack.erase(B3dStack.size()-1);
825 825
826 return true; 826 return true;
827} 827}
828 828
829 829
830bool CB3DMeshFileLoader::readChunkBRUS() 830bool CB3DMeshFileLoader::readChunkBRUS()
831{ 831{
832#ifdef _B3D_READER_DEBUG 832#ifdef _B3D_READER_DEBUG
833 core::stringc logStr; 833 core::stringc logStr;
834 for ( u32 i=1; i < B3dStack.size(); ++i ) 834 for ( u32 i=1; i < B3dStack.size(); ++i )
835 logStr += "-"; 835 logStr += "-";
836 logStr += "read ChunkBRUS"; 836 logStr += "read ChunkBRUS";
837 os::Printer::log(logStr.c_str()); 837 os::Printer::log(logStr.c_str());
838#endif 838#endif
839 839
840 u32 n_texs; 840 u32 n_texs;
841 B3DFile->read(&n_texs, sizeof(u32)); 841 B3DFile->read(&n_texs, sizeof(u32));
842#ifdef __BIG_ENDIAN__ 842#ifdef __BIG_ENDIAN__
843 n_texs = os::Byteswap::byteswap(n_texs); 843 n_texs = os::Byteswap::byteswap(n_texs);
844#endif 844#endif
845 845
846 // number of texture ids read for Irrlicht 846 // number of texture ids read for Irrlicht
847 const u32 num_textures = core::min_(n_texs, video::MATERIAL_MAX_TEXTURES); 847 const u32 num_textures = core::min_(n_texs, video::MATERIAL_MAX_TEXTURES);
848 // number of bytes to skip (for ignored texture ids) 848 // number of bytes to skip (for ignored texture ids)
849 const u32 n_texs_offset = (num_textures<n_texs)?(n_texs-num_textures):0; 849 const u32 n_texs_offset = (num_textures<n_texs)?(n_texs-num_textures):0;
850 850
851 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats 851 while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats
852 { 852 {
853 // This is what blitz basic calls a brush, like a Irrlicht Material 853 // This is what blitz basic calls a brush, like a Irrlicht Material
854 854
855 core::stringc name; 855 core::stringc name;
856 readString(name); 856 readString(name);
857#ifdef _B3D_READER_DEBUG 857#ifdef _B3D_READER_DEBUG
858 os::Printer::log("read Material", name); 858 os::Printer::log("read Material", name);
859#endif 859#endif
860 Materials.push_back(SB3dMaterial()); 860 Materials.push_back(SB3dMaterial());
861 SB3dMaterial& B3dMaterial=Materials.getLast(); 861 SB3dMaterial& B3dMaterial=Materials.getLast();
862 862
863 readFloats(&B3dMaterial.red, 1); 863 readFloats(&B3dMaterial.red, 1);
864 readFloats(&B3dMaterial.green, 1); 864 readFloats(&B3dMaterial.green, 1);
865 readFloats(&B3dMaterial.blue, 1); 865 readFloats(&B3dMaterial.blue, 1);
866 readFloats(&B3dMaterial.alpha, 1); 866 readFloats(&B3dMaterial.alpha, 1);
867 readFloats(&B3dMaterial.shininess, 1); 867 readFloats(&B3dMaterial.shininess, 1);
868 868
869 B3DFile->read(&B3dMaterial.blend, sizeof(B3dMaterial.blend)); 869 B3DFile->read(&B3dMaterial.blend, sizeof(B3dMaterial.blend));
870 B3DFile->read(&B3dMaterial.fx, sizeof(B3dMaterial.fx)); 870 B3DFile->read(&B3dMaterial.fx, sizeof(B3dMaterial.fx));
871#ifdef __BIG_ENDIAN__ 871#ifdef __BIG_ENDIAN__
872 B3dMaterial.blend = os::Byteswap::byteswap(B3dMaterial.blend); 872 B3dMaterial.blend = os::Byteswap::byteswap(B3dMaterial.blend);
873 B3dMaterial.fx = os::Byteswap::byteswap(B3dMaterial.fx); 873 B3dMaterial.fx = os::Byteswap::byteswap(B3dMaterial.fx);
874#endif 874#endif
875#ifdef _B3D_READER_DEBUG 875#ifdef _B3D_READER_DEBUG
876 os::Printer::log("Blend", core::stringc(B3dMaterial.blend).c_str()); 876 os::Printer::log("Blend", core::stringc(B3dMaterial.blend).c_str());
877 os::Printer::log("FX", core::stringc(B3dMaterial.fx).c_str()); 877 os::Printer::log("FX", core::stringc(B3dMaterial.fx).c_str());
878#endif 878#endif
879 879
880 u32 i; 880 u32 i;
881 for (i=0; i<num_textures; ++i) 881 for (i=0; i<num_textures; ++i)
882 { 882 {
883 s32 texture_id=-1; 883 s32 texture_id=-1;
884 B3DFile->read(&texture_id, sizeof(s32)); 884 B3DFile->read(&texture_id, sizeof(s32));
885#ifdef __BIG_ENDIAN__ 885#ifdef __BIG_ENDIAN__
886 texture_id = os::Byteswap::byteswap(texture_id); 886 texture_id = os::Byteswap::byteswap(texture_id);
887#endif 887#endif
888 //--- Get pointers to the texture, based on the IDs --- 888 //--- Get pointers to the texture, based on the IDs ---
889 if ((u32)texture_id < Textures.size()) 889 if ((u32)texture_id < Textures.size())
890 { 890 {
891 B3dMaterial.Textures[i]=&Textures[texture_id]; 891 B3dMaterial.Textures[i]=&Textures[texture_id];
892#ifdef _B3D_READER_DEBUG 892#ifdef _B3D_READER_DEBUG
893 os::Printer::log("Layer", core::stringc(i).c_str()); 893 os::Printer::log("Layer", core::stringc(i).c_str());
894 os::Printer::log("using texture", Textures[texture_id].TextureName.c_str()); 894 os::Printer::log("using texture", Textures[texture_id].TextureName.c_str());
895#endif 895#endif
896 } 896 }
897 else 897 else
898 B3dMaterial.Textures[i]=0; 898 B3dMaterial.Textures[i]=0;
899 } 899 }
900 // skip other texture ids 900 // skip other texture ids
901 for (i=0; i<n_texs_offset; ++i) 901 for (i=0; i<n_texs_offset; ++i)
902 { 902 {
903 s32 texture_id=-1; 903 s32 texture_id=-1;
904 B3DFile->read(&texture_id, sizeof(s32)); 904 B3DFile->read(&texture_id, sizeof(s32));
905#ifdef __BIG_ENDIAN__ 905#ifdef __BIG_ENDIAN__
906 texture_id = os::Byteswap::byteswap(texture_id); 906 texture_id = os::Byteswap::byteswap(texture_id);
907#endif 907#endif
908 if (ShowWarning && (texture_id != -1) && (n_texs>video::MATERIAL_MAX_TEXTURES)) 908 if (ShowWarning && (texture_id != -1) && (n_texs>video::MATERIAL_MAX_TEXTURES))
909 { 909 {
910 os::Printer::log("Too many textures used in one material", B3DFile->getFileName(), ELL_WARNING); 910 os::Printer::log("Too many textures used in one material", B3DFile->getFileName(), ELL_WARNING);
911 ShowWarning = false; 911 ShowWarning = false;
912 } 912 }
913 } 913 }
914 914
915 //Fixes problems when the lightmap is on the first texture: 915 //Fixes problems when the lightmap is on the first texture:
916 if (B3dMaterial.Textures[0] != 0) 916 if (B3dMaterial.Textures[0] != 0)
917 { 917 {
918 if (B3dMaterial.Textures[0]->Flags & 65536) // 65536 = secondary UV 918 if (B3dMaterial.Textures[0]->Flags & 65536) // 65536 = secondary UV
919 { 919 {
920 SB3dTexture *TmpTexture; 920 SB3dTexture *TmpTexture;
921 TmpTexture = B3dMaterial.Textures[1]; 921 TmpTexture = B3dMaterial.Textures[1];
922 B3dMaterial.Textures[1] = B3dMaterial.Textures[0]; 922 B3dMaterial.Textures[1] = B3dMaterial.Textures[0];
923 B3dMaterial.Textures[0] = TmpTexture; 923 B3dMaterial.Textures[0] = TmpTexture;
924 } 924 }
925 } 925 }
926 926
927 //If a preceeding texture slot is empty move the others down: 927 //If a preceeding texture slot is empty move the others down:
928 for (i=num_textures; i>0; --i) 928 for (i=num_textures; i>0; --i)
929 { 929 {
930 for (u32 j=i-1; j<num_textures-1; ++j) 930 for (u32 j=i-1; j<num_textures-1; ++j)
931 { 931 {
932 if (B3dMaterial.Textures[j+1] != 0 && B3dMaterial.Textures[j] == 0) 932 if (B3dMaterial.Textures[j+1] != 0 && B3dMaterial.Textures[j] == 0)
933 { 933 {
934 B3dMaterial.Textures[j] = B3dMaterial.Textures[j+1]; 934 B3dMaterial.Textures[j] = B3dMaterial.Textures[j+1];
935 B3dMaterial.Textures[j+1] = 0; 935 B3dMaterial.Textures[j+1] = 0;
936 } 936 }
937 } 937 }
938 } 938 }
939 939
940 //------ Convert blitz flags/blend to irrlicht ------- 940 //------ Convert blitz flags/blend to irrlicht -------
941 941
942 //Two textures: 942 //Two textures:
943 if (B3dMaterial.Textures[1]) 943 if (B3dMaterial.Textures[1])
944 { 944 {
945 if (B3dMaterial.alpha==1.f) 945 if (B3dMaterial.alpha==1.f)
946 { 946 {
947 if (B3dMaterial.Textures[1]->Blend == 5) //(Multiply 2) 947 if (B3dMaterial.Textures[1]->Blend == 5) //(Multiply 2)
948 B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP_M2; 948 B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP_M2;
949 else 949 else
950 B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP; 950 B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP;
951 B3dMaterial.Material.Lighting = false; 951 B3dMaterial.Material.Lighting = false;
952 } 952 }
953 else 953 else
954 { 954 {
955 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; 955 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
956 B3dMaterial.Material.ZWriteEnable = false; 956 B3dMaterial.Material.ZWriteEnable = false;
957 } 957 }
958 } 958 }
959 else if (B3dMaterial.Textures[0]) //One texture: 959 else if (B3dMaterial.Textures[0]) //One texture:
960 { 960 {
961 // Flags & 0x1 is usual SOLID, 0x8 is mipmap (handled before) 961 // Flags & 0x1 is usual SOLID, 0x8 is mipmap (handled before)
962 if (B3dMaterial.Textures[0]->Flags & 0x2) //(Alpha mapped) 962 if (B3dMaterial.Textures[0]->Flags & 0x2) //(Alpha mapped)
963 { 963 {
964 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; 964 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
965 B3dMaterial.Material.ZWriteEnable = false; 965 B3dMaterial.Material.ZWriteEnable = false;
966 } 966 }
967 else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked) 967 else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked)
968 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture 968 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture
969 else if (B3dMaterial.Textures[0]->Flags & 0x40) 969 else if (B3dMaterial.Textures[0]->Flags & 0x40)
970 B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; 970 B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP;
971 else if (B3dMaterial.Textures[0]->Flags & 0x80) 971 else if (B3dMaterial.Textures[0]->Flags & 0x80)
972 B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; // TODO: Should be cube map 972 B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; // TODO: Should be cube map
973 else if (B3dMaterial.alpha == 1.f) 973 else if (B3dMaterial.alpha == 1.f)
974 B3dMaterial.Material.MaterialType = video::EMT_SOLID; 974 B3dMaterial.Material.MaterialType = video::EMT_SOLID;
975 else 975 else
976 { 976 {
977 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; 977 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
978 B3dMaterial.Material.ZWriteEnable = false; 978 B3dMaterial.Material.ZWriteEnable = false;
979 } 979 }
980 } 980 }
981 else //No texture: 981 else //No texture:
982 { 982 {
983 if (B3dMaterial.alpha == 1.f) 983 if (B3dMaterial.alpha == 1.f)
984 B3dMaterial.Material.MaterialType = video::EMT_SOLID; 984 B3dMaterial.Material.MaterialType = video::EMT_SOLID;
985 else 985 else
986 { 986 {
987 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; 987 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
988 B3dMaterial.Material.ZWriteEnable = false; 988 B3dMaterial.Material.ZWriteEnable = false;
989 } 989 }
990 } 990 }
991 991
992 B3dMaterial.Material.DiffuseColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor(); 992 B3dMaterial.Material.DiffuseColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor();
993 B3dMaterial.Material.ColorMaterial=video::ECM_NONE; 993 B3dMaterial.Material.ColorMaterial=video::ECM_NONE;
994 994
995 //------ Material fx ------ 995 //------ Material fx ------
996 996
997 if (B3dMaterial.fx & 1) //full-bright 997 if (B3dMaterial.fx & 1) //full-bright
998 { 998 {
999 B3dMaterial.Material.AmbientColor = video::SColor(255, 255, 255, 255); 999 B3dMaterial.Material.AmbientColor = video::SColor(255, 255, 255, 255);
1000 B3dMaterial.Material.Lighting = false; 1000 B3dMaterial.Material.Lighting = false;
1001 } 1001 }
1002 else 1002 else
1003 B3dMaterial.Material.AmbientColor = B3dMaterial.Material.DiffuseColor; 1003 B3dMaterial.Material.AmbientColor = B3dMaterial.Material.DiffuseColor;
1004 1004
1005 if (B3dMaterial.fx & 2) //use vertex colors instead of brush color 1005 if (B3dMaterial.fx & 2) //use vertex colors instead of brush color
1006 B3dMaterial.Material.ColorMaterial=video::ECM_DIFFUSE_AND_AMBIENT; 1006 B3dMaterial.Material.ColorMaterial=video::ECM_DIFFUSE_AND_AMBIENT;
1007 1007
1008 if (B3dMaterial.fx & 4) //flatshaded 1008 if (B3dMaterial.fx & 4) //flatshaded
1009 B3dMaterial.Material.GouraudShading = false; 1009 B3dMaterial.Material.GouraudShading = false;
1010 1010
1011 if (B3dMaterial.fx & 16) //disable backface culling 1011 if (B3dMaterial.fx & 16) //disable backface culling
1012 B3dMaterial.Material.BackfaceCulling = false; 1012 B3dMaterial.Material.BackfaceCulling = false;
1013 1013
1014 if (B3dMaterial.fx & 32) //force vertex alpha-blending 1014 if (B3dMaterial.fx & 32) //force vertex alpha-blending
1015 { 1015 {
1016 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; 1016 B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
1017 B3dMaterial.Material.ZWriteEnable = false; 1017 B3dMaterial.Material.ZWriteEnable = false;
1018 } 1018 }
1019 1019
1020 B3dMaterial.Material.Shininess = B3dMaterial.shininess; 1020 B3dMaterial.Material.Shininess = B3dMaterial.shininess;
1021 } 1021 }
1022 1022
1023 B3dStack.erase(B3dStack.size()-1); 1023 B3dStack.erase(B3dStack.size()-1);
1024 1024
1025 return true; 1025 return true;
1026} 1026}
1027 1027
1028 1028
1029void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const 1029void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const
1030{ 1030{
1031 const bool previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT); 1031 const bool previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT);
1032 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true); 1032 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
1033 1033
1034 // read texture from disk 1034 // read texture from disk
1035 // note that mipmaps might be disabled by Flags & 0x8 1035 // note that mipmaps might be disabled by Flags & 0x8
1036 const bool doMipMaps = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); 1036 const bool doMipMaps = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
1037 1037
1038 for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) 1038 for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
1039 { 1039 {
1040 SB3dTexture* B3dTexture = material.Textures[i]; 1040 SB3dTexture* B3dTexture = material.Textures[i];
1041 if (B3dTexture && B3dTexture->TextureName.size() && !material.Material.getTexture(i)) 1041 if (B3dTexture && B3dTexture->TextureName.size() && !material.Material.getTexture(i))
1042 { 1042 {
1043 if (!SceneManager->getParameters()->getAttributeAsBool(B3D_LOADER_IGNORE_MIPMAP_FLAG)) 1043 if (!SceneManager->getParameters()->getAttributeAsBool(B3D_LOADER_IGNORE_MIPMAP_FLAG))
1044 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, (B3dTexture->Flags & 0x8) ? true:false); 1044 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, (B3dTexture->Flags & 0x8) ? true:false);
1045 { 1045 {
1046 video::ITexture* tex = 0; 1046 video::ITexture* tex = 0;
1047 io::IFileSystem* fs = SceneManager->getFileSystem(); 1047 io::IFileSystem* fs = SceneManager->getFileSystem();
1048 io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) ); 1048 io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) );
1049 if ( texnameWithUserPath.size() ) 1049 if ( texnameWithUserPath.size() )
1050 { 1050 {
1051 texnameWithUserPath += '/'; 1051 texnameWithUserPath += '/';
1052 texnameWithUserPath += B3dTexture->TextureName; 1052 texnameWithUserPath += B3dTexture->TextureName;
1053 } 1053 }
1054 if (fs->existFile(texnameWithUserPath)) 1054 if (fs->existFile(texnameWithUserPath))
1055 tex = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath); 1055 tex = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath);
1056 else if (fs->existFile(B3dTexture->TextureName)) 1056 else if (fs->existFile(B3dTexture->TextureName))
1057 tex = SceneManager->getVideoDriver()->getTexture(B3dTexture->TextureName); 1057 tex = SceneManager->getVideoDriver()->getTexture(B3dTexture->TextureName);
1058 else if (fs->existFile(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName))) 1058 else if (fs->existFile(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName)))
1059 tex = SceneManager->getVideoDriver()->getTexture(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName)); 1059 tex = SceneManager->getVideoDriver()->getTexture(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName));
1060 else 1060 else
1061 tex = SceneManager->getVideoDriver()->getTexture(fs->getFileBasename(B3dTexture->TextureName)); 1061 tex = SceneManager->getVideoDriver()->getTexture(fs->getFileBasename(B3dTexture->TextureName));
1062 1062
1063 material.Material.setTexture(i, tex); 1063 material.Material.setTexture(i, tex);
1064 } 1064 }
1065 if (material.Textures[i]->Flags & 0x10) // Clamp U 1065 if (material.Textures[i]->Flags & 0x10) // Clamp U
1066 material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP; 1066 material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP;
1067 if (material.Textures[i]->Flags & 0x20) // Clamp V 1067 if (material.Textures[i]->Flags & 0x20) // Clamp V
1068 material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP; 1068 material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP;
1069 } 1069 }
1070 } 1070 }
1071 1071
1072 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, doMipMaps); 1072 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, doMipMaps);
1073 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, previous32BitTextureFlag); 1073 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, previous32BitTextureFlag);
1074} 1074}
1075 1075
1076 1076
1077void CB3DMeshFileLoader::readString(core::stringc& newstring) 1077void CB3DMeshFileLoader::readString(core::stringc& newstring)
1078{ 1078{
1079 newstring=""; 1079 newstring="";
1080 while (B3DFile->getPos() <= B3DFile->getSize()) 1080 while (B3DFile->getPos() <= B3DFile->getSize())
1081 { 1081 {
1082 c8 character; 1082 c8 character;
1083 B3DFile->read(&character, sizeof(character)); 1083 B3DFile->read(&character, sizeof(character));
1084 if (character==0) 1084 if (character==0)
1085 return; 1085 return;
1086 newstring.append(character); 1086 newstring.append(character);
1087 } 1087 }
1088} 1088}
1089 1089
1090 1090
1091void CB3DMeshFileLoader::readFloats(f32* vec, u32 count) 1091void CB3DMeshFileLoader::readFloats(f32* vec, u32 count)
1092{ 1092{
1093 B3DFile->read(vec, count*sizeof(f32)); 1093 B3DFile->read(vec, count*sizeof(f32));
1094 #ifdef __BIG_ENDIAN__ 1094 #ifdef __BIG_ENDIAN__
1095 for (u32 n=0; n<count; ++n) 1095 for (u32 n=0; n<count; ++n)
1096 vec[n] = os::Byteswap::byteswap(vec[n]); 1096 vec[n] = os::Byteswap::byteswap(vec[n]);
1097 #endif 1097 #endif
1098} 1098}
1099 1099
1100} // end namespace scene 1100} // end namespace scene
1101} // end namespace irr 1101} // end namespace irr
1102 1102
1103 1103
1104#endif // _IRR_COMPILE_WITH_B3D_LOADER_ 1104#endif // _IRR_COMPILE_WITH_B3D_LOADER_
1105 1105