diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp | 2114 |
1 files changed, 2114 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp new file mode 100644 index 0000000..6534727 --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/CLWOMeshFileLoader.cpp | |||
@@ -0,0 +1,2114 @@ | |||
1 | // Copyright (C) 2007-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "CLWOMeshFileLoader.h" | ||
6 | #include "os.h" | ||
7 | #include "SAnimatedMesh.h" | ||
8 | #include "SMesh.h" | ||
9 | #include "IReadFile.h" | ||
10 | #include "ISceneManager.h" | ||
11 | #include "IFileSystem.h" | ||
12 | #include "IVideoDriver.h" | ||
13 | #include "IMeshManipulator.h" | ||
14 | |||
15 | namespace irr | ||
16 | { | ||
17 | namespace scene | ||
18 | { | ||
19 | |||
20 | #ifdef _DEBUG | ||
21 | #define LWO_READER_DEBUG | ||
22 | #endif | ||
23 | |||
24 | #define charsToUIntD(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d) | ||
25 | inline unsigned int charsToUInt(const char *str) | ||
26 | { | ||
27 | return (str[0] << 24) | (str[1] << 16) | (str[2] << 8) | str[3]; | ||
28 | } | ||
29 | |||
30 | |||
31 | struct tLWOTextureInfo | ||
32 | { | ||
33 | tLWOTextureInfo() : UVTag(0), DUVTag(0), Flags(0), WidthWrap(2), | ||
34 | HeightWrap(2), OpacType(0), Color(0xffffffff), | ||
35 | Value(0.0f), AntiAliasing(1.0f), Opacity(1.0f), | ||
36 | Axis(255), Projection(0), Active(false) {} | ||
37 | core::stringc Type; | ||
38 | core::stringc Map; | ||
39 | core::stringc AlphaMap; | ||
40 | core::stringc UVname; | ||
41 | u16 UVTag; | ||
42 | u16 DUVTag; | ||
43 | u16 Flags; | ||
44 | u16 WidthWrap; | ||
45 | u16 HeightWrap; | ||
46 | u16 OpacType; | ||
47 | u16 IParam[3]; | ||
48 | core::vector3df Size; | ||
49 | core::vector3df Center; | ||
50 | core::vector3df Falloff; | ||
51 | core::vector3df Velocity; | ||
52 | video::SColor Color; | ||
53 | f32 Value; | ||
54 | f32 AntiAliasing; | ||
55 | f32 Opacity; | ||
56 | f32 FParam[3]; | ||
57 | u8 Axis; | ||
58 | u8 Projection; | ||
59 | bool Active; | ||
60 | }; | ||
61 | |||
62 | struct CLWOMeshFileLoader::tLWOMaterial | ||
63 | { | ||
64 | tLWOMaterial() : Meshbuffer(0), TagType(0), Flags(0), ReflMode(3), TranspMode(3), | ||
65 | Glow(0), AlphaMode(2), Luminance(0.0f), Diffuse(1.0f), Specular(0.0f), | ||
66 | Reflection(0.0f), Transparency(0.0f), Translucency(0.0f), | ||
67 | Sharpness(0.0f), ReflSeamAngle(0.0f), ReflBlur(0.0f), | ||
68 | RefrIndex(1.0f), TranspBlur(0.0f), SmoothingAngle(0.0f), | ||
69 | EdgeTransparency(0.0f), HighlightColor(0.0f), ColorFilter(0.0f), | ||
70 | AdditiveTransparency(0.0f), GlowIntensity(0.0f), GlowSize(0.0f), | ||
71 | AlphaValue(0.0f), VertexColorIntensity(0.0f), VertexColor() {} | ||
72 | |||
73 | core::stringc Name; | ||
74 | scene::SMeshBuffer *Meshbuffer; | ||
75 | core::stringc ReflMap; | ||
76 | u16 TagType; | ||
77 | u16 Flags; | ||
78 | u16 ReflMode; | ||
79 | u16 TranspMode; | ||
80 | u16 Glow; | ||
81 | u16 AlphaMode; | ||
82 | f32 Luminance; | ||
83 | f32 Diffuse; | ||
84 | f32 Specular; | ||
85 | f32 Reflection; | ||
86 | f32 Transparency; | ||
87 | f32 Translucency; | ||
88 | f32 Sharpness; | ||
89 | f32 ReflSeamAngle; | ||
90 | f32 ReflBlur; | ||
91 | f32 RefrIndex; | ||
92 | f32 TranspBlur; | ||
93 | f32 SmoothingAngle; | ||
94 | f32 EdgeTransparency; | ||
95 | f32 HighlightColor; | ||
96 | f32 ColorFilter; | ||
97 | f32 AdditiveTransparency; | ||
98 | f32 GlowIntensity; | ||
99 | f32 GlowSize; | ||
100 | f32 AlphaValue; | ||
101 | f32 VertexColorIntensity; | ||
102 | video::SColorf VertexColor; | ||
103 | u32 Envelope[23]; | ||
104 | tLWOTextureInfo Texture[7]; | ||
105 | }; | ||
106 | |||
107 | struct tLWOLayerInfo | ||
108 | { | ||
109 | u16 Number; | ||
110 | u16 Parent; | ||
111 | u16 Flags; | ||
112 | bool Active; | ||
113 | core::stringc Name; | ||
114 | core::vector3df Pivot; | ||
115 | }; | ||
116 | |||
117 | |||
118 | //! Constructor | ||
119 | CLWOMeshFileLoader::CLWOMeshFileLoader(scene::ISceneManager* smgr, | ||
120 | io::IFileSystem* fs) | ||
121 | : SceneManager(smgr), FileSystem(fs), File(0), Mesh(0) | ||
122 | { | ||
123 | #ifdef _DEBUG | ||
124 | setDebugName("CLWOMeshFileLoader"); | ||
125 | #endif | ||
126 | } | ||
127 | |||
128 | |||
129 | //! destructor | ||
130 | CLWOMeshFileLoader::~CLWOMeshFileLoader() | ||
131 | { | ||
132 | if (Mesh) | ||
133 | Mesh->drop(); | ||
134 | } | ||
135 | |||
136 | |||
137 | //! returns true if the file maybe is able to be loaded by this class | ||
138 | //! based on the file extension (e.g. ".bsp") | ||
139 | bool CLWOMeshFileLoader::isALoadableFileExtension(const io::path& filename) const | ||
140 | { | ||
141 | return core::hasFileExtension(filename, "lwo"); | ||
142 | } | ||
143 | |||
144 | |||
145 | //! creates/loads an animated mesh from the file. | ||
146 | IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file) | ||
147 | { | ||
148 | File = file; | ||
149 | |||
150 | if (Mesh) | ||
151 | Mesh->drop(); | ||
152 | |||
153 | Mesh = new SMesh(); | ||
154 | |||
155 | if (!readFileHeader()) | ||
156 | return 0; | ||
157 | |||
158 | if (!readChunks()) | ||
159 | return 0; | ||
160 | |||
161 | #ifdef LWO_READER_DEBUG | ||
162 | os::Printer::log("LWO loader: Creating geometry."); | ||
163 | os::Printer::log("LWO loader: Assigning UV maps."); | ||
164 | #endif | ||
165 | u32 i; | ||
166 | for (i=0; i<Materials.size(); ++i) | ||
167 | { | ||
168 | u16 uvTag; | ||
169 | for (u32 j=0; j<2; ++j) // max 2 texture coords | ||
170 | { | ||
171 | if (Materials[i]->Texture[j].UVname.size()) | ||
172 | { | ||
173 | for (uvTag=0; uvTag<UvName.size(); ++uvTag) | ||
174 | { | ||
175 | if (Materials[i]->Texture[j].UVname == UvName[uvTag]) | ||
176 | { | ||
177 | Materials[i]->Texture[j].UVTag=uvTag; | ||
178 | break; | ||
179 | } | ||
180 | } | ||
181 | for (uvTag=0; uvTag<DUvName.size(); ++uvTag) | ||
182 | { | ||
183 | if (Materials[i]->Texture[j].UVname == DUvName[uvTag]) | ||
184 | { | ||
185 | Materials[i]->Texture[j].DUVTag=uvTag; | ||
186 | break; | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | #ifdef LWO_READER_DEBUG | ||
193 | os::Printer::log("LWO loader: Creating polys."); | ||
194 | #endif | ||
195 | // create actual geometry for lwo2 | ||
196 | if (FormatVersion==2) | ||
197 | { | ||
198 | core::array<u32> vertexCount; | ||
199 | vertexCount.reallocate(Materials.size()); | ||
200 | for (i=0; i<Materials.size(); ++i) | ||
201 | vertexCount.push_back(0); | ||
202 | for (u32 polyIndex=0; polyIndex<Indices.size(); ++polyIndex) | ||
203 | vertexCount[MaterialMapping[polyIndex]] += Indices[polyIndex].size(); | ||
204 | for (i=0; i<Materials.size(); ++i) | ||
205 | { | ||
206 | Materials[i]->Meshbuffer->Vertices.reallocate(vertexCount[i]); | ||
207 | Materials[i]->Meshbuffer->Indices.reallocate(vertexCount[i]); | ||
208 | } | ||
209 | } | ||
210 | // create actual geometry for lwo2 | ||
211 | for (u32 polyIndex=0; polyIndex<Indices.size(); ++polyIndex) | ||
212 | { | ||
213 | const u16 tag = MaterialMapping[polyIndex]; | ||
214 | scene::SMeshBuffer *mb=Materials[tag]->Meshbuffer; | ||
215 | const core::array<u32>& poly = Indices[polyIndex]; | ||
216 | const u32 polySize=poly.size(); | ||
217 | const u16 uvTag = Materials[tag]->Texture[0].UVTag; | ||
218 | const u16 duvTag = Materials[tag]->Texture[0].DUVTag; | ||
219 | video::S3DVertex vertex; | ||
220 | vertex.Color=0xffffffff; | ||
221 | const u32 vertCount=mb->Vertices.size(); | ||
222 | for (u32 i=0; i<polySize; ++i) | ||
223 | { | ||
224 | const u32 j=poly[i]; | ||
225 | vertex.Pos=Points[j]; | ||
226 | if (uvTag<UvIndex.size()) | ||
227 | { | ||
228 | for (u32 uvsearch=0; uvsearch < UvIndex[uvTag].size(); ++uvsearch) | ||
229 | { | ||
230 | if(j==UvIndex[uvTag][uvsearch]) | ||
231 | { | ||
232 | vertex.TCoords=TCoords[uvTag][uvsearch]; | ||
233 | break; | ||
234 | } | ||
235 | } | ||
236 | if (duvTag<DUvName.size()) | ||
237 | { | ||
238 | for (u32 polysearch = 0; polysearch < VmPolyPointsIndex[duvTag].size(); polysearch += 2) | ||
239 | { | ||
240 | if (polyIndex==VmPolyPointsIndex[duvTag][polysearch] && j==VmPolyPointsIndex[duvTag][polysearch+1]) | ||
241 | { | ||
242 | vertex.TCoords=VmCoordsIndex[duvTag][polysearch/2]; | ||
243 | break; | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | mb->Vertices.push_back(vertex); | ||
249 | } | ||
250 | // triangulate as trifan | ||
251 | if (polySize>2) | ||
252 | { | ||
253 | for (u32 i=1; i<polySize-1; ++i) | ||
254 | { | ||
255 | mb->Indices.push_back(vertCount); | ||
256 | mb->Indices.push_back(vertCount+i); | ||
257 | mb->Indices.push_back(vertCount+i+1); | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | #ifdef LWO_READER_DEBUG | ||
262 | os::Printer::log("LWO loader: Fixing meshbuffers."); | ||
263 | #endif | ||
264 | for (u32 i=0; i<Materials.size(); ++i) | ||
265 | { | ||
266 | #ifdef LWO_READER_DEBUG | ||
267 | os::Printer::log("LWO loader: Material name", Materials[i]->Name); | ||
268 | os::Printer::log("LWO loader: Vertex count", core::stringc(Materials[i]->Meshbuffer->Vertices.size())); | ||
269 | #endif | ||
270 | if (!Materials[i]->Meshbuffer->Vertices.size()) | ||
271 | { | ||
272 | Materials[i]->Meshbuffer->drop(); | ||
273 | delete Materials[i]; | ||
274 | continue; | ||
275 | } | ||
276 | for (u32 j=0; j<Materials[i]->Meshbuffer->Vertices.size(); ++j) | ||
277 | Materials[i]->Meshbuffer->Vertices[j].Color=Materials[i]->Meshbuffer->Material.DiffuseColor; | ||
278 | Materials[i]->Meshbuffer->recalculateBoundingBox(); | ||
279 | |||
280 | // load textures | ||
281 | video::SMaterial& irrMat=Materials[i]->Meshbuffer->Material; | ||
282 | if (Materials[i]->Texture[0].Map != "") // diffuse | ||
283 | irrMat.setTexture(0,loadTexture(Materials[i]->Texture[0].Map)); | ||
284 | if (Materials[i]->Texture[3].Map != "") // reflection | ||
285 | { | ||
286 | #ifdef LWO_READER_DEBUG | ||
287 | os::Printer::log("LWO loader: loading reflection texture."); | ||
288 | #endif | ||
289 | video::ITexture* reflTexture = loadTexture(Materials[i]->Texture[3].Map); | ||
290 | if (reflTexture && irrMat.getTexture(0)) | ||
291 | irrMat.setTexture(1, irrMat.getTexture(0)); | ||
292 | irrMat.setTexture(0, reflTexture); | ||
293 | irrMat.MaterialType=video::EMT_REFLECTION_2_LAYER; | ||
294 | } | ||
295 | if (Materials[i]->Texture[4].Map != "") // transparency | ||
296 | { | ||
297 | #ifdef LWO_READER_DEBUG | ||
298 | os::Printer::log("LWO loader: loading transparency texture."); | ||
299 | #endif | ||
300 | video::ITexture* transTexture = loadTexture(Materials[i]->Texture[4].Map); | ||
301 | if (transTexture && irrMat.getTexture(0)) | ||
302 | irrMat.setTexture(1, irrMat.getTexture(0)); | ||
303 | irrMat.setTexture(0, transTexture); | ||
304 | irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; | ||
305 | } | ||
306 | if (Materials[i]->Texture[6].Map != "") // bump | ||
307 | { | ||
308 | #ifdef LWO_READER_DEBUG | ||
309 | os::Printer::log("LWO loader: loading bump texture."); | ||
310 | #endif | ||
311 | const u8 pos = irrMat.getTexture(0)?1:0; | ||
312 | irrMat.setTexture(pos, loadTexture(Materials[i]->Texture[6].Map)); | ||
313 | if (irrMat.getTexture(pos)) | ||
314 | { | ||
315 | // SceneManager->getVideoDriver()->makeNormalMapTexture(irrMat.getTexture(1)); | ||
316 | // irrMat.MaterialType=video::EMT_NORMAL_MAP_SOLID; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | // cope with planar mapping texture coords | ||
321 | if (Materials[i]->Texture[0].Projection != 5) | ||
322 | { | ||
323 | if (FormatVersion!=2) | ||
324 | { | ||
325 | if (Materials[i]->Texture[0].Flags&1) | ||
326 | Materials[i]->Texture[0].Axis=0; | ||
327 | else if (Materials[i]->Texture[0].Flags&2) | ||
328 | Materials[i]->Texture[0].Axis=1; | ||
329 | else if (Materials[i]->Texture[0].Flags&4) | ||
330 | Materials[i]->Texture[0].Axis=2; | ||
331 | } | ||
332 | // if no axis given choose the dominant one | ||
333 | else if (Materials[i]->Texture[0].Axis>2) | ||
334 | { | ||
335 | if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().Y<Materials[i]->Meshbuffer->getBoundingBox().getExtent().X) | ||
336 | { | ||
337 | if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().Y<Materials[i]->Meshbuffer->getBoundingBox().getExtent().Z) | ||
338 | Materials[i]->Texture[0].Axis=1; | ||
339 | else | ||
340 | Materials[i]->Texture[0].Axis=2; | ||
341 | } | ||
342 | else | ||
343 | { | ||
344 | if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().X<Materials[i]->Meshbuffer->getBoundingBox().getExtent().Z) | ||
345 | Materials[i]->Texture[0].Axis=0; | ||
346 | else | ||
347 | Materials[i]->Texture[0].Axis=2; | ||
348 | } | ||
349 | } | ||
350 | // get the resolution for this axis | ||
351 | f32 resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.Z); | ||
352 | f32 resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); | ||
353 | if (Materials[i]->Texture[0].Axis==1) | ||
354 | { | ||
355 | resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); | ||
356 | resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Z); | ||
357 | } | ||
358 | else if (Materials[i]->Texture[0].Axis==2) | ||
359 | { | ||
360 | resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); | ||
361 | resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); | ||
362 | } | ||
363 | // use the two-way planar mapping | ||
364 | SceneManager->getMeshManipulator()->makePlanarTextureMapping(Materials[i]->Meshbuffer, resolutionS, resolutionT, Materials[i]->Texture[0].Axis, Materials[i]->Texture[0].Center); | ||
365 | } | ||
366 | |||
367 | // add bump maps | ||
368 | if (Materials[i]->Meshbuffer->Material.MaterialType==video::EMT_NORMAL_MAP_SOLID) | ||
369 | { | ||
370 | SMesh* tmpmesh = new SMesh(); | ||
371 | tmpmesh->addMeshBuffer(Materials[i]->Meshbuffer); | ||
372 | SceneManager->getMeshManipulator()->createMeshWithTangents(tmpmesh, true, true); | ||
373 | Mesh->addMeshBuffer(tmpmesh->getMeshBuffer(0)); | ||
374 | tmpmesh->getMeshBuffer(0)->drop(); | ||
375 | tmpmesh->drop(); | ||
376 | } | ||
377 | else | ||
378 | { | ||
379 | SceneManager->getMeshManipulator()->recalculateNormals(Materials[i]->Meshbuffer); | ||
380 | Mesh->addMeshBuffer(Materials[i]->Meshbuffer); | ||
381 | } | ||
382 | Materials[i]->Meshbuffer->drop(); | ||
383 | // clear the material array elements | ||
384 | delete Materials[i]; | ||
385 | } | ||
386 | Mesh->recalculateBoundingBox(); | ||
387 | |||
388 | SAnimatedMesh* am = new SAnimatedMesh(); | ||
389 | am->Type = EAMT_3DS; | ||
390 | am->addMesh(Mesh); | ||
391 | am->recalculateBoundingBox(); | ||
392 | Mesh->drop(); | ||
393 | Mesh = 0; | ||
394 | |||
395 | Points.clear(); | ||
396 | Indices.clear(); | ||
397 | MaterialMapping.clear(); | ||
398 | TCoords.clear(); | ||
399 | Materials.clear(); | ||
400 | Images.clear(); | ||
401 | VmPolyPointsIndex.clear(); | ||
402 | VmCoordsIndex.clear(); | ||
403 | UvIndex.clear(); | ||
404 | UvName.clear(); | ||
405 | |||
406 | return am; | ||
407 | } | ||
408 | |||
409 | |||
410 | bool CLWOMeshFileLoader::readChunks() | ||
411 | { | ||
412 | s32 lastPos; | ||
413 | u32 size; | ||
414 | unsigned int uiType; | ||
415 | char type[5]; | ||
416 | type[4]=0; | ||
417 | tLWOLayerInfo layer; | ||
418 | |||
419 | while(File->getPos()<File->getSize()) | ||
420 | { | ||
421 | File->read(&type, 4); | ||
422 | //Convert 4-char string to 4-byte integer | ||
423 | //Makes it possible to do a switch statement | ||
424 | uiType = charsToUInt(type); | ||
425 | File->read(&size, 4); | ||
426 | #ifndef __BIG_ENDIAN__ | ||
427 | size=os::Byteswap::byteswap(size); | ||
428 | #endif | ||
429 | lastPos=File->getPos(); | ||
430 | |||
431 | switch(uiType) | ||
432 | { | ||
433 | case charsToUIntD('L','A','Y','R'): | ||
434 | { | ||
435 | #ifdef LWO_READER_DEBUG | ||
436 | os::Printer::log("LWO loader: loading layer."); | ||
437 | #endif | ||
438 | u16 tmp16; | ||
439 | File->read(&tmp16, 2); // number | ||
440 | File->read(&tmp16, 2); // flags | ||
441 | size -= 4; | ||
442 | #ifndef __BIG_ENDIAN__ | ||
443 | tmp16=os::Byteswap::byteswap(tmp16); | ||
444 | #endif | ||
445 | if (((FormatVersion==1)&&(tmp16!=1)) || | ||
446 | ((FormatVersion==2)&&(tmp16&1))) | ||
447 | layer.Active=false; | ||
448 | else | ||
449 | layer.Active=true; | ||
450 | if (FormatVersion==2) | ||
451 | size -= readVec(layer.Pivot); | ||
452 | size -= readString(layer.Name); | ||
453 | if (size) | ||
454 | { | ||
455 | File->read(&tmp16, 2); | ||
456 | #ifndef __BIG_ENDIAN__ | ||
457 | tmp16=os::Byteswap::byteswap(tmp16); | ||
458 | #endif | ||
459 | layer.Parent = tmp16; | ||
460 | } | ||
461 | } | ||
462 | break; | ||
463 | case charsToUIntD('P','N','T','S'): | ||
464 | { | ||
465 | #ifdef LWO_READER_DEBUG | ||
466 | os::Printer::log("LWO loader: loading points."); | ||
467 | #endif | ||
468 | core::vector3df vec; | ||
469 | Points.clear(); | ||
470 | const u32 tmpsize = size/12; | ||
471 | Points.reallocate(tmpsize); | ||
472 | for (u32 i=0; i<tmpsize; ++i) | ||
473 | { | ||
474 | readVec(vec); | ||
475 | Points.push_back(vec); | ||
476 | } | ||
477 | } | ||
478 | break; | ||
479 | case charsToUIntD('V','M','A','P'): | ||
480 | #ifdef LWO_READER_DEBUG | ||
481 | os::Printer::log("LWO loader: loading Vertex mapping."); | ||
482 | #endif | ||
483 | readVertexMapping(size); | ||
484 | break; | ||
485 | case charsToUIntD('P','O','L','S'): | ||
486 | case charsToUIntD('P','T','C','H'): // TODO: should be a subdivison mesh | ||
487 | #ifdef LWO_READER_DEBUG | ||
488 | os::Printer::log("LWO loader: loading polygons."); | ||
489 | #endif | ||
490 | if (FormatVersion!=2) | ||
491 | readObj1(size); | ||
492 | else | ||
493 | readObj2(size); | ||
494 | #ifdef LWO_READER_DEBUG | ||
495 | os::Printer::log("LWO loader: Done loading polygons."); | ||
496 | #endif | ||
497 | break; | ||
498 | case charsToUIntD('T','A','G','S'): | ||
499 | case charsToUIntD('S','R','F','S'): | ||
500 | { | ||
501 | #ifdef LWO_READER_DEBUG | ||
502 | os::Printer::log("LWO loader: loading surface names."); | ||
503 | #endif | ||
504 | while (size!=0) | ||
505 | { | ||
506 | tLWOMaterial *mat=new tLWOMaterial(); | ||
507 | mat->Name=""; | ||
508 | mat->Meshbuffer=new scene::SMeshBuffer(); | ||
509 | size -= readString(mat->Name); | ||
510 | if (FormatVersion!=2) | ||
511 | mat->TagType = 1; // format 2 has more types | ||
512 | Materials.push_back(mat); | ||
513 | } | ||
514 | } | ||
515 | break; | ||
516 | case charsToUIntD('P','T','A','G'): | ||
517 | #ifdef LWO_READER_DEBUG | ||
518 | os::Printer::log("LWO loader: loading tag mapping."); | ||
519 | #endif | ||
520 | readTagMapping(size); | ||
521 | break; | ||
522 | case charsToUIntD('V','M','A','D'): // discontinuous vertex mapping, i.e. additional texcoords | ||
523 | #ifdef LWO_READER_DEBUG | ||
524 | os::Printer::log("LWO loader: loading Vertex mapping VMAD."); | ||
525 | #endif | ||
526 | readDiscVertexMapping(size); | ||
527 | // case charsToUIntD('V','M','P','A'): | ||
528 | // case charsToUIntD('E','N','V','L'): | ||
529 | break; | ||
530 | case charsToUIntD('C','L','I','P'): | ||
531 | { | ||
532 | #ifdef LWO_READER_DEBUG | ||
533 | os::Printer::log("LWO loader: loading clips."); | ||
534 | #endif | ||
535 | u32 index; | ||
536 | u16 subsize; | ||
537 | File->read(&index, 4); | ||
538 | #ifndef __BIG_ENDIAN__ | ||
539 | index=os::Byteswap::byteswap(index); | ||
540 | #endif | ||
541 | size -= 4; | ||
542 | while (size != 0) | ||
543 | { | ||
544 | File->read(&type, 4); | ||
545 | File->read(&subsize, 2); | ||
546 | #ifndef __BIG_ENDIAN__ | ||
547 | subsize=os::Byteswap::byteswap(subsize); | ||
548 | #endif | ||
549 | size -= 6; | ||
550 | if (strncmp(type, "STIL", 4)) | ||
551 | { | ||
552 | File->seek(subsize, true); | ||
553 | size -= subsize; | ||
554 | continue; | ||
555 | } | ||
556 | core::stringc path; | ||
557 | size -= readString(path, subsize); | ||
558 | #ifdef LWO_READER_DEBUG | ||
559 | os::Printer::log("LWO loader: loaded clip", path.c_str()); | ||
560 | #endif | ||
561 | Images.push_back(path); | ||
562 | } | ||
563 | } | ||
564 | break; | ||
565 | case charsToUIntD('S','U','R','F'): | ||
566 | #ifdef LWO_READER_DEBUG | ||
567 | os::Printer::log("LWO loader: loading material."); | ||
568 | #endif | ||
569 | readMat(size); | ||
570 | break; | ||
571 | case charsToUIntD('B','B','O','X'): | ||
572 | { | ||
573 | #ifdef LWO_READER_DEBUG | ||
574 | os::Printer::log("LWO loader: loading bbox."); | ||
575 | #endif | ||
576 | // not stored | ||
577 | core::vector3df vec; | ||
578 | for (u32 i=0; i<2; ++i) | ||
579 | readVec(vec); | ||
580 | size -= 24; | ||
581 | } | ||
582 | break; | ||
583 | case charsToUIntD('D','E','S','C'): | ||
584 | case charsToUIntD('T','E','X','T'): | ||
585 | { | ||
586 | core::stringc text; | ||
587 | size -= readString(text, size); | ||
588 | #ifdef LWO_READER_DEBUG | ||
589 | os::Printer::log("LWO loader text", text); | ||
590 | #endif | ||
591 | } | ||
592 | break; | ||
593 | // not needed | ||
594 | case charsToUIntD('I','C','O','N'): | ||
595 | // not yet supported | ||
596 | case charsToUIntD('P','C','H','S'): | ||
597 | case charsToUIntD('C','R','V','S'): | ||
598 | default: | ||
599 | #ifdef LWO_READER_DEBUG | ||
600 | os::Printer::log("LWO loader: skipping ", type); | ||
601 | #endif | ||
602 | //Go to next chunk | ||
603 | File->seek(lastPos + size, false); | ||
604 | break; | ||
605 | } | ||
606 | } | ||
607 | return true; | ||
608 | } | ||
609 | |||
610 | |||
611 | void CLWOMeshFileLoader::readObj1(u32 size) | ||
612 | { | ||
613 | u32 pos; | ||
614 | u16 numVerts, vertIndex; | ||
615 | s16 material; | ||
616 | video::S3DVertex vertex; | ||
617 | vertex.Color=0xffffffff; | ||
618 | |||
619 | while (size!=0) | ||
620 | { | ||
621 | File->read(&numVerts, 2); | ||
622 | #ifndef __BIG_ENDIAN__ | ||
623 | numVerts=os::Byteswap::byteswap(numVerts); | ||
624 | #endif | ||
625 | pos=File->getPos(); | ||
626 | // skip forward to material number | ||
627 | File->seek(2*numVerts, true); | ||
628 | File->read(&material, 2); | ||
629 | #ifndef __BIG_ENDIAN__ | ||
630 | material=os::Byteswap::byteswap(material); | ||
631 | #endif | ||
632 | size -=2*numVerts+4; | ||
633 | // detail meshes ? | ||
634 | scene::SMeshBuffer *mb; | ||
635 | if (material<0) | ||
636 | mb=Materials[-material-1]->Meshbuffer; | ||
637 | else | ||
638 | mb=Materials[material-1]->Meshbuffer; | ||
639 | // back to vertex list start | ||
640 | File->seek(pos, false); | ||
641 | |||
642 | const u16 vertCount=mb->Vertices.size(); | ||
643 | for (u16 i=0; i<numVerts; ++i) | ||
644 | { | ||
645 | File->read(&vertIndex, 2); | ||
646 | #ifndef __BIG_ENDIAN__ | ||
647 | vertIndex=os::Byteswap::byteswap(vertIndex); | ||
648 | #endif | ||
649 | vertex.Pos=Points[vertIndex]; | ||
650 | mb->Vertices.push_back(vertex); | ||
651 | } | ||
652 | for (u16 i=1; i<numVerts-1; ++i) | ||
653 | { | ||
654 | mb->Indices.push_back(vertCount); | ||
655 | mb->Indices.push_back(vertCount+i); | ||
656 | mb->Indices.push_back(vertCount+i+1); | ||
657 | } | ||
658 | // skip material number and detail surface count | ||
659 | // detail surface can be read just as a normal one now | ||
660 | if (material<0) | ||
661 | File->read(&material, 2); | ||
662 | File->read(&material, 2); | ||
663 | } | ||
664 | } | ||
665 | |||
666 | |||
667 | void CLWOMeshFileLoader::readVertexMapping(u32 size) | ||
668 | { | ||
669 | char type[5]={0}; | ||
670 | u16 dimension; | ||
671 | core::stringc name; | ||
672 | File->read(&type, 4); | ||
673 | #ifdef LWO_READER_DEBUG | ||
674 | os::Printer::log("LWO loader: Vertex map type", type); | ||
675 | #endif | ||
676 | File->read(&dimension,2); | ||
677 | #ifndef __BIG_ENDIAN__ | ||
678 | dimension=os::Byteswap::byteswap(dimension); | ||
679 | #endif | ||
680 | size -= 6; | ||
681 | size -= readString(name); | ||
682 | #ifdef LWO_READER_DEBUG | ||
683 | os::Printer::log("LWO loader: Vertex map", name.c_str()); | ||
684 | #endif | ||
685 | if (strncmp(type, "TXUV", 4)) // also support RGB, RGBA, WGHT, ... | ||
686 | { | ||
687 | File->seek(size, true); | ||
688 | return; | ||
689 | } | ||
690 | UvName.push_back(name); | ||
691 | |||
692 | TCoords.push_back(core::array<core::vector2df>()); | ||
693 | core::array<core::vector2df>& UvCoords=TCoords.getLast(); | ||
694 | UvCoords.reallocate(Points.size()); | ||
695 | UvIndex.push_back(core::array<u32>()); | ||
696 | core::array<u32>& UvPointsArray=UvIndex.getLast(); | ||
697 | UvPointsArray.reallocate(Points.size()); | ||
698 | |||
699 | u32 index; | ||
700 | core::vector2df tcoord; | ||
701 | while (size) | ||
702 | { | ||
703 | size -= readVX(index); | ||
704 | File->read(&tcoord.X, 4); | ||
705 | File->read(&tcoord.Y, 4); | ||
706 | size -= 8; | ||
707 | #ifndef __BIG_ENDIAN__ | ||
708 | index=os::Byteswap::byteswap(index); | ||
709 | tcoord.X=os::Byteswap::byteswap(tcoord.X); | ||
710 | tcoord.Y=os::Byteswap::byteswap(tcoord.Y); | ||
711 | #endif | ||
712 | UvCoords.push_back(tcoord); | ||
713 | UvPointsArray.push_back(index); | ||
714 | } | ||
715 | #ifdef LWO_READER_DEBUG | ||
716 | os::Printer::log("LWO loader: UvCoords", core::stringc(UvCoords.size())); | ||
717 | #endif | ||
718 | } | ||
719 | |||
720 | |||
721 | void CLWOMeshFileLoader::readDiscVertexMapping(u32 size) | ||
722 | { | ||
723 | char type[5]={0}; | ||
724 | u16 dimension; | ||
725 | core::stringc name; | ||
726 | File->read(&type, 4); | ||
727 | #ifdef LWO_READER_DEBUG | ||
728 | os::Printer::log("LWO loader: Discontinuous vertex map type", type); | ||
729 | #endif | ||
730 | File->read(&dimension,2); | ||
731 | #ifndef __BIG_ENDIAN__ | ||
732 | dimension=os::Byteswap::byteswap(dimension); | ||
733 | #endif | ||
734 | size -= 6; | ||
735 | size -= readString(name); | ||
736 | #ifdef LWO_READER_DEBUG | ||
737 | os::Printer::log("LWO loader: Discontinuous vertex map", name.c_str()); | ||
738 | #endif | ||
739 | if (strncmp(type, "TXUV", 4)) | ||
740 | { | ||
741 | File->seek(size, true); | ||
742 | return; | ||
743 | } | ||
744 | DUvName.push_back(name); | ||
745 | VmPolyPointsIndex.push_back(core::array<u32>()); | ||
746 | core::array<u32>& VmPolyPoints=VmPolyPointsIndex.getLast(); | ||
747 | |||
748 | VmCoordsIndex.push_back(core::array<core::vector2df>()); | ||
749 | core::array<core::vector2df>& VmCoords=VmCoordsIndex.getLast(); | ||
750 | |||
751 | u32 vmpolys; | ||
752 | u32 vmpoints; | ||
753 | core::vector2df vmcoords; | ||
754 | while (size) | ||
755 | { | ||
756 | size-=readVX(vmpoints); | ||
757 | size-=readVX(vmpolys); | ||
758 | File->read(&vmcoords.X, 4); | ||
759 | File->read(&vmcoords.Y, 4); | ||
760 | size -= 8; | ||
761 | #ifndef __BIG_ENDIAN__ | ||
762 | vmpoints=os::Byteswap::byteswap(vmpoints); | ||
763 | vmpolys=os::Byteswap::byteswap(vmpolys); | ||
764 | vmcoords.X=os::Byteswap::byteswap(vmcoords.X); | ||
765 | vmcoords.Y=os::Byteswap::byteswap(vmcoords.Y); | ||
766 | #endif | ||
767 | VmCoords.push_back(vmcoords); | ||
768 | VmPolyPoints.push_back(vmpolys); | ||
769 | VmPolyPoints.push_back(vmpoints); | ||
770 | } | ||
771 | #ifdef LWO_READER_DEBUG | ||
772 | os::Printer::log("LWO loader: VmCoords", core::stringc(VmCoords.size())); | ||
773 | #endif | ||
774 | } | ||
775 | |||
776 | |||
777 | void CLWOMeshFileLoader::readTagMapping(u32 size) | ||
778 | { | ||
779 | char type[5]; | ||
780 | type[4]=0; | ||
781 | File->read(&type, 4); | ||
782 | size -= 4; | ||
783 | if ((strncmp(type, "SURF", 4))||(Indices.size()==0)) | ||
784 | { | ||
785 | File->seek(size, true); | ||
786 | return; | ||
787 | } | ||
788 | |||
789 | while (size!=0) | ||
790 | { | ||
791 | u16 tag; | ||
792 | u32 polyIndex; | ||
793 | size-=readVX(polyIndex); | ||
794 | File->read(&tag, 2); | ||
795 | #ifndef __BIG_ENDIAN__ | ||
796 | tag=os::Byteswap::byteswap(tag); | ||
797 | #endif | ||
798 | size -= 2; | ||
799 | MaterialMapping[polyIndex]=tag; | ||
800 | Materials[tag]->TagType=1; | ||
801 | } | ||
802 | } | ||
803 | |||
804 | |||
805 | void CLWOMeshFileLoader::readObj2(u32 size) | ||
806 | { | ||
807 | char type[5]; | ||
808 | type[4]=0; | ||
809 | File->read(&type, 4); | ||
810 | size -= 4; | ||
811 | Indices.clear(); | ||
812 | if (strncmp(type, "FACE", 4)) // also possible are splines, subdivision patches, metaballs, and bones | ||
813 | { | ||
814 | File->seek(size, true); | ||
815 | return; | ||
816 | } | ||
817 | u16 numVerts=0; | ||
818 | while (size!=0) | ||
819 | { | ||
820 | File->read(&numVerts, 2); | ||
821 | #ifndef __BIG_ENDIAN__ | ||
822 | numVerts=os::Byteswap::byteswap(numVerts); | ||
823 | #endif | ||
824 | // mask out flags | ||
825 | numVerts &= 0x03FF; | ||
826 | |||
827 | size -= 2; | ||
828 | Indices.push_back(core::array<u32>()); | ||
829 | u32 vertIndex; | ||
830 | core::array<u32>& polyArray = Indices.getLast(); | ||
831 | polyArray.reallocate(numVerts); | ||
832 | for (u16 i=0; i<numVerts; ++i) | ||
833 | { | ||
834 | size -= readVX(vertIndex); | ||
835 | polyArray.push_back(vertIndex); | ||
836 | } | ||
837 | } | ||
838 | MaterialMapping.reallocate(Indices.size()); | ||
839 | for (u32 j=0; j<Indices.size(); ++j) | ||
840 | MaterialMapping.push_back(0); | ||
841 | } | ||
842 | |||
843 | |||
844 | void CLWOMeshFileLoader::readMat(u32 size) | ||
845 | { | ||
846 | core::stringc name; | ||
847 | |||
848 | tLWOMaterial* mat=0; | ||
849 | size -= readString(name); | ||
850 | #ifdef LWO_READER_DEBUG | ||
851 | os::Printer::log("LWO loader: material name", name.c_str()); | ||
852 | #endif | ||
853 | for (u32 i=0; i<Materials.size(); ++i) | ||
854 | { | ||
855 | if ((Materials[i]->TagType==1) && (Materials[i]->Name==name)) | ||
856 | { | ||
857 | mat=Materials[i]; | ||
858 | break; | ||
859 | } | ||
860 | } | ||
861 | if (!mat) | ||
862 | { | ||
863 | File->seek(size, true); | ||
864 | return; | ||
865 | } | ||
866 | if (FormatVersion==2) | ||
867 | size -= readString(name); | ||
868 | |||
869 | video::SMaterial& irrMat=mat->Meshbuffer->Material; | ||
870 | |||
871 | u8 currTexture=0; | ||
872 | while (size!=0) | ||
873 | { | ||
874 | char type[5]; | ||
875 | type[4]=0; | ||
876 | u32 uiType; | ||
877 | u32 tmp32; | ||
878 | u16 subsize, tmp16; | ||
879 | f32 tmpf32; | ||
880 | File->read(&type, 4); | ||
881 | //Convert 4-char string to 4-byte integer | ||
882 | //Makes it possible to do a switch statement | ||
883 | uiType = charsToUInt(type); | ||
884 | File->read(&subsize, 2); | ||
885 | #ifndef __BIG_ENDIAN__ | ||
886 | subsize=os::Byteswap::byteswap(subsize); | ||
887 | #endif | ||
888 | size -= 6; | ||
889 | switch (uiType) | ||
890 | { | ||
891 | case charsToUIntD('C','O','L','R'): | ||
892 | #ifdef LWO_READER_DEBUG | ||
893 | os::Printer::log("LWO loader: loading Ambient color."); | ||
894 | #endif | ||
895 | { | ||
896 | s32 colSize = readColor(irrMat.DiffuseColor); | ||
897 | irrMat.AmbientColor=irrMat.DiffuseColor; | ||
898 | size -= colSize; | ||
899 | subsize -= colSize; | ||
900 | if (FormatVersion==2) | ||
901 | size -= readVX(mat->Envelope[0]); | ||
902 | } | ||
903 | break; | ||
904 | case charsToUIntD('D','I','F','F'): | ||
905 | #ifdef LWO_READER_DEBUG | ||
906 | os::Printer::log("LWO loader: loading Diffuse color."); | ||
907 | #endif | ||
908 | { | ||
909 | if (FormatVersion==2) | ||
910 | { | ||
911 | File->read(&mat->Diffuse, 4); | ||
912 | #ifndef __BIG_ENDIAN__ | ||
913 | mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); | ||
914 | #endif | ||
915 | size -= 4; | ||
916 | subsize -= 4; | ||
917 | size -= readVX(mat->Envelope[1]); | ||
918 | } | ||
919 | else | ||
920 | { | ||
921 | File->read(&tmp16, 2); | ||
922 | #ifndef __BIG_ENDIAN__ | ||
923 | tmp16=os::Byteswap::byteswap(tmp16); | ||
924 | #endif | ||
925 | mat->Diffuse=tmp16/256.0f; | ||
926 | size -= 2; | ||
927 | subsize -= 2; | ||
928 | } | ||
929 | } | ||
930 | break; | ||
931 | case charsToUIntD('V','D','I','F'): | ||
932 | #ifdef LWO_READER_DEBUG | ||
933 | os::Printer::log("LWO loader: loading Diffuse color."); | ||
934 | #endif | ||
935 | { | ||
936 | File->read(&mat->Diffuse, 4); | ||
937 | #ifndef __BIG_ENDIAN__ | ||
938 | mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); | ||
939 | #endif | ||
940 | size -= 4; | ||
941 | } | ||
942 | break; | ||
943 | case charsToUIntD('L','U','M','I'): | ||
944 | #ifdef LWO_READER_DEBUG | ||
945 | os::Printer::log("LWO loader: loading luminance."); | ||
946 | #endif | ||
947 | { | ||
948 | if (FormatVersion==2) | ||
949 | { | ||
950 | File->read(&mat->Luminance, 4); | ||
951 | #ifndef __BIG_ENDIAN__ | ||
952 | mat->Luminance=os::Byteswap::byteswap(mat->Luminance); | ||
953 | #endif | ||
954 | size -= 4; | ||
955 | subsize -= 4; | ||
956 | size -= readVX(mat->Envelope[2]); | ||
957 | } | ||
958 | else | ||
959 | { | ||
960 | File->read(&tmp16, 2); | ||
961 | #ifndef __BIG_ENDIAN__ | ||
962 | tmp16=os::Byteswap::byteswap(tmp16); | ||
963 | #endif | ||
964 | mat->Luminance=tmp16/256.0f; | ||
965 | size -= 2; | ||
966 | subsize -= 2; | ||
967 | } } | ||
968 | break; | ||
969 | case charsToUIntD('V','L','U','M'): | ||
970 | #ifdef LWO_READER_DEBUG | ||
971 | os::Printer::log("LWO loader: loading luminance."); | ||
972 | #endif | ||
973 | { | ||
974 | File->read(&mat->Luminance, 4); | ||
975 | #ifndef __BIG_ENDIAN__ | ||
976 | mat->Luminance=os::Byteswap::byteswap(mat->Luminance); | ||
977 | #endif | ||
978 | size -= 4; | ||
979 | } | ||
980 | break; | ||
981 | case charsToUIntD('S','P','E','C'): | ||
982 | #ifdef LWO_READER_DEBUG | ||
983 | os::Printer::log("LWO loader: loading specular."); | ||
984 | #endif | ||
985 | { | ||
986 | if (FormatVersion==2) | ||
987 | { | ||
988 | File->read(&mat->Specular, 4); | ||
989 | #ifndef __BIG_ENDIAN__ | ||
990 | mat->Specular=os::Byteswap::byteswap(mat->Specular); | ||
991 | #endif | ||
992 | size -= 4; | ||
993 | subsize -= 4; | ||
994 | size -= readVX(mat->Envelope[3]); | ||
995 | } | ||
996 | else | ||
997 | { | ||
998 | File->read(&tmp16, 2); | ||
999 | #ifndef __BIG_ENDIAN__ | ||
1000 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1001 | #endif | ||
1002 | mat->Specular=tmp16/256.0f;; | ||
1003 | size -= 2; | ||
1004 | subsize -= 2; | ||
1005 | } | ||
1006 | } | ||
1007 | break; | ||
1008 | case charsToUIntD('V','S','P','C'): | ||
1009 | #ifdef LWO_READER_DEBUG | ||
1010 | os::Printer::log("LWO loader: loading specular."); | ||
1011 | #endif | ||
1012 | { | ||
1013 | File->read(&mat->Specular, 4); | ||
1014 | #ifndef __BIG_ENDIAN__ | ||
1015 | mat->Specular=os::Byteswap::byteswap(mat->Specular); | ||
1016 | #endif | ||
1017 | size -= 4; | ||
1018 | } | ||
1019 | break; | ||
1020 | case charsToUIntD('R','E','F','L'): | ||
1021 | #ifdef LWO_READER_DEBUG | ||
1022 | os::Printer::log("LWO loader: loading reflection."); | ||
1023 | #endif | ||
1024 | { | ||
1025 | if (FormatVersion==2) | ||
1026 | { | ||
1027 | File->read(&mat->Reflection, 4); | ||
1028 | #ifndef __BIG_ENDIAN__ | ||
1029 | mat->Reflection=os::Byteswap::byteswap(mat->Reflection); | ||
1030 | #endif | ||
1031 | size -= 4; | ||
1032 | subsize -= 4; | ||
1033 | size -= readVX(mat->Envelope[4]); | ||
1034 | } | ||
1035 | else | ||
1036 | { | ||
1037 | File->read(&tmp16, 2); | ||
1038 | #ifndef __BIG_ENDIAN__ | ||
1039 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1040 | #endif | ||
1041 | mat->Reflection=tmp16/256.0f; | ||
1042 | size -= 2; | ||
1043 | subsize -= 2; | ||
1044 | } | ||
1045 | } | ||
1046 | break; | ||
1047 | case charsToUIntD('V','R','F','L'): | ||
1048 | #ifdef LWO_READER_DEBUG | ||
1049 | os::Printer::log("LWO loader: loading reflection."); | ||
1050 | #endif | ||
1051 | { | ||
1052 | File->read(&mat->Reflection, 4); | ||
1053 | #ifndef __BIG_ENDIAN__ | ||
1054 | mat->Reflection=os::Byteswap::byteswap(mat->Reflection); | ||
1055 | #endif | ||
1056 | size -= 4; | ||
1057 | } | ||
1058 | break; | ||
1059 | case charsToUIntD('T','R','A','N'): | ||
1060 | { | ||
1061 | if (FormatVersion==2) | ||
1062 | { | ||
1063 | File->read(&mat->Transparency, 4); | ||
1064 | #ifndef __BIG_ENDIAN__ | ||
1065 | mat->Transparency=os::Byteswap::byteswap(mat->Transparency); | ||
1066 | #endif | ||
1067 | size -= 4; | ||
1068 | subsize -= 4; | ||
1069 | size -= readVX(mat->Envelope[5]); | ||
1070 | } | ||
1071 | else | ||
1072 | { | ||
1073 | File->read(&tmp16, 2); | ||
1074 | #ifndef __BIG_ENDIAN__ | ||
1075 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1076 | #endif | ||
1077 | mat->Transparency=tmp16/256.0f; | ||
1078 | size -= 2; | ||
1079 | subsize -= 2; | ||
1080 | } | ||
1081 | #ifdef LWO_READER_DEBUG | ||
1082 | os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); | ||
1083 | #endif | ||
1084 | } | ||
1085 | break; | ||
1086 | case charsToUIntD('V','T','R','N'): | ||
1087 | { | ||
1088 | File->read(&mat->Transparency, 4); | ||
1089 | #ifndef __BIG_ENDIAN__ | ||
1090 | mat->Transparency=os::Byteswap::byteswap(mat->Transparency); | ||
1091 | #endif | ||
1092 | size -= 4; | ||
1093 | } | ||
1094 | #ifdef LWO_READER_DEBUG | ||
1095 | os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); | ||
1096 | #endif | ||
1097 | break; | ||
1098 | case charsToUIntD('T','R','N','L'): | ||
1099 | #ifdef LWO_READER_DEBUG | ||
1100 | os::Printer::log("LWO loader: loading translucency."); | ||
1101 | #endif | ||
1102 | { | ||
1103 | File->read(&mat->Translucency, 4); | ||
1104 | #ifndef __BIG_ENDIAN__ | ||
1105 | mat->Translucency=os::Byteswap::byteswap(mat->Translucency); | ||
1106 | #endif | ||
1107 | size -= 4; | ||
1108 | subsize -= 4; | ||
1109 | if (FormatVersion==2) | ||
1110 | size -= readVX(mat->Envelope[6]); | ||
1111 | } | ||
1112 | break; | ||
1113 | case charsToUIntD('G','L','O','S'): | ||
1114 | #ifdef LWO_READER_DEBUG | ||
1115 | os::Printer::log("LWO loader: loading glossy."); | ||
1116 | #endif | ||
1117 | { | ||
1118 | if (FormatVersion == 2) | ||
1119 | { | ||
1120 | File->read(&irrMat.Shininess, 4); | ||
1121 | #ifndef __BIG_ENDIAN__ | ||
1122 | irrMat.Shininess=os::Byteswap::byteswap(irrMat.Shininess); | ||
1123 | #endif | ||
1124 | size -= 4; | ||
1125 | subsize -= 4; | ||
1126 | size -= readVX(mat->Envelope[7]); | ||
1127 | } | ||
1128 | else | ||
1129 | { | ||
1130 | File->read(&tmp16, 2); | ||
1131 | #ifndef __BIG_ENDIAN__ | ||
1132 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1133 | #endif | ||
1134 | irrMat.Shininess=tmp16/16.f; | ||
1135 | size -= 2; | ||
1136 | subsize -= 2; | ||
1137 | } | ||
1138 | } | ||
1139 | break; | ||
1140 | case charsToUIntD('S','H','R','P'): | ||
1141 | #ifdef LWO_READER_DEBUG | ||
1142 | os::Printer::log("LWO loader: loading sharpness."); | ||
1143 | #endif | ||
1144 | { | ||
1145 | File->read(&mat->Sharpness, 4); | ||
1146 | #ifndef __BIG_ENDIAN__ | ||
1147 | mat->Sharpness=os::Byteswap::byteswap(mat->Sharpness); | ||
1148 | #endif | ||
1149 | size -= 4; | ||
1150 | subsize -= 4; | ||
1151 | if (FormatVersion==2) | ||
1152 | size -= readVX(mat->Envelope[8]); | ||
1153 | } | ||
1154 | break; | ||
1155 | case charsToUIntD('B','U','M','P'): | ||
1156 | case charsToUIntD('T','A','M','P'): | ||
1157 | #ifdef LWO_READER_DEBUG | ||
1158 | os::Printer::log("LWO loader: loading bumpiness."); | ||
1159 | #endif | ||
1160 | { | ||
1161 | File->read(&tmpf32, 4); | ||
1162 | #ifndef __BIG_ENDIAN__ | ||
1163 | tmpf32=os::Byteswap::byteswap(tmpf32); | ||
1164 | #endif | ||
1165 | if (currTexture==6) | ||
1166 | irrMat.MaterialTypeParam=tmpf32; | ||
1167 | size -= 4; | ||
1168 | subsize -= 4; | ||
1169 | if (FormatVersion==2) | ||
1170 | size -= readVX(mat->Envelope[9]); | ||
1171 | } | ||
1172 | break; | ||
1173 | case charsToUIntD('S','I','D','E'): | ||
1174 | #ifdef LWO_READER_DEBUG | ||
1175 | os::Printer::log("LWO loader: loading backface culled."); | ||
1176 | #endif | ||
1177 | { | ||
1178 | File->read(&tmp16, 2); | ||
1179 | #ifndef __BIG_ENDIAN__ | ||
1180 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1181 | #endif | ||
1182 | if (tmp16==1) | ||
1183 | irrMat.BackfaceCulling=true; | ||
1184 | else if (tmp16==3) | ||
1185 | irrMat.BackfaceCulling=false; | ||
1186 | size -= 2; | ||
1187 | } | ||
1188 | break; | ||
1189 | case charsToUIntD('S','M','A','N'): | ||
1190 | #ifdef LWO_READER_DEBUG | ||
1191 | os::Printer::log("LWO loader: loading smoothing angle."); | ||
1192 | #endif | ||
1193 | { | ||
1194 | File->read(&mat->SmoothingAngle, 4); | ||
1195 | #ifndef __BIG_ENDIAN__ | ||
1196 | mat->SmoothingAngle=os::Byteswap::byteswap(mat->SmoothingAngle); | ||
1197 | #endif | ||
1198 | size -= 4; | ||
1199 | } | ||
1200 | break; | ||
1201 | case charsToUIntD('R','F','O','P'): | ||
1202 | case charsToUIntD('R','F','L','T'): | ||
1203 | #ifdef LWO_READER_DEBUG | ||
1204 | os::Printer::log("LWO loader: loading reflection mode."); | ||
1205 | #endif | ||
1206 | { | ||
1207 | File->read(&mat->ReflMode, 2); | ||
1208 | #ifndef __BIG_ENDIAN__ | ||
1209 | mat->ReflMode=os::Byteswap::byteswap(mat->ReflMode); | ||
1210 | #endif | ||
1211 | size -= 2; | ||
1212 | } | ||
1213 | break; | ||
1214 | case charsToUIntD('R','I','M','G'): | ||
1215 | #ifdef LWO_READER_DEBUG | ||
1216 | os::Printer::log("LWO loader: loading reflection map."); | ||
1217 | #endif | ||
1218 | { | ||
1219 | if (FormatVersion==2) | ||
1220 | { | ||
1221 | size -= readVX(tmp32); | ||
1222 | if (tmp32) | ||
1223 | mat->ReflMap=Images[tmp32-1]; | ||
1224 | } | ||
1225 | else | ||
1226 | size -= readString(mat->ReflMap, size); | ||
1227 | } | ||
1228 | break; | ||
1229 | case charsToUIntD('R','S','A','N'): | ||
1230 | #ifdef LWO_READER_DEBUG | ||
1231 | os::Printer::log("LWO loader: loading reflection seam angle."); | ||
1232 | #endif | ||
1233 | { | ||
1234 | File->read(&mat->ReflSeamAngle, 4); | ||
1235 | #ifndef __BIG_ENDIAN__ | ||
1236 | mat->ReflSeamAngle=os::Byteswap::byteswap(mat->ReflSeamAngle); | ||
1237 | #endif | ||
1238 | size -= 4; | ||
1239 | if (FormatVersion==2) | ||
1240 | size -= readVX(mat->Envelope[10]); | ||
1241 | } | ||
1242 | break; | ||
1243 | case charsToUIntD('R','B','L','R'): | ||
1244 | #ifdef LWO_READER_DEBUG | ||
1245 | os::Printer::log("LWO loader: loading reflection blur."); | ||
1246 | #endif | ||
1247 | { | ||
1248 | File->read(&mat->ReflBlur, 4); | ||
1249 | #ifndef __BIG_ENDIAN__ | ||
1250 | mat->ReflBlur=os::Byteswap::byteswap(mat->ReflBlur); | ||
1251 | #endif | ||
1252 | size -= 4; | ||
1253 | if (FormatVersion==2) | ||
1254 | size -= readVX(mat->Envelope[11]); | ||
1255 | } | ||
1256 | break; | ||
1257 | case charsToUIntD('R','I','N','D'): | ||
1258 | #ifdef LWO_READER_DEBUG | ||
1259 | os::Printer::log("LWO loader: loading refraction index."); | ||
1260 | #endif | ||
1261 | { | ||
1262 | File->read(&mat->RefrIndex, 4); | ||
1263 | #ifndef __BIG_ENDIAN__ | ||
1264 | mat->RefrIndex=os::Byteswap::byteswap(mat->RefrIndex); | ||
1265 | #endif | ||
1266 | size -= 4; | ||
1267 | subsize -= 4; | ||
1268 | if (FormatVersion==2) | ||
1269 | size -= readVX(mat->Envelope[12]); | ||
1270 | } | ||
1271 | break; | ||
1272 | case charsToUIntD('T','R','O','P'): | ||
1273 | #ifdef LWO_READER_DEBUG | ||
1274 | os::Printer::log("LWO loader: loading refraction options."); | ||
1275 | #endif | ||
1276 | { | ||
1277 | File->read(&mat->TranspMode, 2); | ||
1278 | #ifndef __BIG_ENDIAN__ | ||
1279 | mat->TranspMode=os::Byteswap::byteswap(mat->TranspMode); | ||
1280 | #endif | ||
1281 | size -= 2; | ||
1282 | } | ||
1283 | break; | ||
1284 | case charsToUIntD('T','I','M','G'): | ||
1285 | { | ||
1286 | if (FormatVersion==2) | ||
1287 | { | ||
1288 | #ifdef LWO_READER_DEBUG | ||
1289 | os::Printer::log("LWO loader: loading refraction map."); | ||
1290 | #endif | ||
1291 | size -= readVX(tmp32); | ||
1292 | #ifndef __BIG_ENDIAN__ | ||
1293 | tmp32=os::Byteswap::byteswap(tmp32); | ||
1294 | #endif | ||
1295 | if (tmp32) | ||
1296 | mat->Texture[currTexture].Map=Images[tmp32-1]; | ||
1297 | } | ||
1298 | else | ||
1299 | { | ||
1300 | size -= readString(mat->Texture[currTexture].Map, size); | ||
1301 | #ifdef LWO_READER_DEBUG | ||
1302 | os::Printer::log("LWO loader: loading image", mat->Texture[currTexture].Map.c_str()); | ||
1303 | #endif | ||
1304 | } | ||
1305 | } | ||
1306 | break; | ||
1307 | case charsToUIntD('T','B','L','R'): | ||
1308 | #ifdef LWO_READER_DEBUG | ||
1309 | os::Printer::log("LWO loader: loading transparency blur."); | ||
1310 | #endif | ||
1311 | { | ||
1312 | File->read(&mat->TranspBlur, 4); | ||
1313 | #ifndef __BIG_ENDIAN__ | ||
1314 | mat->TranspBlur=os::Byteswap::byteswap(mat->TranspBlur); | ||
1315 | #endif | ||
1316 | size -= 4; | ||
1317 | if (FormatVersion==2) | ||
1318 | size -= readVX(mat->Envelope[13]); | ||
1319 | } | ||
1320 | break; | ||
1321 | case charsToUIntD('C','L','R','H'): | ||
1322 | #ifdef LWO_READER_DEBUG | ||
1323 | os::Printer::log("LWO loader: loading highlight color."); | ||
1324 | #endif | ||
1325 | { | ||
1326 | File->read(&mat->HighlightColor, 4); | ||
1327 | #ifndef __BIG_ENDIAN__ | ||
1328 | mat->HighlightColor=os::Byteswap::byteswap(mat->HighlightColor); | ||
1329 | #endif | ||
1330 | size -= 4; | ||
1331 | if (FormatVersion==2) | ||
1332 | size -= readVX(mat->Envelope[14]); | ||
1333 | } | ||
1334 | break; | ||
1335 | case charsToUIntD('C','L','R','F'): | ||
1336 | #ifdef LWO_READER_DEBUG | ||
1337 | os::Printer::log("LWO loader: loading color filter."); | ||
1338 | #endif | ||
1339 | { | ||
1340 | File->read(&mat->ColorFilter, 4); | ||
1341 | #ifndef __BIG_ENDIAN__ | ||
1342 | mat->ColorFilter=os::Byteswap::byteswap(mat->ColorFilter); | ||
1343 | #endif | ||
1344 | size -= 4; | ||
1345 | if (FormatVersion==2) | ||
1346 | size -= readVX(mat->Envelope[15]); | ||
1347 | } | ||
1348 | break; | ||
1349 | case charsToUIntD('A','D','T','R'): | ||
1350 | #ifdef LWO_READER_DEBUG | ||
1351 | os::Printer::log("LWO loader: loading additive transparency."); | ||
1352 | #endif | ||
1353 | { | ||
1354 | File->read(&mat->AdditiveTransparency, 4); | ||
1355 | #ifndef __BIG_ENDIAN__ | ||
1356 | mat->AdditiveTransparency=os::Byteswap::byteswap(mat->AdditiveTransparency); | ||
1357 | #endif | ||
1358 | size -= 4; | ||
1359 | if (FormatVersion==2) | ||
1360 | size -= readVX(mat->Envelope[16]); | ||
1361 | } | ||
1362 | break; | ||
1363 | case charsToUIntD('G','L','O','W'): | ||
1364 | #ifdef LWO_READER_DEBUG | ||
1365 | os::Printer::log("LWO loader: loading glow."); | ||
1366 | #endif | ||
1367 | { | ||
1368 | if (FormatVersion==0) | ||
1369 | { | ||
1370 | File->read(&mat->GlowIntensity, 4); | ||
1371 | #ifndef __BIG_ENDIAN__ | ||
1372 | mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); | ||
1373 | #endif | ||
1374 | size -= 4; | ||
1375 | } | ||
1376 | else | ||
1377 | { | ||
1378 | File->read(&mat->Glow, 2); | ||
1379 | #ifndef __BIG_ENDIAN__ | ||
1380 | mat->Glow=os::Byteswap::byteswap(mat->Glow); | ||
1381 | #endif | ||
1382 | size -= 2; | ||
1383 | File->read(&mat->GlowIntensity, 4); | ||
1384 | #ifndef __BIG_ENDIAN__ | ||
1385 | mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); | ||
1386 | #endif | ||
1387 | size -= 4; | ||
1388 | if (FormatVersion==2) | ||
1389 | size -= readVX(mat->Envelope[17]); | ||
1390 | File->read(&mat->GlowSize, 4); | ||
1391 | #ifndef __BIG_ENDIAN__ | ||
1392 | mat->GlowSize=os::Byteswap::byteswap(mat->GlowSize); | ||
1393 | #endif | ||
1394 | size -= 4; | ||
1395 | if (FormatVersion==2) | ||
1396 | size -= readVX(mat->Envelope[18]); | ||
1397 | } | ||
1398 | } | ||
1399 | break; | ||
1400 | case charsToUIntD('G','V','A','L'): | ||
1401 | #ifdef LWO_READER_DEBUG | ||
1402 | os::Printer::log("LWO loader: loading glow intensity."); | ||
1403 | #endif | ||
1404 | { | ||
1405 | File->read(&mat->GlowIntensity, 4); | ||
1406 | #ifndef __BIG_ENDIAN__ | ||
1407 | mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); | ||
1408 | #endif | ||
1409 | size -= 4; | ||
1410 | if (FormatVersion==2) | ||
1411 | size -= readVX(mat->Envelope[17]); | ||
1412 | } | ||
1413 | break; | ||
1414 | case charsToUIntD('L','I','N','E'): | ||
1415 | #ifdef LWO_READER_DEBUG | ||
1416 | os::Printer::log("LWO loader: loading isWireframe."); | ||
1417 | #endif | ||
1418 | { | ||
1419 | File->read(&tmp16, 2); | ||
1420 | #ifndef __BIG_ENDIAN__ | ||
1421 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1422 | #endif | ||
1423 | if (tmp16&1) | ||
1424 | irrMat.Wireframe=true; | ||
1425 | size -= 2; | ||
1426 | if (size!=0) | ||
1427 | { | ||
1428 | File->read(&irrMat.Thickness, 4); | ||
1429 | #ifndef __BIG_ENDIAN__ | ||
1430 | irrMat.Thickness=os::Byteswap::byteswap(irrMat.Thickness); | ||
1431 | #endif | ||
1432 | size -= 4; | ||
1433 | if (FormatVersion==2) | ||
1434 | size -= readVX(mat->Envelope[19]); | ||
1435 | } | ||
1436 | if (size!=0) | ||
1437 | { | ||
1438 | video::SColor lineColor; | ||
1439 | size -= readColor(lineColor); | ||
1440 | if (FormatVersion==2) | ||
1441 | size -= readVX(mat->Envelope[20]); | ||
1442 | } | ||
1443 | } | ||
1444 | break; | ||
1445 | case charsToUIntD('A','L','P','H'): | ||
1446 | #ifdef LWO_READER_DEBUG | ||
1447 | os::Printer::log("LWO loader: loading alpha mode."); | ||
1448 | #endif | ||
1449 | { | ||
1450 | File->read(&mat->AlphaMode, 2); | ||
1451 | #ifndef __BIG_ENDIAN__ | ||
1452 | mat->AlphaMode=os::Byteswap::byteswap(mat->AlphaMode); | ||
1453 | #endif | ||
1454 | size -= 2; | ||
1455 | File->read(&mat->AlphaValue, 4); | ||
1456 | #ifndef __BIG_ENDIAN__ | ||
1457 | mat->AlphaValue=os::Byteswap::byteswap(mat->AlphaValue); | ||
1458 | #endif | ||
1459 | size -= 4; | ||
1460 | } | ||
1461 | break; | ||
1462 | case charsToUIntD('V','C','O','L'): | ||
1463 | #ifdef LWO_READER_DEBUG | ||
1464 | os::Printer::log("LWO loader: loading vertex color."); | ||
1465 | #endif | ||
1466 | { | ||
1467 | File->read(&mat->VertexColorIntensity, 4); | ||
1468 | #ifndef __BIG_ENDIAN__ | ||
1469 | mat->VertexColorIntensity=os::Byteswap::byteswap(mat->VertexColorIntensity); | ||
1470 | #endif | ||
1471 | size -= 4; | ||
1472 | if (FormatVersion==2) | ||
1473 | size -= readVX(mat->Envelope[21]); | ||
1474 | File->read(&tmp32, 4); // skip type | ||
1475 | size -= 4; | ||
1476 | core::stringc tmpname; | ||
1477 | size -= readString(tmpname, size); | ||
1478 | // mat->VertexColor = getColorVMAP(tmpname); | ||
1479 | } | ||
1480 | break; | ||
1481 | case charsToUIntD('F','L','A','G'): | ||
1482 | #ifdef LWO_READER_DEBUG | ||
1483 | os::Printer::log("LWO loader: loading flag."); | ||
1484 | #endif | ||
1485 | { | ||
1486 | File->read(&mat->Flags, 2); | ||
1487 | #ifndef __BIG_ENDIAN__ | ||
1488 | mat->Flags=os::Byteswap::byteswap(mat->Flags); | ||
1489 | #endif | ||
1490 | if (mat->Flags&1) | ||
1491 | mat->Luminance=1.0f; | ||
1492 | if (mat->Flags&256) | ||
1493 | irrMat.BackfaceCulling=false; | ||
1494 | size -= 2; | ||
1495 | } | ||
1496 | break; | ||
1497 | case charsToUIntD('E','D','G','E'): | ||
1498 | #ifdef LWO_READER_DEBUG | ||
1499 | os::Printer::log("LWO loader: loading edge."); | ||
1500 | #endif | ||
1501 | { | ||
1502 | File->read(&mat->EdgeTransparency, 4); | ||
1503 | #ifndef __BIG_ENDIAN__ | ||
1504 | mat->EdgeTransparency=os::Byteswap::byteswap(mat->EdgeTransparency); | ||
1505 | #endif | ||
1506 | size -= 4; | ||
1507 | } | ||
1508 | break; | ||
1509 | case charsToUIntD('C','T','E','X'): | ||
1510 | #ifdef LWO_READER_DEBUG | ||
1511 | os::Printer::log("LWO loader: loading ctex."); | ||
1512 | #endif | ||
1513 | currTexture=0; | ||
1514 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1515 | break; | ||
1516 | case charsToUIntD('D','T','E','X'): | ||
1517 | #ifdef LWO_READER_DEBUG | ||
1518 | os::Printer::log("LWO loader: loading dtex."); | ||
1519 | #endif | ||
1520 | currTexture=1; | ||
1521 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1522 | break; | ||
1523 | case charsToUIntD('S','T','E','X'): | ||
1524 | #ifdef LWO_READER_DEBUG | ||
1525 | os::Printer::log("LWO loader: loading stex."); | ||
1526 | #endif | ||
1527 | currTexture=2; | ||
1528 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1529 | break; | ||
1530 | case charsToUIntD('R','T','E','X'): | ||
1531 | #ifdef LWO_READER_DEBUG | ||
1532 | os::Printer::log("LWO loader: loading rtex."); | ||
1533 | #endif | ||
1534 | currTexture=3; | ||
1535 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1536 | break; | ||
1537 | case charsToUIntD('T','T','E','X'): | ||
1538 | #ifdef LWO_READER_DEBUG | ||
1539 | os::Printer::log("LWO loader: loading ttex."); | ||
1540 | #endif | ||
1541 | currTexture=4; | ||
1542 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1543 | break; | ||
1544 | case charsToUIntD('L','T','E','X'): | ||
1545 | #ifdef LWO_READER_DEBUG | ||
1546 | os::Printer::log("LWO loader: loading ltex."); | ||
1547 | #endif | ||
1548 | currTexture=5; | ||
1549 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1550 | break; | ||
1551 | case charsToUIntD('B','T','E','X'): | ||
1552 | #ifdef LWO_READER_DEBUG | ||
1553 | os::Printer::log("LWO loader: loading btex."); | ||
1554 | #endif | ||
1555 | currTexture=6; | ||
1556 | size -= readString(mat->Texture[currTexture].Type, size); | ||
1557 | break; | ||
1558 | case charsToUIntD('T','A','L','P'): | ||
1559 | #ifdef LWO_READER_DEBUG | ||
1560 | os::Printer::log("LWO loader: loading alpha map."); | ||
1561 | #endif | ||
1562 | size -= readString(mat->Texture[currTexture].AlphaMap, size); | ||
1563 | break; | ||
1564 | case charsToUIntD('T','F','L','G'): | ||
1565 | #ifdef LWO_READER_DEBUG | ||
1566 | os::Printer::log("LWO loader: loading texture flag."); | ||
1567 | #endif | ||
1568 | { | ||
1569 | File->read(&mat->Texture[currTexture].Flags, 2); | ||
1570 | #ifndef __BIG_ENDIAN__ | ||
1571 | mat->Texture[currTexture].Flags=os::Byteswap::byteswap(mat->Texture[currTexture].Flags); | ||
1572 | #endif | ||
1573 | size -= 2; | ||
1574 | } | ||
1575 | break; | ||
1576 | case charsToUIntD('E','N','A','B'): | ||
1577 | #ifdef LWO_READER_DEBUG | ||
1578 | os::Printer::log("LWO loader: loading isEnabled."); | ||
1579 | #endif | ||
1580 | { | ||
1581 | File->read(&tmp16, 2); | ||
1582 | #ifndef __BIG_ENDIAN__ | ||
1583 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1584 | #endif | ||
1585 | mat->Texture[currTexture].Active=(tmp16!=0); | ||
1586 | size -= 2; | ||
1587 | } | ||
1588 | break; | ||
1589 | case charsToUIntD('W','R','A','P'): | ||
1590 | case charsToUIntD('T','W','R','P'): | ||
1591 | #ifdef LWO_READER_DEBUG | ||
1592 | os::Printer::log("LWO loader: loading texture wrap."); | ||
1593 | #endif | ||
1594 | { | ||
1595 | File->read(&mat->Texture[currTexture].WidthWrap, 2); | ||
1596 | #ifndef __BIG_ENDIAN__ | ||
1597 | mat->Texture[currTexture].WidthWrap=os::Byteswap::byteswap(mat->Texture[currTexture].WidthWrap); | ||
1598 | #endif | ||
1599 | File->read(&mat->Texture[currTexture].HeightWrap, 2); | ||
1600 | #ifndef __BIG_ENDIAN__ | ||
1601 | mat->Texture[currTexture].HeightWrap=os::Byteswap::byteswap(mat->Texture[currTexture].HeightWrap); | ||
1602 | #endif | ||
1603 | size -= 4; | ||
1604 | } | ||
1605 | break; | ||
1606 | case charsToUIntD('T','V','E','L'): | ||
1607 | #ifdef LWO_READER_DEBUG | ||
1608 | os::Printer::log("LWO loader: loading texture velocity."); | ||
1609 | #endif | ||
1610 | size -= readVec(mat->Texture[currTexture].Velocity); | ||
1611 | break; | ||
1612 | case charsToUIntD('T','C','L','R'): | ||
1613 | #ifdef LWO_READER_DEBUG | ||
1614 | os::Printer::log("LWO loader: loading texture color."); | ||
1615 | #endif | ||
1616 | size -= readColor(mat->Texture[currTexture].Color); | ||
1617 | break; | ||
1618 | case charsToUIntD('A','A','S','T'): | ||
1619 | case charsToUIntD('T','A','A','S'): | ||
1620 | #ifdef LWO_READER_DEBUG | ||
1621 | os::Printer::log("LWO loader: loading texture antialias."); | ||
1622 | #endif | ||
1623 | { | ||
1624 | tmp16=0; | ||
1625 | if (FormatVersion==2) | ||
1626 | { | ||
1627 | File->read(&tmp16, 2); | ||
1628 | #ifndef __BIG_ENDIAN__ | ||
1629 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1630 | #endif | ||
1631 | size -= 2; | ||
1632 | } | ||
1633 | File->read(&mat->Texture[currTexture].AntiAliasing, 4); | ||
1634 | #ifndef __BIG_ENDIAN__ | ||
1635 | mat->Texture[currTexture].AntiAliasing=os::Byteswap::byteswap(mat->Texture[currTexture].AntiAliasing); | ||
1636 | #endif | ||
1637 | if (tmp16 & ~0x01) | ||
1638 | mat->Texture[currTexture].AntiAliasing=0.0f; // disabled | ||
1639 | size -= 4; | ||
1640 | } | ||
1641 | break; | ||
1642 | case charsToUIntD('T','O','P','C'): | ||
1643 | #ifdef LWO_READER_DEBUG | ||
1644 | os::Printer::log("LWO loader: loading texture opacity."); | ||
1645 | #endif | ||
1646 | { | ||
1647 | File->read(&mat->Texture[currTexture].Opacity, 4); | ||
1648 | #ifndef __BIG_ENDIAN__ | ||
1649 | mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); | ||
1650 | #endif | ||
1651 | size -= 4; | ||
1652 | } | ||
1653 | break; | ||
1654 | case charsToUIntD('O','P','A','C'): | ||
1655 | { | ||
1656 | #ifdef LWO_READER_DEBUG | ||
1657 | os::Printer::log("LWO loader: loading texture opacity and type."); | ||
1658 | #endif | ||
1659 | File->read(&mat->Texture[currTexture].OpacType, 2); | ||
1660 | #ifndef __BIG_ENDIAN__ | ||
1661 | mat->Texture[currTexture].OpacType=os::Byteswap::byteswap(mat->Texture[currTexture].OpacType); | ||
1662 | #endif | ||
1663 | File->read(&mat->Texture[currTexture].Opacity, 4); | ||
1664 | #ifndef __BIG_ENDIAN__ | ||
1665 | mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); | ||
1666 | #endif | ||
1667 | size -= 6; | ||
1668 | subsize -= 6; | ||
1669 | if (FormatVersion==2) | ||
1670 | size -= readVX(mat->Envelope[22]); | ||
1671 | } | ||
1672 | break; | ||
1673 | case charsToUIntD('A','X','I','S'): | ||
1674 | { | ||
1675 | File->read(&tmp16, 2); | ||
1676 | #ifndef __BIG_ENDIAN__ | ||
1677 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1678 | #endif | ||
1679 | mat->Texture[currTexture].Axis=(u8)tmp16; | ||
1680 | size -= 2; | ||
1681 | #ifdef LWO_READER_DEBUG | ||
1682 | os::Printer::log("LWO loader: loading axis value", core::stringc(tmp16).c_str()); | ||
1683 | #endif | ||
1684 | } | ||
1685 | break; | ||
1686 | case charsToUIntD('T','M','A','P'): // empty separation chunk | ||
1687 | break; | ||
1688 | case charsToUIntD('T','C','T','R'): | ||
1689 | case charsToUIntD('C','N','T','R'): | ||
1690 | { | ||
1691 | core::vector3df& center=mat->Texture[currTexture].Center; | ||
1692 | size -= readVec(center); | ||
1693 | if (FormatVersion==2) | ||
1694 | size -= readVX(mat->Envelope[22]); | ||
1695 | #ifdef LWO_READER_DEBUG | ||
1696 | os::Printer::log("LWO loader: loading texture center", (core::stringc(center.X)+" "+core::stringc(center.Y)+" "+core::stringc(center.Z)).c_str()); | ||
1697 | #endif | ||
1698 | } | ||
1699 | break; | ||
1700 | case charsToUIntD('T','S','I','Z'): | ||
1701 | case charsToUIntD('S','I','Z','E'): | ||
1702 | { | ||
1703 | core::vector3df& tsize=mat->Texture[currTexture].Size; | ||
1704 | size -= readVec(tsize); | ||
1705 | if (FormatVersion==2) | ||
1706 | size -= readVX(mat->Envelope[22]); | ||
1707 | #ifdef LWO_READER_DEBUG | ||
1708 | os::Printer::log("LWO loader: loading texture size", (core::stringc(tsize.X)+" "+core::stringc(tsize.Y)+" "+core::stringc(tsize.Z)).c_str()); | ||
1709 | #endif | ||
1710 | } | ||
1711 | break; | ||
1712 | case charsToUIntD('R','O','T','A'): | ||
1713 | { | ||
1714 | core::vector3df rotation; | ||
1715 | size -= readVec(rotation); | ||
1716 | if (FormatVersion==2) | ||
1717 | size -= readVX(mat->Envelope[22]); | ||
1718 | #ifdef LWO_READER_DEBUG | ||
1719 | os::Printer::log("LWO loader: loading texture rotation", (core::stringc(rotation.X)+" "+core::stringc(rotation.Y)+" "+core::stringc(rotation.Z)).c_str()); | ||
1720 | #endif | ||
1721 | } | ||
1722 | break; | ||
1723 | case charsToUIntD('O','R','E','F'): | ||
1724 | { | ||
1725 | core::stringc tmpname; | ||
1726 | size -= readString(tmpname); | ||
1727 | #ifdef LWO_READER_DEBUG | ||
1728 | os::Printer::log("LWO loader: texture reference object", tmpname.c_str()); | ||
1729 | #endif | ||
1730 | } | ||
1731 | break; | ||
1732 | case charsToUIntD('T','F','A','L'): | ||
1733 | case charsToUIntD('F','A','L','L'): | ||
1734 | { | ||
1735 | if (FormatVersion==2) | ||
1736 | { | ||
1737 | u16 tmp16; | ||
1738 | File->read(&tmp16, 2); | ||
1739 | size -= 2; | ||
1740 | #ifndef __BIG_ENDIAN__ | ||
1741 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1742 | #endif | ||
1743 | } | ||
1744 | |||
1745 | core::vector3df& falloff=mat->Texture[currTexture].Falloff; | ||
1746 | size -= readVec(falloff); | ||
1747 | if (FormatVersion==2) | ||
1748 | size -= readVX(mat->Envelope[22]); | ||
1749 | #ifdef LWO_READER_DEBUG | ||
1750 | os::Printer::log("LWO loader: loading texture falloff"); | ||
1751 | #endif | ||
1752 | } | ||
1753 | break; | ||
1754 | case charsToUIntD('C','S','Y','S'): | ||
1755 | { | ||
1756 | u16 tmp16; | ||
1757 | File->read(&tmp16, 2); | ||
1758 | size -= 2; | ||
1759 | #ifndef __BIG_ENDIAN__ | ||
1760 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1761 | #endif | ||
1762 | #ifdef LWO_READER_DEBUG | ||
1763 | os::Printer::log("LWO loader: texture coordinate system", tmp16==0?"object coords":"world coords"); | ||
1764 | #endif | ||
1765 | } | ||
1766 | break; | ||
1767 | case charsToUIntD('T','V','A','L'): | ||
1768 | #ifdef LWO_READER_DEBUG | ||
1769 | os::Printer::log("LWO loader: loading texture value."); | ||
1770 | #endif | ||
1771 | { | ||
1772 | File->read(&tmp16, 2); | ||
1773 | #ifndef __BIG_ENDIAN__ | ||
1774 | tmp16=os::Byteswap::byteswap(tmp16); | ||
1775 | #endif | ||
1776 | mat->Texture[currTexture].Value=tmp16/256.0f; | ||
1777 | size -= 2; | ||
1778 | } | ||
1779 | break; | ||
1780 | case charsToUIntD('T','F','P','0'): | ||
1781 | case charsToUIntD('T','S','P','0'): | ||
1782 | #ifdef LWO_READER_DEBUG | ||
1783 | os::Printer::log("LWO loader: loading texture param 0."); | ||
1784 | #endif | ||
1785 | { | ||
1786 | File->read(&mat->Texture[currTexture].FParam[0], 4); | ||
1787 | #ifndef __BIG_ENDIAN__ | ||
1788 | mat->Texture[currTexture].FParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[0]); | ||
1789 | #endif | ||
1790 | size -= 4; | ||
1791 | } | ||
1792 | break; | ||
1793 | case charsToUIntD('T','F','P','1'): | ||
1794 | case charsToUIntD('T','S','P','1'): | ||
1795 | #ifdef LWO_READER_DEBUG | ||
1796 | os::Printer::log("LWO loader: loading texture param 1."); | ||
1797 | #endif | ||
1798 | { | ||
1799 | File->read(&mat->Texture[currTexture].FParam[1], 4); | ||
1800 | #ifndef __BIG_ENDIAN__ | ||
1801 | mat->Texture[currTexture].FParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[1]); | ||
1802 | #endif | ||
1803 | size -= 4; | ||
1804 | } | ||
1805 | break; | ||
1806 | case charsToUIntD('T','F','P','2'): | ||
1807 | case charsToUIntD('T','S','P','2'): | ||
1808 | #ifdef LWO_READER_DEBUG | ||
1809 | os::Printer::log("LWO loader: loading texture param 2."); | ||
1810 | #endif | ||
1811 | { | ||
1812 | File->read(&mat->Texture[currTexture].FParam[2], 4); | ||
1813 | #ifndef __BIG_ENDIAN__ | ||
1814 | mat->Texture[currTexture].FParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[2]); | ||
1815 | #endif | ||
1816 | size -= 4; | ||
1817 | } | ||
1818 | break; | ||
1819 | case charsToUIntD('T','F','R','Q'): | ||
1820 | case charsToUIntD('T','I','P','0'): | ||
1821 | #ifdef LWO_READER_DEBUG | ||
1822 | os::Printer::log("LWO loader: loading texture iparam 0."); | ||
1823 | #endif | ||
1824 | { | ||
1825 | File->read(&mat->Texture[currTexture].IParam[0], 2); | ||
1826 | #ifndef __BIG_ENDIAN__ | ||
1827 | mat->Texture[currTexture].IParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[0]); | ||
1828 | #endif | ||
1829 | size -= 2; | ||
1830 | } | ||
1831 | break; | ||
1832 | case charsToUIntD('T','I','P','1'): | ||
1833 | #ifdef LWO_READER_DEBUG | ||
1834 | os::Printer::log("LWO loader: loading texture param 1."); | ||
1835 | #endif | ||
1836 | { | ||
1837 | File->read(&mat->Texture[currTexture].IParam[1], 2); | ||
1838 | #ifndef __BIG_ENDIAN__ | ||
1839 | mat->Texture[currTexture].IParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[1]); | ||
1840 | #endif | ||
1841 | size -= 2; | ||
1842 | } | ||
1843 | break; | ||
1844 | case charsToUIntD('T','I','P','2'): | ||
1845 | #ifdef LWO_READER_DEBUG | ||
1846 | os::Printer::log("LWO loader: loading texture param 2."); | ||
1847 | #endif | ||
1848 | { | ||
1849 | File->read(&mat->Texture[currTexture].IParam[2], 2); | ||
1850 | #ifndef __BIG_ENDIAN__ | ||
1851 | mat->Texture[currTexture].IParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[2]); | ||
1852 | #endif | ||
1853 | size -= 2; | ||
1854 | } | ||
1855 | break; | ||
1856 | case charsToUIntD('V','M','A','P'): | ||
1857 | { | ||
1858 | size -= readString(mat->Texture[currTexture].UVname); | ||
1859 | #ifdef LWO_READER_DEBUG | ||
1860 | os::Printer::log("LWO loader: loading material vmap binding",mat->Texture[currTexture].UVname.c_str()); | ||
1861 | #endif | ||
1862 | } | ||
1863 | break; | ||
1864 | case charsToUIntD('B','L','O','K'): | ||
1865 | #ifdef LWO_READER_DEBUG | ||
1866 | os::Printer::log("LWO loader: loading blok."); | ||
1867 | #endif | ||
1868 | { | ||
1869 | core::stringc ordinal; | ||
1870 | File->read(&type, 4); | ||
1871 | File->read(&subsize, 2); | ||
1872 | #ifndef __BIG_ENDIAN__ | ||
1873 | subsize=os::Byteswap::byteswap(subsize); | ||
1874 | #endif | ||
1875 | size -= 6; | ||
1876 | size -= readString(ordinal, size); | ||
1877 | } | ||
1878 | break; | ||
1879 | case charsToUIntD('C','H','A','N'): | ||
1880 | { | ||
1881 | File->read(&type, 4); | ||
1882 | size -= 4; | ||
1883 | if (!strncmp(type, "COLR", 4)) | ||
1884 | currTexture=0; | ||
1885 | else if (!strncmp(type, "DIFF", 4)) | ||
1886 | currTexture=1; | ||
1887 | else if (!strncmp(type, "LUMI", 4)) | ||
1888 | currTexture=5; | ||
1889 | else if (!strncmp(type, "SPEC", 4)) | ||
1890 | currTexture=2; | ||
1891 | else if (!strncmp(type, "REFL", 4)) | ||
1892 | currTexture=3; | ||
1893 | else if (!strncmp(type, "TRAN", 4)) | ||
1894 | currTexture=4; | ||
1895 | else if (!strncmp(type, "BUMP", 4)) | ||
1896 | currTexture=6; | ||
1897 | } | ||
1898 | #ifdef LWO_READER_DEBUG | ||
1899 | os::Printer::log("LWO loader: loading channel ", type); | ||
1900 | #endif | ||
1901 | break; | ||
1902 | case charsToUIntD('I','M','A','G'): | ||
1903 | #ifdef LWO_READER_DEBUG | ||
1904 | os::Printer::log("LWO loader: loading channel map."); | ||
1905 | #endif | ||
1906 | { | ||
1907 | u16 index; | ||
1908 | File->read(&index, 2); | ||
1909 | #ifndef __BIG_ENDIAN__ | ||
1910 | index=os::Byteswap::byteswap(index); | ||
1911 | #endif | ||
1912 | size -= 2; | ||
1913 | if (index) | ||
1914 | mat->Texture[currTexture].Map=Images[index-1]; | ||
1915 | } | ||
1916 | break; | ||
1917 | case charsToUIntD('P','R','O','J'): // define the projection type | ||
1918 | #ifdef LWO_READER_DEBUG | ||
1919 | os::Printer::log("LWO loader: loading channel projection type."); | ||
1920 | #endif | ||
1921 | { | ||
1922 | u16 index; | ||
1923 | File->read(&index, 2); | ||
1924 | #ifndef __BIG_ENDIAN__ | ||
1925 | index=os::Byteswap::byteswap(index); | ||
1926 | #endif | ||
1927 | size -= 2; | ||
1928 | #ifdef LWO_READER_DEBUG | ||
1929 | if (index != 5) | ||
1930 | os::Printer::log("LWO loader: wrong channel projection type", core::stringc(index).c_str()); | ||
1931 | #endif | ||
1932 | mat->Texture[currTexture].Projection=(u8)index; | ||
1933 | } | ||
1934 | break; | ||
1935 | case charsToUIntD('W','R','P','W'): // for cylindrical and spherical projections | ||
1936 | case charsToUIntD('W','R','P','H'): // for cylindrical and spherical projections | ||
1937 | default: | ||
1938 | { | ||
1939 | #ifdef LWO_READER_DEBUG | ||
1940 | os::Printer::log("LWO loader: skipping ", core::stringc((char*)&uiType, 4)); | ||
1941 | #endif | ||
1942 | File->seek(subsize, true); | ||
1943 | size -= subsize; | ||
1944 | } | ||
1945 | } | ||
1946 | } | ||
1947 | |||
1948 | if (mat->Transparency != 0.f) | ||
1949 | { | ||
1950 | irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; | ||
1951 | } | ||
1952 | } | ||
1953 | |||
1954 | |||
1955 | u32 CLWOMeshFileLoader::readColor(video::SColor& color) | ||
1956 | { | ||
1957 | if (FormatVersion!=2) | ||
1958 | { | ||
1959 | u8 colorComponent; | ||
1960 | File->read(&colorComponent, 1); | ||
1961 | color.setRed(colorComponent); | ||
1962 | File->read(&colorComponent, 1); | ||
1963 | color.setGreen(colorComponent); | ||
1964 | File->read(&colorComponent, 1); | ||
1965 | color.setBlue(colorComponent); | ||
1966 | // unknown value | ||
1967 | File->read(&colorComponent, 1); | ||
1968 | return 4; | ||
1969 | } | ||
1970 | else | ||
1971 | { | ||
1972 | video::SColorf col; | ||
1973 | File->read(&col.r, 4); | ||
1974 | #ifndef __BIG_ENDIAN__ | ||
1975 | col.r=os::Byteswap::byteswap(col.r); | ||
1976 | #endif | ||
1977 | File->read(&col.g, 4); | ||
1978 | #ifndef __BIG_ENDIAN__ | ||
1979 | col.g=os::Byteswap::byteswap(col.g); | ||
1980 | #endif | ||
1981 | File->read(&col.b, 4); | ||
1982 | #ifndef __BIG_ENDIAN__ | ||
1983 | col.b=os::Byteswap::byteswap(col.b); | ||
1984 | #endif | ||
1985 | color=col.toSColor(); | ||
1986 | return 12; | ||
1987 | } | ||
1988 | } | ||
1989 | |||
1990 | u32 CLWOMeshFileLoader::readString(core::stringc& name, u32 size) | ||
1991 | { | ||
1992 | c8 c; | ||
1993 | |||
1994 | name=""; | ||
1995 | if (size) | ||
1996 | name.reserve(size); | ||
1997 | File->read(&c, 1); | ||
1998 | while (c) | ||
1999 | { | ||
2000 | name.append(c); | ||
2001 | File->read(&c, 1); | ||
2002 | } | ||
2003 | // read extra 0 upon odd file position | ||
2004 | if (File->getPos() & 0x1) | ||
2005 | { | ||
2006 | File->read(&c, 1); | ||
2007 | return (name.size()+2); | ||
2008 | } | ||
2009 | return (name.size()+1); | ||
2010 | } | ||
2011 | |||
2012 | |||
2013 | u32 CLWOMeshFileLoader::readVec(core::vector3df& vec) | ||
2014 | { | ||
2015 | File->read(&vec.X, 4); | ||
2016 | #ifndef __BIG_ENDIAN__ | ||
2017 | vec.X=os::Byteswap::byteswap(vec.X); | ||
2018 | #endif | ||
2019 | File->read(&vec.Y, 4); | ||
2020 | #ifndef __BIG_ENDIAN__ | ||
2021 | vec.Y=os::Byteswap::byteswap(vec.Y); | ||
2022 | #endif | ||
2023 | File->read(&vec.Z, 4); | ||
2024 | #ifndef __BIG_ENDIAN__ | ||
2025 | vec.Z=os::Byteswap::byteswap(vec.Z); | ||
2026 | #endif | ||
2027 | return 12; | ||
2028 | } | ||
2029 | |||
2030 | |||
2031 | u32 CLWOMeshFileLoader::readVX(u32& num) | ||
2032 | { | ||
2033 | u16 tmpIndex; | ||
2034 | |||
2035 | File->read(&tmpIndex, 2); | ||
2036 | #ifndef __BIG_ENDIAN__ | ||
2037 | tmpIndex=os::Byteswap::byteswap(tmpIndex); | ||
2038 | #endif | ||
2039 | num=tmpIndex; | ||
2040 | if (num >= 0xFF00) | ||
2041 | { | ||
2042 | File->read(&tmpIndex, 2); | ||
2043 | #ifndef __BIG_ENDIAN__ | ||
2044 | tmpIndex=os::Byteswap::byteswap(tmpIndex); | ||
2045 | #endif | ||
2046 | num=((num << 16)|tmpIndex) & ~0xFF000000; | ||
2047 | return 4; | ||
2048 | } | ||
2049 | return 2; | ||
2050 | } | ||
2051 | |||
2052 | |||
2053 | bool CLWOMeshFileLoader::readFileHeader() | ||
2054 | { | ||
2055 | u32 Id; | ||
2056 | |||
2057 | File->read(&Id, 4); | ||
2058 | #ifndef __BIG_ENDIAN__ | ||
2059 | Id=os::Byteswap::byteswap(Id); | ||
2060 | #endif | ||
2061 | if (Id != 0x464f524d) // FORM | ||
2062 | return false; | ||
2063 | |||
2064 | //skip the file length | ||
2065 | File->read(&Id, 4); | ||
2066 | |||
2067 | File->read(&Id, 4); | ||
2068 | #ifndef __BIG_ENDIAN__ | ||
2069 | Id=os::Byteswap::byteswap(Id); | ||
2070 | #endif | ||
2071 | // Currently supported: LWOB, LWLO, LWO2 | ||
2072 | switch (Id) | ||
2073 | { | ||
2074 | case 0x4c574f42: | ||
2075 | FormatVersion = 0; // LWOB | ||
2076 | break; | ||
2077 | case 0x4c574c4f: | ||
2078 | FormatVersion = 1; // LWLO | ||
2079 | break; | ||
2080 | case 0x4c574f32: | ||
2081 | FormatVersion = 2; // LWO2 | ||
2082 | break; | ||
2083 | default: | ||
2084 | return false; // unsupported | ||
2085 | } | ||
2086 | |||
2087 | return true; | ||
2088 | } | ||
2089 | |||
2090 | |||
2091 | video::ITexture* CLWOMeshFileLoader::loadTexture(const core::stringc& file) | ||
2092 | { | ||
2093 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); | ||
2094 | |||
2095 | if (FileSystem->existFile(file)) | ||
2096 | return driver->getTexture(file); | ||
2097 | |||
2098 | core::stringc strippedName=FileSystem->getFileBasename(file); | ||
2099 | if (FileSystem->existFile(strippedName)) | ||
2100 | return driver->getTexture(strippedName); | ||
2101 | core::stringc newpath = FileSystem->getFileDir(File->getFileName()); | ||
2102 | newpath.append("/"); | ||
2103 | newpath.append(strippedName); | ||
2104 | if (FileSystem->existFile(newpath)) | ||
2105 | return driver->getTexture(newpath); | ||
2106 | os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING); | ||
2107 | |||
2108 | return 0; | ||
2109 | } | ||
2110 | |||
2111 | |||
2112 | } // end namespace scene | ||
2113 | } // end namespace irr | ||
2114 | |||