aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp2792
1 files changed, 1396 insertions, 1396 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp
index cc59c4d..e1f312d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/C3DSMeshFileLoader.cpp
@@ -1,1396 +1,1396 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "IrrCompileConfig.h" 5#include "IrrCompileConfig.h"
6#ifdef _IRR_COMPILE_WITH_3DS_LOADER_ 6#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
7 7
8#include "C3DSMeshFileLoader.h" 8#include "C3DSMeshFileLoader.h"
9#include "os.h" 9#include "os.h"
10#include "SMeshBuffer.h" 10#include "SMeshBuffer.h"
11#include "SAnimatedMesh.h" 11#include "SAnimatedMesh.h"
12#include "IReadFile.h" 12#include "IReadFile.h"
13#include "IVideoDriver.h" 13#include "IVideoDriver.h"
14#include "IMeshManipulator.h" 14#include "IMeshManipulator.h"
15 15
16#ifdef _DEBUG 16#ifdef _DEBUG
17#define _IRR_DEBUG_3DS_LOADER_ 17#define _IRR_DEBUG_3DS_LOADER_
18#endif 18#endif
19 19
20namespace irr 20namespace irr
21{ 21{
22namespace scene 22namespace scene
23{ 23{
24 24
25 25
26namespace 26namespace
27{ 27{
28enum e3DSChunk 28enum e3DSChunk
29{ 29{
30 // Primary chunk 30 // Primary chunk
31 C3DS_MAIN3DS = 0x4D4D, 31 C3DS_MAIN3DS = 0x4D4D,
32 32
33 // Main Chunks 33 // Main Chunks
34 C3DS_EDIT3DS = 0x3D3D, 34 C3DS_EDIT3DS = 0x3D3D,
35 C3DS_KEYF3DS = 0xB000, 35 C3DS_KEYF3DS = 0xB000,
36 C3DS_VERSION = 0x0002, 36 C3DS_VERSION = 0x0002,
37 C3DS_MESHVERSION = 0x3D3E, 37 C3DS_MESHVERSION = 0x3D3E,
38 38
39 // sub chunks of C3DS_EDIT3DS 39 // sub chunks of C3DS_EDIT3DS
40 C3DS_EDIT_MATERIAL = 0xAFFF, 40 C3DS_EDIT_MATERIAL = 0xAFFF,
41 C3DS_EDIT_OBJECT = 0x4000, 41 C3DS_EDIT_OBJECT = 0x4000,
42 42
43 // sub chunks of C3DS_EDIT_MATERIAL 43 // sub chunks of C3DS_EDIT_MATERIAL
44 C3DS_MATNAME = 0xA000, 44 C3DS_MATNAME = 0xA000,
45 C3DS_MATAMBIENT = 0xA010, 45 C3DS_MATAMBIENT = 0xA010,
46 C3DS_MATDIFFUSE = 0xA020, 46 C3DS_MATDIFFUSE = 0xA020,
47 C3DS_MATSPECULAR = 0xA030, 47 C3DS_MATSPECULAR = 0xA030,
48 C3DS_MATSHININESS = 0xA040, 48 C3DS_MATSHININESS = 0xA040,
49 C3DS_MATSHIN2PCT = 0xA041, 49 C3DS_MATSHIN2PCT = 0xA041,
50 C3DS_TRANSPARENCY = 0xA050, 50 C3DS_TRANSPARENCY = 0xA050,
51 C3DS_TRANSPARENCY_FALLOFF = 0xA052, 51 C3DS_TRANSPARENCY_FALLOFF = 0xA052,
52 C3DS_REFL_BLUR = 0xA053, 52 C3DS_REFL_BLUR = 0xA053,
53 C3DS_TWO_SIDE = 0xA081, 53 C3DS_TWO_SIDE = 0xA081,
54 C3DS_WIRE = 0xA085, 54 C3DS_WIRE = 0xA085,
55 C3DS_SHADING = 0xA100, 55 C3DS_SHADING = 0xA100,
56 C3DS_MATTEXMAP = 0xA200, 56 C3DS_MATTEXMAP = 0xA200,
57 C3DS_MATSPECMAP = 0xA204, 57 C3DS_MATSPECMAP = 0xA204,
58 C3DS_MATOPACMAP = 0xA210, 58 C3DS_MATOPACMAP = 0xA210,
59 C3DS_MATREFLMAP = 0xA220, 59 C3DS_MATREFLMAP = 0xA220,
60 C3DS_MATBUMPMAP = 0xA230, 60 C3DS_MATBUMPMAP = 0xA230,
61 C3DS_MATMAPFILE = 0xA300, 61 C3DS_MATMAPFILE = 0xA300,
62 C3DS_MAT_TEXTILING = 0xA351, 62 C3DS_MAT_TEXTILING = 0xA351,
63 C3DS_MAT_USCALE = 0xA354, 63 C3DS_MAT_USCALE = 0xA354,
64 C3DS_MAT_VSCALE = 0xA356, 64 C3DS_MAT_VSCALE = 0xA356,
65 C3DS_MAT_UOFFSET = 0xA358, 65 C3DS_MAT_UOFFSET = 0xA358,
66 C3DS_MAT_VOFFSET = 0xA35A, 66 C3DS_MAT_VOFFSET = 0xA35A,
67 67
68 // subs of C3DS_EDIT_OBJECT 68 // subs of C3DS_EDIT_OBJECT
69 C3DS_OBJTRIMESH = 0x4100, 69 C3DS_OBJTRIMESH = 0x4100,
70 70
71 // subs of C3DS_OBJTRIMESH 71 // subs of C3DS_OBJTRIMESH
72 C3DS_TRIVERT = 0x4110, 72 C3DS_TRIVERT = 0x4110,
73 C3DS_POINTFLAGARRAY= 0x4111, 73 C3DS_POINTFLAGARRAY= 0x4111,
74 C3DS_TRIFACE = 0x4120, 74 C3DS_TRIFACE = 0x4120,
75 C3DS_TRIFACEMAT = 0x4130, 75 C3DS_TRIFACEMAT = 0x4130,
76 C3DS_TRIUV = 0x4140, 76 C3DS_TRIUV = 0x4140,
77 C3DS_TRISMOOTH = 0x4150, 77 C3DS_TRISMOOTH = 0x4150,
78 C3DS_TRIMATRIX = 0x4160, 78 C3DS_TRIMATRIX = 0x4160,
79 C3DS_MESHCOLOR = 0x4165, 79 C3DS_MESHCOLOR = 0x4165,
80 C3DS_DIRECT_LIGHT = 0x4600, 80 C3DS_DIRECT_LIGHT = 0x4600,
81 C3DS_DL_INNER_RANGE= 0x4659, 81 C3DS_DL_INNER_RANGE= 0x4659,
82 C3DS_DL_OUTER_RANGE= 0x465A, 82 C3DS_DL_OUTER_RANGE= 0x465A,
83 C3DS_DL_MULTIPLIER = 0x465B, 83 C3DS_DL_MULTIPLIER = 0x465B,
84 C3DS_CAMERA = 0x4700, 84 C3DS_CAMERA = 0x4700,
85 C3DS_CAM_SEE_CONE = 0x4710, 85 C3DS_CAM_SEE_CONE = 0x4710,
86 C3DS_CAM_RANGES = 0x4720, 86 C3DS_CAM_RANGES = 0x4720,
87 87
88 // subs of C3DS_KEYF3DS 88 // subs of C3DS_KEYF3DS
89 C3DS_KF_HDR = 0xB00A, 89 C3DS_KF_HDR = 0xB00A,
90 C3DS_AMBIENT_TAG = 0xB001, 90 C3DS_AMBIENT_TAG = 0xB001,
91 C3DS_OBJECT_TAG = 0xB002, 91 C3DS_OBJECT_TAG = 0xB002,
92 C3DS_CAMERA_TAG = 0xB003, 92 C3DS_CAMERA_TAG = 0xB003,
93 C3DS_TARGET_TAG = 0xB004, 93 C3DS_TARGET_TAG = 0xB004,
94 C3DS_LIGHTNODE_TAG = 0xB005, 94 C3DS_LIGHTNODE_TAG = 0xB005,
95 C3DS_KF_SEG = 0xB008, 95 C3DS_KF_SEG = 0xB008,
96 C3DS_KF_CURTIME = 0xB009, 96 C3DS_KF_CURTIME = 0xB009,
97 C3DS_KF_NODE_HDR = 0xB010, 97 C3DS_KF_NODE_HDR = 0xB010,
98 C3DS_PIVOTPOINT = 0xB013, 98 C3DS_PIVOTPOINT = 0xB013,
99 C3DS_BOUNDBOX = 0xB014, 99 C3DS_BOUNDBOX = 0xB014,
100 C3DS_MORPH_SMOOTH = 0xB015, 100 C3DS_MORPH_SMOOTH = 0xB015,
101 C3DS_POS_TRACK_TAG = 0xB020, 101 C3DS_POS_TRACK_TAG = 0xB020,
102 C3DS_ROT_TRACK_TAG = 0xB021, 102 C3DS_ROT_TRACK_TAG = 0xB021,
103 C3DS_SCL_TRACK_TAG = 0xB022, 103 C3DS_SCL_TRACK_TAG = 0xB022,
104 C3DS_NODE_ID = 0xB030, 104 C3DS_NODE_ID = 0xB030,
105 105
106 // Viewport definitions 106 // Viewport definitions
107 C3DS_VIEWPORT_LAYOUT = 0x7001, 107 C3DS_VIEWPORT_LAYOUT = 0x7001,
108 C3DS_VIEWPORT_DATA = 0x7011, 108 C3DS_VIEWPORT_DATA = 0x7011,
109 C3DS_VIEWPORT_DATA_3 = 0x7012, 109 C3DS_VIEWPORT_DATA_3 = 0x7012,
110 C3DS_VIEWPORT_SIZE = 0x7020, 110 C3DS_VIEWPORT_SIZE = 0x7020,
111 111
112 // different color chunk types 112 // different color chunk types
113 C3DS_COL_RGB = 0x0010, 113 C3DS_COL_RGB = 0x0010,
114 C3DS_COL_TRU = 0x0011, 114 C3DS_COL_TRU = 0x0011,
115 C3DS_COL_LIN_24 = 0x0012, 115 C3DS_COL_LIN_24 = 0x0012,
116 C3DS_COL_LIN_F = 0x0013, 116 C3DS_COL_LIN_F = 0x0013,
117 117
118 // percentage chunk types 118 // percentage chunk types
119 C3DS_PERCENTAGE_I = 0x0030, 119 C3DS_PERCENTAGE_I = 0x0030,
120 C3DS_PERCENTAGE_F = 0x0031, 120 C3DS_PERCENTAGE_F = 0x0031,
121 121
122 C3DS_CHUNK_MAX = 0xFFFF 122 C3DS_CHUNK_MAX = 0xFFFF
123}; 123};
124} 124}
125 125
126 126
127//! Constructor 127//! Constructor
128C3DSMeshFileLoader::C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs) 128C3DSMeshFileLoader::C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs)
129: SceneManager(smgr), FileSystem(fs), Vertices(0), Indices(0), SmoothingGroups(0), TCoords(0), 129: SceneManager(smgr), FileSystem(fs), Vertices(0), Indices(0), SmoothingGroups(0), TCoords(0),
130 CountVertices(0), CountFaces(0), CountTCoords(0), Mesh(0) 130 CountVertices(0), CountFaces(0), CountTCoords(0), Mesh(0)
131{ 131{
132 132
133 #ifdef _DEBUG 133 #ifdef _DEBUG
134 setDebugName("C3DSMeshFileLoader"); 134 setDebugName("C3DSMeshFileLoader");
135 #endif 135 #endif
136 136
137 if (FileSystem) 137 if (FileSystem)
138 FileSystem->grab(); 138 FileSystem->grab();
139} 139}
140 140
141 141
142//! destructor 142//! destructor
143C3DSMeshFileLoader::~C3DSMeshFileLoader() 143C3DSMeshFileLoader::~C3DSMeshFileLoader()
144{ 144{
145 cleanUp(); 145 cleanUp();
146 146
147 if (FileSystem) 147 if (FileSystem)
148 FileSystem->drop(); 148 FileSystem->drop();
149 149
150 if (Mesh) 150 if (Mesh)
151 Mesh->drop(); 151 Mesh->drop();
152} 152}
153 153
154 154
155//! returns true if the file maybe is able to be loaded by this class 155//! returns true if the file maybe is able to be loaded by this class
156//! based on the file extension (e.g. ".bsp") 156//! based on the file extension (e.g. ".bsp")
157bool C3DSMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 157bool C3DSMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
158{ 158{
159 return core::hasFileExtension ( filename, "3ds" ); 159 return core::hasFileExtension ( filename, "3ds" );
160} 160}
161 161
162 162
163//! creates/loads an animated mesh from the file. 163//! creates/loads an animated mesh from the file.
164//! \return Pointer to the created mesh. Returns 0 if loading failed. 164//! \return Pointer to the created mesh. Returns 0 if loading failed.
165//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). 165//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
166//! See IReferenceCounted::drop() for more information. 166//! See IReferenceCounted::drop() for more information.
167IAnimatedMesh* C3DSMeshFileLoader::createMesh(io::IReadFile* file) 167IAnimatedMesh* C3DSMeshFileLoader::createMesh(io::IReadFile* file)
168{ 168{
169 ChunkData data; 169 ChunkData data;
170 170
171 readChunkData(file, data); 171 readChunkData(file, data);
172 172
173 if (data.header.id != C3DS_MAIN3DS ) 173 if (data.header.id != C3DS_MAIN3DS )
174 return 0; 174 return 0;
175 175
176 CurrentMaterial.clear(); 176 CurrentMaterial.clear();
177 Materials.clear(); 177 Materials.clear();
178 MeshBufferNames.clear(); 178 MeshBufferNames.clear();
179 cleanUp(); 179 cleanUp();
180 180
181 if (Mesh) 181 if (Mesh)
182 Mesh->drop(); 182 Mesh->drop();
183 183
184 Mesh = new SMesh(); 184 Mesh = new SMesh();
185 185
186 if (readChunk(file, &data)) 186 if (readChunk(file, &data))
187 { 187 {
188 // success 188 // success
189 189
190 for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) 190 for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
191 { 191 {
192 SMeshBuffer* mb = ((SMeshBuffer*)Mesh->getMeshBuffer(i)); 192 SMeshBuffer* mb = ((SMeshBuffer*)Mesh->getMeshBuffer(i));
193 // drop empty buffers 193 // drop empty buffers
194 if (mb->getIndexCount() == 0 || mb->getVertexCount() == 0) 194 if (mb->getIndexCount() == 0 || mb->getVertexCount() == 0)
195 { 195 {
196 Mesh->MeshBuffers.erase(i--); 196 Mesh->MeshBuffers.erase(i--);
197 mb->drop(); 197 mb->drop();
198 } 198 }
199 else 199 else
200 { 200 {
201 if (mb->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID) 201 if (mb->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID)
202 { 202 {
203 SMesh tmp; 203 SMesh tmp;
204 tmp.addMeshBuffer(mb); 204 tmp.addMeshBuffer(mb);
205 mb->drop(); 205 mb->drop();
206 IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp); 206 IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp);
207 Mesh->MeshBuffers[i]=tangentMesh->getMeshBuffer(0); 207 Mesh->MeshBuffers[i]=tangentMesh->getMeshBuffer(0);
208 // we need to grab because we replace the buffer manually. 208 // we need to grab because we replace the buffer manually.
209 Mesh->MeshBuffers[i]->grab(); 209 Mesh->MeshBuffers[i]->grab();
210 // clean up intermediate mesh struct 210 // clean up intermediate mesh struct
211 tangentMesh->drop(); 211 tangentMesh->drop();
212 } 212 }
213 Mesh->MeshBuffers[i]->recalculateBoundingBox(); 213 Mesh->MeshBuffers[i]->recalculateBoundingBox();
214 } 214 }
215 } 215 }
216 216
217 Mesh->recalculateBoundingBox(); 217 Mesh->recalculateBoundingBox();
218 218
219 SAnimatedMesh* am = new SAnimatedMesh(); 219 SAnimatedMesh* am = new SAnimatedMesh();
220 am->Type = EAMT_3DS; 220 am->Type = EAMT_3DS;
221 am->addMesh(Mesh); 221 am->addMesh(Mesh);
222 am->recalculateBoundingBox(); 222 am->recalculateBoundingBox();
223 Mesh->drop(); 223 Mesh->drop();
224 Mesh = 0; 224 Mesh = 0;
225 return am; 225 return am;
226 } 226 }
227 227
228 Mesh->drop(); 228 Mesh->drop();
229 Mesh = 0; 229 Mesh = 0;
230 230
231 return 0; 231 return 0;
232} 232}
233 233
234 234
235bool C3DSMeshFileLoader::readPercentageChunk(io::IReadFile* file, 235bool C3DSMeshFileLoader::readPercentageChunk(io::IReadFile* file,
236 ChunkData* chunk, f32& percentage) 236 ChunkData* chunk, f32& percentage)
237{ 237{
238#ifdef _IRR_DEBUG_3DS_LOADER_ 238#ifdef _IRR_DEBUG_3DS_LOADER_
239 os::Printer::log("Load percentage chunk.", ELL_DEBUG); 239 os::Printer::log("Load percentage chunk.", ELL_DEBUG);
240#endif 240#endif
241 241
242 ChunkData data; 242 ChunkData data;
243 readChunkData(file, data); 243 readChunkData(file, data);
244 244
245 short intpercentage; 245 short intpercentage;
246 float fpercentage; 246 float fpercentage;
247 247
248 switch(data.header.id) 248 switch(data.header.id)
249 { 249 {
250 case C3DS_PERCENTAGE_I: 250 case C3DS_PERCENTAGE_I:
251 { 251 {
252 // read short 252 // read short
253 file->read(&intpercentage, 2); 253 file->read(&intpercentage, 2);
254#ifdef __BIG_ENDIAN__ 254#ifdef __BIG_ENDIAN__
255 intpercentage = os::Byteswap::byteswap(intpercentage); 255 intpercentage = os::Byteswap::byteswap(intpercentage);
256#endif 256#endif
257 percentage=intpercentage/100.0f; 257 percentage=intpercentage/100.0f;
258 data.read += 2; 258 data.read += 2;
259 } 259 }
260 break; 260 break;
261 case C3DS_PERCENTAGE_F: 261 case C3DS_PERCENTAGE_F:
262 { 262 {
263 // read float 263 // read float
264 file->read(&fpercentage, sizeof(float)); 264 file->read(&fpercentage, sizeof(float));
265 data.read += sizeof(float); 265 data.read += sizeof(float);
266#ifdef __BIG_ENDIAN__ 266#ifdef __BIG_ENDIAN__
267 percentage = os::Byteswap::byteswap(fpercentage); 267 percentage = os::Byteswap::byteswap(fpercentage);
268#else 268#else
269 percentage = (f32)fpercentage; 269 percentage = (f32)fpercentage;
270#endif 270#endif
271 } 271 }
272 break; 272 break;
273 default: 273 default:
274 { 274 {
275 // unknown percentage chunk 275 // unknown percentage chunk
276 os::Printer::log("Unknown percentage chunk in 3Ds file.", ELL_WARNING); 276 os::Printer::log("Unknown percentage chunk in 3Ds file.", ELL_WARNING);
277 file->seek(data.header.length - data.read, true); 277 file->seek(data.header.length - data.read, true);
278 data.read += data.header.length - data.read; 278 data.read += data.header.length - data.read;
279 } 279 }
280 } 280 }
281 281
282 chunk->read += data.read; 282 chunk->read += data.read;
283 283
284 return true; 284 return true;
285} 285}
286 286
287bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk, 287bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk,
288 video::SColor& out) 288 video::SColor& out)
289{ 289{
290#ifdef _IRR_DEBUG_3DS_LOADER_ 290#ifdef _IRR_DEBUG_3DS_LOADER_
291 os::Printer::log("Load color chunk.", ELL_DEBUG); 291 os::Printer::log("Load color chunk.", ELL_DEBUG);
292#endif 292#endif
293 ChunkData data; 293 ChunkData data;
294 readChunkData(file, data); 294 readChunkData(file, data);
295 295
296 u8 c[3]; 296 u8 c[3];
297 f32 cf[3]; 297 f32 cf[3];
298 298
299 switch(data.header.id) 299 switch(data.header.id)
300 { 300 {
301 case C3DS_COL_TRU: 301 case C3DS_COL_TRU:
302 case C3DS_COL_LIN_24: 302 case C3DS_COL_LIN_24:
303 { 303 {
304 // read 8 bit data 304 // read 8 bit data
305 file->read(c, sizeof(c)); 305 file->read(c, sizeof(c));
306 out.set(255, c[0], c[1], c[2]); 306 out.set(255, c[0], c[1], c[2]);
307 data.read += sizeof(c); 307 data.read += sizeof(c);
308 } 308 }
309 break; 309 break;
310 case C3DS_COL_RGB: 310 case C3DS_COL_RGB:
311 case C3DS_COL_LIN_F: 311 case C3DS_COL_LIN_F:
312 { 312 {
313 // read float data 313 // read float data
314 file->read(cf, sizeof(cf)); 314 file->read(cf, sizeof(cf));
315#ifdef __BIG_ENDIAN__ 315#ifdef __BIG_ENDIAN__
316 cf[0] = os::Byteswap::byteswap(cf[0]); 316 cf[0] = os::Byteswap::byteswap(cf[0]);
317 cf[1] = os::Byteswap::byteswap(cf[1]); 317 cf[1] = os::Byteswap::byteswap(cf[1]);
318 cf[2] = os::Byteswap::byteswap(cf[2]); 318 cf[2] = os::Byteswap::byteswap(cf[2]);
319#endif 319#endif
320 out.set(255, (s32)(cf[0]*255.0f), (s32)(cf[1]*255.0f), (s32)(cf[2]*255.0f)); 320 out.set(255, (s32)(cf[0]*255.0f), (s32)(cf[1]*255.0f), (s32)(cf[2]*255.0f));
321 data.read += sizeof(cf); 321 data.read += sizeof(cf);
322 } 322 }
323 break; 323 break;
324 default: 324 default:
325 { 325 {
326 // unknown color chunk size 326 // unknown color chunk size
327 os::Printer::log("Unknown size of color chunk in 3Ds file.", ELL_WARNING); 327 os::Printer::log("Unknown size of color chunk in 3Ds file.", ELL_WARNING);
328 file->seek(data.header.length - data.read, true); 328 file->seek(data.header.length - data.read, true);
329 data.read += data.header.length - data.read; 329 data.read += data.header.length - data.read;
330 } 330 }
331 } 331 }
332 332
333 chunk->read += data.read; 333 chunk->read += data.read;
334 334
335 return true; 335 return true;
336} 336}
337 337
338 338
339bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent) 339bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent)
340{ 340{
341#ifdef _IRR_DEBUG_3DS_LOADER_ 341#ifdef _IRR_DEBUG_3DS_LOADER_
342 os::Printer::log("Load material chunk.", ELL_DEBUG); 342 os::Printer::log("Load material chunk.", ELL_DEBUG);
343#endif 343#endif
344 u16 matSection=0; 344 u16 matSection=0;
345 345
346 while(parent->read < parent->header.length) 346 while(parent->read < parent->header.length)
347 { 347 {
348 ChunkData data; 348 ChunkData data;
349 readChunkData(file, data); 349 readChunkData(file, data);
350 350
351 switch(data.header.id) 351 switch(data.header.id)
352 { 352 {
353 case C3DS_MATNAME: 353 case C3DS_MATNAME:
354 { 354 {
355 c8* c = new c8[data.header.length - data.read]; 355 c8* c = new c8[data.header.length - data.read];
356 file->read(c, data.header.length - data.read); 356 file->read(c, data.header.length - data.read);
357 357
358 if (strlen(c)) 358 if (strlen(c))
359 CurrentMaterial.Name = c; 359 CurrentMaterial.Name = c;
360 360
361 data.read += data.header.length - data.read; 361 data.read += data.header.length - data.read;
362 delete [] c; 362 delete [] c;
363 } 363 }
364 break; 364 break;
365 case C3DS_MATAMBIENT: 365 case C3DS_MATAMBIENT:
366 readColorChunk(file, &data, CurrentMaterial.Material.AmbientColor); 366 readColorChunk(file, &data, CurrentMaterial.Material.AmbientColor);
367 break; 367 break;
368 case C3DS_MATDIFFUSE: 368 case C3DS_MATDIFFUSE:
369 readColorChunk(file, &data, CurrentMaterial.Material.DiffuseColor); 369 readColorChunk(file, &data, CurrentMaterial.Material.DiffuseColor);
370 break; 370 break;
371 case C3DS_MATSPECULAR: 371 case C3DS_MATSPECULAR:
372 readColorChunk(file, &data, CurrentMaterial.Material.SpecularColor); 372 readColorChunk(file, &data, CurrentMaterial.Material.SpecularColor);
373 break; 373 break;
374 case C3DS_MATSHININESS: 374 case C3DS_MATSHININESS:
375 readPercentageChunk(file, &data, CurrentMaterial.Material.Shininess); 375 readPercentageChunk(file, &data, CurrentMaterial.Material.Shininess);
376 CurrentMaterial.Material.Shininess = (1.f-CurrentMaterial.Material.Shininess)*128.f; 376 CurrentMaterial.Material.Shininess = (1.f-CurrentMaterial.Material.Shininess)*128.f;
377 break; 377 break;
378 case C3DS_TRANSPARENCY: 378 case C3DS_TRANSPARENCY:
379 { 379 {
380 f32 percentage; 380 f32 percentage;
381 readPercentageChunk(file, &data, percentage); 381 readPercentageChunk(file, &data, percentage);
382 if (percentage>0.0f) 382 if (percentage>0.0f)
383 { 383 {
384 CurrentMaterial.Material.MaterialTypeParam=percentage; 384 CurrentMaterial.Material.MaterialTypeParam=percentage;
385 CurrentMaterial.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; 385 CurrentMaterial.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA;
386 } 386 }
387 else 387 else
388 { 388 {
389 CurrentMaterial.Material.MaterialType=video::EMT_SOLID; 389 CurrentMaterial.Material.MaterialType=video::EMT_SOLID;
390 } 390 }
391 } 391 }
392 break; 392 break;
393 case C3DS_WIRE: 393 case C3DS_WIRE:
394 CurrentMaterial.Material.Wireframe=true; 394 CurrentMaterial.Material.Wireframe=true;
395 break; 395 break;
396 case C3DS_TWO_SIDE: 396 case C3DS_TWO_SIDE:
397 CurrentMaterial.Material.BackfaceCulling=false; 397 CurrentMaterial.Material.BackfaceCulling=false;
398 break; 398 break;
399 case C3DS_SHADING: 399 case C3DS_SHADING:
400 { 400 {
401 s16 flags; 401 s16 flags;
402 file->read(&flags, 2); 402 file->read(&flags, 2);
403#ifdef __BIG_ENDIAN__ 403#ifdef __BIG_ENDIAN__
404 flags = os::Byteswap::byteswap(flags); 404 flags = os::Byteswap::byteswap(flags);
405#endif 405#endif
406 switch (flags) 406 switch (flags)
407 { 407 {
408 case 0: 408 case 0:
409 CurrentMaterial.Material.Wireframe=true; 409 CurrentMaterial.Material.Wireframe=true;
410 break; 410 break;
411 case 1: 411 case 1:
412 CurrentMaterial.Material.Wireframe=false; 412 CurrentMaterial.Material.Wireframe=false;
413 CurrentMaterial.Material.GouraudShading=false; 413 CurrentMaterial.Material.GouraudShading=false;
414 break; 414 break;
415 case 2: 415 case 2:
416 CurrentMaterial.Material.Wireframe=false; 416 CurrentMaterial.Material.Wireframe=false;
417 CurrentMaterial.Material.GouraudShading=true; 417 CurrentMaterial.Material.GouraudShading=true;
418 break; 418 break;
419 default: 419 default:
420 // phong and metal missing 420 // phong and metal missing
421 break; 421 break;
422 } 422 }
423 data.read += data.header.length - data.read; 423 data.read += data.header.length - data.read;
424 } 424 }
425 break; 425 break;
426 case C3DS_MATTEXMAP: 426 case C3DS_MATTEXMAP:
427 case C3DS_MATSPECMAP: 427 case C3DS_MATSPECMAP:
428 case C3DS_MATOPACMAP: 428 case C3DS_MATOPACMAP:
429 case C3DS_MATREFLMAP: 429 case C3DS_MATREFLMAP:
430 case C3DS_MATBUMPMAP: 430 case C3DS_MATBUMPMAP:
431 { 431 {
432 matSection=data.header.id; 432 matSection=data.header.id;
433 // Should contain a percentage chunk, but does 433 // Should contain a percentage chunk, but does
434 // not always have it 434 // not always have it
435 s16 testval; 435 s16 testval;
436 const long pos = file->getPos(); 436 const long pos = file->getPos();
437 file->read(&testval, 2); 437 file->read(&testval, 2);
438#ifdef __BIG_ENDIAN__ 438#ifdef __BIG_ENDIAN__
439 testval = os::Byteswap::byteswap(testval); 439 testval = os::Byteswap::byteswap(testval);
440#endif 440#endif
441 file->seek(pos, false); 441 file->seek(pos, false);
442 if ((testval == C3DS_PERCENTAGE_I) || 442 if ((testval == C3DS_PERCENTAGE_I) ||
443 (testval == C3DS_PERCENTAGE_F)) 443 (testval == C3DS_PERCENTAGE_F))
444 switch (matSection) 444 switch (matSection)
445 { 445 {
446 case C3DS_MATTEXMAP: 446 case C3DS_MATTEXMAP:
447 readPercentageChunk(file, &data, CurrentMaterial.Strength[0]); 447 readPercentageChunk(file, &data, CurrentMaterial.Strength[0]);
448 break; 448 break;
449 case C3DS_MATSPECMAP: 449 case C3DS_MATSPECMAP:
450 readPercentageChunk(file, &data, CurrentMaterial.Strength[1]); 450 readPercentageChunk(file, &data, CurrentMaterial.Strength[1]);
451 break; 451 break;
452 case C3DS_MATOPACMAP: 452 case C3DS_MATOPACMAP:
453 readPercentageChunk(file, &data, CurrentMaterial.Strength[2]); 453 readPercentageChunk(file, &data, CurrentMaterial.Strength[2]);
454 break; 454 break;
455 case C3DS_MATBUMPMAP: 455 case C3DS_MATBUMPMAP:
456 readPercentageChunk(file, &data, CurrentMaterial.Strength[4]); 456 readPercentageChunk(file, &data, CurrentMaterial.Strength[4]);
457 break; 457 break;
458 } 458 }
459 } 459 }
460 break; 460 break;
461 case C3DS_MATMAPFILE: 461 case C3DS_MATMAPFILE:
462 { 462 {
463 // read texture file name 463 // read texture file name
464 c8* c = new c8[data.header.length - data.read]; 464 c8* c = new c8[data.header.length - data.read];
465 file->read(c, data.header.length - data.read); 465 file->read(c, data.header.length - data.read);
466 switch (matSection) 466 switch (matSection)
467 { 467 {
468 case C3DS_MATTEXMAP: 468 case C3DS_MATTEXMAP:
469 CurrentMaterial.Filename[0] = c; 469 CurrentMaterial.Filename[0] = c;
470 break; 470 break;
471 case C3DS_MATSPECMAP: 471 case C3DS_MATSPECMAP:
472 CurrentMaterial.Filename[1] = c; 472 CurrentMaterial.Filename[1] = c;
473 break; 473 break;
474 case C3DS_MATOPACMAP: 474 case C3DS_MATOPACMAP:
475 CurrentMaterial.Filename[2] = c; 475 CurrentMaterial.Filename[2] = c;
476 break; 476 break;
477 case C3DS_MATREFLMAP: 477 case C3DS_MATREFLMAP:
478 CurrentMaterial.Filename[3] = c; 478 CurrentMaterial.Filename[3] = c;
479 break; 479 break;
480 case C3DS_MATBUMPMAP: 480 case C3DS_MATBUMPMAP:
481 CurrentMaterial.Filename[4] = c; 481 CurrentMaterial.Filename[4] = c;
482 break; 482 break;
483 } 483 }
484 data.read += data.header.length - data.read; 484 data.read += data.header.length - data.read;
485 delete [] c; 485 delete [] c;
486 } 486 }
487 break; 487 break;
488 case C3DS_MAT_TEXTILING: 488 case C3DS_MAT_TEXTILING:
489 { 489 {
490 s16 flags; 490 s16 flags;
491 file->read(&flags, 2); 491 file->read(&flags, 2);
492#ifdef __BIG_ENDIAN__ 492#ifdef __BIG_ENDIAN__
493 flags = os::Byteswap::byteswap(flags); 493 flags = os::Byteswap::byteswap(flags);
494#endif 494#endif
495 data.read += 2; 495 data.read += 2;
496 } 496 }
497 break; 497 break;
498 case C3DS_MAT_USCALE: 498 case C3DS_MAT_USCALE:
499 case C3DS_MAT_VSCALE: 499 case C3DS_MAT_VSCALE:
500 case C3DS_MAT_UOFFSET: 500 case C3DS_MAT_UOFFSET:
501 case C3DS_MAT_VOFFSET: 501 case C3DS_MAT_VOFFSET:
502 { 502 {
503 f32 value; 503 f32 value;
504 file->read(&value, 4); 504 file->read(&value, 4);
505#ifdef __BIG_ENDIAN__ 505#ifdef __BIG_ENDIAN__
506 value = os::Byteswap::byteswap(value); 506 value = os::Byteswap::byteswap(value);
507#endif 507#endif
508 u32 i=0; 508 u32 i=0;
509 if (matSection != C3DS_MATTEXMAP) 509 if (matSection != C3DS_MATTEXMAP)
510 i=1; 510 i=1;
511 u32 j=0,k=0; 511 u32 j=0,k=0;
512 if (data.header.id == C3DS_MAT_VSCALE) 512 if (data.header.id == C3DS_MAT_VSCALE)
513 { 513 {
514 j=1; 514 j=1;
515 k=1; 515 k=1;
516 } 516 }
517 else if (data.header.id == C3DS_MAT_UOFFSET) 517 else if (data.header.id == C3DS_MAT_UOFFSET)
518 { 518 {
519 j=2; 519 j=2;
520 k=0; 520 k=0;
521 } 521 }
522 else if (data.header.id == C3DS_MAT_VOFFSET) 522 else if (data.header.id == C3DS_MAT_VOFFSET)
523 { 523 {
524 j=2; 524 j=2;
525 k=1; 525 k=1;
526 } 526 }
527 CurrentMaterial.Material.getTextureMatrix(i)(j,k)=value; 527 CurrentMaterial.Material.getTextureMatrix(i)(j,k)=value;
528 528
529 data.read += 4; 529 data.read += 4;
530 } 530 }
531 break; 531 break;
532 default: 532 default:
533 // ignore chunk 533 // ignore chunk
534 file->seek(data.header.length - data.read, true); 534 file->seek(data.header.length - data.read, true);
535 data.read += data.header.length - data.read; 535 data.read += data.header.length - data.read;
536 } 536 }
537 537
538 parent->read += data.read; 538 parent->read += data.read;
539 } 539 }
540 540
541 Materials.push_back(CurrentMaterial); 541 Materials.push_back(CurrentMaterial);
542 CurrentMaterial.clear(); 542 CurrentMaterial.clear();
543 543
544 return true; 544 return true;
545} 545}
546 546
547 547
548 548
549bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data, 549bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data,
550 IMeshBuffer* mb, const core::vector3df& pivot) 550 IMeshBuffer* mb, const core::vector3df& pivot)
551{ 551{
552#ifdef _IRR_DEBUG_3DS_LOADER_ 552#ifdef _IRR_DEBUG_3DS_LOADER_
553 os::Printer::log("Load track chunk.", ELL_DEBUG); 553 os::Printer::log("Load track chunk.", ELL_DEBUG);
554#endif 554#endif
555 u16 flags; 555 u16 flags;
556 u32 flags2; 556 u32 flags2;
557 // Track flags 557 // Track flags
558 file->read(&flags, 2); 558 file->read(&flags, 2);
559#ifdef __BIG_ENDIAN__ 559#ifdef __BIG_ENDIAN__
560 flags = os::Byteswap::byteswap(flags); 560 flags = os::Byteswap::byteswap(flags);
561#endif 561#endif
562 file->read(&flags2, 4); 562 file->read(&flags2, 4);
563#ifdef __BIG_ENDIAN__ 563#ifdef __BIG_ENDIAN__
564 flags2 = os::Byteswap::byteswap(flags2); 564 flags2 = os::Byteswap::byteswap(flags2);
565#endif 565#endif
566 file->read(&flags2, 4); 566 file->read(&flags2, 4);
567#ifdef __BIG_ENDIAN__ 567#ifdef __BIG_ENDIAN__
568 flags2 = os::Byteswap::byteswap(flags2); 568 flags2 = os::Byteswap::byteswap(flags2);
569#endif 569#endif
570 // Num keys 570 // Num keys
571 file->read(&flags2, 4); 571 file->read(&flags2, 4);
572#ifdef __BIG_ENDIAN__ 572#ifdef __BIG_ENDIAN__
573 flags2 = os::Byteswap::byteswap(flags2); 573 flags2 = os::Byteswap::byteswap(flags2);
574#endif 574#endif
575 file->read(&flags2, 4); 575 file->read(&flags2, 4);
576#ifdef __BIG_ENDIAN__ 576#ifdef __BIG_ENDIAN__
577 flags2 = os::Byteswap::byteswap(flags2); 577 flags2 = os::Byteswap::byteswap(flags2);
578#endif 578#endif
579 // TCB flags 579 // TCB flags
580 file->read(&flags, 2); 580 file->read(&flags, 2);
581#ifdef __BIG_ENDIAN__ 581#ifdef __BIG_ENDIAN__
582 flags = os::Byteswap::byteswap(flags); 582 flags = os::Byteswap::byteswap(flags);
583#endif 583#endif
584 data.read += 20; 584 data.read += 20;
585 585
586 f32 angle=0.0f; 586 f32 angle=0.0f;
587 if (data.header.id== C3DS_ROT_TRACK_TAG) 587 if (data.header.id== C3DS_ROT_TRACK_TAG)
588 { 588 {
589 // Angle 589 // Angle
590 file->read(&angle, sizeof(f32)); 590 file->read(&angle, sizeof(f32));
591#ifdef __BIG_ENDIAN__ 591#ifdef __BIG_ENDIAN__
592 angle = os::Byteswap::byteswap(angle); 592 angle = os::Byteswap::byteswap(angle);
593#endif 593#endif
594 data.read += sizeof(f32); 594 data.read += sizeof(f32);
595 } 595 }
596 core::vector3df vec; 596 core::vector3df vec;
597 file->read(&vec.X, sizeof(f32)); 597 file->read(&vec.X, sizeof(f32));
598 file->read(&vec.Y, sizeof(f32)); 598 file->read(&vec.Y, sizeof(f32));
599 file->read(&vec.Z, sizeof(f32)); 599 file->read(&vec.Z, sizeof(f32));
600#ifdef __BIG_ENDIAN__ 600#ifdef __BIG_ENDIAN__
601 vec.X = os::Byteswap::byteswap(vec.X); 601 vec.X = os::Byteswap::byteswap(vec.X);
602 vec.Y = os::Byteswap::byteswap(vec.Y); 602 vec.Y = os::Byteswap::byteswap(vec.Y);
603 vec.Z = os::Byteswap::byteswap(vec.Z); 603 vec.Z = os::Byteswap::byteswap(vec.Z);
604#endif 604#endif
605 data.read += 12; 605 data.read += 12;
606 vec-=pivot; 606 vec-=pivot;
607 607
608 // apply transformation to mesh buffer 608 // apply transformation to mesh buffer
609 if (false)//mb) 609 if (false)//mb)
610 { 610 {
611 video::S3DVertex *vertices=(video::S3DVertex*)mb->getVertices(); 611 video::S3DVertex *vertices=(video::S3DVertex*)mb->getVertices();
612 if (data.header.id==C3DS_POS_TRACK_TAG) 612 if (data.header.id==C3DS_POS_TRACK_TAG)
613 { 613 {
614 for (u32 i=0; i<mb->getVertexCount(); ++i) 614 for (u32 i=0; i<mb->getVertexCount(); ++i)
615 vertices[i].Pos+=vec; 615 vertices[i].Pos+=vec;
616 } 616 }
617 else if (data.header.id==C3DS_ROT_TRACK_TAG) 617 else if (data.header.id==C3DS_ROT_TRACK_TAG)
618 { 618 {
619 //TODO 619 //TODO
620 } 620 }
621 else if (data.header.id==C3DS_SCL_TRACK_TAG) 621 else if (data.header.id==C3DS_SCL_TRACK_TAG)
622 { 622 {
623 //TODO 623 //TODO
624 } 624 }
625 } 625 }
626 // skip further frames 626 // skip further frames
627 file->seek(data.header.length - data.read, true); 627 file->seek(data.header.length - data.read, true);
628 data.read += data.header.length - data.read; 628 data.read += data.header.length - data.read;
629 return true; 629 return true;
630} 630}
631 631
632 632
633bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent) 633bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
634{ 634{
635#ifdef _IRR_DEBUG_3DS_LOADER_ 635#ifdef _IRR_DEBUG_3DS_LOADER_
636 os::Printer::log("Load frame chunk.", ELL_DEBUG); 636 os::Printer::log("Load frame chunk.", ELL_DEBUG);
637#endif 637#endif
638 ChunkData data; 638 ChunkData data;
639 639
640 //KF_HDR is always at the beginning 640 //KF_HDR is always at the beginning
641 readChunkData(file, data); 641 readChunkData(file, data);
642 if (data.header.id != C3DS_KF_HDR) 642 if (data.header.id != C3DS_KF_HDR)
643 return false; 643 return false;
644 else 644 else
645 { 645 {
646#ifdef _IRR_DEBUG_3DS_LOADER_ 646#ifdef _IRR_DEBUG_3DS_LOADER_
647 os::Printer::log("Load keyframe header.", ELL_DEBUG); 647 os::Printer::log("Load keyframe header.", ELL_DEBUG);
648#endif 648#endif
649 u16 version; 649 u16 version;
650 file->read(&version, 2); 650 file->read(&version, 2);
651#ifdef __BIG_ENDIAN__ 651#ifdef __BIG_ENDIAN__
652 version = os::Byteswap::byteswap(version); 652 version = os::Byteswap::byteswap(version);
653#endif 653#endif
654 core::stringc name; 654 core::stringc name;
655 readString(file, data, name); 655 readString(file, data, name);
656 u32 flags; 656 u32 flags;
657 file->read(&flags, 4); 657 file->read(&flags, 4);
658#ifdef __BIG_ENDIAN__ 658#ifdef __BIG_ENDIAN__
659 flags = os::Byteswap::byteswap(flags); 659 flags = os::Byteswap::byteswap(flags);
660#endif 660#endif
661 661
662 data.read += 4; 662 data.read += 4;
663 parent->read += data.read; 663 parent->read += data.read;
664 } 664 }
665 data.read=0; 665 data.read=0;
666 666
667 IMeshBuffer* mb=0; 667 IMeshBuffer* mb=0;
668 core::vector3df pivot,bboxCenter; 668 core::vector3df pivot,bboxCenter;
669 while(parent->read < parent->header.length) 669 while(parent->read < parent->header.length)
670 { 670 {
671 readChunkData(file, data); 671 readChunkData(file, data);
672 672
673 switch(data.header.id) 673 switch(data.header.id)
674 { 674 {
675 case C3DS_OBJECT_TAG: 675 case C3DS_OBJECT_TAG:
676 { 676 {
677#ifdef _IRR_DEBUG_3DS_LOADER_ 677#ifdef _IRR_DEBUG_3DS_LOADER_
678 os::Printer::log("Load object tag.", ELL_DEBUG); 678 os::Printer::log("Load object tag.", ELL_DEBUG);
679#endif 679#endif
680 mb=0; 680 mb=0;
681 pivot.set(0.0f, 0.0f, 0.0f); 681 pivot.set(0.0f, 0.0f, 0.0f);
682 } 682 }
683 break; 683 break;
684 case C3DS_KF_SEG: 684 case C3DS_KF_SEG:
685 { 685 {
686#ifdef _IRR_DEBUG_3DS_LOADER_ 686#ifdef _IRR_DEBUG_3DS_LOADER_
687 os::Printer::log("Load keyframe segment.", ELL_DEBUG); 687 os::Printer::log("Load keyframe segment.", ELL_DEBUG);
688#endif 688#endif
689 u32 flags; 689 u32 flags;
690 file->read(&flags, 4); 690 file->read(&flags, 4);
691#ifdef __BIG_ENDIAN__ 691#ifdef __BIG_ENDIAN__
692 flags = os::Byteswap::byteswap(flags); 692 flags = os::Byteswap::byteswap(flags);
693#endif 693#endif
694 file->read(&flags, 4); 694 file->read(&flags, 4);
695#ifdef __BIG_ENDIAN__ 695#ifdef __BIG_ENDIAN__
696 flags = os::Byteswap::byteswap(flags); 696 flags = os::Byteswap::byteswap(flags);
697#endif 697#endif
698 data.read += 8; 698 data.read += 8;
699 } 699 }
700 break; 700 break;
701 case C3DS_KF_NODE_HDR: 701 case C3DS_KF_NODE_HDR:
702 { 702 {
703#ifdef _IRR_DEBUG_3DS_LOADER_ 703#ifdef _IRR_DEBUG_3DS_LOADER_
704 os::Printer::log("Load keyframe node header.", ELL_DEBUG); 704 os::Printer::log("Load keyframe node header.", ELL_DEBUG);
705#endif 705#endif
706 s16 flags; 706 s16 flags;
707 c8* c = new c8[data.header.length - data.read-6]; 707 c8* c = new c8[data.header.length - data.read-6];
708 file->read(c, data.header.length - data.read-6); 708 file->read(c, data.header.length - data.read-6);
709 709
710 // search mesh buffer to apply these transformations to 710 // search mesh buffer to apply these transformations to
711 for (u32 i=0; i<MeshBufferNames.size(); ++i) 711 for (u32 i=0; i<MeshBufferNames.size(); ++i)
712 { 712 {
713 if (MeshBufferNames[i]==c) 713 if (MeshBufferNames[i]==c)
714 { 714 {
715 mb=Mesh->getMeshBuffer(i); 715 mb=Mesh->getMeshBuffer(i);
716 break; 716 break;
717 } 717 }
718 } 718 }
719 719
720 file->read(&flags, 2); 720 file->read(&flags, 2);
721#ifdef __BIG_ENDIAN__ 721#ifdef __BIG_ENDIAN__
722 flags = os::Byteswap::byteswap(flags); 722 flags = os::Byteswap::byteswap(flags);
723#endif 723#endif
724 file->read(&flags, 2); 724 file->read(&flags, 2);
725#ifdef __BIG_ENDIAN__ 725#ifdef __BIG_ENDIAN__
726 flags = os::Byteswap::byteswap(flags); 726 flags = os::Byteswap::byteswap(flags);
727#endif 727#endif
728 file->read(&flags, 2); 728 file->read(&flags, 2);
729#ifdef __BIG_ENDIAN__ 729#ifdef __BIG_ENDIAN__
730 flags = os::Byteswap::byteswap(flags); 730 flags = os::Byteswap::byteswap(flags);
731#endif 731#endif
732 data.read += data.header.length - data.read; 732 data.read += data.header.length - data.read;
733 delete [] c; 733 delete [] c;
734 } 734 }
735 break; 735 break;
736 case C3DS_KF_CURTIME: 736 case C3DS_KF_CURTIME:
737 { 737 {
738#ifdef _IRR_DEBUG_3DS_LOADER_ 738#ifdef _IRR_DEBUG_3DS_LOADER_
739 os::Printer::log("Load keyframe current time.", ELL_DEBUG); 739 os::Printer::log("Load keyframe current time.", ELL_DEBUG);
740#endif 740#endif
741 u32 flags; 741 u32 flags;
742 file->read(&flags, 4); 742 file->read(&flags, 4);
743#ifdef __BIG_ENDIAN__ 743#ifdef __BIG_ENDIAN__
744 flags = os::Byteswap::byteswap(flags); 744 flags = os::Byteswap::byteswap(flags);
745#endif 745#endif
746 data.read += 4; 746 data.read += 4;
747 } 747 }
748 break; 748 break;
749 case C3DS_NODE_ID: 749 case C3DS_NODE_ID:
750 { 750 {
751#ifdef _IRR_DEBUG_3DS_LOADER_ 751#ifdef _IRR_DEBUG_3DS_LOADER_
752 os::Printer::log("Load node ID.", ELL_DEBUG); 752 os::Printer::log("Load node ID.", ELL_DEBUG);
753#endif 753#endif
754 u16 flags; 754 u16 flags;
755 file->read(&flags, 2); 755 file->read(&flags, 2);
756#ifdef __BIG_ENDIAN__ 756#ifdef __BIG_ENDIAN__
757 flags = os::Byteswap::byteswap(flags); 757 flags = os::Byteswap::byteswap(flags);
758#endif 758#endif
759 data.read += 2; 759 data.read += 2;
760 } 760 }
761 break; 761 break;
762 case C3DS_PIVOTPOINT: 762 case C3DS_PIVOTPOINT:
763 { 763 {
764#ifdef _IRR_DEBUG_3DS_LOADER_ 764#ifdef _IRR_DEBUG_3DS_LOADER_
765 os::Printer::log("Load pivot point.", ELL_DEBUG); 765 os::Printer::log("Load pivot point.", ELL_DEBUG);
766#endif 766#endif
767 file->read(&pivot.X, sizeof(f32)); 767 file->read(&pivot.X, sizeof(f32));
768 file->read(&pivot.Y, sizeof(f32)); 768 file->read(&pivot.Y, sizeof(f32));
769 file->read(&pivot.Z, sizeof(f32)); 769 file->read(&pivot.Z, sizeof(f32));
770#ifdef __BIG_ENDIAN__ 770#ifdef __BIG_ENDIAN__
771 pivot.X = os::Byteswap::byteswap(pivot.X); 771 pivot.X = os::Byteswap::byteswap(pivot.X);
772 pivot.Y = os::Byteswap::byteswap(pivot.Y); 772 pivot.Y = os::Byteswap::byteswap(pivot.Y);
773 pivot.Z = os::Byteswap::byteswap(pivot.Z); 773 pivot.Z = os::Byteswap::byteswap(pivot.Z);
774#endif 774#endif
775 data.read += 12; 775 data.read += 12;
776 } 776 }
777 break; 777 break;
778 case C3DS_BOUNDBOX: 778 case C3DS_BOUNDBOX:
779 { 779 {
780#ifdef _IRR_DEBUG_3DS_LOADER_ 780#ifdef _IRR_DEBUG_3DS_LOADER_
781 os::Printer::log("Load bounding box.", ELL_DEBUG); 781 os::Printer::log("Load bounding box.", ELL_DEBUG);
782#endif 782#endif
783 core::aabbox3df bbox; 783 core::aabbox3df bbox;
784 // abuse bboxCenter as temporary variable 784 // abuse bboxCenter as temporary variable
785 file->read(&bboxCenter.X, sizeof(f32)); 785 file->read(&bboxCenter.X, sizeof(f32));
786 file->read(&bboxCenter.Y, sizeof(f32)); 786 file->read(&bboxCenter.Y, sizeof(f32));
787 file->read(&bboxCenter.Z, sizeof(f32)); 787 file->read(&bboxCenter.Z, sizeof(f32));
788#ifdef __BIG_ENDIAN__ 788#ifdef __BIG_ENDIAN__
789 bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X); 789 bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X);
790 bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y); 790 bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y);
791 bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z); 791 bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z);
792#endif 792#endif
793 bbox.reset(bboxCenter); 793 bbox.reset(bboxCenter);
794 file->read(&bboxCenter.X, sizeof(f32)); 794 file->read(&bboxCenter.X, sizeof(f32));
795 file->read(&bboxCenter.Y, sizeof(f32)); 795 file->read(&bboxCenter.Y, sizeof(f32));
796 file->read(&bboxCenter.Z, sizeof(f32)); 796 file->read(&bboxCenter.Z, sizeof(f32));
797#ifdef __BIG_ENDIAN__ 797#ifdef __BIG_ENDIAN__
798 bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X); 798 bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X);
799 bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y); 799 bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y);
800 bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z); 800 bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z);
801#endif 801#endif
802 bbox.addInternalPoint(bboxCenter); 802 bbox.addInternalPoint(bboxCenter);
803 bboxCenter=bbox.getCenter(); 803 bboxCenter=bbox.getCenter();
804 data.read += 24; 804 data.read += 24;
805 } 805 }
806 break; 806 break;
807 case C3DS_MORPH_SMOOTH: 807 case C3DS_MORPH_SMOOTH:
808 { 808 {
809#ifdef _IRR_DEBUG_3DS_LOADER_ 809#ifdef _IRR_DEBUG_3DS_LOADER_
810 os::Printer::log("Load morph smooth.", ELL_DEBUG); 810 os::Printer::log("Load morph smooth.", ELL_DEBUG);
811#endif 811#endif
812 f32 flag; 812 f32 flag;
813 file->read(&flag, 4); 813 file->read(&flag, 4);
814#ifdef __BIG_ENDIAN__ 814#ifdef __BIG_ENDIAN__
815 flag = os::Byteswap::byteswap(flag); 815 flag = os::Byteswap::byteswap(flag);
816#endif 816#endif
817 data.read += 4; 817 data.read += 4;
818 } 818 }
819 break; 819 break;
820 case C3DS_POS_TRACK_TAG: 820 case C3DS_POS_TRACK_TAG:
821 case C3DS_ROT_TRACK_TAG: 821 case C3DS_ROT_TRACK_TAG:
822 case C3DS_SCL_TRACK_TAG: 822 case C3DS_SCL_TRACK_TAG:
823 readTrackChunk(file, data, mb, bboxCenter-pivot); 823 readTrackChunk(file, data, mb, bboxCenter-pivot);
824 break; 824 break;
825 default: 825 default:
826 // ignore chunk 826 // ignore chunk
827 file->seek(data.header.length - data.read, true); 827 file->seek(data.header.length - data.read, true);
828 data.read += data.header.length - data.read; 828 data.read += data.header.length - data.read;
829 } 829 }
830 830
831 parent->read += data.read; 831 parent->read += data.read;
832 data.read=0; 832 data.read=0;
833 } 833 }
834 834
835 return true; 835 return true;
836} 836}
837 837
838 838
839bool C3DSMeshFileLoader::readChunk(io::IReadFile* file, ChunkData* parent) 839bool C3DSMeshFileLoader::readChunk(io::IReadFile* file, ChunkData* parent)
840{ 840{
841 while(parent->read < parent->header.length) 841 while(parent->read < parent->header.length)
842 { 842 {
843 ChunkData data; 843 ChunkData data;
844 readChunkData(file, data); 844 readChunkData(file, data);
845 845
846 switch(data.header.id) 846 switch(data.header.id)
847 { 847 {
848 case C3DS_VERSION: 848 case C3DS_VERSION:
849 { 849 {
850 u16 version; 850 u16 version;
851 file->read(&version, sizeof(u16)); 851 file->read(&version, sizeof(u16));
852#ifdef __BIG_ENDIAN__ 852#ifdef __BIG_ENDIAN__
853 version = os::Byteswap::byteswap(version); 853 version = os::Byteswap::byteswap(version);
854#endif 854#endif
855 file->seek(data.header.length - data.read - 2, true); 855 file->seek(data.header.length - data.read - 2, true);
856 data.read += data.header.length - data.read; 856 data.read += data.header.length - data.read;
857 if (version != 0x03) 857 if (version != 0x03)
858 os::Printer::log("3ds file version is other than 3.", ELL_ERROR); 858 os::Printer::log("3ds file version is other than 3.", ELL_ERROR);
859 } 859 }
860 break; 860 break;
861 case C3DS_EDIT_MATERIAL: 861 case C3DS_EDIT_MATERIAL:
862 readMaterialChunk(file, &data); 862 readMaterialChunk(file, &data);
863 break; 863 break;
864 case C3DS_KEYF3DS: 864 case C3DS_KEYF3DS:
865 readFrameChunk(file, &data); 865 readFrameChunk(file, &data);
866 break; 866 break;
867 case C3DS_EDIT3DS: 867 case C3DS_EDIT3DS:
868 break; 868 break;
869 case C3DS_MESHVERSION: 869 case C3DS_MESHVERSION:
870 case 0x01: 870 case 0x01:
871 { 871 {
872 u32 version; 872 u32 version;
873 file->read(&version, sizeof(u32)); 873 file->read(&version, sizeof(u32));
874#ifdef __BIG_ENDIAN__ 874#ifdef __BIG_ENDIAN__
875 version = os::Byteswap::byteswap(version); 875 version = os::Byteswap::byteswap(version);
876#endif 876#endif
877 data.read += sizeof(u32); 877 data.read += sizeof(u32);
878 } 878 }
879 break; 879 break;
880 case C3DS_EDIT_OBJECT: 880 case C3DS_EDIT_OBJECT:
881 { 881 {
882 core::stringc name; 882 core::stringc name;
883 readString(file, data, name); 883 readString(file, data, name);
884 readObjectChunk(file, &data); 884 readObjectChunk(file, &data);
885 composeObject(file, name); 885 composeObject(file, name);
886 } 886 }
887 break; 887 break;
888 888
889 default: 889 default:
890 // ignore chunk 890 // ignore chunk
891 file->seek(data.header.length - data.read, true); 891 file->seek(data.header.length - data.read, true);
892 data.read += data.header.length - data.read; 892 data.read += data.header.length - data.read;
893 } 893 }
894 894
895 parent->read += data.read; 895 parent->read += data.read;
896 } 896 }
897 897
898 return true; 898 return true;
899} 899}
900 900
901 901
902bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent) 902bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent)
903{ 903{
904#ifdef _IRR_DEBUG_3DS_LOADER_ 904#ifdef _IRR_DEBUG_3DS_LOADER_
905 os::Printer::log("Load object chunk.", ELL_DEBUG); 905 os::Printer::log("Load object chunk.", ELL_DEBUG);
906#endif 906#endif
907 while(parent->read < parent->header.length) 907 while(parent->read < parent->header.length)
908 { 908 {
909 ChunkData data; 909 ChunkData data;
910 readChunkData(file, data); 910 readChunkData(file, data);
911 911
912 switch(data.header.id) 912 switch(data.header.id)
913 { 913 {
914 case C3DS_OBJTRIMESH: 914 case C3DS_OBJTRIMESH:
915 readObjectChunk(file, &data); 915 readObjectChunk(file, &data);
916 break; 916 break;
917 917
918 case C3DS_TRIVERT: 918 case C3DS_TRIVERT:
919 readVertices(file, data); 919 readVertices(file, data);
920 break; 920 break;
921 921
922 case C3DS_POINTFLAGARRAY: 922 case C3DS_POINTFLAGARRAY:
923 { 923 {
924 u16 numVertex, flags; 924 u16 numVertex, flags;
925 file->read(&numVertex, sizeof(u16)); 925 file->read(&numVertex, sizeof(u16));
926#ifdef __BIG_ENDIAN__ 926#ifdef __BIG_ENDIAN__
927 numVertex= os::Byteswap::byteswap(numVertex); 927 numVertex= os::Byteswap::byteswap(numVertex);
928#endif 928#endif
929 for (u16 i=0; i<numVertex; ++i) 929 for (u16 i=0; i<numVertex; ++i)
930 { 930 {
931 file->read(&flags, sizeof(u16)); 931 file->read(&flags, sizeof(u16));
932#ifdef __BIG_ENDIAN__ 932#ifdef __BIG_ENDIAN__
933 flags = os::Byteswap::byteswap(flags); 933 flags = os::Byteswap::byteswap(flags);
934#endif 934#endif
935 } 935 }
936 data.read += (numVertex+1)*sizeof(u16); 936 data.read += (numVertex+1)*sizeof(u16);
937 } 937 }
938 break; 938 break;
939 939
940 case C3DS_TRIFACE: 940 case C3DS_TRIFACE:
941 readIndices(file, data); 941 readIndices(file, data);
942 readObjectChunk(file, &data); // read smooth and material groups 942 readObjectChunk(file, &data); // read smooth and material groups
943 break; 943 break;
944 944
945 case C3DS_TRIFACEMAT: 945 case C3DS_TRIFACEMAT:
946 readMaterialGroup(file, data); 946 readMaterialGroup(file, data);
947 break; 947 break;
948 948
949 case C3DS_TRIUV: // getting texture coordinates 949 case C3DS_TRIUV: // getting texture coordinates
950 readTextureCoords(file, data); 950 readTextureCoords(file, data);
951 break; 951 break;
952 952
953 case C3DS_TRIMATRIX: 953 case C3DS_TRIMATRIX:
954 { 954 {
955 f32 mat[4][3]; 955 f32 mat[4][3];
956 file->read(&mat, 12*sizeof(f32)); 956 file->read(&mat, 12*sizeof(f32));
957 TransformationMatrix.makeIdentity(); 957 TransformationMatrix.makeIdentity();
958 for (int i=0; i<4; ++i) 958 for (int i=0; i<4; ++i)
959 { 959 {
960 for (int j=0; j<3; ++j) 960 for (int j=0; j<3; ++j)
961 { 961 {
962#ifdef __BIG_ENDIAN__ 962#ifdef __BIG_ENDIAN__
963 TransformationMatrix(i,j)=os::Byteswap::byteswap(mat[i][j]); 963 TransformationMatrix(i,j)=os::Byteswap::byteswap(mat[i][j]);
964#else 964#else
965 TransformationMatrix(i,j)=mat[i][j]; 965 TransformationMatrix(i,j)=mat[i][j];
966#endif 966#endif
967 } 967 }
968 } 968 }
969 data.read += 12*sizeof(f32); 969 data.read += 12*sizeof(f32);
970 } 970 }
971 break; 971 break;
972 case C3DS_MESHCOLOR: 972 case C3DS_MESHCOLOR:
973 { 973 {
974 u8 flag; 974 u8 flag;
975 file->read(&flag, sizeof(u8)); 975 file->read(&flag, sizeof(u8));
976 ++data.read; 976 ++data.read;
977 } 977 }
978 break; 978 break;
979 case C3DS_TRISMOOTH: // TODO 979 case C3DS_TRISMOOTH: // TODO
980 { 980 {
981 SmoothingGroups = new u32[CountFaces]; 981 SmoothingGroups = new u32[CountFaces];
982 file->read(SmoothingGroups, CountFaces*sizeof(u32)); 982 file->read(SmoothingGroups, CountFaces*sizeof(u32));
983#ifdef __BIG_ENDIAN__ 983#ifdef __BIG_ENDIAN__
984 for (u16 i=0; i<CountFaces; ++i) 984 for (u16 i=0; i<CountFaces; ++i)
985 SmoothingGroups[i] = os::Byteswap::byteswap(SmoothingGroups[i]); 985 SmoothingGroups[i] = os::Byteswap::byteswap(SmoothingGroups[i]);
986#endif 986#endif
987 data.read += CountFaces*sizeof(u32); 987 data.read += CountFaces*sizeof(u32);
988 } 988 }
989 break; 989 break;
990 990
991 default: 991 default:
992 // ignore chunk 992 // ignore chunk
993 file->seek(data.header.length - data.read, true); 993 file->seek(data.header.length - data.read, true);
994 data.read += data.header.length - data.read; 994 data.read += data.header.length - data.read;
995 } 995 }
996 996
997 parent->read += data.read; 997 parent->read += data.read;
998 } 998 }
999 999
1000 return true; 1000 return true;
1001} 1001}
1002 1002
1003 1003
1004void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name) 1004void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name)
1005{ 1005{
1006#ifdef _IRR_DEBUG_3DS_LOADER_ 1006#ifdef _IRR_DEBUG_3DS_LOADER_
1007 os::Printer::log("Compose object.", ELL_DEBUG); 1007 os::Printer::log("Compose object.", ELL_DEBUG);
1008#endif 1008#endif
1009 if (Mesh->getMeshBufferCount() != Materials.size()) 1009 if (Mesh->getMeshBufferCount() != Materials.size())
1010 loadMaterials(file); 1010 loadMaterials(file);
1011 1011
1012 if (MaterialGroups.empty()) 1012 if (MaterialGroups.empty())
1013 { 1013 {
1014 // no material group, so add all 1014 // no material group, so add all
1015 SMaterialGroup group; 1015 SMaterialGroup group;
1016 group.faceCount = CountFaces; 1016 group.faceCount = CountFaces;
1017 group.faces = new u16[group.faceCount]; 1017 group.faces = new u16[group.faceCount];
1018 for (u32 i=0; i<group.faceCount; ++i) 1018 for (u32 i=0; i<group.faceCount; ++i)
1019 group.faces[i] = i; 1019 group.faces[i] = i;
1020 MaterialGroups.push_back(group); 1020 MaterialGroups.push_back(group);
1021 1021
1022 // if we've got no material, add one without a texture 1022 // if we've got no material, add one without a texture
1023 if (Materials.empty()) 1023 if (Materials.empty())
1024 { 1024 {
1025 SCurrentMaterial m; 1025 SCurrentMaterial m;
1026 Materials.push_back(m); 1026 Materials.push_back(m);
1027 SMeshBuffer* mb = new scene::SMeshBuffer(); 1027 SMeshBuffer* mb = new scene::SMeshBuffer();
1028 Mesh->addMeshBuffer(mb); 1028 Mesh->addMeshBuffer(mb);
1029 mb->getMaterial() = Materials[0].Material; 1029 mb->getMaterial() = Materials[0].Material;
1030 mb->drop(); 1030 mb->drop();
1031 // add an empty mesh buffer name 1031 // add an empty mesh buffer name
1032 MeshBufferNames.push_back(""); 1032 MeshBufferNames.push_back("");
1033 } 1033 }
1034 } 1034 }
1035 1035
1036 for (u32 i=0; i<MaterialGroups.size(); ++i) 1036 for (u32 i=0; i<MaterialGroups.size(); ++i)
1037 { 1037 {
1038 SMeshBuffer* mb = 0; 1038 SMeshBuffer* mb = 0;
1039 video::SMaterial* mat=0; 1039 video::SMaterial* mat=0;
1040 u32 mbPos; 1040 u32 mbPos;
1041 // -3 because we add three vertices at once 1041 // -3 because we add three vertices at once
1042 u32 maxPrimitives = core::min_(SceneManager->getVideoDriver()->getMaximalPrimitiveCount(), (u32)((1<<16)-1))-3; // currently hardcoded s16 max value for index pointers 1042 u32 maxPrimitives = core::min_(SceneManager->getVideoDriver()->getMaximalPrimitiveCount(), (u32)((1<<16)-1))-3; // currently hardcoded s16 max value for index pointers
1043 1043
1044 // find mesh buffer for this group 1044 // find mesh buffer for this group
1045 for (mbPos=0; mbPos<Materials.size(); ++mbPos) 1045 for (mbPos=0; mbPos<Materials.size(); ++mbPos)
1046 { 1046 {
1047 if (MaterialGroups[i].MaterialName == Materials[mbPos].Name) 1047 if (MaterialGroups[i].MaterialName == Materials[mbPos].Name)
1048 { 1048 {
1049 mb = (SMeshBuffer*)Mesh->getMeshBuffer(mbPos); 1049 mb = (SMeshBuffer*)Mesh->getMeshBuffer(mbPos);
1050 mat=&Materials[mbPos].Material; 1050 mat=&Materials[mbPos].Material;
1051 MeshBufferNames[mbPos]=name; 1051 MeshBufferNames[mbPos]=name;
1052 break; 1052 break;
1053 } 1053 }
1054 } 1054 }
1055 1055
1056 if (mb != 0) 1056 if (mb != 0)
1057 { 1057 {
1058 // add geometry to the buffer. 1058 // add geometry to the buffer.
1059 1059
1060 video::S3DVertex vtx; 1060 video::S3DVertex vtx;
1061 core::vector3df vec; 1061 core::vector3df vec;
1062 vtx.Color=mat->DiffuseColor; 1062 vtx.Color=mat->DiffuseColor;
1063 if (mat->MaterialType==video::EMT_TRANSPARENT_VERTEX_ALPHA) 1063 if (mat->MaterialType==video::EMT_TRANSPARENT_VERTEX_ALPHA)
1064 { 1064 {
1065 vtx.Color.setAlpha((int)(255.0f*mat->MaterialTypeParam)); 1065 vtx.Color.setAlpha((int)(255.0f*mat->MaterialTypeParam));
1066 } 1066 }
1067 vtx.Normal.set(0,0,0); 1067 vtx.Normal.set(0,0,0);
1068 1068
1069 for (s32 f=0; f<MaterialGroups[i].faceCount; ++f) 1069 for (s32 f=0; f<MaterialGroups[i].faceCount; ++f)
1070 { 1070 {
1071 u32 vtxCount = mb->Vertices.size(); 1071 u32 vtxCount = mb->Vertices.size();
1072 if (vtxCount>maxPrimitives) 1072 if (vtxCount>maxPrimitives)
1073 { 1073 {
1074 IMeshBuffer* tmp = mb; 1074 IMeshBuffer* tmp = mb;
1075 mb = new SMeshBuffer(); 1075 mb = new SMeshBuffer();
1076 Mesh->addMeshBuffer(mb); 1076 Mesh->addMeshBuffer(mb);
1077 mb->drop(); 1077 mb->drop();
1078 Mesh->MeshBuffers[mbPos] = Mesh->MeshBuffers.getLast(); 1078 Mesh->MeshBuffers[mbPos] = Mesh->MeshBuffers.getLast();
1079 Mesh->MeshBuffers[Mesh->MeshBuffers.size()-1] = tmp; 1079 Mesh->MeshBuffers[Mesh->MeshBuffers.size()-1] = tmp;
1080 mb->getMaterial() = tmp->getMaterial(); 1080 mb->getMaterial() = tmp->getMaterial();
1081 vtxCount=0; 1081 vtxCount=0;
1082 } 1082 }
1083 1083
1084 for (s32 v=0; v<3; ++v) 1084 for (s32 v=0; v<3; ++v)
1085 { 1085 {
1086 s32 idx = Indices[MaterialGroups[i].faces[f]*4 +v]; 1086 s32 idx = Indices[MaterialGroups[i].faces[f]*4 +v];
1087 1087
1088 if (CountVertices > idx) 1088 if (CountVertices > idx)
1089 { 1089 {
1090 vtx.Pos.X = Vertices[idx*3 + 0]; 1090 vtx.Pos.X = Vertices[idx*3 + 0];
1091 vtx.Pos.Z = Vertices[idx*3 + 1]; 1091 vtx.Pos.Z = Vertices[idx*3 + 1];
1092 vtx.Pos.Y = Vertices[idx*3 + 2]; 1092 vtx.Pos.Y = Vertices[idx*3 + 2];
1093// TransformationMatrix.transformVect(vtx.Pos); 1093// TransformationMatrix.transformVect(vtx.Pos);
1094 } 1094 }
1095 1095
1096 if (CountTCoords > idx) 1096 if (CountTCoords > idx)
1097 { 1097 {
1098 vtx.TCoords.X = TCoords[idx*2 + 0]; 1098 vtx.TCoords.X = TCoords[idx*2 + 0];
1099 vtx.TCoords.Y = 1.0f -TCoords[idx*2 + 1]; 1099 vtx.TCoords.Y = 1.0f -TCoords[idx*2 + 1];
1100 } 1100 }
1101 1101
1102 mb->Vertices.push_back(vtx); 1102 mb->Vertices.push_back(vtx);
1103 } 1103 }
1104 1104
1105 // compute normal 1105 // compute normal
1106 core::plane3d<f32> pl(mb->Vertices[vtxCount].Pos, mb->Vertices[vtxCount+2].Pos, 1106 core::plane3d<f32> pl(mb->Vertices[vtxCount].Pos, mb->Vertices[vtxCount+2].Pos,
1107 mb->Vertices[vtxCount+1].Pos); 1107 mb->Vertices[vtxCount+1].Pos);
1108 1108
1109 mb->Vertices[vtxCount].Normal = pl.Normal; 1109 mb->Vertices[vtxCount].Normal = pl.Normal;
1110 mb->Vertices[vtxCount+1].Normal = pl.Normal; 1110 mb->Vertices[vtxCount+1].Normal = pl.Normal;
1111 mb->Vertices[vtxCount+2].Normal = pl.Normal; 1111 mb->Vertices[vtxCount+2].Normal = pl.Normal;
1112 1112
1113 // add indices 1113 // add indices
1114 1114
1115 mb->Indices.push_back(vtxCount); 1115 mb->Indices.push_back(vtxCount);
1116 mb->Indices.push_back(vtxCount+2); 1116 mb->Indices.push_back(vtxCount+2);
1117 mb->Indices.push_back(vtxCount+1); 1117 mb->Indices.push_back(vtxCount+1);
1118 } 1118 }
1119 } 1119 }
1120 else 1120 else
1121 os::Printer::log("Found no matching material for Group in 3ds file.", ELL_WARNING); 1121 os::Printer::log("Found no matching material for Group in 3ds file.", ELL_WARNING);
1122 } 1122 }
1123 1123
1124 cleanUp(); 1124 cleanUp();
1125} 1125}
1126 1126
1127 1127
1128void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file) 1128void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file)
1129{ 1129{
1130 // create a mesh buffer for every material 1130 // create a mesh buffer for every material
1131 core::stringc modelFilename = file->getFileName(); 1131 core::stringc modelFilename = file->getFileName();
1132 1132
1133 if (Materials.empty()) 1133 if (Materials.empty())
1134 os::Printer::log("No materials found in 3ds file.", ELL_INFORMATION); 1134 os::Printer::log("No materials found in 3ds file.", ELL_INFORMATION);
1135 1135
1136 MeshBufferNames.reallocate(Materials.size()); 1136 MeshBufferNames.reallocate(Materials.size());
1137 for (u32 i=0; i<Materials.size(); ++i) 1137 for (u32 i=0; i<Materials.size(); ++i)
1138 { 1138 {
1139 MeshBufferNames.push_back(""); 1139 MeshBufferNames.push_back("");
1140 SMeshBuffer* m = new scene::SMeshBuffer(); 1140 SMeshBuffer* m = new scene::SMeshBuffer();
1141 Mesh->addMeshBuffer(m); 1141 Mesh->addMeshBuffer(m);
1142 1142
1143 m->getMaterial() = Materials[i].Material; 1143 m->getMaterial() = Materials[i].Material;
1144 if (Materials[i].Filename[0].size()) 1144 if (Materials[i].Filename[0].size())
1145 { 1145 {
1146 video::ITexture* texture = 0; 1146 video::ITexture* texture = 0;
1147 if (FileSystem->existFile(Materials[i].Filename[0])) 1147 if (FileSystem->existFile(Materials[i].Filename[0]))
1148 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[0]); 1148 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[0]);
1149 if (!texture) 1149 if (!texture)
1150 { 1150 {
1151 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[0]); 1151 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[0]);
1152 if (FileSystem->existFile(fname)) 1152 if (FileSystem->existFile(fname))
1153 texture = SceneManager->getVideoDriver()->getTexture(fname); 1153 texture = SceneManager->getVideoDriver()->getTexture(fname);
1154 } 1154 }
1155 if (!texture) 1155 if (!texture)
1156 os::Printer::log("Could not load a texture for entry in 3ds file", 1156 os::Printer::log("Could not load a texture for entry in 3ds file",
1157 Materials[i].Filename[0].c_str(), ELL_WARNING); 1157 Materials[i].Filename[0].c_str(), ELL_WARNING);
1158 else 1158 else
1159 m->getMaterial().setTexture(0, texture); 1159 m->getMaterial().setTexture(0, texture);
1160 } 1160 }
1161 1161
1162 if (Materials[i].Filename[2].size()) 1162 if (Materials[i].Filename[2].size())
1163 { 1163 {
1164 video::ITexture* texture = 0; 1164 video::ITexture* texture = 0;
1165 if (FileSystem->existFile(Materials[i].Filename[2])) 1165 if (FileSystem->existFile(Materials[i].Filename[2]))
1166 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[2]); 1166 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[2]);
1167 if (!texture) 1167 if (!texture)
1168 { 1168 {
1169 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[2]); 1169 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[2]);
1170 if (FileSystem->existFile(fname)) 1170 if (FileSystem->existFile(fname))
1171 texture = SceneManager->getVideoDriver()->getTexture(fname); 1171 texture = SceneManager->getVideoDriver()->getTexture(fname);
1172 } 1172 }
1173 if (!texture) 1173 if (!texture)
1174 { 1174 {
1175 os::Printer::log("Could not load a texture for entry in 3ds file", 1175 os::Printer::log("Could not load a texture for entry in 3ds file",
1176 Materials[i].Filename[2].c_str(), ELL_WARNING); 1176 Materials[i].Filename[2].c_str(), ELL_WARNING);
1177 } 1177 }
1178 else 1178 else
1179 { 1179 {
1180 m->getMaterial().setTexture(0, texture); 1180 m->getMaterial().setTexture(0, texture);
1181 m->getMaterial().MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; 1181 m->getMaterial().MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
1182 } 1182 }
1183 } 1183 }
1184 1184
1185 if (Materials[i].Filename[3].size()) 1185 if (Materials[i].Filename[3].size())
1186 { 1186 {
1187 video::ITexture* texture = 0; 1187 video::ITexture* texture = 0;
1188 if (FileSystem->existFile(Materials[i].Filename[3])) 1188 if (FileSystem->existFile(Materials[i].Filename[3]))
1189 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[3]); 1189 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[3]);
1190 if (!texture) 1190 if (!texture)
1191 { 1191 {
1192 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[3]); 1192 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[3]);
1193 if (FileSystem->existFile(fname)) 1193 if (FileSystem->existFile(fname))
1194 texture = SceneManager->getVideoDriver()->getTexture(fname); 1194 texture = SceneManager->getVideoDriver()->getTexture(fname);
1195 } 1195 }
1196 1196
1197 if (!texture) 1197 if (!texture)
1198 { 1198 {
1199 os::Printer::log("Could not load a texture for entry in 3ds file", 1199 os::Printer::log("Could not load a texture for entry in 3ds file",
1200 Materials[i].Filename[3].c_str(), ELL_WARNING); 1200 Materials[i].Filename[3].c_str(), ELL_WARNING);
1201 } 1201 }
1202 else 1202 else
1203 { 1203 {
1204 m->getMaterial().setTexture(1, m->getMaterial().getTexture(0)); 1204 m->getMaterial().setTexture(1, m->getMaterial().getTexture(0));
1205 m->getMaterial().setTexture(0, texture); 1205 m->getMaterial().setTexture(0, texture);
1206 m->getMaterial().MaterialType = video::EMT_REFLECTION_2_LAYER; 1206 m->getMaterial().MaterialType = video::EMT_REFLECTION_2_LAYER;
1207 } 1207 }
1208 } 1208 }
1209 1209
1210 if (Materials[i].Filename[4].size()) 1210 if (Materials[i].Filename[4].size())
1211 { 1211 {
1212 video::ITexture* texture = 0; 1212 video::ITexture* texture = 0;
1213 if (FileSystem->existFile(Materials[i].Filename[4])) 1213 if (FileSystem->existFile(Materials[i].Filename[4]))
1214 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[4]); 1214 texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[4]);
1215 if (!texture) 1215 if (!texture)
1216 { 1216 {
1217 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[4]); 1217 const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[4]);
1218 if (FileSystem->existFile(fname)) 1218 if (FileSystem->existFile(fname))
1219 texture = SceneManager->getVideoDriver()->getTexture(fname); 1219 texture = SceneManager->getVideoDriver()->getTexture(fname);
1220 } 1220 }
1221 if (!texture) 1221 if (!texture)
1222 os::Printer::log("Could not load a texture for entry in 3ds file", 1222 os::Printer::log("Could not load a texture for entry in 3ds file",
1223 Materials[i].Filename[4].c_str(), ELL_WARNING); 1223 Materials[i].Filename[4].c_str(), ELL_WARNING);
1224 else 1224 else
1225 { 1225 {
1226 m->getMaterial().setTexture(1, texture); 1226 m->getMaterial().setTexture(1, texture);
1227 SceneManager->getVideoDriver()->makeNormalMapTexture(texture, Materials[i].Strength[4]*10.f); 1227 SceneManager->getVideoDriver()->makeNormalMapTexture(texture, Materials[i].Strength[4]*10.f);
1228 m->getMaterial().MaterialType=video::EMT_PARALLAX_MAP_SOLID; 1228 m->getMaterial().MaterialType=video::EMT_PARALLAX_MAP_SOLID;
1229 m->getMaterial().MaterialTypeParam=.035f; 1229 m->getMaterial().MaterialTypeParam=.035f;
1230 } 1230 }
1231 } 1231 }
1232 1232
1233 m->drop(); 1233 m->drop();
1234 } 1234 }
1235} 1235}
1236 1236
1237 1237
1238void C3DSMeshFileLoader::cleanUp() 1238void C3DSMeshFileLoader::cleanUp()
1239{ 1239{
1240 delete [] Vertices; 1240 delete [] Vertices;
1241 CountVertices = 0; 1241 CountVertices = 0;
1242 Vertices = 0; 1242 Vertices = 0;
1243 delete [] Indices; 1243 delete [] Indices;
1244 Indices = 0; 1244 Indices = 0;
1245 CountFaces = 0; 1245 CountFaces = 0;
1246 delete [] SmoothingGroups; 1246 delete [] SmoothingGroups;
1247 SmoothingGroups = 0; 1247 SmoothingGroups = 0;
1248 delete [] TCoords; 1248 delete [] TCoords;
1249 TCoords = 0; 1249 TCoords = 0;
1250 CountTCoords = 0; 1250 CountTCoords = 0;
1251 1251
1252 MaterialGroups.clear(); 1252 MaterialGroups.clear();
1253} 1253}
1254 1254
1255 1255
1256void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data) 1256void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data)
1257{ 1257{
1258#ifdef _IRR_DEBUG_3DS_LOADER_ 1258#ifdef _IRR_DEBUG_3DS_LOADER_
1259 os::Printer::log("Load texture coords.", ELL_DEBUG); 1259 os::Printer::log("Load texture coords.", ELL_DEBUG);
1260#endif 1260#endif
1261 file->read(&CountTCoords, sizeof(CountTCoords)); 1261 file->read(&CountTCoords, sizeof(CountTCoords));
1262#ifdef __BIG_ENDIAN__ 1262#ifdef __BIG_ENDIAN__
1263 CountTCoords = os::Byteswap::byteswap(CountTCoords); 1263 CountTCoords = os::Byteswap::byteswap(CountTCoords);
1264#endif 1264#endif
1265 data.read += sizeof(CountTCoords); 1265 data.read += sizeof(CountTCoords);
1266 1266
1267 s32 tcoordsBufferByteSize = CountTCoords * sizeof(f32) * 2; 1267 s32 tcoordsBufferByteSize = CountTCoords * sizeof(f32) * 2;
1268 1268
1269 if (data.header.length - data.read != tcoordsBufferByteSize) 1269 if (data.header.length - data.read != tcoordsBufferByteSize)
1270 { 1270 {
1271 os::Printer::log("Invalid size of tcoords found in 3ds file.", ELL_WARNING); 1271 os::Printer::log("Invalid size of tcoords found in 3ds file.", ELL_WARNING);
1272 return; 1272 return;
1273 } 1273 }
1274 1274
1275 TCoords = new f32[CountTCoords * 3]; 1275 TCoords = new f32[CountTCoords * 3];
1276 file->read(TCoords, tcoordsBufferByteSize); 1276 file->read(TCoords, tcoordsBufferByteSize);
1277#ifdef __BIG_ENDIAN__ 1277#ifdef __BIG_ENDIAN__
1278 for (int i=0;i<CountTCoords*2;i++) TCoords[i] = os::Byteswap::byteswap(TCoords[i]); 1278 for (int i=0;i<CountTCoords*2;i++) TCoords[i] = os::Byteswap::byteswap(TCoords[i]);
1279#endif 1279#endif
1280 data.read += tcoordsBufferByteSize; 1280 data.read += tcoordsBufferByteSize;
1281} 1281}
1282 1282
1283 1283
1284void C3DSMeshFileLoader::readMaterialGroup(io::IReadFile* file, ChunkData& data) 1284void C3DSMeshFileLoader::readMaterialGroup(io::IReadFile* file, ChunkData& data)
1285{ 1285{
1286#ifdef _IRR_DEBUG_3DS_LOADER_ 1286#ifdef _IRR_DEBUG_3DS_LOADER_
1287 os::Printer::log("Load material group.", ELL_DEBUG); 1287 os::Printer::log("Load material group.", ELL_DEBUG);
1288#endif 1288#endif
1289 SMaterialGroup group; 1289 SMaterialGroup group;
1290 1290
1291 readString(file, data, group.MaterialName); 1291 readString(file, data, group.MaterialName);
1292 1292
1293 file->read(&group.faceCount, sizeof(group.faceCount)); 1293 file->read(&group.faceCount, sizeof(group.faceCount));
1294#ifdef __BIG_ENDIAN__ 1294#ifdef __BIG_ENDIAN__
1295 group.faceCount = os::Byteswap::byteswap(group.faceCount); 1295 group.faceCount = os::Byteswap::byteswap(group.faceCount);
1296#endif 1296#endif
1297 data.read += sizeof(group.faceCount); 1297 data.read += sizeof(group.faceCount);
1298 1298
1299 // read faces 1299 // read faces
1300 group.faces = new u16[group.faceCount]; 1300 group.faces = new u16[group.faceCount];
1301 file->read(group.faces, sizeof(u16) * group.faceCount); 1301 file->read(group.faces, sizeof(u16) * group.faceCount);
1302#ifdef __BIG_ENDIAN__ 1302#ifdef __BIG_ENDIAN__
1303 for (u32 i=0;i<group.faceCount;++i) 1303 for (u32 i=0;i<group.faceCount;++i)
1304 group.faces[i] = os::Byteswap::byteswap(group.faces[i]); 1304 group.faces[i] = os::Byteswap::byteswap(group.faces[i]);
1305#endif 1305#endif
1306 data.read += sizeof(u16) * group.faceCount; 1306 data.read += sizeof(u16) * group.faceCount;
1307 1307
1308 MaterialGroups.push_back(group); 1308 MaterialGroups.push_back(group);
1309} 1309}
1310 1310
1311 1311
1312void C3DSMeshFileLoader::readIndices(io::IReadFile* file, ChunkData& data) 1312void C3DSMeshFileLoader::readIndices(io::IReadFile* file, ChunkData& data)
1313{ 1313{
1314#ifdef _IRR_DEBUG_3DS_LOADER_ 1314#ifdef _IRR_DEBUG_3DS_LOADER_
1315 os::Printer::log("Load indices.", ELL_DEBUG); 1315 os::Printer::log("Load indices.", ELL_DEBUG);
1316#endif 1316#endif
1317 file->read(&CountFaces, sizeof(CountFaces)); 1317 file->read(&CountFaces, sizeof(CountFaces));
1318#ifdef __BIG_ENDIAN__ 1318#ifdef __BIG_ENDIAN__
1319 CountFaces = os::Byteswap::byteswap(CountFaces); 1319 CountFaces = os::Byteswap::byteswap(CountFaces);
1320#endif 1320#endif
1321 data.read += sizeof(CountFaces); 1321 data.read += sizeof(CountFaces);
1322 1322
1323 s32 indexBufferByteSize = CountFaces * sizeof(u16) * 4; 1323 s32 indexBufferByteSize = CountFaces * sizeof(u16) * 4;
1324 1324
1325 // Indices are u16s. 1325 // Indices are u16s.
1326 // After every 3 Indices in the array, there follows an edge flag. 1326 // After every 3 Indices in the array, there follows an edge flag.
1327 Indices = new u16[CountFaces * 4]; 1327 Indices = new u16[CountFaces * 4];
1328 file->read(Indices, indexBufferByteSize); 1328 file->read(Indices, indexBufferByteSize);
1329#ifdef __BIG_ENDIAN__ 1329#ifdef __BIG_ENDIAN__
1330 for (int i=0;i<CountFaces*4;++i) 1330 for (int i=0;i<CountFaces*4;++i)
1331 Indices[i] = os::Byteswap::byteswap(Indices[i]); 1331 Indices[i] = os::Byteswap::byteswap(Indices[i]);
1332#endif 1332#endif
1333 data.read += indexBufferByteSize; 1333 data.read += indexBufferByteSize;
1334} 1334}
1335 1335
1336 1336
1337void C3DSMeshFileLoader::readVertices(io::IReadFile* file, ChunkData& data) 1337void C3DSMeshFileLoader::readVertices(io::IReadFile* file, ChunkData& data)
1338{ 1338{
1339#ifdef _IRR_DEBUG_3DS_LOADER_ 1339#ifdef _IRR_DEBUG_3DS_LOADER_
1340 os::Printer::log("Load vertices.", ELL_DEBUG); 1340 os::Printer::log("Load vertices.", ELL_DEBUG);
1341#endif 1341#endif
1342 file->read(&CountVertices, sizeof(CountVertices)); 1342 file->read(&CountVertices, sizeof(CountVertices));
1343#ifdef __BIG_ENDIAN__ 1343#ifdef __BIG_ENDIAN__
1344 CountVertices = os::Byteswap::byteswap(CountVertices); 1344 CountVertices = os::Byteswap::byteswap(CountVertices);
1345#endif 1345#endif
1346 data.read += sizeof(CountVertices); 1346 data.read += sizeof(CountVertices);
1347 1347
1348 const s32 vertexBufferByteSize = CountVertices * sizeof(f32) * 3; 1348 const s32 vertexBufferByteSize = CountVertices * sizeof(f32) * 3;
1349 1349
1350 if (data.header.length - data.read != vertexBufferByteSize) 1350 if (data.header.length - data.read != vertexBufferByteSize)
1351 { 1351 {
1352 os::Printer::log("Invalid size of vertices found in 3ds file", core::stringc(CountVertices), ELL_ERROR); 1352 os::Printer::log("Invalid size of vertices found in 3ds file", core::stringc(CountVertices), ELL_ERROR);
1353 return; 1353 return;
1354 } 1354 }
1355 1355
1356 Vertices = new f32[CountVertices * 3]; 1356 Vertices = new f32[CountVertices * 3];
1357 file->read(Vertices, vertexBufferByteSize); 1357 file->read(Vertices, vertexBufferByteSize);
1358#ifdef __BIG_ENDIAN__ 1358#ifdef __BIG_ENDIAN__
1359 for (int i=0;i<CountVertices*3;i++) 1359 for (int i=0;i<CountVertices*3;i++)
1360 Vertices[i] = os::Byteswap::byteswap(Vertices[i]); 1360 Vertices[i] = os::Byteswap::byteswap(Vertices[i]);
1361#endif 1361#endif
1362 data.read += vertexBufferByteSize; 1362 data.read += vertexBufferByteSize;
1363} 1363}
1364 1364
1365 1365
1366void C3DSMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data) 1366void C3DSMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data)
1367{ 1367{
1368 file->read(&data.header, sizeof(ChunkHeader)); 1368 file->read(&data.header, sizeof(ChunkHeader));
1369#ifdef __BIG_ENDIAN__ 1369#ifdef __BIG_ENDIAN__
1370 data.header.id = os::Byteswap::byteswap(data.header.id); 1370 data.header.id = os::Byteswap::byteswap(data.header.id);
1371 data.header.length = os::Byteswap::byteswap(data.header.length); 1371 data.header.length = os::Byteswap::byteswap(data.header.length);
1372#endif 1372#endif
1373 data.read += sizeof(ChunkHeader); 1373 data.read += sizeof(ChunkHeader);
1374} 1374}
1375 1375
1376 1376
1377void C3DSMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) 1377void C3DSMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out)
1378{ 1378{
1379 c8 c = 1; 1379 c8 c = 1;
1380 out = ""; 1380 out = "";
1381 1381
1382 while (c) 1382 while (c)
1383 { 1383 {
1384 file->read(&c, sizeof(c8)); 1384 file->read(&c, sizeof(c8));
1385 if (c) 1385 if (c)
1386 out.append(c); 1386 out.append(c);
1387 } 1387 }
1388 data.read+=out.size()+1; 1388 data.read+=out.size()+1;
1389} 1389}
1390 1390
1391 1391
1392} // end namespace scene 1392} // end namespace scene
1393} // end namespace irr 1393} // end namespace irr
1394 1394
1395#endif // _IRR_COMPILE_WITH_3DS_LOADER_ 1395#endif // _IRR_COMPILE_WITH_3DS_LOADER_
1396 1396