aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/COgreMeshFileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/COgreMeshFileLoader.cpp3184
1 files changed, 1592 insertions, 1592 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/COgreMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/COgreMeshFileLoader.cpp
index 7a2be26..c0a967a 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/COgreMeshFileLoader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/COgreMeshFileLoader.cpp
@@ -1,1592 +1,1592 @@
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// orginally written by Christian Stehno, modified by Nikolaus Gebhardt 4// orginally written by Christian Stehno, modified by Nikolaus Gebhardt
5 5
6#include "IrrCompileConfig.h" 6#include "IrrCompileConfig.h"
7#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ 7#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
8 8
9#include "COgreMeshFileLoader.h" 9#include "COgreMeshFileLoader.h"
10#include "os.h" 10#include "os.h"
11#include "SMeshBuffer.h" 11#include "SMeshBuffer.h"
12#include "SAnimatedMesh.h" 12#include "SAnimatedMesh.h"
13#include "IReadFile.h" 13#include "IReadFile.h"
14#include "fast_atof.h" 14#include "fast_atof.h"
15#include "coreutil.h" 15#include "coreutil.h"
16 16
17#ifdef _DEBUG 17#ifdef _DEBUG
18#define IRR_OGRE_LOADER_DEBUG 18#define IRR_OGRE_LOADER_DEBUG
19#endif 19#endif
20 20
21namespace irr 21namespace irr
22{ 22{
23namespace scene 23namespace scene
24{ 24{
25 25
26namespace 26namespace
27{ 27{
28 enum OGRE_CHUNKS 28 enum OGRE_CHUNKS
29 { 29 {
30 // Main Chunks 30 // Main Chunks
31 COGRE_HEADER= 0x1000, 31 COGRE_HEADER= 0x1000,
32 COGRE_SKELETON= 0x2000, 32 COGRE_SKELETON= 0x2000,
33 COGRE_MESH= 0x3000, 33 COGRE_MESH= 0x3000,
34 34
35 // sub chunks of COGRE_MESH 35 // sub chunks of COGRE_MESH
36 COGRE_SUBMESH= 0x4000, 36 COGRE_SUBMESH= 0x4000,
37 COGRE_GEOMETRY= 0x5000, 37 COGRE_GEOMETRY= 0x5000,
38 COGRE_SKELETON_LINK= 0x6000, 38 COGRE_SKELETON_LINK= 0x6000,
39 COGRE_BONE_ASSIGNMENT= 0x7000, 39 COGRE_BONE_ASSIGNMENT= 0x7000,
40 COGRE_MESH_LOD= 0x8000, 40 COGRE_MESH_LOD= 0x8000,
41 COGRE_MESH_BOUNDS= 0x9000, 41 COGRE_MESH_BOUNDS= 0x9000,
42 COGRE_MESH_SUBMESH_NAME_TABLE= 0xA000, 42 COGRE_MESH_SUBMESH_NAME_TABLE= 0xA000,
43 COGRE_MESH_EDGE_LISTS= 0xB000, 43 COGRE_MESH_EDGE_LISTS= 0xB000,
44 44
45 // sub chunks of COGRE_SKELETON 45 // sub chunks of COGRE_SKELETON
46 COGRE_BONE_PARENT= 0x3000, 46 COGRE_BONE_PARENT= 0x3000,
47 COGRE_ANIMATION= 0x4000, 47 COGRE_ANIMATION= 0x4000,
48 COGRE_ANIMATION_TRACK= 0x4100, 48 COGRE_ANIMATION_TRACK= 0x4100,
49 COGRE_ANIMATION_KEYFRAME= 0x4110, 49 COGRE_ANIMATION_KEYFRAME= 0x4110,
50 COGRE_ANIMATION_LINK= 0x5000, 50 COGRE_ANIMATION_LINK= 0x5000,
51 51
52 // sub chunks of COGRE_SUBMESH 52 // sub chunks of COGRE_SUBMESH
53 COGRE_SUBMESH_OPERATION= 0x4010, 53 COGRE_SUBMESH_OPERATION= 0x4010,
54 COGRE_SUBMESH_BONE_ASSIGNMENT= 0x4100, 54 COGRE_SUBMESH_BONE_ASSIGNMENT= 0x4100,
55 COGRE_SUBMESH_TEXTURE_ALIAS= 0x4200, 55 COGRE_SUBMESH_TEXTURE_ALIAS= 0x4200,
56 56
57 // sub chunks of COGRE_GEOMETRY 57 // sub chunks of COGRE_GEOMETRY
58 COGRE_GEOMETRY_VERTEX_DECLARATION= 0x5100, 58 COGRE_GEOMETRY_VERTEX_DECLARATION= 0x5100,
59 COGRE_GEOMETRY_VERTEX_ELEMENT= 0x5110, 59 COGRE_GEOMETRY_VERTEX_ELEMENT= 0x5110,
60 COGRE_GEOMETRY_VERTEX_BUFFER= 0x5200, 60 COGRE_GEOMETRY_VERTEX_BUFFER= 0x5200,
61 COGRE_GEOMETRY_VERTEX_BUFFER_DATA= 0x5210 61 COGRE_GEOMETRY_VERTEX_BUFFER_DATA= 0x5210
62 }; 62 };
63} 63}
64 64
65//! Constructor 65//! Constructor
66COgreMeshFileLoader::COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) 66COgreMeshFileLoader::COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver)
67: FileSystem(fs), Driver(driver), SwapEndian(false), Mesh(0), NumUV(0) 67: FileSystem(fs), Driver(driver), SwapEndian(false), Mesh(0), NumUV(0)
68{ 68{
69 69
70 #ifdef _DEBUG 70 #ifdef _DEBUG
71 setDebugName("COgreMeshFileLoader"); 71 setDebugName("COgreMeshFileLoader");
72 #endif 72 #endif
73 73
74 if (FileSystem) 74 if (FileSystem)
75 FileSystem->grab(); 75 FileSystem->grab();
76 76
77 if (Driver) 77 if (Driver)
78 Driver->grab(); 78 Driver->grab();
79} 79}
80 80
81 81
82//! destructor 82//! destructor
83COgreMeshFileLoader::~COgreMeshFileLoader() 83COgreMeshFileLoader::~COgreMeshFileLoader()
84{ 84{
85 clearMeshes(); 85 clearMeshes();
86 86
87 if (FileSystem) 87 if (FileSystem)
88 FileSystem->drop(); 88 FileSystem->drop();
89 89
90 if (Driver) 90 if (Driver)
91 Driver->drop(); 91 Driver->drop();
92 92
93 if (Mesh) 93 if (Mesh)
94 Mesh->drop(); 94 Mesh->drop();
95} 95}
96 96
97 97
98//! returns true if the file maybe is able to be loaded by this class 98//! returns true if the file maybe is able to be loaded by this class
99//! based on the file extension (e.g. ".bsp") 99//! based on the file extension (e.g. ".bsp")
100bool COgreMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 100bool COgreMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
101{ 101{
102 return core::hasFileExtension ( filename, "mesh" ); 102 return core::hasFileExtension ( filename, "mesh" );
103} 103}
104 104
105 105
106//! creates/loads an animated mesh from the file. 106//! creates/loads an animated mesh from the file.
107//! \return Pointer to the created mesh. Returns 0 if loading failed. 107//! \return Pointer to the created mesh. Returns 0 if loading failed.
108//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). 108//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
109//! See IReferenceCounted::drop() for more information. 109//! See IReferenceCounted::drop() for more information.
110IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file) 110IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file)
111{ 111{
112 s16 id; 112 s16 id;
113 113
114 file->read(&id, 2); 114 file->read(&id, 2);
115 115
116 if (id == COGRE_HEADER) 116 if (id == COGRE_HEADER)
117 SwapEndian=false; 117 SwapEndian=false;
118 else if (id == 0x0010) 118 else if (id == 0x0010)
119 SwapEndian=true; 119 SwapEndian=true;
120 else 120 else
121 return 0; 121 return 0;
122 ChunkData data; 122 ChunkData data;
123 readString(file, data, Version); 123 readString(file, data, Version);
124 if ((Version != "[MeshSerializer_v1.30]") && (Version != "[MeshSerializer_v1.40]") && (Version != "[MeshSerializer_v1.41]")) 124 if ((Version != "[MeshSerializer_v1.30]") && (Version != "[MeshSerializer_v1.40]") && (Version != "[MeshSerializer_v1.41]"))
125 return 0; 125 return 0;
126 126
127 clearMeshes(); 127 clearMeshes();
128 if (Mesh) 128 if (Mesh)
129 Mesh->drop(); 129 Mesh->drop();
130 130
131 CurrentlyLoadingFromPath = FileSystem->getFileDir(file->getFileName()); 131 CurrentlyLoadingFromPath = FileSystem->getFileDir(file->getFileName());
132 loadMaterials(file); 132 loadMaterials(file);
133 133
134 if (readChunk(file)) 134 if (readChunk(file))
135 { 135 {
136 // delete data loaded from file 136 // delete data loaded from file
137 clearMeshes(); 137 clearMeshes();
138 138
139 if (Skeleton.Bones.size()) 139 if (Skeleton.Bones.size())
140 { 140 {
141 ISkinnedMesh* tmp = static_cast<CSkinnedMesh*>(Mesh); 141 ISkinnedMesh* tmp = static_cast<CSkinnedMesh*>(Mesh);
142 static_cast<CSkinnedMesh*>(Mesh)->updateBoundingBox(); 142 static_cast<CSkinnedMesh*>(Mesh)->updateBoundingBox();
143 Skeleton.Animations.clear(); 143 Skeleton.Animations.clear();
144 Skeleton.Bones.clear(); 144 Skeleton.Bones.clear();
145 Mesh=0; 145 Mesh=0;
146 return tmp; 146 return tmp;
147 } 147 }
148 else 148 else
149 { 149 {
150 for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) 150 for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
151 ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox(); 151 ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox();
152 152
153 ((SMesh*)Mesh)->recalculateBoundingBox(); 153 ((SMesh*)Mesh)->recalculateBoundingBox();
154 SAnimatedMesh* am = new SAnimatedMesh(); 154 SAnimatedMesh* am = new SAnimatedMesh();
155 am->Type = EAMT_3DS; 155 am->Type = EAMT_3DS;
156 am->addMesh(Mesh); 156 am->addMesh(Mesh);
157 am->recalculateBoundingBox(); 157 am->recalculateBoundingBox();
158 Mesh->drop(); 158 Mesh->drop();
159 Mesh = 0; 159 Mesh = 0;
160 return am; 160 return am;
161 } 161 }
162 } 162 }
163 163
164 Mesh->drop(); 164 Mesh->drop();
165 Mesh = 0; 165 Mesh = 0;
166 166
167 return 0; 167 return 0;
168} 168}
169 169
170 170
171bool COgreMeshFileLoader::readChunk(io::IReadFile* file) 171bool COgreMeshFileLoader::readChunk(io::IReadFile* file)
172{ 172{
173 while(file->getPos() < file->getSize()) 173 while(file->getPos() < file->getSize())
174 { 174 {
175 ChunkData data; 175 ChunkData data;
176 readChunkData(file, data); 176 readChunkData(file, data);
177 177
178 switch(data.header.id) 178 switch(data.header.id)
179 { 179 {
180 case COGRE_MESH: 180 case COGRE_MESH:
181 { 181 {
182 Meshes.push_back(OgreMesh()); 182 Meshes.push_back(OgreMesh());
183 readObjectChunk(file, data, Meshes.getLast()); 183 readObjectChunk(file, data, Meshes.getLast());
184 if (Skeleton.Bones.size()) 184 if (Skeleton.Bones.size())
185 Mesh = new CSkinnedMesh(); 185 Mesh = new CSkinnedMesh();
186 else 186 else
187 Mesh = new SMesh(); 187 Mesh = new SMesh();
188 composeObject(); 188 composeObject();
189 } 189 }
190 break; 190 break;
191 default: 191 default:
192 return true; 192 return true;
193 } 193 }
194 } 194 }
195 195
196 return true; 196 return true;
197} 197}
198 198
199 199
200bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh) 200bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh)
201{ 201{
202#ifdef IRR_OGRE_LOADER_DEBUG 202#ifdef IRR_OGRE_LOADER_DEBUG
203 os::Printer::log("Read Object Chunk", ELL_DEBUG); 203 os::Printer::log("Read Object Chunk", ELL_DEBUG);
204#endif 204#endif
205 readBool(file, parent, mesh.SkeletalAnimation); 205 readBool(file, parent, mesh.SkeletalAnimation);
206 bool skeleton_loaded=false; 206 bool skeleton_loaded=false;
207 while ((parent.read < parent.header.length)&&(file->getPos() < file->getSize())) 207 while ((parent.read < parent.header.length)&&(file->getPos() < file->getSize()))
208 { 208 {
209 ChunkData data; 209 ChunkData data;
210 readChunkData(file, data); 210 readChunkData(file, data);
211 211
212 switch(data.header.id) 212 switch(data.header.id)
213 { 213 {
214 case COGRE_GEOMETRY: 214 case COGRE_GEOMETRY:
215 readGeometry(file, data, mesh.Geometry); 215 readGeometry(file, data, mesh.Geometry);
216 break; 216 break;
217 case COGRE_SUBMESH: 217 case COGRE_SUBMESH:
218 mesh.SubMeshes.push_back(OgreSubMesh()); 218 mesh.SubMeshes.push_back(OgreSubMesh());
219 readSubMesh(file, data, mesh.SubMeshes.getLast()); 219 readSubMesh(file, data, mesh.SubMeshes.getLast());
220 break; 220 break;
221 case COGRE_MESH_BOUNDS: 221 case COGRE_MESH_BOUNDS:
222 { 222 {
223#ifdef IRR_OGRE_LOADER_DEBUG 223#ifdef IRR_OGRE_LOADER_DEBUG
224 os::Printer::log("Read Mesh Bounds", ELL_DEBUG); 224 os::Printer::log("Read Mesh Bounds", ELL_DEBUG);
225#endif 225#endif
226 readVector(file, data, mesh.BBoxMinEdge); 226 readVector(file, data, mesh.BBoxMinEdge);
227 readVector(file, data, mesh.BBoxMaxEdge); 227 readVector(file, data, mesh.BBoxMaxEdge);
228 readFloat(file, data, &mesh.BBoxRadius); 228 readFloat(file, data, &mesh.BBoxRadius);
229 } 229 }
230 break; 230 break;
231 case COGRE_SKELETON_LINK: 231 case COGRE_SKELETON_LINK:
232 { 232 {
233#ifdef IRR_OGRE_LOADER_DEBUG 233#ifdef IRR_OGRE_LOADER_DEBUG
234 os::Printer::log("Read Skeleton link", ELL_DEBUG); 234 os::Printer::log("Read Skeleton link", ELL_DEBUG);
235#endif 235#endif
236 core::stringc name; 236 core::stringc name;
237 readString(file, data, name); 237 readString(file, data, name);
238 loadSkeleton(file, name); 238 loadSkeleton(file, name);
239 skeleton_loaded=true; 239 skeleton_loaded=true;
240 } 240 }
241 break; 241 break;
242 case COGRE_BONE_ASSIGNMENT: 242 case COGRE_BONE_ASSIGNMENT:
243 { 243 {
244 mesh.BoneAssignments.push_back(OgreBoneAssignment()); 244 mesh.BoneAssignments.push_back(OgreBoneAssignment());
245 readInt(file, data, &mesh.BoneAssignments.getLast().VertexID); 245 readInt(file, data, &mesh.BoneAssignments.getLast().VertexID);
246 readShort(file, data, &mesh.BoneAssignments.getLast().BoneID); 246 readShort(file, data, &mesh.BoneAssignments.getLast().BoneID);
247 readFloat(file, data, &mesh.BoneAssignments.getLast().Weight); 247 readFloat(file, data, &mesh.BoneAssignments.getLast().Weight);
248 } 248 }
249 break; 249 break;
250 case COGRE_MESH_LOD: 250 case COGRE_MESH_LOD:
251 case COGRE_MESH_SUBMESH_NAME_TABLE: 251 case COGRE_MESH_SUBMESH_NAME_TABLE:
252 case COGRE_MESH_EDGE_LISTS: 252 case COGRE_MESH_EDGE_LISTS:
253 // ignore chunk 253 // ignore chunk
254 file->seek(data.header.length-data.read, true); 254 file->seek(data.header.length-data.read, true);
255 data.read += data.header.length-data.read; 255 data.read += data.header.length-data.read;
256 break; 256 break;
257 default: 257 default:
258#ifdef IRR_OGRE_LOADER_DEBUG 258#ifdef IRR_OGRE_LOADER_DEBUG
259 os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG); 259 os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG);
260#endif 260#endif
261 // ignore chunk 261 // ignore chunk
262 file->seek(data.header.length-data.read, true); 262 file->seek(data.header.length-data.read, true);
263 data.read += data.header.length-data.read; 263 data.read += data.header.length-data.read;
264 break; 264 break;
265 } 265 }
266 parent.read += data.read; 266 parent.read += data.read;
267 } 267 }
268 if (!skeleton_loaded) 268 if (!skeleton_loaded)
269 loadSkeleton(file, FileSystem->getFileBasename(file->getFileName(), false)); 269 loadSkeleton(file, FileSystem->getFileBasename(file->getFileName(), false));
270 return true; 270 return true;
271} 271}
272 272
273 273
274bool COgreMeshFileLoader::readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) 274bool COgreMeshFileLoader::readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry)
275{ 275{
276#ifdef IRR_OGRE_LOADER_DEBUG 276#ifdef IRR_OGRE_LOADER_DEBUG
277 os::Printer::log("Read Geometry", ELL_DEBUG); 277 os::Printer::log("Read Geometry", ELL_DEBUG);
278#endif 278#endif
279 readInt(file, parent, &geometry.NumVertex); 279 readInt(file, parent, &geometry.NumVertex);
280 while(parent.read < parent.header.length) 280 while(parent.read < parent.header.length)
281 { 281 {
282 ChunkData data; 282 ChunkData data;
283 readChunkData(file, data); 283 readChunkData(file, data);
284 284
285 switch(data.header.id) 285 switch(data.header.id)
286 { 286 {
287 case COGRE_GEOMETRY_VERTEX_DECLARATION: 287 case COGRE_GEOMETRY_VERTEX_DECLARATION:
288 readVertexDeclaration(file, data, geometry); 288 readVertexDeclaration(file, data, geometry);
289 break; 289 break;
290 case COGRE_GEOMETRY_VERTEX_BUFFER: 290 case COGRE_GEOMETRY_VERTEX_BUFFER:
291 readVertexBuffer(file, data, geometry); 291 readVertexBuffer(file, data, geometry);
292 break; 292 break;
293 default: 293 default:
294 // ignore chunk 294 // ignore chunk
295#ifdef IRR_OGRE_LOADER_DEBUG 295#ifdef IRR_OGRE_LOADER_DEBUG
296 os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG); 296 os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG);
297#endif 297#endif
298 file->seek(data.header.length-data.read, true); 298 file->seek(data.header.length-data.read, true);
299 data.read += data.header.length-data.read; 299 data.read += data.header.length-data.read;
300 } 300 }
301 parent.read += data.read; 301 parent.read += data.read;
302 } 302 }
303 if (parent.read != parent.header.length) 303 if (parent.read != parent.header.length)
304 os::Printer::log("Incorrect geometry length. File might be corrupted."); 304 os::Printer::log("Incorrect geometry length. File might be corrupted.");
305 return true; 305 return true;
306} 306}
307 307
308 308
309bool COgreMeshFileLoader::readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) 309bool COgreMeshFileLoader::readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry)
310{ 310{
311#ifdef IRR_OGRE_LOADER_DEBUG 311#ifdef IRR_OGRE_LOADER_DEBUG
312 os::Printer::log("Read Vertex Declaration", ELL_DEBUG); 312 os::Printer::log("Read Vertex Declaration", ELL_DEBUG);
313#endif 313#endif
314 NumUV = 0; 314 NumUV = 0;
315 while(parent.read < parent.header.length) 315 while(parent.read < parent.header.length)
316 { 316 {
317 ChunkData data; 317 ChunkData data;
318 readChunkData(file, data); 318 readChunkData(file, data);
319 319
320 switch(data.header.id) 320 switch(data.header.id)
321 { 321 {
322 case COGRE_GEOMETRY_VERTEX_ELEMENT: 322 case COGRE_GEOMETRY_VERTEX_ELEMENT:
323 { 323 {
324 geometry.Elements.push_back(OgreVertexElement()); 324 geometry.Elements.push_back(OgreVertexElement());
325 OgreVertexElement& elem = geometry.Elements.getLast(); 325 OgreVertexElement& elem = geometry.Elements.getLast();
326 readShort(file, data, &elem.Source); 326 readShort(file, data, &elem.Source);
327 readShort(file, data, &elem.Type); 327 readShort(file, data, &elem.Type);
328 readShort(file, data, &elem.Semantic); 328 readShort(file, data, &elem.Semantic);
329 if (elem.Semantic == 7) //Tex coords 329 if (elem.Semantic == 7) //Tex coords
330 { 330 {
331 ++NumUV; 331 ++NumUV;
332 } 332 }
333 readShort(file, data, &elem.Offset); 333 readShort(file, data, &elem.Offset);
334 elem.Offset /= sizeof(f32); 334 elem.Offset /= sizeof(f32);
335 readShort(file, data, &elem.Index); 335 readShort(file, data, &elem.Index);
336 } 336 }
337 break; 337 break;
338 default: 338 default:
339 // ignore chunk 339 // ignore chunk
340 file->seek(data.header.length-data.read, true); 340 file->seek(data.header.length-data.read, true);
341 data.read += data.header.length-data.read; 341 data.read += data.header.length-data.read;
342 } 342 }
343 parent.read += data.read; 343 parent.read += data.read;
344 } 344 }
345 if (parent.read != parent.header.length) 345 if (parent.read != parent.header.length)
346 os::Printer::log("Incorrect vertex declaration length. File might be corrupted."); 346 os::Printer::log("Incorrect vertex declaration length. File might be corrupted.");
347 return true; 347 return true;
348} 348}
349 349
350 350
351bool COgreMeshFileLoader::readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) 351bool COgreMeshFileLoader::readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry)
352{ 352{
353#ifdef IRR_OGRE_LOADER_DEBUG 353#ifdef IRR_OGRE_LOADER_DEBUG
354 os::Printer::log("Read Vertex Buffer", ELL_DEBUG); 354 os::Printer::log("Read Vertex Buffer", ELL_DEBUG);
355#endif 355#endif
356 OgreVertexBuffer buf; 356 OgreVertexBuffer buf;
357 readShort(file, parent, &buf.BindIndex); 357 readShort(file, parent, &buf.BindIndex);
358 readShort(file, parent, &buf.VertexSize); 358 readShort(file, parent, &buf.VertexSize);
359 buf.VertexSize /= sizeof(f32); 359 buf.VertexSize /= sizeof(f32);
360 ChunkData data; 360 ChunkData data;
361 readChunkData(file, data); 361 readChunkData(file, data);
362 362
363 if (data.header.id == COGRE_GEOMETRY_VERTEX_BUFFER_DATA) 363 if (data.header.id == COGRE_GEOMETRY_VERTEX_BUFFER_DATA)
364 { 364 {
365 buf.Data.set_used(geometry.NumVertex*buf.VertexSize); 365 buf.Data.set_used(geometry.NumVertex*buf.VertexSize);
366 readFloat(file, data, buf.Data.pointer(), geometry.NumVertex*buf.VertexSize); 366 readFloat(file, data, buf.Data.pointer(), geometry.NumVertex*buf.VertexSize);
367 } 367 }
368 368
369 geometry.Buffers.push_back(buf); 369 geometry.Buffers.push_back(buf);
370 parent.read += data.read; 370 parent.read += data.read;
371 if (parent.read != parent.header.length) 371 if (parent.read != parent.header.length)
372 os::Printer::log("Incorrect vertex buffer length. File might be corrupted."); 372 os::Printer::log("Incorrect vertex buffer length. File might be corrupted.");
373 return true; 373 return true;
374} 374}
375 375
376 376
377bool COgreMeshFileLoader::readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh) 377bool COgreMeshFileLoader::readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh)
378{ 378{
379#ifdef IRR_OGRE_LOADER_DEBUG 379#ifdef IRR_OGRE_LOADER_DEBUG
380 os::Printer::log("Read Submesh", ELL_DEBUG); 380 os::Printer::log("Read Submesh", ELL_DEBUG);
381#endif 381#endif
382 readString(file, parent, subMesh.Material); 382 readString(file, parent, subMesh.Material);
383#ifdef IRR_OGRE_LOADER_DEBUG 383#ifdef IRR_OGRE_LOADER_DEBUG
384 os::Printer::log("using material", subMesh.Material, ELL_DEBUG); 384 os::Printer::log("using material", subMesh.Material, ELL_DEBUG);
385#endif 385#endif
386 readBool(file, parent, subMesh.SharedVertices); 386 readBool(file, parent, subMesh.SharedVertices);
387 387
388 s32 numIndices; 388 s32 numIndices;
389 readInt(file, parent, &numIndices); 389 readInt(file, parent, &numIndices);
390 subMesh.Indices.set_used(numIndices); 390 subMesh.Indices.set_used(numIndices);
391 391
392 readBool(file, parent, subMesh.Indices32Bit); 392 readBool(file, parent, subMesh.Indices32Bit);
393 393
394 if (subMesh.Indices32Bit) 394 if (subMesh.Indices32Bit)
395 readInt(file, parent, subMesh.Indices.pointer(), numIndices); 395 readInt(file, parent, subMesh.Indices.pointer(), numIndices);
396 else 396 else
397 { 397 {
398 for (s32 i=0; i<numIndices; ++i) 398 for (s32 i=0; i<numIndices; ++i)
399 { 399 {
400 u16 num; 400 u16 num;
401 readShort(file, parent, &num); 401 readShort(file, parent, &num);
402 subMesh.Indices[i]=num; 402 subMesh.Indices[i]=num;
403 } 403 }
404 } 404 }
405 405
406 while(parent.read < parent.header.length) 406 while(parent.read < parent.header.length)
407 { 407 {
408 ChunkData data; 408 ChunkData data;
409 readChunkData(file, data); 409 readChunkData(file, data);
410 410
411 switch(data.header.id) 411 switch(data.header.id)
412 { 412 {
413 case COGRE_GEOMETRY: 413 case COGRE_GEOMETRY:
414 readGeometry(file, data, subMesh.Geometry); 414 readGeometry(file, data, subMesh.Geometry);
415 break; 415 break;
416 case COGRE_SUBMESH_OPERATION: 416 case COGRE_SUBMESH_OPERATION:
417 readShort(file, data, &subMesh.Operation); 417 readShort(file, data, &subMesh.Operation);
418#ifdef IRR_OGRE_LOADER_DEBUG 418#ifdef IRR_OGRE_LOADER_DEBUG
419 os::Printer::log("Read Submesh Operation",core::stringc(subMesh.Operation), ELL_DEBUG); 419 os::Printer::log("Read Submesh Operation",core::stringc(subMesh.Operation), ELL_DEBUG);
420#endif 420#endif
421 if (subMesh.Operation != 4) 421 if (subMesh.Operation != 4)
422 os::Printer::log("Primitive type != trilist not yet implemented", ELL_WARNING); 422 os::Printer::log("Primitive type != trilist not yet implemented", ELL_WARNING);
423 break; 423 break;
424 case COGRE_SUBMESH_TEXTURE_ALIAS: 424 case COGRE_SUBMESH_TEXTURE_ALIAS:
425 { 425 {
426#ifdef IRR_OGRE_LOADER_DEBUG 426#ifdef IRR_OGRE_LOADER_DEBUG
427 os::Printer::log("Read Submesh Texture Alias", ELL_DEBUG); 427 os::Printer::log("Read Submesh Texture Alias", ELL_DEBUG);
428#endif 428#endif
429 core::stringc texture, alias; 429 core::stringc texture, alias;
430 readString(file, data, texture); 430 readString(file, data, texture);
431 readString(file, data, alias); 431 readString(file, data, alias);
432 subMesh.TextureAliases.push_back(OgreTextureAlias(texture,alias)); 432 subMesh.TextureAliases.push_back(OgreTextureAlias(texture,alias));
433 } 433 }
434 break; 434 break;
435 case COGRE_SUBMESH_BONE_ASSIGNMENT: 435 case COGRE_SUBMESH_BONE_ASSIGNMENT:
436 { 436 {
437 subMesh.BoneAssignments.push_back(OgreBoneAssignment()); 437 subMesh.BoneAssignments.push_back(OgreBoneAssignment());
438 readInt(file, data, &subMesh.BoneAssignments.getLast().VertexID); 438 readInt(file, data, &subMesh.BoneAssignments.getLast().VertexID);
439 readShort(file, data, &subMesh.BoneAssignments.getLast().BoneID); 439 readShort(file, data, &subMesh.BoneAssignments.getLast().BoneID);
440 readFloat(file, data, &subMesh.BoneAssignments.getLast().Weight); 440 readFloat(file, data, &subMesh.BoneAssignments.getLast().Weight);
441 } 441 }
442 break; 442 break;
443 default: 443 default:
444#ifdef IRR_OGRE_LOADER_DEBUG 444#ifdef IRR_OGRE_LOADER_DEBUG
445 os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG); 445 os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG);
446#endif 446#endif
447 parent.read=parent.header.length; 447 parent.read=parent.header.length;
448 file->seek(-(long)sizeof(ChunkHeader), true); 448 file->seek(-(long)sizeof(ChunkHeader), true);
449 return true; 449 return true;
450 } 450 }
451 parent.read += data.read; 451 parent.read += data.read;
452 } 452 }
453 if (parent.read != parent.header.length) 453 if (parent.read != parent.header.length)
454 os::Printer::log("Incorrect submesh length. File might be corrupted."); 454 os::Printer::log("Incorrect submesh length. File might be corrupted.");
455#ifdef IRR_OGRE_LOADER_DEBUG 455#ifdef IRR_OGRE_LOADER_DEBUG
456 os::Printer::log("Done with submesh", ELL_DEBUG); 456 os::Printer::log("Done with submesh", ELL_DEBUG);
457#endif 457#endif
458 return true; 458 return true;
459} 459}
460 460
461 461
462void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName) 462void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName)
463{ 463{
464 video::SMaterial& material=mb->getMaterial(); 464 video::SMaterial& material=mb->getMaterial();
465 for (u32 k=0; k<Materials.size(); ++k) 465 for (u32 k=0; k<Materials.size(); ++k)
466 { 466 {
467 if ((materialName==Materials[k].Name)&&(Materials[k].Techniques.size())&&(Materials[k].Techniques[0].Passes.size())) 467 if ((materialName==Materials[k].Name)&&(Materials[k].Techniques.size())&&(Materials[k].Techniques[0].Passes.size()))
468 { 468 {
469 material=Materials[k].Techniques[0].Passes[0].Material; 469 material=Materials[k].Techniques[0].Passes[0].Material;
470 for (u32 i=0; i<Materials[k].Techniques[0].Passes[0].Texture.Filename.size(); ++i) 470 for (u32 i=0; i<Materials[k].Techniques[0].Passes[0].Texture.Filename.size(); ++i)
471 { 471 {
472 if (FileSystem->existFile(Materials[k].Techniques[0].Passes[0].Texture.Filename[i])) 472 if (FileSystem->existFile(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]))
473 material.setTexture(i, Driver->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename[i])); 473 material.setTexture(i, Driver->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]));
474 else 474 else
475 material.setTexture(i, Driver->getTexture((CurrentlyLoadingFromPath+"/"+FileSystem->getFileBasename(Materials[k].Techniques[0].Passes[0].Texture.Filename[i])))); 475 material.setTexture(i, Driver->getTexture((CurrentlyLoadingFromPath+"/"+FileSystem->getFileBasename(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]))));
476 } 476 }
477 break; 477 break;
478 } 478 }
479 } 479 }
480} 480}
481 481
482 482
483scene::SMeshBuffer* COgreMeshFileLoader::composeMeshBuffer(const core::array<s32>& indices, const OgreGeometry& geom) 483scene::SMeshBuffer* COgreMeshFileLoader::composeMeshBuffer(const core::array<s32>& indices, const OgreGeometry& geom)
484{ 484{
485 scene::SMeshBuffer *mb=new scene::SMeshBuffer(); 485 scene::SMeshBuffer *mb=new scene::SMeshBuffer();
486 486
487 u32 i; 487 u32 i;
488 mb->Indices.set_used(indices.size()); 488 mb->Indices.set_used(indices.size());
489 for (i=0; i<indices.size(); ++i) 489 for (i=0; i<indices.size(); ++i)
490 mb->Indices[i]=indices[i]; 490 mb->Indices[i]=indices[i];
491 491
492 mb->Vertices.set_used(geom.NumVertex); 492 mb->Vertices.set_used(geom.NumVertex);
493 for (i=0; i<geom.Elements.size(); ++i) 493 for (i=0; i<geom.Elements.size(); ++i)
494 { 494 {
495 if (geom.Elements[i].Semantic==1) //Pos 495 if (geom.Elements[i].Semantic==1) //Pos
496 { 496 {
497 for (u32 j=0; j<geom.Buffers.size(); ++j) 497 for (u32 j=0; j<geom.Buffers.size(); ++j)
498 { 498 {
499 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 499 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
500 { 500 {
501 u32 eSize=geom.Buffers[j].VertexSize; 501 u32 eSize=geom.Buffers[j].VertexSize;
502 u32 ePos=geom.Elements[i].Offset; 502 u32 ePos=geom.Elements[i].Offset;
503 for (s32 k=0; k<geom.NumVertex; ++k) 503 for (s32 k=0; k<geom.NumVertex; ++k)
504 { 504 {
505 mb->Vertices[k].Color=mb->Material.DiffuseColor; 505 mb->Vertices[k].Color=mb->Material.DiffuseColor;
506 mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); 506 mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
507 ePos += eSize; 507 ePos += eSize;
508 } 508 }
509 } 509 }
510 } 510 }
511 } 511 }
512 512
513 if (geom.Elements[i].Semantic==4) //Normal 513 if (geom.Elements[i].Semantic==4) //Normal
514 { 514 {
515 for (u32 j=0; j<geom.Buffers.size(); ++j) 515 for (u32 j=0; j<geom.Buffers.size(); ++j)
516 { 516 {
517 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 517 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
518 { 518 {
519 u32 eSize=geom.Buffers[j].VertexSize; 519 u32 eSize=geom.Buffers[j].VertexSize;
520 u32 ePos=geom.Elements[i].Offset; 520 u32 ePos=geom.Elements[i].Offset;
521 for (s32 k=0; k<geom.NumVertex; ++k) 521 for (s32 k=0; k<geom.NumVertex; ++k)
522 { 522 {
523 mb->Vertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); 523 mb->Vertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
524 ePos += eSize; 524 ePos += eSize;
525 } 525 }
526 } 526 }
527 } 527 }
528 } 528 }
529 529
530 if (geom.Elements[i].Semantic==7) //TexCoord 530 if (geom.Elements[i].Semantic==7) //TexCoord
531 { 531 {
532 for (u32 j=0; j<geom.Buffers.size(); ++j) 532 for (u32 j=0; j<geom.Buffers.size(); ++j)
533 { 533 {
534 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 534 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
535 { 535 {
536 u32 eSize=geom.Buffers[j].VertexSize; 536 u32 eSize=geom.Buffers[j].VertexSize;
537 u32 ePos=geom.Elements[i].Offset; 537 u32 ePos=geom.Elements[i].Offset;
538 for (s32 k=0; k<geom.NumVertex; ++k) 538 for (s32 k=0; k<geom.NumVertex; ++k)
539 { 539 {
540 mb->Vertices[k].TCoords.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1]); 540 mb->Vertices[k].TCoords.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1]);
541 ePos += eSize; 541 ePos += eSize;
542 } 542 }
543 } 543 }
544 } 544 }
545 } 545 }
546 } 546 }
547 return mb; 547 return mb;
548} 548}
549 549
550 550
551scene::SMeshBufferLightMap* COgreMeshFileLoader::composeMeshBufferLightMap(const core::array<s32>& indices, const OgreGeometry& geom) 551scene::SMeshBufferLightMap* COgreMeshFileLoader::composeMeshBufferLightMap(const core::array<s32>& indices, const OgreGeometry& geom)
552{ 552{
553 scene::SMeshBufferLightMap *mb=new scene::SMeshBufferLightMap(); 553 scene::SMeshBufferLightMap *mb=new scene::SMeshBufferLightMap();
554 554
555 u32 i; 555 u32 i;
556 mb->Indices.set_used(indices.size()); 556 mb->Indices.set_used(indices.size());
557 for (i=0; i<indices.size(); ++i) 557 for (i=0; i<indices.size(); ++i)
558 mb->Indices[i]=indices[i]; 558 mb->Indices[i]=indices[i];
559 559
560 mb->Vertices.set_used(geom.NumVertex); 560 mb->Vertices.set_used(geom.NumVertex);
561 561
562 for (i=0; i<geom.Elements.size(); ++i) 562 for (i=0; i<geom.Elements.size(); ++i)
563 { 563 {
564 if (geom.Elements[i].Semantic==1) //Pos 564 if (geom.Elements[i].Semantic==1) //Pos
565 { 565 {
566 for (u32 j=0; j<geom.Buffers.size(); ++j) 566 for (u32 j=0; j<geom.Buffers.size(); ++j)
567 { 567 {
568 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 568 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
569 { 569 {
570 u32 eSize=geom.Buffers[j].VertexSize; 570 u32 eSize=geom.Buffers[j].VertexSize;
571 u32 ePos=geom.Elements[i].Offset; 571 u32 ePos=geom.Elements[i].Offset;
572 for (s32 k=0; k<geom.NumVertex; ++k) 572 for (s32 k=0; k<geom.NumVertex; ++k)
573 { 573 {
574 mb->Vertices[k].Color=mb->Material.DiffuseColor; 574 mb->Vertices[k].Color=mb->Material.DiffuseColor;
575 mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); 575 mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
576 ePos += eSize; 576 ePos += eSize;
577 } 577 }
578 } 578 }
579 } 579 }
580 } 580 }
581 581
582 if (geom.Elements[i].Semantic==4) //Normal 582 if (geom.Elements[i].Semantic==4) //Normal
583 { 583 {
584 for (u32 j=0; j<geom.Buffers.size(); ++j) 584 for (u32 j=0; j<geom.Buffers.size(); ++j)
585 { 585 {
586 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 586 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
587 { 587 {
588 u32 eSize=geom.Buffers[j].VertexSize; 588 u32 eSize=geom.Buffers[j].VertexSize;
589 u32 ePos=geom.Elements[i].Offset; 589 u32 ePos=geom.Elements[i].Offset;
590 for (s32 k=0; k<geom.NumVertex; ++k) 590 for (s32 k=0; k<geom.NumVertex; ++k)
591 { 591 {
592 mb->Vertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); 592 mb->Vertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
593 ePos += eSize; 593 ePos += eSize;
594 } 594 }
595 } 595 }
596 } 596 }
597 } 597 }
598 598
599 if (geom.Elements[i].Semantic==7) //TexCoord 599 if (geom.Elements[i].Semantic==7) //TexCoord
600 { 600 {
601 for (u32 j=0; j<geom.Buffers.size(); ++j) 601 for (u32 j=0; j<geom.Buffers.size(); ++j)
602 { 602 {
603 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 603 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
604 { 604 {
605 u32 eSize=geom.Buffers[j].VertexSize; 605 u32 eSize=geom.Buffers[j].VertexSize;
606 u32 ePos=geom.Elements[i].Offset; 606 u32 ePos=geom.Elements[i].Offset;
607 // make sure we have data for a second texture coord 607 // make sure we have data for a second texture coord
608 const bool secondCoord = (eSize>ePos+3); 608 const bool secondCoord = (eSize>ePos+3);
609 for (s32 k=0; k<geom.NumVertex; ++k) 609 for (s32 k=0; k<geom.NumVertex; ++k)
610 { 610 {
611 mb->Vertices[k].TCoords.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); 611 mb->Vertices[k].TCoords.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
612 if (secondCoord) 612 if (secondCoord)
613 mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]); 613 mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]);
614 else 614 else
615 mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); 615 mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
616 ePos += eSize; 616 ePos += eSize;
617 } 617 }
618 } 618 }
619 } 619 }
620 } 620 }
621 } 621 }
622 622
623 return mb; 623 return mb;
624} 624}
625 625
626 626
627scene::IMeshBuffer* COgreMeshFileLoader::composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array<s32>& indices, const OgreGeometry& geom) 627scene::IMeshBuffer* COgreMeshFileLoader::composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array<s32>& indices, const OgreGeometry& geom)
628{ 628{
629 scene::SSkinMeshBuffer *mb=mesh.addMeshBuffer(); 629 scene::SSkinMeshBuffer *mb=mesh.addMeshBuffer();
630 if (NumUV>1) 630 if (NumUV>1)
631 { 631 {
632 mb->convertTo2TCoords(); 632 mb->convertTo2TCoords();
633 mb->Vertices_2TCoords.set_used(geom.NumVertex); 633 mb->Vertices_2TCoords.set_used(geom.NumVertex);
634 } 634 }
635 else 635 else
636 mb->Vertices_Standard.set_used(geom.NumVertex); 636 mb->Vertices_Standard.set_used(geom.NumVertex);
637 637
638 u32 i; 638 u32 i;
639 mb->Indices.set_used(indices.size()); 639 mb->Indices.set_used(indices.size());
640 for (i=0; i<indices.size(); i+=3) 640 for (i=0; i<indices.size(); i+=3)
641 { 641 {
642 mb->Indices[i+0]=indices[i+2]; 642 mb->Indices[i+0]=indices[i+2];
643 mb->Indices[i+1]=indices[i+1]; 643 mb->Indices[i+1]=indices[i+1];
644 mb->Indices[i+2]=indices[i+0]; 644 mb->Indices[i+2]=indices[i+0];
645 } 645 }
646 646
647 for (i=0; i<geom.Elements.size(); ++i) 647 for (i=0; i<geom.Elements.size(); ++i)
648 { 648 {
649 if (geom.Elements[i].Semantic==1) //Pos 649 if (geom.Elements[i].Semantic==1) //Pos
650 { 650 {
651 for (u32 j=0; j<geom.Buffers.size(); ++j) 651 for (u32 j=0; j<geom.Buffers.size(); ++j)
652 { 652 {
653 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 653 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
654 { 654 {
655 u32 eSize=geom.Buffers[j].VertexSize; 655 u32 eSize=geom.Buffers[j].VertexSize;
656 u32 ePos=geom.Elements[i].Offset; 656 u32 ePos=geom.Elements[i].Offset;
657 for (s32 k=0; k<geom.NumVertex; ++k) 657 for (s32 k=0; k<geom.NumVertex; ++k)
658 { 658 {
659 if (NumUV>1) 659 if (NumUV>1)
660 mb->Vertices_2TCoords[k].Color=mb->Material.DiffuseColor; 660 mb->Vertices_2TCoords[k].Color=mb->Material.DiffuseColor;
661 else 661 else
662 mb->Vertices_Standard[k].Color=mb->Material.DiffuseColor; 662 mb->Vertices_Standard[k].Color=mb->Material.DiffuseColor;
663 mb->getPosition(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); 663 mb->getPosition(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
664 ePos += eSize; 664 ePos += eSize;
665 } 665 }
666 } 666 }
667 } 667 }
668 } 668 }
669 669
670 if (geom.Elements[i].Semantic==4) //Normal 670 if (geom.Elements[i].Semantic==4) //Normal
671 { 671 {
672 for (u32 j=0; j<geom.Buffers.size(); ++j) 672 for (u32 j=0; j<geom.Buffers.size(); ++j)
673 { 673 {
674 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 674 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
675 { 675 {
676 u32 eSize=geom.Buffers[j].VertexSize; 676 u32 eSize=geom.Buffers[j].VertexSize;
677 u32 ePos=geom.Elements[i].Offset; 677 u32 ePos=geom.Elements[i].Offset;
678 for (s32 k=0; k<geom.NumVertex; ++k) 678 for (s32 k=0; k<geom.NumVertex; ++k)
679 { 679 {
680 mb->getNormal(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); 680 mb->getNormal(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]);
681 ePos += eSize; 681 ePos += eSize;
682 } 682 }
683 } 683 }
684 } 684 }
685 } 685 }
686 686
687 if (geom.Elements[i].Semantic==7) //TexCoord 687 if (geom.Elements[i].Semantic==7) //TexCoord
688 { 688 {
689 for (u32 j=0; j<geom.Buffers.size(); ++j) 689 for (u32 j=0; j<geom.Buffers.size(); ++j)
690 { 690 {
691 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex) 691 if (geom.Elements[i].Source==geom.Buffers[j].BindIndex)
692 { 692 {
693 u32 eSize=geom.Buffers[j].VertexSize; 693 u32 eSize=geom.Buffers[j].VertexSize;
694 u32 ePos=geom.Elements[i].Offset; 694 u32 ePos=geom.Elements[i].Offset;
695 // make sure we have data for a second texture coord 695 // make sure we have data for a second texture coord
696 const bool secondCoord = (eSize>ePos+3); 696 const bool secondCoord = (eSize>ePos+3);
697 for (s32 k=0; k<geom.NumVertex; ++k) 697 for (s32 k=0; k<geom.NumVertex; ++k)
698 { 698 {
699 mb->getTCoords(k).set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); 699 mb->getTCoords(k).set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
700 if (NumUV>1) 700 if (NumUV>1)
701 { 701 {
702 if (secondCoord) 702 if (secondCoord)
703 mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]); 703 mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]);
704 else 704 else
705 mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); 705 mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]);
706 } 706 }
707 ePos += eSize; 707 ePos += eSize;
708 } 708 }
709 } 709 }
710 } 710 }
711 } 711 }
712 } 712 }
713 713
714 return mb; 714 return mb;
715} 715}
716 716
717 717
718void COgreMeshFileLoader::composeObject(void) 718void COgreMeshFileLoader::composeObject(void)
719{ 719{
720 for (u32 i=0; i<Meshes.size(); ++i) 720 for (u32 i=0; i<Meshes.size(); ++i)
721 { 721 {
722 for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j) 722 for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
723 { 723 {
724 IMeshBuffer* mb; 724 IMeshBuffer* mb;
725 if (Meshes[i].SubMeshes[j].SharedVertices) 725 if (Meshes[i].SubMeshes[j].SharedVertices)
726 { 726 {
727 if (Skeleton.Bones.size()) 727 if (Skeleton.Bones.size())
728 { 728 {
729 mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry); 729 mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
730 } 730 }
731 else if (NumUV < 2) 731 else if (NumUV < 2)
732 { 732 {
733 mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry); 733 mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
734 } 734 }
735 else 735 else
736 { 736 {
737 mb = composeMeshBufferLightMap(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry); 737 mb = composeMeshBufferLightMap(Meshes[i].SubMeshes[j].Indices, Meshes[i].Geometry);
738 } 738 }
739 } 739 }
740 else 740 else
741 { 741 {
742 if (Skeleton.Bones.size()) 742 if (Skeleton.Bones.size())
743 { 743 {
744 mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry); 744 mb = composeMeshBufferSkinned(*(CSkinnedMesh*)Mesh, Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
745 } 745 }
746 else if (NumUV < 2) 746 else if (NumUV < 2)
747 { 747 {
748 mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry); 748 mb = composeMeshBuffer(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
749 } 749 }
750 else 750 else
751 { 751 {
752 mb = composeMeshBufferLightMap(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry); 752 mb = composeMeshBufferLightMap(Meshes[i].SubMeshes[j].Indices, Meshes[i].SubMeshes[j].Geometry);
753 } 753 }
754 } 754 }
755 755
756 if (mb != 0) 756 if (mb != 0)
757 { 757 {
758 composeMeshBufferMaterial(mb, Meshes[i].SubMeshes[j].Material); 758 composeMeshBufferMaterial(mb, Meshes[i].SubMeshes[j].Material);
759 if (!Skeleton.Bones.size()) 759 if (!Skeleton.Bones.size())
760 { 760 {
761 ((SMesh*)Mesh)->addMeshBuffer(mb); 761 ((SMesh*)Mesh)->addMeshBuffer(mb);
762 mb->drop(); 762 mb->drop();
763 } 763 }
764 } 764 }
765 } 765 }
766 } 766 }
767 if (Skeleton.Bones.size()) 767 if (Skeleton.Bones.size())
768 { 768 {
769 CSkinnedMesh* m = (CSkinnedMesh*)Mesh; 769 CSkinnedMesh* m = (CSkinnedMesh*)Mesh;
770 // Create Joints 770 // Create Joints
771 for (u32 i=0; i<Skeleton.Bones.size(); ++i) 771 for (u32 i=0; i<Skeleton.Bones.size(); ++i)
772 { 772 {
773 ISkinnedMesh::SJoint* joint = m->addJoint(); 773 ISkinnedMesh::SJoint* joint = m->addJoint();
774 joint->Name=Skeleton.Bones[i].Name; 774 joint->Name=Skeleton.Bones[i].Name;
775 775
776 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility. 776 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility.
777 // Not tested so far if this was correct or wrong before quaternion fix! 777 // Not tested so far if this was correct or wrong before quaternion fix!
778 Skeleton.Bones[i].Orientation.getMatrix_transposed(joint->LocalMatrix); 778 Skeleton.Bones[i].Orientation.getMatrix_transposed(joint->LocalMatrix);
779 779
780 if (Skeleton.Bones[i].Scale != core::vector3df(1,1,1)) 780 if (Skeleton.Bones[i].Scale != core::vector3df(1,1,1))
781 { 781 {
782 core::matrix4 scaleMatrix; 782 core::matrix4 scaleMatrix;
783 scaleMatrix.setScale( Skeleton.Bones[i].Scale ); 783 scaleMatrix.setScale( Skeleton.Bones[i].Scale );
784 joint->LocalMatrix *= scaleMatrix; 784 joint->LocalMatrix *= scaleMatrix;
785 } 785 }
786 joint->LocalMatrix.setTranslation( Skeleton.Bones[i].Position ); 786 joint->LocalMatrix.setTranslation( Skeleton.Bones[i].Position );
787 } 787 }
788 // Joints hierarchy 788 // Joints hierarchy
789 for (u32 i=0; i<Skeleton.Bones.size(); ++i) 789 for (u32 i=0; i<Skeleton.Bones.size(); ++i)
790 { 790 {
791 if (Skeleton.Bones[i].Parent<m->getJointCount()) 791 if (Skeleton.Bones[i].Parent<m->getJointCount())
792 { 792 {
793 m->getAllJoints()[Skeleton.Bones[i].Parent]->Children.push_back(m->getAllJoints()[Skeleton.Bones[i].Handle]); 793 m->getAllJoints()[Skeleton.Bones[i].Parent]->Children.push_back(m->getAllJoints()[Skeleton.Bones[i].Handle]);
794 } 794 }
795 } 795 }
796 796
797 // Weights 797 // Weights
798 u32 bufCount=0; 798 u32 bufCount=0;
799 for (u32 i=0; i<Meshes.size(); ++i) 799 for (u32 i=0; i<Meshes.size(); ++i)
800 { 800 {
801 for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j) 801 for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
802 { 802 {
803 for (u32 k=0; k<Meshes[i].SubMeshes[j].BoneAssignments.size(); ++k) 803 for (u32 k=0; k<Meshes[i].SubMeshes[j].BoneAssignments.size(); ++k)
804 { 804 {
805 const OgreBoneAssignment& ba = Meshes[i].SubMeshes[j].BoneAssignments[k]; 805 const OgreBoneAssignment& ba = Meshes[i].SubMeshes[j].BoneAssignments[k];
806 if (ba.BoneID<m->getJointCount()) 806 if (ba.BoneID<m->getJointCount())
807 { 807 {
808 ISkinnedMesh::SWeight* w = m->addWeight(m->getAllJoints()[ba.BoneID]); 808 ISkinnedMesh::SWeight* w = m->addWeight(m->getAllJoints()[ba.BoneID]);
809 w->strength=ba.Weight; 809 w->strength=ba.Weight;
810 w->vertex_id=ba.VertexID; 810 w->vertex_id=ba.VertexID;
811 w->buffer_id=bufCount; 811 w->buffer_id=bufCount;
812 } 812 }
813 } 813 }
814 ++bufCount; 814 ++bufCount;
815 } 815 }
816 } 816 }
817 817
818 for (u32 i=0; i<Skeleton.Animations.size(); ++i) 818 for (u32 i=0; i<Skeleton.Animations.size(); ++i)
819 { 819 {
820 for (u32 j=0; j<Skeleton.Animations[i].Keyframes.size(); ++j) 820 for (u32 j=0; j<Skeleton.Animations[i].Keyframes.size(); ++j)
821 { 821 {
822 OgreKeyframe& frame = Skeleton.Animations[i].Keyframes[j]; 822 OgreKeyframe& frame = Skeleton.Animations[i].Keyframes[j];
823 ISkinnedMesh::SJoint* keyjoint = m->getAllJoints()[frame.BoneID]; 823 ISkinnedMesh::SJoint* keyjoint = m->getAllJoints()[frame.BoneID];
824 ISkinnedMesh::SPositionKey* poskey = m->addPositionKey(keyjoint); 824 ISkinnedMesh::SPositionKey* poskey = m->addPositionKey(keyjoint);
825 poskey->frame=frame.Time*25; 825 poskey->frame=frame.Time*25;
826 poskey->position=keyjoint->LocalMatrix.getTranslation()+frame.Position; 826 poskey->position=keyjoint->LocalMatrix.getTranslation()+frame.Position;
827 ISkinnedMesh::SRotationKey* rotkey = m->addRotationKey(keyjoint); 827 ISkinnedMesh::SRotationKey* rotkey = m->addRotationKey(keyjoint);
828 rotkey->frame=frame.Time*25; 828 rotkey->frame=frame.Time*25;
829 829
830 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from keyjoint->LocalMatrix to keyjoint->LocalMatrix.getTransposed() for downward compatibility. 830 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from keyjoint->LocalMatrix to keyjoint->LocalMatrix.getTransposed() for downward compatibility.
831 // Not tested so far if this was correct or wrong before quaternion fix! 831 // Not tested so far if this was correct or wrong before quaternion fix!
832 rotkey->rotation=core::quaternion(keyjoint->LocalMatrix.getTransposed())*frame.Orientation; 832 rotkey->rotation=core::quaternion(keyjoint->LocalMatrix.getTransposed())*frame.Orientation;
833 833
834 ISkinnedMesh::SScaleKey* scalekey = m->addScaleKey(keyjoint); 834 ISkinnedMesh::SScaleKey* scalekey = m->addScaleKey(keyjoint);
835 scalekey->frame=frame.Time*25; 835 scalekey->frame=frame.Time*25;
836 scalekey->scale=frame.Scale; 836 scalekey->scale=frame.Scale;
837 } 837 }
838 } 838 }
839 m->finalize(); 839 m->finalize();
840 } 840 }
841} 841}
842 842
843 843
844void COgreMeshFileLoader::getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine) 844void COgreMeshFileLoader::getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine)
845{ 845{
846 bool parseString=false; 846 bool parseString=false;
847 c8 c=0; 847 c8 c=0;
848 token = ""; 848 token = "";
849 849
850 if (file->getPos() >= file->getSize()) 850 if (file->getPos() >= file->getSize())
851 return; 851 return;
852 852
853 file->read(&c, sizeof(c8)); 853 file->read(&c, sizeof(c8));
854 // search for word beginning 854 // search for word beginning
855 while ( core::isspace(c) && (file->getPos() < file->getSize())) 855 while ( core::isspace(c) && (file->getPos() < file->getSize()))
856 { 856 {
857 if (noNewLine && c=='\n') 857 if (noNewLine && c=='\n')
858 { 858 {
859 file->seek(-1, true); 859 file->seek(-1, true);
860 return; 860 return;
861 } 861 }
862 file->read(&c, sizeof(c8)); 862 file->read(&c, sizeof(c8));
863 } 863 }
864 // check if we read a string 864 // check if we read a string
865 if (c=='"') 865 if (c=='"')
866 { 866 {
867 parseString = true; 867 parseString = true;
868 file->read(&c, sizeof(c8)); 868 file->read(&c, sizeof(c8));
869 } 869 }
870 do 870 do
871 { 871 {
872 if (c=='/') 872 if (c=='/')
873 { 873 {
874 file->read(&c, sizeof(c8)); 874 file->read(&c, sizeof(c8));
875 // check for comments, cannot be part of strings 875 // check for comments, cannot be part of strings
876 if (!parseString && (c=='/')) 876 if (!parseString && (c=='/'))
877 { 877 {
878 // skip comments 878 // skip comments
879 while(c!='\n') 879 while(c!='\n')
880 file->read(&c, sizeof(c8)); 880 file->read(&c, sizeof(c8));
881 if (!token.size()) 881 if (!token.size())
882 { 882 {
883 // if we start with a comment we need to skip 883 // if we start with a comment we need to skip
884 // following whitespaces, so restart 884 // following whitespaces, so restart
885 getMaterialToken(file, token, noNewLine); 885 getMaterialToken(file, token, noNewLine);
886 return; 886 return;
887 } 887 }
888 else 888 else
889 { 889 {
890 // else continue with next character 890 // else continue with next character
891 file->read(&c, sizeof(c8)); 891 file->read(&c, sizeof(c8));
892 continue; 892 continue;
893 } 893 }
894 } 894 }
895 else 895 else
896 { 896 {
897 // else append first slash and check if second char 897 // else append first slash and check if second char
898 // ends this token 898 // ends this token
899 token.append('/'); 899 token.append('/');
900 if ((!parseString && core::isspace(c)) || 900 if ((!parseString && core::isspace(c)) ||
901 (parseString && (c=='"'))) 901 (parseString && (c=='"')))
902 return; 902 return;
903 } 903 }
904 } 904 }
905 token.append(c); 905 token.append(c);
906 file->read(&c, sizeof(c8)); 906 file->read(&c, sizeof(c8));
907 // read until a token delimiter is found 907 // read until a token delimiter is found
908 } 908 }
909 while (((!parseString && !core::isspace(c)) || (parseString && (c!='"'))) && 909 while (((!parseString && !core::isspace(c)) || (parseString && (c!='"'))) &&
910 (file->getPos() < file->getSize())); 910 (file->getPos() < file->getSize()));
911 // we want to skip the last quotes of a string , but other chars might be the next 911 // we want to skip the last quotes of a string , but other chars might be the next
912 // token already. 912 // token already.
913 if (!parseString) 913 if (!parseString)
914 file->seek(-1, true); 914 file->seek(-1, true);
915} 915}
916 916
917 917
918bool COgreMeshFileLoader::readColor(io::IReadFile* file, video::SColor& col) 918bool COgreMeshFileLoader::readColor(io::IReadFile* file, video::SColor& col)
919{ 919{
920 core::stringc token; 920 core::stringc token;
921 921
922 getMaterialToken(file, token); 922 getMaterialToken(file, token);
923 if (token!="vertexcolour") 923 if (token!="vertexcolour")
924 { 924 {
925 video::SColorf col_f; 925 video::SColorf col_f;
926 col_f.r=core::fast_atof(token.c_str()); 926 col_f.r=core::fast_atof(token.c_str());
927 getMaterialToken(file, token); 927 getMaterialToken(file, token);
928 col_f.g=core::fast_atof(token.c_str()); 928 col_f.g=core::fast_atof(token.c_str());
929 getMaterialToken(file, token); 929 getMaterialToken(file, token);
930 col_f.b=core::fast_atof(token.c_str()); 930 col_f.b=core::fast_atof(token.c_str());
931 getMaterialToken(file, token, true); 931 getMaterialToken(file, token, true);
932 if (token.size()) 932 if (token.size())
933 col_f.a=core::fast_atof(token.c_str()); 933 col_f.a=core::fast_atof(token.c_str());
934 else 934 else
935 col_f.a=1.0f; 935 col_f.a=1.0f;
936 if ((col_f.r==0.0f)&&(col_f.g==0.0f)&&(col_f.b==0.0f)) 936 if ((col_f.r==0.0f)&&(col_f.g==0.0f)&&(col_f.b==0.0f))
937 col.set(255,255,255,255); 937 col.set(255,255,255,255);
938 else 938 else
939 col=col_f.toSColor(); 939 col=col_f.toSColor();
940 return false; 940 return false;
941 } 941 }
942 return true; 942 return true;
943} 943}
944 944
945 945
946void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique) 946void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique)
947{ 947{
948#ifdef IRR_OGRE_LOADER_DEBUG 948#ifdef IRR_OGRE_LOADER_DEBUG
949 os::Printer::log("Read Pass"); 949 os::Printer::log("Read Pass");
950#endif 950#endif
951 core::stringc token; 951 core::stringc token;
952 technique.Passes.push_back(OgrePass()); 952 technique.Passes.push_back(OgrePass());
953 OgrePass& pass=technique.Passes.getLast(); 953 OgrePass& pass=technique.Passes.getLast();
954 954
955 getMaterialToken(file, token); //open brace or name 955 getMaterialToken(file, token); //open brace or name
956 if (token != "{") 956 if (token != "{")
957 getMaterialToken(file, token); //open brace 957 getMaterialToken(file, token); //open brace
958 958
959 getMaterialToken(file, token); 959 getMaterialToken(file, token);
960 if (token == "}") 960 if (token == "}")
961 return; 961 return;
962 u32 inBlocks=1; 962 u32 inBlocks=1;
963 u32 textureUnit=0; 963 u32 textureUnit=0;
964 while(inBlocks) 964 while(inBlocks)
965 { 965 {
966 if (token=="ambient") 966 if (token=="ambient")
967 pass.AmbientTokenColor=readColor(file, pass.Material.AmbientColor); 967 pass.AmbientTokenColor=readColor(file, pass.Material.AmbientColor);
968 else if (token=="diffuse") 968 else if (token=="diffuse")
969 pass.DiffuseTokenColor=readColor(file, pass.Material.DiffuseColor); 969 pass.DiffuseTokenColor=readColor(file, pass.Material.DiffuseColor);
970 else if (token=="specular") 970 else if (token=="specular")
971 { 971 {
972 pass.SpecularTokenColor=readColor(file, pass.Material.SpecularColor); 972 pass.SpecularTokenColor=readColor(file, pass.Material.SpecularColor);
973 getMaterialToken(file, token); 973 getMaterialToken(file, token);
974 pass.Material.Shininess=core::fast_atof(token.c_str()); 974 pass.Material.Shininess=core::fast_atof(token.c_str());
975 } 975 }
976 else if (token=="emissive") 976 else if (token=="emissive")
977 pass.EmissiveTokenColor=readColor(file, pass.Material.EmissiveColor); 977 pass.EmissiveTokenColor=readColor(file, pass.Material.EmissiveColor);
978 else if (token=="scene_blend") 978 else if (token=="scene_blend")
979 { // TODO: Choose correct values 979 { // TODO: Choose correct values
980 getMaterialToken(file, token); 980 getMaterialToken(file, token);
981 if (token=="add") 981 if (token=="add")
982 pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; 982 pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR;
983 else if (token=="modulate") 983 else if (token=="modulate")
984 pass.Material.MaterialType=video::EMT_SOLID; 984 pass.Material.MaterialType=video::EMT_SOLID;
985 else if (token=="alpha_blend") 985 else if (token=="alpha_blend")
986 pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; 986 pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
987 else if (token=="colour_blend") 987 else if (token=="colour_blend")
988 pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; 988 pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA;
989 else 989 else
990 getMaterialToken(file, token); 990 getMaterialToken(file, token);
991 } 991 }
992 else if (token=="depth_check") 992 else if (token=="depth_check")
993 { 993 {
994 getMaterialToken(file, token); 994 getMaterialToken(file, token);
995 if (token!="on") 995 if (token!="on")
996 pass.Material.ZBuffer=video::ECFN_NEVER; 996 pass.Material.ZBuffer=video::ECFN_NEVER;
997 } 997 }
998 else if (token=="depth_write") 998 else if (token=="depth_write")
999 { 999 {
1000 getMaterialToken(file, token); 1000 getMaterialToken(file, token);
1001 pass.Material.ZWriteEnable=(token=="on"); 1001 pass.Material.ZWriteEnable=(token=="on");
1002 } 1002 }
1003 else if (token=="depth_func") 1003 else if (token=="depth_func")
1004 { 1004 {
1005 getMaterialToken(file, token); // Function name 1005 getMaterialToken(file, token); // Function name
1006 if (token=="always_fail") 1006 if (token=="always_fail")
1007 pass.Material.ZBuffer=video::ECFN_NEVER; 1007 pass.Material.ZBuffer=video::ECFN_NEVER;
1008 else if (token=="always_pass") 1008 else if (token=="always_pass")
1009 pass.Material.ZBuffer=video::ECFN_ALWAYS; 1009 pass.Material.ZBuffer=video::ECFN_ALWAYS;
1010 else if (token=="equal") 1010 else if (token=="equal")
1011 pass.Material.ZBuffer=video::ECFN_EQUAL; 1011 pass.Material.ZBuffer=video::ECFN_EQUAL;
1012 else if (token=="greater") 1012 else if (token=="greater")
1013 pass.Material.ZBuffer=video::ECFN_GREATER; 1013 pass.Material.ZBuffer=video::ECFN_GREATER;
1014 else if (token=="greater_equal") 1014 else if (token=="greater_equal")
1015 pass.Material.ZBuffer=video::ECFN_GREATEREQUAL; 1015 pass.Material.ZBuffer=video::ECFN_GREATEREQUAL;
1016 else if (token=="less") 1016 else if (token=="less")
1017 pass.Material.ZBuffer=video::ECFN_LESS; 1017 pass.Material.ZBuffer=video::ECFN_LESS;
1018 else if (token=="less_equal") 1018 else if (token=="less_equal")
1019 pass.Material.ZBuffer=video::ECFN_LESSEQUAL; 1019 pass.Material.ZBuffer=video::ECFN_LESSEQUAL;
1020 else if (token=="not_equal") 1020 else if (token=="not_equal")
1021 pass.Material.ZBuffer=video::ECFN_NOTEQUAL; 1021 pass.Material.ZBuffer=video::ECFN_NOTEQUAL;
1022 } 1022 }
1023 else if (token=="normalise_normals") 1023 else if (token=="normalise_normals")
1024 { 1024 {
1025 getMaterialToken(file, token); 1025 getMaterialToken(file, token);
1026 pass.Material.NormalizeNormals=(token=="on"); 1026 pass.Material.NormalizeNormals=(token=="on");
1027 } 1027 }
1028 else if (token=="depth_bias") 1028 else if (token=="depth_bias")
1029 { 1029 {
1030 getMaterialToken(file, token); // bias value 1030 getMaterialToken(file, token); // bias value
1031 } 1031 }
1032 else if (token=="alpha_rejection") 1032 else if (token=="alpha_rejection")
1033 { 1033 {
1034 getMaterialToken(file, token); // function name 1034 getMaterialToken(file, token); // function name
1035 getMaterialToken(file, token); // value 1035 getMaterialToken(file, token); // value
1036 pass.Material.MaterialTypeParam=core::fast_atof(token.c_str()); 1036 pass.Material.MaterialTypeParam=core::fast_atof(token.c_str());
1037 } 1037 }
1038 else if (token=="alpha_to_coverage") 1038 else if (token=="alpha_to_coverage")
1039 { 1039 {
1040 getMaterialToken(file, token); 1040 getMaterialToken(file, token);
1041 if (token=="on") 1041 if (token=="on")
1042 pass.Material.AntiAliasing |= video::EAAM_ALPHA_TO_COVERAGE; 1042 pass.Material.AntiAliasing |= video::EAAM_ALPHA_TO_COVERAGE;
1043 } 1043 }
1044 else if (token=="colour_write") 1044 else if (token=="colour_write")
1045 { 1045 {
1046 getMaterialToken(file, token); 1046 getMaterialToken(file, token);
1047 pass.Material.ColorMask = (token=="on")?video::ECP_ALL:video::ECP_NONE; 1047 pass.Material.ColorMask = (token=="on")?video::ECP_ALL:video::ECP_NONE;
1048 } 1048 }
1049 else if (token=="cull_hardware") 1049 else if (token=="cull_hardware")
1050 { 1050 {
1051 getMaterialToken(file, token); // rotation name 1051 getMaterialToken(file, token); // rotation name
1052 } 1052 }
1053 else if (token=="cull_software") 1053 else if (token=="cull_software")
1054 { 1054 {
1055 getMaterialToken(file, token); // culling side 1055 getMaterialToken(file, token); // culling side
1056 } 1056 }
1057 else if (token=="lighting") 1057 else if (token=="lighting")
1058 { 1058 {
1059 getMaterialToken(file, token); 1059 getMaterialToken(file, token);
1060 pass.Material.Lighting=(token=="on"); 1060 pass.Material.Lighting=(token=="on");
1061 } 1061 }
1062 else if (token=="shading") 1062 else if (token=="shading")
1063 { 1063 {
1064 getMaterialToken(file, token); 1064 getMaterialToken(file, token);
1065 // We take phong as gouraud 1065 // We take phong as gouraud
1066 pass.Material.GouraudShading=(token!="flat"); 1066 pass.Material.GouraudShading=(token!="flat");
1067 } 1067 }
1068 else if (token=="polygon_mode") 1068 else if (token=="polygon_mode")
1069 { 1069 {
1070 getMaterialToken(file, token); 1070 getMaterialToken(file, token);
1071 pass.Material.Wireframe=(token=="wireframe"); 1071 pass.Material.Wireframe=(token=="wireframe");
1072 pass.Material.PointCloud=(token=="points"); 1072 pass.Material.PointCloud=(token=="points");
1073 } 1073 }
1074 else if (token=="max_lights") 1074 else if (token=="max_lights")
1075 { 1075 {
1076 getMaterialToken(file, token); 1076 getMaterialToken(file, token);
1077 pass.MaxLights=core::strtoul10(token.c_str()); 1077 pass.MaxLights=core::strtoul10(token.c_str());
1078 } 1078 }
1079 else if (token=="point_size") 1079 else if (token=="point_size")
1080 { 1080 {
1081 getMaterialToken(file, token); 1081 getMaterialToken(file, token);
1082 pass.PointSize=core::fast_atof(token.c_str()); 1082 pass.PointSize=core::fast_atof(token.c_str());
1083 } 1083 }
1084 else if (token=="point_sprites") 1084 else if (token=="point_sprites")
1085 { 1085 {
1086 getMaterialToken(file, token); 1086 getMaterialToken(file, token);
1087 pass.PointSprites=(token=="on"); 1087 pass.PointSprites=(token=="on");
1088 } 1088 }
1089 else if (token=="point_size_min") 1089 else if (token=="point_size_min")
1090 { 1090 {
1091 getMaterialToken(file, token); 1091 getMaterialToken(file, token);
1092 pass.PointSizeMin=core::strtoul10(token.c_str()); 1092 pass.PointSizeMin=core::strtoul10(token.c_str());
1093 } 1093 }
1094 else if (token=="point_size_max") 1094 else if (token=="point_size_max")
1095 { 1095 {
1096 getMaterialToken(file, token); 1096 getMaterialToken(file, token);
1097 pass.PointSizeMax=core::strtoul10(token.c_str()); 1097 pass.PointSizeMax=core::strtoul10(token.c_str());
1098 } 1098 }
1099 else if (token=="texture_unit") 1099 else if (token=="texture_unit")
1100 { 1100 {
1101#ifdef IRR_OGRE_LOADER_DEBUG 1101#ifdef IRR_OGRE_LOADER_DEBUG
1102 os::Printer::log("Read Texture unit", ELL_DEBUG); 1102 os::Printer::log("Read Texture unit", ELL_DEBUG);
1103#endif 1103#endif
1104 getMaterialToken(file, token); //open brace 1104 getMaterialToken(file, token); //open brace
1105 getMaterialToken(file, token); 1105 getMaterialToken(file, token);
1106 while(token != "}") 1106 while(token != "}")
1107 { 1107 {
1108 if (token=="texture") 1108 if (token=="texture")
1109 { 1109 {
1110 getMaterialToken(file, token); 1110 getMaterialToken(file, token);
1111 pass.Texture.Filename.push_back(token); 1111 pass.Texture.Filename.push_back(token);
1112#ifdef IRR_OGRE_LOADER_DEBUG 1112#ifdef IRR_OGRE_LOADER_DEBUG
1113 os::Printer::log("Read Texture", token, ELL_DEBUG); 1113 os::Printer::log("Read Texture", token, ELL_DEBUG);
1114#endif 1114#endif
1115 getMaterialToken(file, pass.Texture.CoordsType, true); 1115 getMaterialToken(file, pass.Texture.CoordsType, true);
1116 getMaterialToken(file, pass.Texture.MipMaps, true); 1116 getMaterialToken(file, pass.Texture.MipMaps, true);
1117 getMaterialToken(file, pass.Texture.Alpha, true); 1117 getMaterialToken(file, pass.Texture.Alpha, true);
1118 // Hmm, we might need more hints for other material types using two textures... 1118 // Hmm, we might need more hints for other material types using two textures...
1119 if (textureUnit>0) 1119 if (textureUnit>0)
1120 pass.Material.MaterialType=video::EMT_LIGHTMAP; 1120 pass.Material.MaterialType=video::EMT_LIGHTMAP;
1121 } 1121 }
1122 else if (token=="filtering") 1122 else if (token=="filtering")
1123 { 1123 {
1124 getMaterialToken(file, token); 1124 getMaterialToken(file, token);
1125 pass.Material.TextureLayer[textureUnit].AnisotropicFilter=0; 1125 pass.Material.TextureLayer[textureUnit].AnisotropicFilter=0;
1126 if (token=="point") 1126 if (token=="point")
1127 { 1127 {
1128 pass.Material.TextureLayer[textureUnit].BilinearFilter=false; 1128 pass.Material.TextureLayer[textureUnit].BilinearFilter=false;
1129 pass.Material.TextureLayer[textureUnit].TrilinearFilter=false; 1129 pass.Material.TextureLayer[textureUnit].TrilinearFilter=false;
1130 getMaterialToken(file, token); 1130 getMaterialToken(file, token);
1131 getMaterialToken(file, token); 1131 getMaterialToken(file, token);
1132 } 1132 }
1133 else if (token=="linear") 1133 else if (token=="linear")
1134 { 1134 {
1135 getMaterialToken(file, token); 1135 getMaterialToken(file, token);
1136 if (token=="point") 1136 if (token=="point")
1137 { 1137 {
1138 pass.Material.TextureLayer[textureUnit].BilinearFilter=false; 1138 pass.Material.TextureLayer[textureUnit].BilinearFilter=false;
1139 pass.Material.TextureLayer[textureUnit].TrilinearFilter=false; 1139 pass.Material.TextureLayer[textureUnit].TrilinearFilter=false;
1140 getMaterialToken(file, token); 1140 getMaterialToken(file, token);
1141 } 1141 }
1142 else 1142 else
1143 { 1143 {
1144 pass.Material.TextureLayer[textureUnit].BilinearFilter=true; 1144 pass.Material.TextureLayer[textureUnit].BilinearFilter=true;
1145 getMaterialToken(file, token); 1145 getMaterialToken(file, token);
1146 pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="linear"); 1146 pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="linear");
1147 } 1147 }
1148 } 1148 }
1149 else 1149 else
1150 { 1150 {
1151 pass.Material.TextureLayer[textureUnit].BilinearFilter=(token=="bilinear"); 1151 pass.Material.TextureLayer[textureUnit].BilinearFilter=(token=="bilinear");
1152 pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="trilinear"); 1152 pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="trilinear");
1153 pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(token=="anisotropic")?2:1; 1153 pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(token=="anisotropic")?2:1;
1154 } 1154 }
1155 } 1155 }
1156 else if (token=="max_anisotropy") 1156 else if (token=="max_anisotropy")
1157 { 1157 {
1158 getMaterialToken(file, token); 1158 getMaterialToken(file, token);
1159 pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(u8)core::strtoul10(token.c_str()); 1159 pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(u8)core::strtoul10(token.c_str());
1160 } 1160 }
1161 else if (token=="texture_alias") 1161 else if (token=="texture_alias")
1162 { 1162 {
1163 getMaterialToken(file, pass.Texture.Alias); 1163 getMaterialToken(file, pass.Texture.Alias);
1164 } 1164 }
1165 else if (token=="mipmap_bias") 1165 else if (token=="mipmap_bias")
1166 { 1166 {
1167 getMaterialToken(file, token); 1167 getMaterialToken(file, token);
1168 pass.Material.TextureLayer[textureUnit].LODBias=(s8)core::fast_atof(token.c_str()); 1168 pass.Material.TextureLayer[textureUnit].LODBias=(s8)core::fast_atof(token.c_str());
1169 } 1169 }
1170 else if (token=="colour_op") 1170 else if (token=="colour_op")
1171 { // TODO: Choose correct values 1171 { // TODO: Choose correct values
1172 getMaterialToken(file, token); 1172 getMaterialToken(file, token);
1173 if (token=="add") 1173 if (token=="add")
1174 pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; 1174 pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR;
1175 else if (token=="modulate") 1175 else if (token=="modulate")
1176 pass.Material.MaterialType=video::EMT_SOLID; 1176 pass.Material.MaterialType=video::EMT_SOLID;
1177 else if (token=="alpha_blend") 1177 else if (token=="alpha_blend")
1178 pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; 1178 pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
1179 else if (token=="colour_blend") 1179 else if (token=="colour_blend")
1180 pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; 1180 pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA;
1181 else 1181 else
1182 getMaterialToken(file, token); 1182 getMaterialToken(file, token);
1183 } 1183 }
1184 getMaterialToken(file, token); 1184 getMaterialToken(file, token);
1185 } 1185 }
1186 ++textureUnit; 1186 ++textureUnit;
1187 } 1187 }
1188 else if (token=="shadow_caster_program_ref") 1188 else if (token=="shadow_caster_program_ref")
1189 { 1189 {
1190 do 1190 do
1191 { 1191 {
1192 getMaterialToken(file, token); 1192 getMaterialToken(file, token);
1193 } while (token != "}"); 1193 } while (token != "}");
1194 } 1194 }
1195 else if (token=="shadow_caster_vertex_program_ref") 1195 else if (token=="shadow_caster_vertex_program_ref")
1196 { 1196 {
1197 do 1197 do
1198 { 1198 {
1199 getMaterialToken(file, token); 1199 getMaterialToken(file, token);
1200 } while (token != "}"); 1200 } while (token != "}");
1201 } 1201 }
1202 else if (token=="vertex_program_ref") 1202 else if (token=="vertex_program_ref")
1203 { 1203 {
1204 do 1204 do
1205 { 1205 {
1206 getMaterialToken(file, token); 1206 getMaterialToken(file, token);
1207 } while (token != "}"); 1207 } while (token != "}");
1208 } 1208 }
1209 //fog_override, iteration, point_size_attenuation 1209 //fog_override, iteration, point_size_attenuation
1210 //not considered yet! 1210 //not considered yet!
1211 getMaterialToken(file, token); 1211 getMaterialToken(file, token);
1212 if (token=="{") 1212 if (token=="{")
1213 ++inBlocks; 1213 ++inBlocks;
1214 else if (token=="}") 1214 else if (token=="}")
1215 --inBlocks; 1215 --inBlocks;
1216 } 1216 }
1217} 1217}
1218 1218
1219 1219
1220void COgreMeshFileLoader::readTechnique(io::IReadFile* file, OgreMaterial& mat) 1220void COgreMeshFileLoader::readTechnique(io::IReadFile* file, OgreMaterial& mat)
1221{ 1221{
1222#ifdef IRR_OGRE_LOADER_DEBUG 1222#ifdef IRR_OGRE_LOADER_DEBUG
1223 os::Printer::log("Read Technique"); 1223 os::Printer::log("Read Technique");
1224#endif 1224#endif
1225 core::stringc token; 1225 core::stringc token;
1226 mat.Techniques.push_back(OgreTechnique()); 1226 mat.Techniques.push_back(OgreTechnique());
1227 OgreTechnique& technique=mat.Techniques.getLast(); 1227 OgreTechnique& technique=mat.Techniques.getLast();
1228 1228
1229 getMaterialToken(file, technique.Name); //open brace or name 1229 getMaterialToken(file, technique.Name); //open brace or name
1230 if (technique.Name != "{") 1230 if (technique.Name != "{")
1231 getMaterialToken(file, token); //open brace 1231 getMaterialToken(file, token); //open brace
1232 else 1232 else
1233 technique.Name=core::stringc((int)mat.Techniques.size()); 1233 technique.Name=core::stringc((int)mat.Techniques.size());
1234 1234
1235 getMaterialToken(file, token); 1235 getMaterialToken(file, token);
1236 while (token != "}") 1236 while (token != "}")
1237 { 1237 {
1238 if (token == "pass") 1238 if (token == "pass")
1239 readPass(file, technique); 1239 readPass(file, technique);
1240 else if (token == "scheme") 1240 else if (token == "scheme")
1241 getMaterialToken(file, token); 1241 getMaterialToken(file, token);
1242 else if (token == "lod_index") 1242 else if (token == "lod_index")
1243 getMaterialToken(file, token); 1243 getMaterialToken(file, token);
1244 getMaterialToken(file, token); 1244 getMaterialToken(file, token);
1245 } 1245 }
1246} 1246}
1247 1247
1248 1248
1249void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile) 1249void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile)
1250{ 1250{
1251#ifdef IRR_OGRE_LOADER_DEBUG 1251#ifdef IRR_OGRE_LOADER_DEBUG
1252 os::Printer::log("Load Materials", ELL_DEBUG); 1252 os::Printer::log("Load Materials", ELL_DEBUG);
1253#endif 1253#endif
1254 core::stringc token; 1254 core::stringc token;
1255 io::IReadFile* file = 0; 1255 io::IReadFile* file = 0;
1256 io::path filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".material"; 1256 io::path filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".material";
1257 if (FileSystem->existFile(filename)) 1257 if (FileSystem->existFile(filename))
1258 file = FileSystem->createAndOpenFile(filename); 1258 file = FileSystem->createAndOpenFile(filename);
1259 else 1259 else
1260 file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename); 1260 file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename);
1261 1261
1262 if (!file) 1262 if (!file)
1263 { 1263 {
1264 os::Printer::log("Could not load OGRE material", filename); 1264 os::Printer::log("Could not load OGRE material", filename);
1265 return; 1265 return;
1266 } 1266 }
1267 1267
1268 getMaterialToken(file, token); 1268 getMaterialToken(file, token);
1269 1269
1270 while (file->getPos() < file->getSize()) 1270 while (file->getPos() < file->getSize())
1271 { 1271 {
1272 if ((token == "fragment_program") || (token == "vertex_program")) 1272 if ((token == "fragment_program") || (token == "vertex_program"))
1273 { 1273 {
1274 // skip whole block 1274 // skip whole block
1275 u32 blocks=1; 1275 u32 blocks=1;
1276 do 1276 do
1277 { 1277 {
1278 getMaterialToken(file, token); 1278 getMaterialToken(file, token);
1279 } while (token != "{"); 1279 } while (token != "{");
1280 do 1280 do
1281 { 1281 {
1282 getMaterialToken(file, token); 1282 getMaterialToken(file, token);
1283 if (token == "{") 1283 if (token == "{")
1284 ++blocks; 1284 ++blocks;
1285 else if (token == "}") 1285 else if (token == "}")
1286 --blocks; 1286 --blocks;
1287 } while (blocks); 1287 } while (blocks);
1288 getMaterialToken(file, token); 1288 getMaterialToken(file, token);
1289 continue; 1289 continue;
1290 } 1290 }
1291 if (token != "material") 1291 if (token != "material")
1292 { 1292 {
1293 if (token.trim().size()) 1293 if (token.trim().size())
1294 os::Printer::log("Unknown material group", token.c_str()); 1294 os::Printer::log("Unknown material group", token.c_str());
1295 break; 1295 break;
1296 } 1296 }
1297 1297
1298 Materials.push_back(OgreMaterial()); 1298 Materials.push_back(OgreMaterial());
1299 OgreMaterial& mat = Materials.getLast(); 1299 OgreMaterial& mat = Materials.getLast();
1300 1300
1301 getMaterialToken(file, mat.Name); 1301 getMaterialToken(file, mat.Name);
1302#ifdef IRR_OGRE_LOADER_DEBUG 1302#ifdef IRR_OGRE_LOADER_DEBUG
1303 os::Printer::log("Load Material", mat.Name.c_str(), ELL_DEBUG); 1303 os::Printer::log("Load Material", mat.Name.c_str(), ELL_DEBUG);
1304#endif 1304#endif
1305 getMaterialToken(file, token); //open brace 1305 getMaterialToken(file, token); //open brace
1306 getMaterialToken(file, token); 1306 getMaterialToken(file, token);
1307 while(token != "}") 1307 while(token != "}")
1308 { 1308 {
1309 if (token=="lod_distances") // can have several items 1309 if (token=="lod_distances") // can have several items
1310 getMaterialToken(file, token); 1310 getMaterialToken(file, token);
1311 else if (token=="receive_shadows") 1311 else if (token=="receive_shadows")
1312 { 1312 {
1313 getMaterialToken(file, token); 1313 getMaterialToken(file, token);
1314 mat.ReceiveShadows=(token=="on"); 1314 mat.ReceiveShadows=(token=="on");
1315 } 1315 }
1316 else if (token=="transparency_casts_shadows") 1316 else if (token=="transparency_casts_shadows")
1317 { 1317 {
1318 getMaterialToken(file, token); 1318 getMaterialToken(file, token);
1319 mat.TransparencyCastsShadows=(token=="on"); 1319 mat.TransparencyCastsShadows=(token=="on");
1320 } 1320 }
1321 else if (token=="set_texture_alias") 1321 else if (token=="set_texture_alias")
1322 { 1322 {
1323 getMaterialToken(file, token); 1323 getMaterialToken(file, token);
1324 getMaterialToken(file, token); 1324 getMaterialToken(file, token);
1325 } 1325 }
1326 else if (token=="technique") 1326 else if (token=="technique")
1327 readTechnique(file, mat); 1327 readTechnique(file, mat);
1328 getMaterialToken(file, token); 1328 getMaterialToken(file, token);
1329 } 1329 }
1330 getMaterialToken(file, token); 1330 getMaterialToken(file, token);
1331 } 1331 }
1332 1332
1333 file->drop(); 1333 file->drop();
1334#ifdef IRR_OGRE_LOADER_DEBUG 1334#ifdef IRR_OGRE_LOADER_DEBUG
1335 os::Printer::log("Finished loading Materials", ELL_DEBUG); 1335 os::Printer::log("Finished loading Materials", ELL_DEBUG);
1336#endif 1336#endif
1337} 1337}
1338 1338
1339 1339
1340bool COgreMeshFileLoader::loadSkeleton(io::IReadFile* meshFile, const core::stringc& name) 1340bool COgreMeshFileLoader::loadSkeleton(io::IReadFile* meshFile, const core::stringc& name)
1341{ 1341{
1342#ifdef IRR_OGRE_LOADER_DEBUG 1342#ifdef IRR_OGRE_LOADER_DEBUG
1343 os::Printer::log("Load Skeleton", name, ELL_DEBUG); 1343 os::Printer::log("Load Skeleton", name, ELL_DEBUG);
1344#endif 1344#endif
1345 io::IReadFile* file = 0; 1345 io::IReadFile* file = 0;
1346 io::path filename; 1346 io::path filename;
1347 if (FileSystem->existFile(name)) 1347 if (FileSystem->existFile(name))
1348 file = FileSystem->createAndOpenFile(name); 1348 file = FileSystem->createAndOpenFile(name);
1349 else if (FileSystem->existFile(filename = FileSystem->getFileDir(meshFile->getFileName())+"/"+name)) 1349 else if (FileSystem->existFile(filename = FileSystem->getFileDir(meshFile->getFileName())+"/"+name))
1350 file = FileSystem->createAndOpenFile(filename); 1350 file = FileSystem->createAndOpenFile(filename);
1351 else if (FileSystem->existFile(filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".skeleton")) 1351 else if (FileSystem->existFile(filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".skeleton"))
1352 file = FileSystem->createAndOpenFile(filename); 1352 file = FileSystem->createAndOpenFile(filename);
1353 else 1353 else
1354 file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename); 1354 file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename);
1355 if (!file) 1355 if (!file)
1356 { 1356 {
1357 os::Printer::log("Could not load matching skeleton", name); 1357 os::Printer::log("Could not load matching skeleton", name);
1358 return false; 1358 return false;
1359 } 1359 }
1360 1360
1361 s16 id; 1361 s16 id;
1362 file->read(&id, 2); 1362 file->read(&id, 2);
1363 if (SwapEndian) 1363 if (SwapEndian)
1364 id = os::Byteswap::byteswap(id); 1364 id = os::Byteswap::byteswap(id);
1365 if (id != COGRE_HEADER) 1365 if (id != COGRE_HEADER)
1366 { 1366 {
1367 file->drop(); 1367 file->drop();
1368 return false; 1368 return false;
1369 } 1369 }
1370 1370
1371 core::stringc skeletonVersion; 1371 core::stringc skeletonVersion;
1372 ChunkData head; 1372 ChunkData head;
1373 readString(file, head, skeletonVersion); 1373 readString(file, head, skeletonVersion);
1374 if (skeletonVersion != "[Serializer_v1.10]") 1374 if (skeletonVersion != "[Serializer_v1.10]")
1375 { 1375 {
1376 file->drop(); 1376 file->drop();
1377 return false; 1377 return false;
1378 } 1378 }
1379 1379
1380 u16 bone=0; 1380 u16 bone=0;
1381 f32 animationTotal=0.f; 1381 f32 animationTotal=0.f;
1382 while(file->getPos() < file->getSize()) 1382 while(file->getPos() < file->getSize())
1383 { 1383 {
1384 ChunkData data; 1384 ChunkData data;
1385 readChunkData(file, data); 1385 readChunkData(file, data);
1386 1386
1387 switch(data.header.id) 1387 switch(data.header.id)
1388 { 1388 {
1389 case COGRE_SKELETON: 1389 case COGRE_SKELETON:
1390 { 1390 {
1391 Skeleton.Bones.push_back(OgreBone()); 1391 Skeleton.Bones.push_back(OgreBone());
1392 OgreBone& bone = Skeleton.Bones.getLast(); 1392 OgreBone& bone = Skeleton.Bones.getLast();
1393 readString(file, data, bone.Name); 1393 readString(file, data, bone.Name);
1394 readShort(file, data, &bone.Handle); 1394 readShort(file, data, &bone.Handle);
1395 readVector(file, data, bone.Position); 1395 readVector(file, data, bone.Position);
1396 readQuaternion(file, data, bone.Orientation); 1396 readQuaternion(file, data, bone.Orientation);
1397#ifdef IRR_OGRE_LOADER_DEBUG 1397#ifdef IRR_OGRE_LOADER_DEBUG
1398 os::Printer::log("Bone", bone.Name+" ("+core::stringc(bone.Handle)+")", ELL_DEBUG); 1398 os::Printer::log("Bone", bone.Name+" ("+core::stringc(bone.Handle)+")", ELL_DEBUG);
1399 os::Printer::log("Position", core::stringc(bone.Position.X)+" "+core::stringc(bone.Position.Y)+" "+core::stringc(bone.Position.Z), ELL_DEBUG); 1399 os::Printer::log("Position", core::stringc(bone.Position.X)+" "+core::stringc(bone.Position.Y)+" "+core::stringc(bone.Position.Z), ELL_DEBUG);
1400 os::Printer::log("Rotation quat", core::stringc(bone.Orientation.W)+" "+core::stringc(bone.Orientation.X)+" "+core::stringc(bone.Orientation.Y)+" "+core::stringc(bone.Orientation.Z), ELL_DEBUG); 1400 os::Printer::log("Rotation quat", core::stringc(bone.Orientation.W)+" "+core::stringc(bone.Orientation.X)+" "+core::stringc(bone.Orientation.Y)+" "+core::stringc(bone.Orientation.Z), ELL_DEBUG);
1401// core::vector3df rot; 1401// core::vector3df rot;
1402// bone.Orientation.toEuler(rot); 1402// bone.Orientation.toEuler(rot);
1403// rot *= core::RADTODEG; 1403// rot *= core::RADTODEG;
1404// os::Printer::log("Rotation", core::stringc(rot.X)+" "+core::stringc(rot.Y)+" "+core::stringc(rot.Z)); 1404// os::Printer::log("Rotation", core::stringc(rot.X)+" "+core::stringc(rot.Y)+" "+core::stringc(rot.Z));
1405#endif 1405#endif
1406 if (data.read<(data.header.length-bone.Name.size())) 1406 if (data.read<(data.header.length-bone.Name.size()))
1407 { 1407 {
1408 readVector(file, data, bone.Scale); 1408 readVector(file, data, bone.Scale);
1409 bone.Scale.X *= -1.f; 1409 bone.Scale.X *= -1.f;
1410 } 1410 }
1411 else 1411 else
1412 bone.Scale=core::vector3df(1,1,1); 1412 bone.Scale=core::vector3df(1,1,1);
1413 bone.Parent=0xffff; 1413 bone.Parent=0xffff;
1414 } 1414 }
1415 break; 1415 break;
1416 case COGRE_BONE_PARENT: 1416 case COGRE_BONE_PARENT:
1417 { 1417 {
1418 u16 parent; 1418 u16 parent;
1419 readShort(file, data, &bone); 1419 readShort(file, data, &bone);
1420 readShort(file, data, &parent); 1420 readShort(file, data, &parent);
1421 if (bone<Skeleton.Bones.size() && parent<Skeleton.Bones.size()) 1421 if (bone<Skeleton.Bones.size() && parent<Skeleton.Bones.size())
1422 Skeleton.Bones[bone].Parent=parent; 1422 Skeleton.Bones[bone].Parent=parent;
1423 } 1423 }
1424 break; 1424 break;
1425 case COGRE_ANIMATION: 1425 case COGRE_ANIMATION:
1426 { 1426 {
1427 if (Skeleton.Animations.size()) 1427 if (Skeleton.Animations.size())
1428 animationTotal+=Skeleton.Animations.getLast().Length; 1428 animationTotal+=Skeleton.Animations.getLast().Length;
1429 Skeleton.Animations.push_back(OgreAnimation()); 1429 Skeleton.Animations.push_back(OgreAnimation());
1430 OgreAnimation& anim = Skeleton.Animations.getLast(); 1430 OgreAnimation& anim = Skeleton.Animations.getLast();
1431 readString(file, data, anim.Name); 1431 readString(file, data, anim.Name);
1432 readFloat(file, data, &anim.Length); 1432 readFloat(file, data, &anim.Length);
1433#ifdef IRR_OGRE_LOADER_DEBUG 1433#ifdef IRR_OGRE_LOADER_DEBUG
1434 os::Printer::log("Animation", anim.Name, ELL_DEBUG); 1434 os::Printer::log("Animation", anim.Name, ELL_DEBUG);
1435 os::Printer::log("Length", core::stringc(anim.Length), ELL_DEBUG); 1435 os::Printer::log("Length", core::stringc(anim.Length), ELL_DEBUG);
1436#endif 1436#endif
1437 } 1437 }
1438 break; 1438 break;
1439 case COGRE_ANIMATION_TRACK: 1439 case COGRE_ANIMATION_TRACK:
1440#ifdef IRR_OGRE_LOADER_DEBUG 1440#ifdef IRR_OGRE_LOADER_DEBUG
1441 os::Printer::log("for Bone ", core::stringc(bone), ELL_DEBUG); 1441 os::Printer::log("for Bone ", core::stringc(bone), ELL_DEBUG);
1442#endif 1442#endif
1443 readShort(file, data, &bone); // store current bone 1443 readShort(file, data, &bone); // store current bone
1444 break; 1444 break;
1445 case COGRE_ANIMATION_KEYFRAME: 1445 case COGRE_ANIMATION_KEYFRAME:
1446 { 1446 {
1447 Skeleton.Animations.getLast().Keyframes.push_back(OgreKeyframe()); 1447 Skeleton.Animations.getLast().Keyframes.push_back(OgreKeyframe());
1448 OgreKeyframe& keyframe = Skeleton.Animations.getLast().Keyframes.getLast(); 1448 OgreKeyframe& keyframe = Skeleton.Animations.getLast().Keyframes.getLast();
1449 readFloat(file, data, &keyframe.Time); 1449 readFloat(file, data, &keyframe.Time);
1450 keyframe.Time+=animationTotal; 1450 keyframe.Time+=animationTotal;
1451 readQuaternion(file, data, keyframe.Orientation); 1451 readQuaternion(file, data, keyframe.Orientation);
1452 readVector(file, data, keyframe.Position); 1452 readVector(file, data, keyframe.Position);
1453 if (data.read<data.header.length) 1453 if (data.read<data.header.length)
1454 { 1454 {
1455 readVector(file, data, keyframe.Scale); 1455 readVector(file, data, keyframe.Scale);
1456 keyframe.Scale.X *= -1.f; 1456 keyframe.Scale.X *= -1.f;
1457 } 1457 }
1458 else 1458 else
1459 keyframe.Scale=core::vector3df(1,1,1); 1459 keyframe.Scale=core::vector3df(1,1,1);
1460 keyframe.BoneID=bone; 1460 keyframe.BoneID=bone;
1461 } 1461 }
1462 break; 1462 break;
1463 case COGRE_ANIMATION_LINK: 1463 case COGRE_ANIMATION_LINK:
1464#ifdef IRR_OGRE_LOADER_DEBUG 1464#ifdef IRR_OGRE_LOADER_DEBUG
1465 os::Printer::log("Animation link", ELL_DEBUG); 1465 os::Printer::log("Animation link", ELL_DEBUG);
1466#endif 1466#endif
1467 break; 1467 break;
1468 default: 1468 default:
1469 break; 1469 break;
1470 } 1470 }
1471 } 1471 }
1472 file->drop(); 1472 file->drop();
1473 return true; 1473 return true;
1474} 1474}
1475 1475
1476 1476
1477void COgreMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data) 1477void COgreMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data)
1478{ 1478{
1479 file->read(&data.header, sizeof(ChunkHeader)); 1479 file->read(&data.header, sizeof(ChunkHeader));
1480 if (SwapEndian) 1480 if (SwapEndian)
1481 { 1481 {
1482 data.header.id = os::Byteswap::byteswap(data.header.id); 1482 data.header.id = os::Byteswap::byteswap(data.header.id);
1483 data.header.length = os::Byteswap::byteswap(data.header.length); 1483 data.header.length = os::Byteswap::byteswap(data.header.length);
1484 } 1484 }
1485 data.read += sizeof(ChunkHeader); 1485 data.read += sizeof(ChunkHeader);
1486} 1486}
1487 1487
1488 1488
1489void COgreMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) 1489void COgreMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out)
1490{ 1490{
1491 c8 c = 0; 1491 c8 c = 0;
1492 out = ""; 1492 out = "";
1493 1493
1494 while (c!='\n') 1494 while (c!='\n')
1495 { 1495 {
1496 file->read(&c, sizeof(c8)); 1496 file->read(&c, sizeof(c8));
1497 if (c!='\n') 1497 if (c!='\n')
1498 out.append(c); 1498 out.append(c);
1499 1499
1500 } 1500 }
1501 data.read+=out.size()+1; 1501 data.read+=out.size()+1;
1502} 1502}
1503 1503
1504 1504
1505void COgreMeshFileLoader::readBool(io::IReadFile* file, ChunkData& data, bool& out) 1505void COgreMeshFileLoader::readBool(io::IReadFile* file, ChunkData& data, bool& out)
1506{ 1506{
1507 // normal C type because we read a bit string 1507 // normal C type because we read a bit string
1508 char c = 0; 1508 char c = 0;
1509 file->read(&c, sizeof(char)); 1509 file->read(&c, sizeof(char));
1510 out=(c!=0); 1510 out=(c!=0);
1511 ++data.read; 1511 ++data.read;
1512} 1512}
1513 1513
1514 1514
1515void COgreMeshFileLoader::readInt(io::IReadFile* file, ChunkData& data, s32* out, u32 num) 1515void COgreMeshFileLoader::readInt(io::IReadFile* file, ChunkData& data, s32* out, u32 num)
1516{ 1516{
1517 // normal C type because we read a bit string 1517 // normal C type because we read a bit string
1518 file->read(out, sizeof(int)*num); 1518 file->read(out, sizeof(int)*num);
1519 if (SwapEndian) 1519 if (SwapEndian)
1520 { 1520 {
1521 for (u32 i=0; i<num; ++i) 1521 for (u32 i=0; i<num; ++i)
1522 out[i] = os::Byteswap::byteswap(out[i]); 1522 out[i] = os::Byteswap::byteswap(out[i]);
1523 } 1523 }
1524 data.read+=sizeof(int)*num; 1524 data.read+=sizeof(int)*num;
1525} 1525}
1526 1526
1527 1527
1528void COgreMeshFileLoader::readShort(io::IReadFile* file, ChunkData& data, u16* out, u32 num) 1528void COgreMeshFileLoader::readShort(io::IReadFile* file, ChunkData& data, u16* out, u32 num)
1529{ 1529{
1530 // normal C type because we read a bit string 1530 // normal C type because we read a bit string
1531 file->read(out, sizeof(short)*num); 1531 file->read(out, sizeof(short)*num);
1532 if (SwapEndian) 1532 if (SwapEndian)
1533 { 1533 {
1534 for (u32 i=0; i<num; ++i) 1534 for (u32 i=0; i<num; ++i)
1535 out[i] = os::Byteswap::byteswap(out[i]); 1535 out[i] = os::Byteswap::byteswap(out[i]);
1536 } 1536 }
1537 data.read+=sizeof(short)*num; 1537 data.read+=sizeof(short)*num;
1538} 1538}
1539 1539
1540 1540
1541void COgreMeshFileLoader::readFloat(io::IReadFile* file, ChunkData& data, f32* out, u32 num) 1541void COgreMeshFileLoader::readFloat(io::IReadFile* file, ChunkData& data, f32* out, u32 num)
1542{ 1542{
1543 // normal C type because we read a bit string 1543 // normal C type because we read a bit string
1544 file->read(out, sizeof(float)*num); 1544 file->read(out, sizeof(float)*num);
1545 if (SwapEndian) 1545 if (SwapEndian)
1546 { 1546 {
1547 for (u32 i=0; i<num; ++i) 1547 for (u32 i=0; i<num; ++i)
1548 out[i] = os::Byteswap::byteswap(out[i]); 1548 out[i] = os::Byteswap::byteswap(out[i]);
1549 } 1549 }
1550 data.read+=sizeof(float)*num; 1550 data.read+=sizeof(float)*num;
1551} 1551}
1552 1552
1553 1553
1554void COgreMeshFileLoader::readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out) 1554void COgreMeshFileLoader::readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out)
1555{ 1555{
1556 readFloat(file, data, &out.X); 1556 readFloat(file, data, &out.X);
1557 readFloat(file, data, &out.Y); 1557 readFloat(file, data, &out.Y);
1558 readFloat(file, data, &out.Z); 1558 readFloat(file, data, &out.Z);
1559 out.X *= -1.f; 1559 out.X *= -1.f;
1560} 1560}
1561 1561
1562 1562
1563void COgreMeshFileLoader::readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out) 1563void COgreMeshFileLoader::readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out)
1564{ 1564{
1565 readVector(file, data, *((core::vector3df*)&out.X)); 1565 readVector(file, data, *((core::vector3df*)&out.X));
1566 readFloat(file, data, &out.W); 1566 readFloat(file, data, &out.W);
1567} 1567}
1568 1568
1569 1569
1570void COgreMeshFileLoader::clearMeshes() 1570void COgreMeshFileLoader::clearMeshes()
1571{ 1571{
1572 for (u32 i=0; i<Meshes.size(); ++i) 1572 for (u32 i=0; i<Meshes.size(); ++i)
1573 { 1573 {
1574 for (int k=0; k<(int)Meshes[i].Geometry.Buffers.size(); ++k) 1574 for (int k=0; k<(int)Meshes[i].Geometry.Buffers.size(); ++k)
1575 Meshes[i].Geometry.Buffers[k].Data.clear(); 1575 Meshes[i].Geometry.Buffers[k].Data.clear();
1576 1576
1577 for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j) 1577 for (u32 j=0; j<Meshes[i].SubMeshes.size(); ++j)
1578 { 1578 {
1579 for (int h=0; h<(int)Meshes[i].SubMeshes[j].Geometry.Buffers.size(); ++h) 1579 for (int h=0; h<(int)Meshes[i].SubMeshes[j].Geometry.Buffers.size(); ++h)
1580 Meshes[i].SubMeshes[j].Geometry.Buffers[h].Data.clear(); 1580 Meshes[i].SubMeshes[j].Geometry.Buffers[h].Data.clear();
1581 } 1581 }
1582 } 1582 }
1583 1583
1584 Meshes.clear(); 1584 Meshes.clear();
1585} 1585}
1586 1586
1587 1587
1588} // end namespace scene 1588} // end namespace scene
1589} // end namespace irr 1589} // end namespace irr
1590 1590
1591#endif // _IRR_COMPILE_WITH_OGRE_LOADER_ 1591#endif // _IRR_COMPILE_WITH_OGRE_LOADER_
1592 1592