aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp4838
1 files changed, 2419 insertions, 2419 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp
index 595e911..1c67434 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CXMeshFileLoader.cpp
@@ -1,2419 +1,2419 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "IrrCompileConfig.h" 5#include "IrrCompileConfig.h"
6 6
7#ifdef _IRR_COMPILE_WITH_X_LOADER_ 7#ifdef _IRR_COMPILE_WITH_X_LOADER_
8 8
9#include "CXMeshFileLoader.h" 9#include "CXMeshFileLoader.h"
10#include "os.h" 10#include "os.h"
11 11
12#include "fast_atof.h" 12#include "fast_atof.h"
13#include "coreutil.h" 13#include "coreutil.h"
14#include "ISceneManager.h" 14#include "ISceneManager.h"
15#include "IVideoDriver.h" 15#include "IVideoDriver.h"
16#include "IFileSystem.h" 16#include "IFileSystem.h"
17#include "IReadFile.h" 17#include "IReadFile.h"
18 18
19#ifdef _DEBUG 19#ifdef _DEBUG
20#define _XREADER_DEBUG 20#define _XREADER_DEBUG
21#endif 21#endif
22//#define BETTER_MESHBUFFER_SPLITTING_FOR_X 22//#define BETTER_MESHBUFFER_SPLITTING_FOR_X
23 23
24namespace irr 24namespace irr
25{ 25{
26namespace scene 26namespace scene
27{ 27{
28 28
29//! Constructor 29//! Constructor
30CXMeshFileLoader::CXMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs) 30CXMeshFileLoader::CXMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs)
31: SceneManager(smgr), FileSystem(fs), AllJoints(0), AnimatedMesh(0), 31: SceneManager(smgr), FileSystem(fs), AllJoints(0), AnimatedMesh(0),
32 Buffer(0), P(0), End(0), BinaryNumCount(0), Line(0), 32 Buffer(0), P(0), End(0), BinaryNumCount(0), Line(0),
33 CurFrame(0), MajorVersion(0), MinorVersion(0), BinaryFormat(false), FloatSize(0) 33 CurFrame(0), MajorVersion(0), MinorVersion(0), BinaryFormat(false), FloatSize(0)
34{ 34{
35 #ifdef _DEBUG 35 #ifdef _DEBUG
36 setDebugName("CXMeshFileLoader"); 36 setDebugName("CXMeshFileLoader");
37 #endif 37 #endif
38} 38}
39 39
40 40
41//! returns true if the file maybe is able to be loaded by this class 41//! returns true if the file maybe is able to be loaded by this class
42//! based on the file extension (e.g. ".bsp") 42//! based on the file extension (e.g. ".bsp")
43bool CXMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 43bool CXMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
44{ 44{
45 return core::hasFileExtension ( filename, "x" ); 45 return core::hasFileExtension ( filename, "x" );
46} 46}
47 47
48 48
49//! creates/loads an animated mesh from the file. 49//! creates/loads an animated mesh from the file.
50//! \return Pointer to the created mesh. Returns 0 if loading failed. 50//! \return Pointer to the created mesh. Returns 0 if loading failed.
51//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). 51//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
52//! See IReferenceCounted::drop() for more information. 52//! See IReferenceCounted::drop() for more information.
53IAnimatedMesh* CXMeshFileLoader::createMesh(io::IReadFile* f) 53IAnimatedMesh* CXMeshFileLoader::createMesh(io::IReadFile* f)
54{ 54{
55 if (!f) 55 if (!f)
56 return 0; 56 return 0;
57 57
58#ifdef _XREADER_DEBUG 58#ifdef _XREADER_DEBUG
59 u32 time = os::Timer::getRealTime(); 59 u32 time = os::Timer::getRealTime();
60#endif 60#endif
61 61
62 AnimatedMesh = new CSkinnedMesh(); 62 AnimatedMesh = new CSkinnedMesh();
63 63
64 if (load(f)) 64 if (load(f))
65 { 65 {
66 AnimatedMesh->finalize(); 66 AnimatedMesh->finalize();
67 } 67 }
68 else 68 else
69 { 69 {
70 AnimatedMesh->drop(); 70 AnimatedMesh->drop();
71 AnimatedMesh = 0; 71 AnimatedMesh = 0;
72 } 72 }
73#ifdef _XREADER_DEBUG 73#ifdef _XREADER_DEBUG
74 time = os::Timer::getRealTime() - time; 74 time = os::Timer::getRealTime() - time;
75 core::stringc tmpString = "Time to load "; 75 core::stringc tmpString = "Time to load ";
76 tmpString += BinaryFormat ? "binary" : "ascii"; 76 tmpString += BinaryFormat ? "binary" : "ascii";
77 tmpString += " X file: "; 77 tmpString += " X file: ";
78 tmpString += time; 78 tmpString += time;
79 tmpString += "ms"; 79 tmpString += "ms";
80 os::Printer::log(tmpString.c_str()); 80 os::Printer::log(tmpString.c_str());
81#endif 81#endif
82 //Clear up 82 //Clear up
83 83
84 MajorVersion=0; 84 MajorVersion=0;
85 MinorVersion=0; 85 MinorVersion=0;
86 BinaryFormat=0; 86 BinaryFormat=0;
87 BinaryNumCount=0; 87 BinaryNumCount=0;
88 FloatSize=0; 88 FloatSize=0;
89 P=0; 89 P=0;
90 End=0; 90 End=0;
91 CurFrame=0; 91 CurFrame=0;
92 TemplateMaterials.clear(); 92 TemplateMaterials.clear();
93 93
94 delete [] Buffer; 94 delete [] Buffer;
95 Buffer = 0; 95 Buffer = 0;
96 96
97 for (u32 i=0; i<Meshes.size(); ++i) 97 for (u32 i=0; i<Meshes.size(); ++i)
98 delete Meshes[i]; 98 delete Meshes[i];
99 Meshes.clear(); 99 Meshes.clear();
100 100
101 return AnimatedMesh; 101 return AnimatedMesh;
102} 102}
103 103
104 104
105bool CXMeshFileLoader::load(io::IReadFile* file) 105bool CXMeshFileLoader::load(io::IReadFile* file)
106{ 106{
107 if (!readFileIntoMemory(file)) 107 if (!readFileIntoMemory(file))
108 return false; 108 return false;
109 109
110 if (!parseFile()) 110 if (!parseFile())
111 return false; 111 return false;
112 112
113 for (u32 n=0; n<Meshes.size(); ++n) 113 for (u32 n=0; n<Meshes.size(); ++n)
114 { 114 {
115 SXMesh *mesh=Meshes[n]; 115 SXMesh *mesh=Meshes[n];
116 116
117 // default material if nothing loaded 117 // default material if nothing loaded
118 if (!mesh->Materials.size()) 118 if (!mesh->Materials.size())
119 { 119 {
120 mesh->Materials.push_back(video::SMaterial()); 120 mesh->Materials.push_back(video::SMaterial());
121 mesh->Materials[0].DiffuseColor.set(0xff777777); 121 mesh->Materials[0].DiffuseColor.set(0xff777777);
122 mesh->Materials[0].Shininess=0.f; 122 mesh->Materials[0].Shininess=0.f;
123 mesh->Materials[0].SpecularColor.set(0xff777777); 123 mesh->Materials[0].SpecularColor.set(0xff777777);
124 mesh->Materials[0].EmissiveColor.set(0xff000000); 124 mesh->Materials[0].EmissiveColor.set(0xff000000);
125 } 125 }
126 126
127 u32 i; 127 u32 i;
128 128
129 mesh->Buffers.reallocate(mesh->Materials.size()); 129 mesh->Buffers.reallocate(mesh->Materials.size());
130#ifndef BETTER_MESHBUFFER_SPLITTING_FOR_X 130#ifndef BETTER_MESHBUFFER_SPLITTING_FOR_X
131 const u32 bufferOffset = AnimatedMesh->getMeshBufferCount(); 131 const u32 bufferOffset = AnimatedMesh->getMeshBufferCount();
132#endif 132#endif
133 for (i=0; i<mesh->Materials.size(); ++i) 133 for (i=0; i<mesh->Materials.size(); ++i)
134 { 134 {
135 mesh->Buffers.push_back( AnimatedMesh->addMeshBuffer() ); 135 mesh->Buffers.push_back( AnimatedMesh->addMeshBuffer() );
136 mesh->Buffers.getLast()->Material = mesh->Materials[i]; 136 mesh->Buffers.getLast()->Material = mesh->Materials[i];
137 137
138 if (!mesh->HasSkinning) 138 if (!mesh->HasSkinning)
139 { 139 {
140 //Set up rigid animation 140 //Set up rigid animation
141 if (mesh->AttachedJointID!=-1) 141 if (mesh->AttachedJointID!=-1)
142 { 142 {
143 AnimatedMesh->getAllJoints()[mesh->AttachedJointID]->AttachedMeshes.push_back( AnimatedMesh->getMeshBuffers().size()-1 ); 143 AnimatedMesh->getAllJoints()[mesh->AttachedJointID]->AttachedMeshes.push_back( AnimatedMesh->getMeshBuffers().size()-1 );
144 } 144 }
145 } 145 }
146 } 146 }
147 147
148 if (!mesh->FaceMaterialIndices.size()) 148 if (!mesh->FaceMaterialIndices.size())
149 { 149 {
150 mesh->FaceMaterialIndices.set_used(mesh->Indices.size() / 3); 150 mesh->FaceMaterialIndices.set_used(mesh->Indices.size() / 3);
151 for (i=0; i<mesh->FaceMaterialIndices.size(); ++i) 151 for (i=0; i<mesh->FaceMaterialIndices.size(); ++i)
152 mesh->FaceMaterialIndices[i]=0; 152 mesh->FaceMaterialIndices[i]=0;
153 } 153 }
154 154
155 if (!mesh->HasVertexColors) 155 if (!mesh->HasVertexColors)
156 { 156 {
157 for (u32 j=0;j<mesh->FaceMaterialIndices.size();++j) 157 for (u32 j=0;j<mesh->FaceMaterialIndices.size();++j)
158 { 158 {
159 for (u32 id=j*3+0;id<=j*3+2;++id) 159 for (u32 id=j*3+0;id<=j*3+2;++id)
160 { 160 {
161 mesh->Vertices[ mesh->Indices[id] ].Color = mesh->Buffers[mesh->FaceMaterialIndices[j]]->Material.DiffuseColor; 161 mesh->Vertices[ mesh->Indices[id] ].Color = mesh->Buffers[mesh->FaceMaterialIndices[j]]->Material.DiffuseColor;
162 } 162 }
163 } 163 }
164 } 164 }
165 165
166 #ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X 166 #ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X
167 { 167 {
168 //the same vertex can be used in many different meshbuffers, but it's slow to work out 168 //the same vertex can be used in many different meshbuffers, but it's slow to work out
169 169
170 core::array< core::array< u32 > > verticesLinkIndex; 170 core::array< core::array< u32 > > verticesLinkIndex;
171 verticesLinkIndex.reallocate(mesh->Vertices.size()); 171 verticesLinkIndex.reallocate(mesh->Vertices.size());
172 core::array< core::array< u16 > > verticesLinkBuffer; 172 core::array< core::array< u16 > > verticesLinkBuffer;
173 verticesLinkBuffer.reallocate(mesh->Vertices.size()); 173 verticesLinkBuffer.reallocate(mesh->Vertices.size());
174 174
175 for (i=0;i<mesh->Vertices.size();++i) 175 for (i=0;i<mesh->Vertices.size();++i)
176 { 176 {
177 verticesLinkIndex.push_back( core::array< u32 >() ); 177 verticesLinkIndex.push_back( core::array< u32 >() );
178 verticesLinkBuffer.push_back( core::array< u16 >() ); 178 verticesLinkBuffer.push_back( core::array< u16 >() );
179 } 179 }
180 180
181 for (i=0;i<mesh->FaceMaterialIndices.size();++i) 181 for (i=0;i<mesh->FaceMaterialIndices.size();++i)
182 { 182 {
183 for (u32 id=i*3+0;id<=i*3+2;++id) 183 for (u32 id=i*3+0;id<=i*3+2;++id)
184 { 184 {
185 core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; 185 core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ];
186 bool found=false; 186 bool found=false;
187 187
188 for (u32 j=0; j < Array.size(); ++j) 188 for (u32 j=0; j < Array.size(); ++j)
189 { 189 {
190 if (Array[j]==mesh->FaceMaterialIndices[i]) 190 if (Array[j]==mesh->FaceMaterialIndices[i])
191 { 191 {
192 found=true; 192 found=true;
193 break; 193 break;
194 } 194 }
195 } 195 }
196 196
197 if (!found) 197 if (!found)
198 Array.push_back( mesh->FaceMaterialIndices[i] ); 198 Array.push_back( mesh->FaceMaterialIndices[i] );
199 } 199 }
200 } 200 }
201 201
202 for (i=0;i<verticesLinkBuffer.size();++i) 202 for (i=0;i<verticesLinkBuffer.size();++i)
203 { 203 {
204 if (!verticesLinkBuffer[i].size()) 204 if (!verticesLinkBuffer[i].size())
205 verticesLinkBuffer[i].push_back(0); 205 verticesLinkBuffer[i].push_back(0);
206 } 206 }
207 207
208 for (i=0;i<mesh->Vertices.size();++i) 208 for (i=0;i<mesh->Vertices.size();++i)
209 { 209 {
210 core::array< u16 > &Array = verticesLinkBuffer[i]; 210 core::array< u16 > &Array = verticesLinkBuffer[i];
211 verticesLinkIndex[i].reallocate(Array.size()); 211 verticesLinkIndex[i].reallocate(Array.size());
212 for (u32 j=0; j < Array.size(); ++j) 212 for (u32 j=0; j < Array.size(); ++j)
213 { 213 {
214 scene::SSkinMeshBuffer *buffer = mesh->Buffers[ Array[j] ]; 214 scene::SSkinMeshBuffer *buffer = mesh->Buffers[ Array[j] ];
215 verticesLinkIndex[i].push_back( buffer->Vertices_Standard.size() ); 215 verticesLinkIndex[i].push_back( buffer->Vertices_Standard.size() );
216 buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); 216 buffer->Vertices_Standard.push_back( mesh->Vertices[i] );
217 } 217 }
218 } 218 }
219 219
220 for (i=0;i<mesh->FaceMaterialIndices.size();++i) 220 for (i=0;i<mesh->FaceMaterialIndices.size();++i)
221 { 221 {
222 scene::SSkinMeshBuffer *buffer=mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; 222 scene::SSkinMeshBuffer *buffer=mesh->Buffers[ mesh->FaceMaterialIndices[i] ];
223 223
224 for (u32 id=i*3+0;id<=i*3+2;++id) 224 for (u32 id=i*3+0;id<=i*3+2;++id)
225 { 225 {
226 core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; 226 core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ];
227 227
228 for (u32 j=0;j< Array.size() ;++j) 228 for (u32 j=0;j< Array.size() ;++j)
229 { 229 {
230 if ( Array[j]== mesh->FaceMaterialIndices[i] ) 230 if ( Array[j]== mesh->FaceMaterialIndices[i] )
231 buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ][j] ); 231 buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ][j] );
232 } 232 }
233 } 233 }
234 } 234 }
235 235
236 for (u32 j=0;j<mesh->WeightJoint.size();++j) 236 for (u32 j=0;j<mesh->WeightJoint.size();++j)
237 { 237 {
238 ISkinnedMesh::SJoint* joint = AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]; 238 ISkinnedMesh::SJoint* joint = AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]];
239 ISkinnedMesh::SWeight& weight = joint->Weights[mesh->WeightNum[j]]; 239 ISkinnedMesh::SWeight& weight = joint->Weights[mesh->WeightNum[j]];
240 240
241 u32 id = weight.vertex_id; 241 u32 id = weight.vertex_id;
242 242
243 if (id>=verticesLinkIndex.size()) 243 if (id>=verticesLinkIndex.size())
244 { 244 {
245 os::Printer::log("X loader: Weight id out of range", ELL_WARNING); 245 os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
246 id=0; 246 id=0;
247 weight.strength=0.f; 247 weight.strength=0.f;
248 } 248 }
249 249
250 if (verticesLinkBuffer[id].size()==1) 250 if (verticesLinkBuffer[id].size()==1)
251 { 251 {
252 weight.vertex_id=verticesLinkIndex[id][0]; 252 weight.vertex_id=verticesLinkIndex[id][0];
253 weight.buffer_id=verticesLinkBuffer[id][0]; 253 weight.buffer_id=verticesLinkBuffer[id][0];
254 } 254 }
255 else if (verticesLinkBuffer[id].size() != 0) 255 else if (verticesLinkBuffer[id].size() != 0)
256 { 256 {
257 for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k) 257 for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k)
258 { 258 {
259 ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->addWeight(joint); 259 ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->addWeight(joint);
260 WeightClone->strength = weight.strength; 260 WeightClone->strength = weight.strength;
261 WeightClone->vertex_id = verticesLinkIndex[id][k]; 261 WeightClone->vertex_id = verticesLinkIndex[id][k];
262 WeightClone->buffer_id = verticesLinkBuffer[id][k]; 262 WeightClone->buffer_id = verticesLinkBuffer[id][k];
263 } 263 }
264 } 264 }
265 } 265 }
266 } 266 }
267 #else 267 #else
268 { 268 {
269 core::array< u32 > verticesLinkIndex; 269 core::array< u32 > verticesLinkIndex;
270 core::array< s16 > verticesLinkBuffer; 270 core::array< s16 > verticesLinkBuffer;
271 verticesLinkBuffer.set_used(mesh->Vertices.size()); 271 verticesLinkBuffer.set_used(mesh->Vertices.size());
272 272
273 // init with 0 273 // init with 0
274 for (i=0;i<mesh->Vertices.size();++i) 274 for (i=0;i<mesh->Vertices.size();++i)
275 { 275 {
276 // watch out for vertices which are not part of the mesh 276 // watch out for vertices which are not part of the mesh
277 // they will keep the -1 and can lead to out-of-bounds access 277 // they will keep the -1 and can lead to out-of-bounds access
278 verticesLinkBuffer[i]=-1; 278 verticesLinkBuffer[i]=-1;
279 } 279 }
280 280
281 bool warned = false; 281 bool warned = false;
282 // store meshbuffer number per vertex 282 // store meshbuffer number per vertex
283 for (i=0;i<mesh->FaceMaterialIndices.size();++i) 283 for (i=0;i<mesh->FaceMaterialIndices.size();++i)
284 { 284 {
285 for (u32 id=i*3+0;id<=i*3+2;++id) 285 for (u32 id=i*3+0;id<=i*3+2;++id)
286 { 286 {
287 if ((verticesLinkBuffer[mesh->Indices[id]] != -1) && (verticesLinkBuffer[mesh->Indices[id]] != (s16)mesh->FaceMaterialIndices[i])) 287 if ((verticesLinkBuffer[mesh->Indices[id]] != -1) && (verticesLinkBuffer[mesh->Indices[id]] != (s16)mesh->FaceMaterialIndices[i]))
288 { 288 {
289 if (!warned) 289 if (!warned)
290 { 290 {
291 os::Printer::log("X loader", "Duplicated vertex, animation might be corrupted.", ELL_WARNING); 291 os::Printer::log("X loader", "Duplicated vertex, animation might be corrupted.", ELL_WARNING);
292 warned=true; 292 warned=true;
293 } 293 }
294 const u32 tmp = mesh->Vertices.size(); 294 const u32 tmp = mesh->Vertices.size();
295 mesh->Vertices.push_back(mesh->Vertices[ mesh->Indices[id] ]); 295 mesh->Vertices.push_back(mesh->Vertices[ mesh->Indices[id] ]);
296 mesh->Indices[id] = tmp; 296 mesh->Indices[id] = tmp;
297 verticesLinkBuffer.set_used(mesh->Vertices.size()); 297 verticesLinkBuffer.set_used(mesh->Vertices.size());
298 } 298 }
299 verticesLinkBuffer[ mesh->Indices[id] ] = mesh->FaceMaterialIndices[i]; 299 verticesLinkBuffer[ mesh->Indices[id] ] = mesh->FaceMaterialIndices[i];
300 } 300 }
301 } 301 }
302 302
303 if (mesh->FaceMaterialIndices.size() != 0) 303 if (mesh->FaceMaterialIndices.size() != 0)
304 { 304 {
305 // store vertices in buffers and remember relation in verticesLinkIndex 305 // store vertices in buffers and remember relation in verticesLinkIndex
306 u32* vCountArray = new u32[mesh->Buffers.size()]; 306 u32* vCountArray = new u32[mesh->Buffers.size()];
307 memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); 307 memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32));
308 // count vertices in each buffer and reallocate 308 // count vertices in each buffer and reallocate
309 for (i=0; i<mesh->Vertices.size(); ++i) 309 for (i=0; i<mesh->Vertices.size(); ++i)
310 { 310 {
311 if (verticesLinkBuffer[i] != -1) 311 if (verticesLinkBuffer[i] != -1)
312 ++vCountArray[verticesLinkBuffer[i]]; 312 ++vCountArray[verticesLinkBuffer[i]];
313 } 313 }
314 if (mesh->TCoords2.size()) 314 if (mesh->TCoords2.size())
315 { 315 {
316 for (i=0; i!=mesh->Buffers.size(); ++i) 316 for (i=0; i!=mesh->Buffers.size(); ++i)
317 { 317 {
318 mesh->Buffers[i]->Vertices_2TCoords.reallocate(vCountArray[i]); 318 mesh->Buffers[i]->Vertices_2TCoords.reallocate(vCountArray[i]);
319 mesh->Buffers[i]->VertexType=video::EVT_2TCOORDS; 319 mesh->Buffers[i]->VertexType=video::EVT_2TCOORDS;
320 } 320 }
321 } 321 }
322 else 322 else
323 { 323 {
324 for (i=0; i!=mesh->Buffers.size(); ++i) 324 for (i=0; i!=mesh->Buffers.size(); ++i)
325 mesh->Buffers[i]->Vertices_Standard.reallocate(vCountArray[i]); 325 mesh->Buffers[i]->Vertices_Standard.reallocate(vCountArray[i]);
326 } 326 }
327 327
328 verticesLinkIndex.set_used(mesh->Vertices.size()); 328 verticesLinkIndex.set_used(mesh->Vertices.size());
329 // actually store vertices 329 // actually store vertices
330 for (i=0; i<mesh->Vertices.size(); ++i) 330 for (i=0; i<mesh->Vertices.size(); ++i)
331 { 331 {
332 // if a vertex is missing for some reason, just skip it 332 // if a vertex is missing for some reason, just skip it
333 if (verticesLinkBuffer[i]==-1) 333 if (verticesLinkBuffer[i]==-1)
334 continue; 334 continue;
335 scene::SSkinMeshBuffer *buffer = mesh->Buffers[ verticesLinkBuffer[i] ]; 335 scene::SSkinMeshBuffer *buffer = mesh->Buffers[ verticesLinkBuffer[i] ];
336 336
337 if (mesh->TCoords2.size()) 337 if (mesh->TCoords2.size())
338 { 338 {
339 verticesLinkIndex[i] = buffer->Vertices_2TCoords.size(); 339 verticesLinkIndex[i] = buffer->Vertices_2TCoords.size();
340 buffer->Vertices_2TCoords.push_back( mesh->Vertices[i] ); 340 buffer->Vertices_2TCoords.push_back( mesh->Vertices[i] );
341 // We have a problem with correct tcoord2 handling here 341 // We have a problem with correct tcoord2 handling here
342 // crash fixed for now by checking the values 342 // crash fixed for now by checking the values
343 buffer->Vertices_2TCoords.getLast().TCoords2=(i<mesh->TCoords2.size())?mesh->TCoords2[i]:mesh->Vertices[i].TCoords; 343 buffer->Vertices_2TCoords.getLast().TCoords2=(i<mesh->TCoords2.size())?mesh->TCoords2[i]:mesh->Vertices[i].TCoords;
344 } 344 }
345 else 345 else
346 { 346 {
347 verticesLinkIndex[i] = buffer->Vertices_Standard.size(); 347 verticesLinkIndex[i] = buffer->Vertices_Standard.size();
348 buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); 348 buffer->Vertices_Standard.push_back( mesh->Vertices[i] );
349 } 349 }
350 } 350 }
351 351
352 // count indices per buffer and reallocate 352 // count indices per buffer and reallocate
353 memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); 353 memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32));
354 for (i=0; i<mesh->FaceMaterialIndices.size(); ++i) 354 for (i=0; i<mesh->FaceMaterialIndices.size(); ++i)
355 ++vCountArray[ mesh->FaceMaterialIndices[i] ]; 355 ++vCountArray[ mesh->FaceMaterialIndices[i] ];
356 for (i=0; i!=mesh->Buffers.size(); ++i) 356 for (i=0; i!=mesh->Buffers.size(); ++i)
357 mesh->Buffers[i]->Indices.reallocate(vCountArray[i]); 357 mesh->Buffers[i]->Indices.reallocate(vCountArray[i]);
358 delete [] vCountArray; 358 delete [] vCountArray;
359 // create indices per buffer 359 // create indices per buffer
360 for (i=0; i<mesh->FaceMaterialIndices.size(); ++i) 360 for (i=0; i<mesh->FaceMaterialIndices.size(); ++i)
361 { 361 {
362 scene::SSkinMeshBuffer *buffer = mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; 362 scene::SSkinMeshBuffer *buffer = mesh->Buffers[ mesh->FaceMaterialIndices[i] ];
363 for (u32 id=i*3+0; id!=i*3+3; ++id) 363 for (u32 id=i*3+0; id!=i*3+3; ++id)
364 { 364 {
365 buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ] ); 365 buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ] );
366 } 366 }
367 } 367 }
368 } 368 }
369 369
370 for (u32 j=0; j<mesh->WeightJoint.size(); ++j) 370 for (u32 j=0; j<mesh->WeightJoint.size(); ++j)
371 { 371 {
372 ISkinnedMesh::SWeight& weight = (AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]->Weights[mesh->WeightNum[j]]); 372 ISkinnedMesh::SWeight& weight = (AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]->Weights[mesh->WeightNum[j]]);
373 373
374 u32 id = weight.vertex_id; 374 u32 id = weight.vertex_id;
375 375
376 if (id>=verticesLinkIndex.size()) 376 if (id>=verticesLinkIndex.size())
377 { 377 {
378 os::Printer::log("X loader: Weight id out of range", ELL_WARNING); 378 os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
379 id=0; 379 id=0;
380 weight.strength=0.f; 380 weight.strength=0.f;
381 } 381 }
382 382
383 weight.vertex_id=verticesLinkIndex[id]; 383 weight.vertex_id=verticesLinkIndex[id];
384 weight.buffer_id=verticesLinkBuffer[id] + bufferOffset; 384 weight.buffer_id=verticesLinkBuffer[id] + bufferOffset;
385 } 385 }
386 } 386 }
387 #endif 387 #endif
388 388
389 } 389 }
390 390
391 return true; 391 return true;
392} 392}
393 393
394 394
395//! Reads file into memory 395//! Reads file into memory
396bool CXMeshFileLoader::readFileIntoMemory(io::IReadFile* file) 396bool CXMeshFileLoader::readFileIntoMemory(io::IReadFile* file)
397{ 397{
398 const long size = file->getSize(); 398 const long size = file->getSize();
399 if (size < 12) 399 if (size < 12)
400 { 400 {
401 os::Printer::log("X File is too small.", ELL_WARNING); 401 os::Printer::log("X File is too small.", ELL_WARNING);
402 return false; 402 return false;
403 } 403 }
404 404
405 Buffer = new c8[size]; 405 Buffer = new c8[size];
406 406
407 //! read all into memory 407 //! read all into memory
408 if (file->read(Buffer, size) != size) 408 if (file->read(Buffer, size) != size)
409 { 409 {
410 os::Printer::log("Could not read from x file.", ELL_WARNING); 410 os::Printer::log("Could not read from x file.", ELL_WARNING);
411 return false; 411 return false;
412 } 412 }
413 413
414 Line = 1; 414 Line = 1;
415 End = Buffer + size; 415 End = Buffer + size;
416 416
417 //! check header "xof " 417 //! check header "xof "
418 if (strncmp(Buffer, "xof ", 4)!=0) 418 if (strncmp(Buffer, "xof ", 4)!=0)
419 { 419 {
420 os::Printer::log("Not an x file, wrong header.", ELL_WARNING); 420 os::Printer::log("Not an x file, wrong header.", ELL_WARNING);
421 return false; 421 return false;
422 } 422 }
423 423
424 //! read minor and major version, e.g. 0302 or 0303 424 //! read minor and major version, e.g. 0302 or 0303
425 c8 tmp[3]; 425 c8 tmp[3];
426 tmp[0] = Buffer[4]; 426 tmp[0] = Buffer[4];
427 tmp[1] = Buffer[5]; 427 tmp[1] = Buffer[5];
428 tmp[2] = 0x0; 428 tmp[2] = 0x0;
429 MajorVersion = core::strtoul10(tmp); 429 MajorVersion = core::strtoul10(tmp);
430 430
431 tmp[0] = Buffer[6]; 431 tmp[0] = Buffer[6];
432 tmp[1] = Buffer[7]; 432 tmp[1] = Buffer[7];
433 MinorVersion = core::strtoul10(tmp); 433 MinorVersion = core::strtoul10(tmp);
434 434
435 //! read format 435 //! read format
436 if (strncmp(&Buffer[8], "txt ", 4) ==0) 436 if (strncmp(&Buffer[8], "txt ", 4) ==0)
437 BinaryFormat = false; 437 BinaryFormat = false;
438 else if (strncmp(&Buffer[8], "bin ", 4) ==0) 438 else if (strncmp(&Buffer[8], "bin ", 4) ==0)
439 BinaryFormat = true; 439 BinaryFormat = true;
440 else 440 else
441 { 441 {
442 os::Printer::log("Only uncompressed x files currently supported.", ELL_WARNING); 442 os::Printer::log("Only uncompressed x files currently supported.", ELL_WARNING);
443 return false; 443 return false;
444 } 444 }
445 BinaryNumCount=0; 445 BinaryNumCount=0;
446 446
447 //! read float size 447 //! read float size
448 if (strncmp(&Buffer[12], "0032", 4) ==0) 448 if (strncmp(&Buffer[12], "0032", 4) ==0)
449 FloatSize = 4; 449 FloatSize = 4;
450 else if (strncmp(&Buffer[12], "0064", 4) ==0) 450 else if (strncmp(&Buffer[12], "0064", 4) ==0)
451 FloatSize = 8; 451 FloatSize = 8;
452 else 452 else
453 { 453 {
454 os::Printer::log("Float size not supported.", ELL_WARNING); 454 os::Printer::log("Float size not supported.", ELL_WARNING);
455 return false; 455 return false;
456 } 456 }
457 457
458 P = &Buffer[16]; 458 P = &Buffer[16];
459 459
460 readUntilEndOfLine(); 460 readUntilEndOfLine();
461 FilePath = FileSystem->getFileDir(file->getFileName()) + "/"; 461 FilePath = FileSystem->getFileDir(file->getFileName()) + "/";
462 462
463 return true; 463 return true;
464} 464}
465 465
466 466
467//! Parses the file 467//! Parses the file
468bool CXMeshFileLoader::parseFile() 468bool CXMeshFileLoader::parseFile()
469{ 469{
470 while(parseDataObject()) 470 while(parseDataObject())
471 { 471 {
472 // loop 472 // loop
473 } 473 }
474 474
475 return true; 475 return true;
476} 476}
477 477
478 478
479//! Parses the next Data object in the file 479//! Parses the next Data object in the file
480bool CXMeshFileLoader::parseDataObject() 480bool CXMeshFileLoader::parseDataObject()
481{ 481{
482 core::stringc objectName = getNextToken(); 482 core::stringc objectName = getNextToken();
483 483
484 if (objectName.size() == 0) 484 if (objectName.size() == 0)
485 return false; 485 return false;
486 486
487 // parse specific object 487 // parse specific object
488#ifdef _XREADER_DEBUG 488#ifdef _XREADER_DEBUG
489 os::Printer::log("debug DataObject:", objectName.c_str(), ELL_DEBUG); 489 os::Printer::log("debug DataObject:", objectName.c_str(), ELL_DEBUG);
490#endif 490#endif
491 491
492 if (objectName == "template") 492 if (objectName == "template")
493 return parseDataObjectTemplate(); 493 return parseDataObjectTemplate();
494 else 494 else
495 if (objectName == "Frame") 495 if (objectName == "Frame")
496 { 496 {
497 return parseDataObjectFrame( 0 ); 497 return parseDataObjectFrame( 0 );
498 } 498 }
499 else 499 else
500 if (objectName == "Mesh") 500 if (objectName == "Mesh")
501 { 501 {
502 // some meshes have no frames at all 502 // some meshes have no frames at all
503 //CurFrame = AnimatedMesh->addJoint(0); 503 //CurFrame = AnimatedMesh->addJoint(0);
504 504
505 SXMesh *mesh=new SXMesh; 505 SXMesh *mesh=new SXMesh;
506 506
507 //mesh->Buffer=AnimatedMesh->addMeshBuffer(); 507 //mesh->Buffer=AnimatedMesh->addMeshBuffer();
508 Meshes.push_back(mesh); 508 Meshes.push_back(mesh);
509 509
510 return parseDataObjectMesh(*mesh); 510 return parseDataObjectMesh(*mesh);
511 } 511 }
512 else 512 else
513 if (objectName == "AnimationSet") 513 if (objectName == "AnimationSet")
514 { 514 {
515 return parseDataObjectAnimationSet(); 515 return parseDataObjectAnimationSet();
516 } 516 }
517 else 517 else
518 if (objectName == "Material") 518 if (objectName == "Material")
519 { 519 {
520 // template materials now available thanks to joeWright 520 // template materials now available thanks to joeWright
521 TemplateMaterials.push_back(SXTemplateMaterial()); 521 TemplateMaterials.push_back(SXTemplateMaterial());
522 TemplateMaterials.getLast().Name = getNextToken(); 522 TemplateMaterials.getLast().Name = getNextToken();
523 return parseDataObjectMaterial(TemplateMaterials.getLast().Material); 523 return parseDataObjectMaterial(TemplateMaterials.getLast().Material);
524 } 524 }
525 else 525 else
526 if (objectName == "}") 526 if (objectName == "}")
527 { 527 {
528 os::Printer::log("} found in dataObject", ELL_WARNING); 528 os::Printer::log("} found in dataObject", ELL_WARNING);
529 return true; 529 return true;
530 } 530 }
531 531
532 os::Printer::log("Unknown data object in animation of .x file", objectName.c_str(), ELL_WARNING); 532 os::Printer::log("Unknown data object in animation of .x file", objectName.c_str(), ELL_WARNING);
533 533
534 return parseUnknownDataObject(); 534 return parseUnknownDataObject();
535} 535}
536 536
537 537
538bool CXMeshFileLoader::parseDataObjectTemplate() 538bool CXMeshFileLoader::parseDataObjectTemplate()
539{ 539{
540#ifdef _XREADER_DEBUG 540#ifdef _XREADER_DEBUG
541 os::Printer::log("CXFileReader: Reading template", ELL_DEBUG); 541 os::Printer::log("CXFileReader: Reading template", ELL_DEBUG);
542#endif 542#endif
543 543
544 // parse a template data object. Currently not stored. 544 // parse a template data object. Currently not stored.
545 core::stringc name; 545 core::stringc name;
546 546
547 if (!readHeadOfDataObject(&name)) 547 if (!readHeadOfDataObject(&name))
548 { 548 {
549 os::Printer::log("Left delimiter in template data object missing.", 549 os::Printer::log("Left delimiter in template data object missing.",
550 name.c_str(), ELL_WARNING); 550 name.c_str(), ELL_WARNING);
551 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 551 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
552 return false; 552 return false;
553 } 553 }
554 554
555 // read GUID 555 // read GUID
556 getNextToken(); 556 getNextToken();
557 557
558 // read and ignore data members 558 // read and ignore data members
559 while(true) 559 while(true)
560 { 560 {
561 core::stringc s = getNextToken(); 561 core::stringc s = getNextToken();
562 562
563 if (s == "}") 563 if (s == "}")
564 break; 564 break;
565 565
566 if (s.size() == 0) 566 if (s.size() == 0)
567 return false; 567 return false;
568 } 568 }
569 569
570 return true; 570 return true;
571} 571}
572 572
573 573
574bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent) 574bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent)
575{ 575{
576#ifdef _XREADER_DEBUG 576#ifdef _XREADER_DEBUG
577 os::Printer::log("CXFileReader: Reading frame", ELL_DEBUG); 577 os::Printer::log("CXFileReader: Reading frame", ELL_DEBUG);
578#endif 578#endif
579 579
580 // A coordinate frame, or "frame of reference." The Frame template 580 // A coordinate frame, or "frame of reference." The Frame template
581 // is open and can contain any object. The Direct3D extensions (D3DX) 581 // is open and can contain any object. The Direct3D extensions (D3DX)
582 // mesh-loading functions recognize Mesh, FrameTransformMatrix, and 582 // mesh-loading functions recognize Mesh, FrameTransformMatrix, and
583 // Frame template instances as child objects when loading a Frame 583 // Frame template instances as child objects when loading a Frame
584 // instance. 584 // instance.
585 585
586 u32 JointID=0; 586 u32 JointID=0;
587 587
588 core::stringc name; 588 core::stringc name;
589 589
590 if (!readHeadOfDataObject(&name)) 590 if (!readHeadOfDataObject(&name))
591 { 591 {
592 os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING); 592 os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING);
593 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 593 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
594 return false; 594 return false;
595 } 595 }
596 596
597 CSkinnedMesh::SJoint *joint=0; 597 CSkinnedMesh::SJoint *joint=0;
598 598
599 if (name.size()) 599 if (name.size())
600 { 600 {
601 for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n) 601 for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
602 { 602 {
603 if (AnimatedMesh->getAllJoints()[n]->Name==name) 603 if (AnimatedMesh->getAllJoints()[n]->Name==name)
604 { 604 {
605 joint=AnimatedMesh->getAllJoints()[n]; 605 joint=AnimatedMesh->getAllJoints()[n];
606 JointID=n; 606 JointID=n;
607 break; 607 break;
608 } 608 }
609 } 609 }
610 } 610 }
611 611
612 if (!joint) 612 if (!joint)
613 { 613 {
614#ifdef _XREADER_DEBUG 614#ifdef _XREADER_DEBUG
615 os::Printer::log("creating joint ", name.c_str(), ELL_DEBUG); 615 os::Printer::log("creating joint ", name.c_str(), ELL_DEBUG);
616#endif 616#endif
617 joint=AnimatedMesh->addJoint(Parent); 617 joint=AnimatedMesh->addJoint(Parent);
618 joint->Name=name; 618 joint->Name=name;
619 JointID=AnimatedMesh->getAllJoints().size()-1; 619 JointID=AnimatedMesh->getAllJoints().size()-1;
620 } 620 }
621 else 621 else
622 { 622 {
623#ifdef _XREADER_DEBUG 623#ifdef _XREADER_DEBUG
624 os::Printer::log("using joint ", name.c_str(), ELL_DEBUG); 624 os::Printer::log("using joint ", name.c_str(), ELL_DEBUG);
625#endif 625#endif
626 if (Parent) 626 if (Parent)
627 Parent->Children.push_back(joint); 627 Parent->Children.push_back(joint);
628 } 628 }
629 629
630 // Now inside a frame. 630 // Now inside a frame.
631 // read tokens until closing brace is reached. 631 // read tokens until closing brace is reached.
632 632
633 while(true) 633 while(true)
634 { 634 {
635 core::stringc objectName = getNextToken(); 635 core::stringc objectName = getNextToken();
636 636
637#ifdef _XREADER_DEBUG 637#ifdef _XREADER_DEBUG
638 os::Printer::log("debug DataObject in frame:", objectName.c_str(), ELL_DEBUG); 638 os::Printer::log("debug DataObject in frame:", objectName.c_str(), ELL_DEBUG);
639#endif 639#endif
640 640
641 if (objectName.size() == 0) 641 if (objectName.size() == 0)
642 { 642 {
643 os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING); 643 os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING);
644 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 644 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
645 return false; 645 return false;
646 } 646 }
647 else 647 else
648 if (objectName == "}") 648 if (objectName == "}")
649 { 649 {
650 break; // frame finished 650 break; // frame finished
651 } 651 }
652 else 652 else
653 if (objectName == "Frame") 653 if (objectName == "Frame")
654 { 654 {
655 655
656 if (!parseDataObjectFrame(joint)) 656 if (!parseDataObjectFrame(joint))
657 return false; 657 return false;
658 } 658 }
659 else 659 else
660 if (objectName == "FrameTransformMatrix") 660 if (objectName == "FrameTransformMatrix")
661 { 661 {
662 if (!parseDataObjectTransformationMatrix(joint->LocalMatrix)) 662 if (!parseDataObjectTransformationMatrix(joint->LocalMatrix))
663 return false; 663 return false;
664 664
665 //joint->LocalAnimatedMatrix 665 //joint->LocalAnimatedMatrix
666 //joint->LocalAnimatedMatrix.makeInverse(); 666 //joint->LocalAnimatedMatrix.makeInverse();
667 //joint->LocalMatrix=tmp*joint->LocalAnimatedMatrix; 667 //joint->LocalMatrix=tmp*joint->LocalAnimatedMatrix;
668 } 668 }
669 else 669 else
670 if (objectName == "Mesh") 670 if (objectName == "Mesh")
671 { 671 {
672 /* 672 /*
673 frame.Meshes.push_back(SXMesh()); 673 frame.Meshes.push_back(SXMesh());
674 if (!parseDataObjectMesh(frame.Meshes.getLast())) 674 if (!parseDataObjectMesh(frame.Meshes.getLast()))
675 return false; 675 return false;
676 */ 676 */
677 SXMesh *mesh=new SXMesh; 677 SXMesh *mesh=new SXMesh;
678 678
679 mesh->AttachedJointID=JointID; 679 mesh->AttachedJointID=JointID;
680 680
681 Meshes.push_back(mesh); 681 Meshes.push_back(mesh);
682 682
683 if (!parseDataObjectMesh(*mesh)) 683 if (!parseDataObjectMesh(*mesh))
684 return false; 684 return false;
685 } 685 }
686 else 686 else
687 { 687 {
688 os::Printer::log("Unknown data object in frame in x file", objectName.c_str(), ELL_WARNING); 688 os::Printer::log("Unknown data object in frame in x file", objectName.c_str(), ELL_WARNING);
689 if (!parseUnknownDataObject()) 689 if (!parseUnknownDataObject())
690 return false; 690 return false;
691 } 691 }
692 } 692 }
693 693
694 return true; 694 return true;
695} 695}
696 696
697 697
698bool CXMeshFileLoader::parseDataObjectTransformationMatrix(core::matrix4 &mat) 698bool CXMeshFileLoader::parseDataObjectTransformationMatrix(core::matrix4 &mat)
699{ 699{
700#ifdef _XREADER_DEBUG 700#ifdef _XREADER_DEBUG
701 os::Printer::log("CXFileReader: Reading Transformation Matrix", ELL_DEBUG); 701 os::Printer::log("CXFileReader: Reading Transformation Matrix", ELL_DEBUG);
702#endif 702#endif
703 703
704 if (!readHeadOfDataObject()) 704 if (!readHeadOfDataObject())
705 { 705 {
706 os::Printer::log("No opening brace in Transformation Matrix found in x file", ELL_WARNING); 706 os::Printer::log("No opening brace in Transformation Matrix found in x file", ELL_WARNING);
707 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 707 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
708 return false; 708 return false;
709 } 709 }
710 710
711 readMatrix(mat); 711 readMatrix(mat);
712 712
713 if (!checkForOneFollowingSemicolons()) 713 if (!checkForOneFollowingSemicolons())
714 { 714 {
715 os::Printer::log("No finishing semicolon in Transformation Matrix found in x file", ELL_WARNING); 715 os::Printer::log("No finishing semicolon in Transformation Matrix found in x file", ELL_WARNING);
716 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 716 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
717 } 717 }
718 718
719 if (!checkForClosingBrace()) 719 if (!checkForClosingBrace())
720 { 720 {
721 os::Printer::log("No closing brace in Transformation Matrix found in x file", ELL_WARNING); 721 os::Printer::log("No closing brace in Transformation Matrix found in x file", ELL_WARNING);
722 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 722 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
723 return false; 723 return false;
724 } 724 }
725 725
726 return true; 726 return true;
727} 727}
728 728
729 729
730bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) 730bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh)
731{ 731{
732 core::stringc name; 732 core::stringc name;
733 733
734 if (!readHeadOfDataObject(&name)) 734 if (!readHeadOfDataObject(&name))
735 { 735 {
736#ifdef _XREADER_DEBUG 736#ifdef _XREADER_DEBUG
737 os::Printer::log("CXFileReader: Reading mesh", ELL_DEBUG); 737 os::Printer::log("CXFileReader: Reading mesh", ELL_DEBUG);
738#endif 738#endif
739 os::Printer::log("No opening brace in Mesh found in x file", ELL_WARNING); 739 os::Printer::log("No opening brace in Mesh found in x file", ELL_WARNING);
740 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 740 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
741 return false; 741 return false;
742 } 742 }
743 743
744#ifdef _XREADER_DEBUG 744#ifdef _XREADER_DEBUG
745 os::Printer::log("CXFileReader: Reading mesh", name.c_str(), ELL_DEBUG); 745 os::Printer::log("CXFileReader: Reading mesh", name.c_str(), ELL_DEBUG);
746#endif 746#endif
747 747
748 // read vertex count 748 // read vertex count
749 const u32 nVertices = readInt(); 749 const u32 nVertices = readInt();
750 750
751 // read vertices 751 // read vertices
752 mesh.Vertices.set_used(nVertices); 752 mesh.Vertices.set_used(nVertices);
753 for (u32 n=0; n<nVertices; ++n) 753 for (u32 n=0; n<nVertices; ++n)
754 { 754 {
755 readVector3(mesh.Vertices[n].Pos); 755 readVector3(mesh.Vertices[n].Pos);
756 mesh.Vertices[n].Color=0xFFFFFFFF; 756 mesh.Vertices[n].Color=0xFFFFFFFF;
757 } 757 }
758 758
759 if (!checkForTwoFollowingSemicolons()) 759 if (!checkForTwoFollowingSemicolons())
760 { 760 {
761 os::Printer::log("No finishing semicolon in Mesh Vertex Array found in x file", ELL_WARNING); 761 os::Printer::log("No finishing semicolon in Mesh Vertex Array found in x file", ELL_WARNING);
762 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 762 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
763 } 763 }
764 764
765 // read faces 765 // read faces
766 const u32 nFaces = readInt(); 766 const u32 nFaces = readInt();
767 767
768 mesh.Indices.set_used(nFaces * 3); 768 mesh.Indices.set_used(nFaces * 3);
769 mesh.IndexCountPerFace.set_used(nFaces); 769 mesh.IndexCountPerFace.set_used(nFaces);
770 770
771 core::array<u32> polygonfaces; 771 core::array<u32> polygonfaces;
772 u32 currentIndex = 0; 772 u32 currentIndex = 0;
773 773
774 for (u32 k=0; k<nFaces; ++k) 774 for (u32 k=0; k<nFaces; ++k)
775 { 775 {
776 const u32 fcnt = readInt(); 776 const u32 fcnt = readInt();
777 777
778 if (fcnt != 3) 778 if (fcnt != 3)
779 { 779 {
780 if (fcnt < 3) 780 if (fcnt < 3)
781 { 781 {
782 os::Printer::log("Invalid face count (<3) found in Mesh x file reader.", ELL_WARNING); 782 os::Printer::log("Invalid face count (<3) found in Mesh x file reader.", ELL_WARNING);
783 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 783 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
784 return false; 784 return false;
785 } 785 }
786 786
787 // read face indices 787 // read face indices
788 polygonfaces.set_used(fcnt); 788 polygonfaces.set_used(fcnt);
789 u32 triangles = (fcnt-2); 789 u32 triangles = (fcnt-2);
790 mesh.Indices.set_used(mesh.Indices.size() + ((triangles-1)*3)); 790 mesh.Indices.set_used(mesh.Indices.size() + ((triangles-1)*3));
791 mesh.IndexCountPerFace[k] = (u16)(triangles * 3); 791 mesh.IndexCountPerFace[k] = (u16)(triangles * 3);
792 792
793 for (u32 f=0; f<fcnt; ++f) 793 for (u32 f=0; f<fcnt; ++f)
794 polygonfaces[f] = readInt(); 794 polygonfaces[f] = readInt();
795 795
796 for (u32 jk=0; jk<triangles; ++jk) 796 for (u32 jk=0; jk<triangles; ++jk)
797 { 797 {
798 mesh.Indices[currentIndex++] = polygonfaces[0]; 798 mesh.Indices[currentIndex++] = polygonfaces[0];
799 mesh.Indices[currentIndex++] = polygonfaces[jk+1]; 799 mesh.Indices[currentIndex++] = polygonfaces[jk+1];
800 mesh.Indices[currentIndex++] = polygonfaces[jk+2]; 800 mesh.Indices[currentIndex++] = polygonfaces[jk+2];
801 } 801 }
802 802
803 // TODO: change face indices in material list 803 // TODO: change face indices in material list
804 } 804 }
805 else 805 else
806 { 806 {
807 mesh.Indices[currentIndex++] = readInt(); 807 mesh.Indices[currentIndex++] = readInt();
808 mesh.Indices[currentIndex++] = readInt(); 808 mesh.Indices[currentIndex++] = readInt();
809 mesh.Indices[currentIndex++] = readInt(); 809 mesh.Indices[currentIndex++] = readInt();
810 mesh.IndexCountPerFace[k] = 3; 810 mesh.IndexCountPerFace[k] = 3;
811 } 811 }
812 } 812 }
813 813
814 if (!checkForTwoFollowingSemicolons()) 814 if (!checkForTwoFollowingSemicolons())
815 { 815 {
816 os::Printer::log("No finishing semicolon in Mesh Face Array found in x file", ELL_WARNING); 816 os::Printer::log("No finishing semicolon in Mesh Face Array found in x file", ELL_WARNING);
817 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 817 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
818 } 818 }
819 819
820 // here, other data objects may follow 820 // here, other data objects may follow
821 821
822 while(true) 822 while(true)
823 { 823 {
824 core::stringc objectName = getNextToken(); 824 core::stringc objectName = getNextToken();
825 825
826 if (objectName.size() == 0) 826 if (objectName.size() == 0)
827 { 827 {
828 os::Printer::log("Unexpected ending found in Mesh in x file.", ELL_WARNING); 828 os::Printer::log("Unexpected ending found in Mesh in x file.", ELL_WARNING);
829 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 829 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
830 return false; 830 return false;
831 } 831 }
832 else 832 else
833 if (objectName == "}") 833 if (objectName == "}")
834 { 834 {
835 break; // mesh finished 835 break; // mesh finished
836 } 836 }
837 837
838#ifdef _XREADER_DEBUG 838#ifdef _XREADER_DEBUG
839 os::Printer::log("debug DataObject in mesh:", objectName.c_str(), ELL_DEBUG); 839 os::Printer::log("debug DataObject in mesh:", objectName.c_str(), ELL_DEBUG);
840#endif 840#endif
841 841
842 if (objectName == "MeshNormals") 842 if (objectName == "MeshNormals")
843 { 843 {
844 if (!parseDataObjectMeshNormals(mesh)) 844 if (!parseDataObjectMeshNormals(mesh))
845 return false; 845 return false;
846 } 846 }
847 else 847 else
848 if (objectName == "MeshTextureCoords") 848 if (objectName == "MeshTextureCoords")
849 { 849 {
850 if (!parseDataObjectMeshTextureCoords(mesh)) 850 if (!parseDataObjectMeshTextureCoords(mesh))
851 return false; 851 return false;
852 } 852 }
853 else 853 else
854 if (objectName == "MeshVertexColors") 854 if (objectName == "MeshVertexColors")
855 { 855 {
856 if (!parseDataObjectMeshVertexColors(mesh)) 856 if (!parseDataObjectMeshVertexColors(mesh))
857 return false; 857 return false;
858 } 858 }
859 else 859 else
860 if (objectName == "MeshMaterialList") 860 if (objectName == "MeshMaterialList")
861 { 861 {
862 if (!parseDataObjectMeshMaterialList(mesh)) 862 if (!parseDataObjectMeshMaterialList(mesh))
863 return false; 863 return false;
864 } 864 }
865 else 865 else
866 if (objectName == "VertexDuplicationIndices") 866 if (objectName == "VertexDuplicationIndices")
867 { 867 {
868 // we'll ignore vertex duplication indices 868 // we'll ignore vertex duplication indices
869 // TODO: read them 869 // TODO: read them
870 if (!parseUnknownDataObject()) 870 if (!parseUnknownDataObject())
871 return false; 871 return false;
872 } 872 }
873 else 873 else
874 if (objectName == "DeclData") 874 if (objectName == "DeclData")
875 { 875 {
876 // arbitrary vertex attributes 876 // arbitrary vertex attributes
877 // first comes the number of element definitions 877 // first comes the number of element definitions
878 // then the vertex element type definitions 878 // then the vertex element type definitions
879 // with format type;tesselator;semantics;usageindex 879 // with format type;tesselator;semantics;usageindex
880 // we want to support 2;0;6;0 == tangent 880 // we want to support 2;0;6;0 == tangent
881 // 2;0;7;0 == binormal 881 // 2;0;7;0 == binormal
882 // 2;0;3;0 == normal 882 // 2;0;3;0 == normal
883 // 1/2;0;5;0 == 1st uv coord 883 // 1/2;0;5;0 == 1st uv coord
884 // and 1/2;0;5;1 == 2nd uv coord 884 // and 1/2;0;5;1 == 2nd uv coord
885 // type==2 is 3xf32, type==1 is 2xf32 885 // type==2 is 3xf32, type==1 is 2xf32
886 u32 j; 886 u32 j;
887 const u32 dcnt = readInt(); 887 const u32 dcnt = readInt();
888 u16 size = 0; 888 u16 size = 0;
889 s16 normalpos = -1; 889 s16 normalpos = -1;
890 s16 uvpos = -1; 890 s16 uvpos = -1;
891 s16 uv2pos = -1; 891 s16 uv2pos = -1;
892 s16 tangentpos = -1; 892 s16 tangentpos = -1;
893 s16 binormalpos = -1; 893 s16 binormalpos = -1;
894 s16 normaltype = -1; 894 s16 normaltype = -1;
895 s16 uvtype = -1; 895 s16 uvtype = -1;
896 s16 uv2type = -1; 896 s16 uv2type = -1;
897 s16 tangenttype = -1; 897 s16 tangenttype = -1;
898 s16 binormaltype = -1; 898 s16 binormaltype = -1;
899 for (j=0; j<dcnt; ++j) 899 for (j=0; j<dcnt; ++j)
900 { 900 {
901 const u32 type = readInt(); 901 const u32 type = readInt();
902 //const u32 tesselator = readInt(); 902 //const u32 tesselator = readInt();
903 readInt(); 903 readInt();
904 const u32 semantics = readInt(); 904 const u32 semantics = readInt();
905 const u32 index = readInt(); 905 const u32 index = readInt();
906 switch (semantics) 906 switch (semantics)
907 { 907 {
908 case 3: 908 case 3:
909 normalpos = size; 909 normalpos = size;
910 normaltype = type; 910 normaltype = type;
911 break; 911 break;
912 case 5: 912 case 5:
913 if (index==0) 913 if (index==0)
914 { 914 {
915 uvpos = size; 915 uvpos = size;
916 uvtype = type; 916 uvtype = type;
917 } 917 }
918 else if (index==1) 918 else if (index==1)
919 { 919 {
920 uv2pos = size; 920 uv2pos = size;
921 uv2type = type; 921 uv2type = type;
922 } 922 }
923 break; 923 break;
924 case 6: 924 case 6:
925 tangentpos = size; 925 tangentpos = size;
926 tangenttype = type; 926 tangenttype = type;
927 break; 927 break;
928 case 7: 928 case 7:
929 binormalpos = size; 929 binormalpos = size;
930 binormaltype = type; 930 binormaltype = type;
931 break; 931 break;
932 default: 932 default:
933 break; 933 break;
934 } 934 }
935 switch (type) 935 switch (type)
936 { 936 {
937 case 0: 937 case 0:
938 size += 4; 938 size += 4;
939 break; 939 break;
940 case 1: 940 case 1:
941 size += 8; 941 size += 8;
942 break; 942 break;
943 case 2: 943 case 2:
944 size += 12; 944 size += 12;
945 break; 945 break;
946 case 3: 946 case 3:
947 size += 16; 947 size += 16;
948 break; 948 break;
949 case 4: 949 case 4:
950 case 5: 950 case 5:
951 case 6: 951 case 6:
952 size += 4; 952 size += 4;
953 break; 953 break;
954 case 7: 954 case 7:
955 size += 8; 955 size += 8;
956 break; 956 break;
957 case 8: 957 case 8:
958 case 9: 958 case 9:
959 size += 4; 959 size += 4;
960 break; 960 break;
961 case 10: 961 case 10:
962 size += 8; 962 size += 8;
963 break; 963 break;
964 case 11: 964 case 11:
965 size += 4; 965 size += 4;
966 break; 966 break;
967 case 12: 967 case 12:
968 size += 8; 968 size += 8;
969 break; 969 break;
970 case 13: 970 case 13:
971 size += 4; 971 size += 4;
972 break; 972 break;
973 case 14: 973 case 14:
974 size += 4; 974 size += 4;
975 break; 975 break;
976 case 15: 976 case 15:
977 size += 4; 977 size += 4;
978 break; 978 break;
979 case 16: 979 case 16:
980 size += 8; 980 size += 8;
981 break; 981 break;
982 } 982 }
983 } 983 }
984 const u32 datasize = readInt(); 984 const u32 datasize = readInt();
985 u32* data = new u32[datasize]; 985 u32* data = new u32[datasize];
986 for (j=0; j<datasize; ++j) 986 for (j=0; j<datasize; ++j)
987 data[j]=readInt(); 987 data[j]=readInt();
988 988
989 if (!checkForOneFollowingSemicolons()) 989 if (!checkForOneFollowingSemicolons())
990 { 990 {
991 os::Printer::log("No finishing semicolon in DeclData found.", ELL_WARNING); 991 os::Printer::log("No finishing semicolon in DeclData found.", ELL_WARNING);
992 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 992 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
993 } 993 }
994 if (!checkForClosingBrace()) 994 if (!checkForClosingBrace())
995 { 995 {
996 os::Printer::log("No closing brace in DeclData.", ELL_WARNING); 996 os::Printer::log("No closing brace in DeclData.", ELL_WARNING);
997 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 997 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
998 delete [] data; 998 delete [] data;
999 return false; 999 return false;
1000 } 1000 }
1001 u8* dataptr = (u8*) data; 1001 u8* dataptr = (u8*) data;
1002 if ((uv2pos != -1) && (uv2type == 1)) 1002 if ((uv2pos != -1) && (uv2type == 1))
1003 mesh.TCoords2.reallocate(mesh.Vertices.size()); 1003 mesh.TCoords2.reallocate(mesh.Vertices.size());
1004 for (j=0; j<mesh.Vertices.size(); ++j) 1004 for (j=0; j<mesh.Vertices.size(); ++j)
1005 { 1005 {
1006 if ((normalpos != -1) && (normaltype == 2)) 1006 if ((normalpos != -1) && (normaltype == 2))
1007 mesh.Vertices[j].Normal.set(*((core::vector3df*)(dataptr+normalpos))); 1007 mesh.Vertices[j].Normal.set(*((core::vector3df*)(dataptr+normalpos)));
1008 if ((uvpos != -1) && (uvtype == 1)) 1008 if ((uvpos != -1) && (uvtype == 1))
1009 mesh.Vertices[j].TCoords.set(*((core::vector2df*)(dataptr+uvpos))); 1009 mesh.Vertices[j].TCoords.set(*((core::vector2df*)(dataptr+uvpos)));
1010 if ((uv2pos != -1) && (uv2type == 1)) 1010 if ((uv2pos != -1) && (uv2type == 1))
1011 mesh.TCoords2.push_back(*((core::vector2df*)(dataptr+uv2pos))); 1011 mesh.TCoords2.push_back(*((core::vector2df*)(dataptr+uv2pos)));
1012 dataptr += size; 1012 dataptr += size;
1013 } 1013 }
1014 delete [] data; 1014 delete [] data;
1015 } 1015 }
1016 else 1016 else
1017 if (objectName == "FVFData") 1017 if (objectName == "FVFData")
1018 { 1018 {
1019 if (!readHeadOfDataObject()) 1019 if (!readHeadOfDataObject())
1020 { 1020 {
1021 os::Printer::log("No starting brace in FVFData found.", ELL_WARNING); 1021 os::Printer::log("No starting brace in FVFData found.", ELL_WARNING);
1022 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1022 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1023 return false; 1023 return false;
1024 } 1024 }
1025 const u32 dataformat = readInt(); 1025 const u32 dataformat = readInt();
1026 const u32 datasize = readInt(); 1026 const u32 datasize = readInt();
1027 u32* data = new u32[datasize]; 1027 u32* data = new u32[datasize];
1028 for (u32 j=0; j<datasize; ++j) 1028 for (u32 j=0; j<datasize; ++j)
1029 data[j]=readInt(); 1029 data[j]=readInt();
1030 if (dataformat&0x102) // 2nd uv set 1030 if (dataformat&0x102) // 2nd uv set
1031 { 1031 {
1032 mesh.TCoords2.reallocate(mesh.Vertices.size()); 1032 mesh.TCoords2.reallocate(mesh.Vertices.size());
1033 u8* dataptr = (u8*) data; 1033 u8* dataptr = (u8*) data;
1034 const u32 size=((dataformat>>8)&0xf)*sizeof(core::vector2df); 1034 const u32 size=((dataformat>>8)&0xf)*sizeof(core::vector2df);
1035 for (u32 j=0; j<mesh.Vertices.size(); ++j) 1035 for (u32 j=0; j<mesh.Vertices.size(); ++j)
1036 { 1036 {
1037 mesh.TCoords2.push_back(*((core::vector2df*)(dataptr))); 1037 mesh.TCoords2.push_back(*((core::vector2df*)(dataptr)));
1038 dataptr += size; 1038 dataptr += size;
1039 } 1039 }
1040 } 1040 }
1041 delete [] data; 1041 delete [] data;
1042 if (!checkForOneFollowingSemicolons()) 1042 if (!checkForOneFollowingSemicolons())
1043 { 1043 {
1044 os::Printer::log("No finishing semicolon in FVFData found.", ELL_WARNING); 1044 os::Printer::log("No finishing semicolon in FVFData found.", ELL_WARNING);
1045 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1045 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1046 } 1046 }
1047 if (!checkForClosingBrace()) 1047 if (!checkForClosingBrace())
1048 { 1048 {
1049 os::Printer::log("No closing brace in FVFData found in x file", ELL_WARNING); 1049 os::Printer::log("No closing brace in FVFData found in x file", ELL_WARNING);
1050 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1050 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1051 return false; 1051 return false;
1052 } 1052 }
1053 } 1053 }
1054 else 1054 else
1055 if (objectName == "XSkinMeshHeader") 1055 if (objectName == "XSkinMeshHeader")
1056 { 1056 {
1057 if (!parseDataObjectSkinMeshHeader(mesh)) 1057 if (!parseDataObjectSkinMeshHeader(mesh))
1058 return false; 1058 return false;
1059 } 1059 }
1060 else 1060 else
1061 if (objectName == "SkinWeights") 1061 if (objectName == "SkinWeights")
1062 { 1062 {
1063 //mesh.SkinWeights.push_back(SXSkinWeight()); 1063 //mesh.SkinWeights.push_back(SXSkinWeight());
1064 //if (!parseDataObjectSkinWeights(mesh.SkinWeights.getLast())) 1064 //if (!parseDataObjectSkinWeights(mesh.SkinWeights.getLast()))
1065 if (!parseDataObjectSkinWeights(mesh)) 1065 if (!parseDataObjectSkinWeights(mesh))
1066 return false; 1066 return false;
1067 } 1067 }
1068 else 1068 else
1069 { 1069 {
1070 os::Printer::log("Unknown data object in mesh in x file", objectName.c_str(), ELL_WARNING); 1070 os::Printer::log("Unknown data object in mesh in x file", objectName.c_str(), ELL_WARNING);
1071 if (!parseUnknownDataObject()) 1071 if (!parseUnknownDataObject())
1072 return false; 1072 return false;
1073 } 1073 }
1074 } 1074 }
1075 1075
1076 return true; 1076 return true;
1077} 1077}
1078 1078
1079 1079
1080bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) 1080bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
1081{ 1081{
1082#ifdef _XREADER_DEBUG 1082#ifdef _XREADER_DEBUG
1083 os::Printer::log("CXFileReader: Reading mesh skin weights", ELL_DEBUG); 1083 os::Printer::log("CXFileReader: Reading mesh skin weights", ELL_DEBUG);
1084#endif 1084#endif
1085 1085
1086 if (!readHeadOfDataObject()) 1086 if (!readHeadOfDataObject())
1087 { 1087 {
1088 os::Printer::log("No opening brace in Skin Weights found in .x file", ELL_WARNING); 1088 os::Printer::log("No opening brace in Skin Weights found in .x file", ELL_WARNING);
1089 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1089 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1090 return false; 1090 return false;
1091 } 1091 }
1092 1092
1093 core::stringc TransformNodeName; 1093 core::stringc TransformNodeName;
1094 1094
1095 if (!getNextTokenAsString(TransformNodeName)) 1095 if (!getNextTokenAsString(TransformNodeName))
1096 { 1096 {
1097 os::Printer::log("Unknown syntax while reading transfrom node name string in .x file", ELL_WARNING); 1097 os::Printer::log("Unknown syntax while reading transfrom node name string in .x file", ELL_WARNING);
1098 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1098 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1099 return false; 1099 return false;
1100 } 1100 }
1101 1101
1102 mesh.HasSkinning=true; 1102 mesh.HasSkinning=true;
1103 1103
1104 CSkinnedMesh::SJoint *joint=0; 1104 CSkinnedMesh::SJoint *joint=0;
1105 1105
1106 u32 n; 1106 u32 n;
1107 for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n) 1107 for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
1108 { 1108 {
1109 if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName) 1109 if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName)
1110 { 1110 {
1111 joint=AnimatedMesh->getAllJoints()[n]; 1111 joint=AnimatedMesh->getAllJoints()[n];
1112 break; 1112 break;
1113 } 1113 }
1114 } 1114 }
1115 1115
1116 if (!joint) 1116 if (!joint)
1117 { 1117 {
1118#ifdef _XREADER_DEBUG 1118#ifdef _XREADER_DEBUG
1119 os::Printer::log("creating joint for skinning ", TransformNodeName.c_str(), ELL_DEBUG); 1119 os::Printer::log("creating joint for skinning ", TransformNodeName.c_str(), ELL_DEBUG);
1120#endif 1120#endif
1121 n = AnimatedMesh->getAllJoints().size(); 1121 n = AnimatedMesh->getAllJoints().size();
1122 joint=AnimatedMesh->addJoint(0); 1122 joint=AnimatedMesh->addJoint(0);
1123 joint->Name=TransformNodeName; 1123 joint->Name=TransformNodeName;
1124 } 1124 }
1125 1125
1126 // read vertex weights 1126 // read vertex weights
1127 const u32 nWeights = readInt(); 1127 const u32 nWeights = readInt();
1128 1128
1129 // read vertex indices 1129 // read vertex indices
1130 u32 i; 1130 u32 i;
1131 1131
1132 const u32 jointStart = joint->Weights.size(); 1132 const u32 jointStart = joint->Weights.size();
1133 joint->Weights.reallocate(jointStart+nWeights); 1133 joint->Weights.reallocate(jointStart+nWeights);
1134 1134
1135 mesh.WeightJoint.reallocate( mesh.WeightJoint.size() + nWeights ); 1135 mesh.WeightJoint.reallocate( mesh.WeightJoint.size() + nWeights );
1136 mesh.WeightNum.reallocate( mesh.WeightNum.size() + nWeights ); 1136 mesh.WeightNum.reallocate( mesh.WeightNum.size() + nWeights );
1137 1137
1138 for (i=0; i<nWeights; ++i) 1138 for (i=0; i<nWeights; ++i)
1139 { 1139 {
1140 mesh.WeightJoint.push_back(n); 1140 mesh.WeightJoint.push_back(n);
1141 mesh.WeightNum.push_back(joint->Weights.size()); 1141 mesh.WeightNum.push_back(joint->Weights.size());
1142 1142
1143 CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(joint); 1143 CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(joint);
1144 1144
1145 weight->buffer_id=0; 1145 weight->buffer_id=0;
1146 weight->vertex_id=readInt(); 1146 weight->vertex_id=readInt();
1147 } 1147 }
1148 1148
1149 // read vertex weights 1149 // read vertex weights
1150 1150
1151 for (i=jointStart; i<jointStart+nWeights; ++i) 1151 for (i=jointStart; i<jointStart+nWeights; ++i)
1152 joint->Weights[i].strength = readFloat(); 1152 joint->Weights[i].strength = readFloat();
1153 1153
1154 // read matrix offset 1154 // read matrix offset
1155 1155
1156 // transforms the mesh vertices to the space of the bone 1156 // transforms the mesh vertices to the space of the bone
1157 // When concatenated to the bone's transform, this provides the 1157 // When concatenated to the bone's transform, this provides the
1158 // world space coordinates of the mesh as affected by the bone 1158 // world space coordinates of the mesh as affected by the bone
1159 core::matrix4& MatrixOffset = joint->GlobalInversedMatrix; 1159 core::matrix4& MatrixOffset = joint->GlobalInversedMatrix;
1160 1160
1161 readMatrix(MatrixOffset); 1161 readMatrix(MatrixOffset);
1162 1162
1163 if (!checkForOneFollowingSemicolons()) 1163 if (!checkForOneFollowingSemicolons())
1164 { 1164 {
1165 os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING); 1165 os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING);
1166 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1166 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1167 } 1167 }
1168 1168
1169 if (!checkForClosingBrace()) 1169 if (!checkForClosingBrace())
1170 { 1170 {
1171 os::Printer::log("No closing brace in Skin Weights found in x file", ELL_WARNING); 1171 os::Printer::log("No closing brace in Skin Weights found in x file", ELL_WARNING);
1172 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1172 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1173 return false; 1173 return false;
1174 } 1174 }
1175 1175
1176 return true; 1176 return true;
1177} 1177}
1178 1178
1179 1179
1180bool CXMeshFileLoader::parseDataObjectSkinMeshHeader(SXMesh& mesh) 1180bool CXMeshFileLoader::parseDataObjectSkinMeshHeader(SXMesh& mesh)
1181{ 1181{
1182#ifdef _XREADER_DEBUG 1182#ifdef _XREADER_DEBUG
1183 os::Printer::log("CXFileReader: Reading skin mesh header", ELL_DEBUG); 1183 os::Printer::log("CXFileReader: Reading skin mesh header", ELL_DEBUG);
1184#endif 1184#endif
1185 1185
1186 if (!readHeadOfDataObject()) 1186 if (!readHeadOfDataObject())
1187 { 1187 {
1188 os::Printer::log("No opening brace in Skin Mesh header found in .x file", ELL_WARNING); 1188 os::Printer::log("No opening brace in Skin Mesh header found in .x file", ELL_WARNING);
1189 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1189 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1190 return false; 1190 return false;
1191 } 1191 }
1192 1192
1193 mesh.MaxSkinWeightsPerVertex = readInt(); 1193 mesh.MaxSkinWeightsPerVertex = readInt();
1194 mesh.MaxSkinWeightsPerFace = readInt(); 1194 mesh.MaxSkinWeightsPerFace = readInt();
1195 mesh.BoneCount = readInt(); 1195 mesh.BoneCount = readInt();
1196 1196
1197 if (!BinaryFormat) 1197 if (!BinaryFormat)
1198 getNextToken(); // skip semicolon 1198 getNextToken(); // skip semicolon
1199 1199
1200 if (!checkForClosingBrace()) 1200 if (!checkForClosingBrace())
1201 { 1201 {
1202 os::Printer::log("No closing brace in skin mesh header in x file", ELL_WARNING); 1202 os::Printer::log("No closing brace in skin mesh header in x file", ELL_WARNING);
1203 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1203 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1204 return false; 1204 return false;
1205 } 1205 }
1206 1206
1207 return true; 1207 return true;
1208} 1208}
1209 1209
1210 1210
1211bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) 1211bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh)
1212{ 1212{
1213#ifdef _XREADER_DEBUG 1213#ifdef _XREADER_DEBUG
1214 os::Printer::log("CXFileReader: reading mesh normals", ELL_DEBUG); 1214 os::Printer::log("CXFileReader: reading mesh normals", ELL_DEBUG);
1215#endif 1215#endif
1216 1216
1217 if (!readHeadOfDataObject()) 1217 if (!readHeadOfDataObject())
1218 { 1218 {
1219 os::Printer::log("No opening brace in Mesh Normals found in x file", ELL_WARNING); 1219 os::Printer::log("No opening brace in Mesh Normals found in x file", ELL_WARNING);
1220 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1220 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1221 return false; 1221 return false;
1222 } 1222 }
1223 1223
1224 // read count 1224 // read count
1225 const u32 nNormals = readInt(); 1225 const u32 nNormals = readInt();
1226 core::array<core::vector3df> normals; 1226 core::array<core::vector3df> normals;
1227 normals.set_used(nNormals); 1227 normals.set_used(nNormals);
1228 1228
1229 // read normals 1229 // read normals
1230 for (u32 i=0; i<nNormals; ++i) 1230 for (u32 i=0; i<nNormals; ++i)
1231 readVector3(normals[i]); 1231 readVector3(normals[i]);
1232 1232
1233 if (!checkForTwoFollowingSemicolons()) 1233 if (!checkForTwoFollowingSemicolons())
1234 { 1234 {
1235 os::Printer::log("No finishing semicolon in Mesh Normals Array found in x file", ELL_WARNING); 1235 os::Printer::log("No finishing semicolon in Mesh Normals Array found in x file", ELL_WARNING);
1236 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1236 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1237 } 1237 }
1238 1238
1239 core::array<u32> normalIndices; 1239 core::array<u32> normalIndices;
1240 normalIndices.set_used(mesh.Indices.size()); 1240 normalIndices.set_used(mesh.Indices.size());
1241 1241
1242 // read face normal indices 1242 // read face normal indices
1243 const u32 nFNormals = readInt(); 1243 const u32 nFNormals = readInt();
1244 1244
1245 u32 normalidx = 0; 1245 u32 normalidx = 0;
1246 core::array<u32> polygonfaces; 1246 core::array<u32> polygonfaces;
1247 for (u32 k=0; k<nFNormals; ++k) 1247 for (u32 k=0; k<nFNormals; ++k)
1248 { 1248 {
1249 const u32 fcnt = readInt(); 1249 const u32 fcnt = readInt();
1250 u32 triangles = fcnt - 2; 1250 u32 triangles = fcnt - 2;
1251 u32 indexcount = triangles * 3; 1251 u32 indexcount = triangles * 3;
1252 1252
1253 if (indexcount != mesh.IndexCountPerFace[k]) 1253 if (indexcount != mesh.IndexCountPerFace[k])
1254 { 1254 {
1255 os::Printer::log("Not matching normal and face index count found in x file", ELL_WARNING); 1255 os::Printer::log("Not matching normal and face index count found in x file", ELL_WARNING);
1256 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1256 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1257 return false; 1257 return false;
1258 } 1258 }
1259 1259
1260 if (indexcount == 3) 1260 if (indexcount == 3)
1261 { 1261 {
1262 // default, only one triangle in this face 1262 // default, only one triangle in this face
1263 for (u32 h=0; h<3; ++h) 1263 for (u32 h=0; h<3; ++h)
1264 { 1264 {
1265 const u32 normalnum = readInt(); 1265 const u32 normalnum = readInt();
1266 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[normalnum]); 1266 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[normalnum]);
1267 } 1267 }
1268 } 1268 }
1269 else 1269 else
1270 { 1270 {
1271 polygonfaces.set_used(fcnt); 1271 polygonfaces.set_used(fcnt);
1272 // multiple triangles in this face 1272 // multiple triangles in this face
1273 for (u32 h=0; h<fcnt; ++h) 1273 for (u32 h=0; h<fcnt; ++h)
1274 polygonfaces[h] = readInt(); 1274 polygonfaces[h] = readInt();
1275 1275
1276 for (u32 jk=0; jk<triangles; ++jk) 1276 for (u32 jk=0; jk<triangles; ++jk)
1277 { 1277 {
1278 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[polygonfaces[0]]); 1278 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[polygonfaces[0]]);
1279 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[polygonfaces[jk+1]]); 1279 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[polygonfaces[jk+1]]);
1280 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[polygonfaces[jk+2]]); 1280 mesh.Vertices[mesh.Indices[normalidx++]].Normal.set(normals[polygonfaces[jk+2]]);
1281 } 1281 }
1282 } 1282 }
1283 } 1283 }
1284 1284
1285 if (!checkForTwoFollowingSemicolons()) 1285 if (!checkForTwoFollowingSemicolons())
1286 { 1286 {
1287 os::Printer::log("No finishing semicolon in Mesh Face Normals Array found in x file", ELL_WARNING); 1287 os::Printer::log("No finishing semicolon in Mesh Face Normals Array found in x file", ELL_WARNING);
1288 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1288 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1289 } 1289 }
1290 1290
1291 if (!checkForClosingBrace()) 1291 if (!checkForClosingBrace())
1292 { 1292 {
1293 os::Printer::log("No closing brace in Mesh Normals found in x file", ELL_WARNING); 1293 os::Printer::log("No closing brace in Mesh Normals found in x file", ELL_WARNING);
1294 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1294 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1295 return false; 1295 return false;
1296 } 1296 }
1297 1297
1298 return true; 1298 return true;
1299} 1299}
1300 1300
1301 1301
1302bool CXMeshFileLoader::parseDataObjectMeshTextureCoords(SXMesh &mesh) 1302bool CXMeshFileLoader::parseDataObjectMeshTextureCoords(SXMesh &mesh)
1303{ 1303{
1304#ifdef _XREADER_DEBUG 1304#ifdef _XREADER_DEBUG
1305 os::Printer::log("CXFileReader: reading mesh texture coordinates", ELL_DEBUG); 1305 os::Printer::log("CXFileReader: reading mesh texture coordinates", ELL_DEBUG);
1306#endif 1306#endif
1307 1307
1308 if (!readHeadOfDataObject()) 1308 if (!readHeadOfDataObject())
1309 { 1309 {
1310 os::Printer::log("No opening brace in Mesh Texture Coordinates found in x file", ELL_WARNING); 1310 os::Printer::log("No opening brace in Mesh Texture Coordinates found in x file", ELL_WARNING);
1311 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1311 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1312 return false; 1312 return false;
1313 } 1313 }
1314 1314
1315 const u32 nCoords = readInt(); 1315 const u32 nCoords = readInt();
1316 for (u32 i=0; i<nCoords; ++i) 1316 for (u32 i=0; i<nCoords; ++i)
1317 readVector2(mesh.Vertices[i].TCoords); 1317 readVector2(mesh.Vertices[i].TCoords);
1318 1318
1319 if (!checkForTwoFollowingSemicolons()) 1319 if (!checkForTwoFollowingSemicolons())
1320 { 1320 {
1321 os::Printer::log("No finishing semicolon in Mesh Texture Coordinates Array found in x file", ELL_WARNING); 1321 os::Printer::log("No finishing semicolon in Mesh Texture Coordinates Array found in x file", ELL_WARNING);
1322 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1322 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1323 } 1323 }
1324 1324
1325 if (!checkForClosingBrace()) 1325 if (!checkForClosingBrace())
1326 { 1326 {
1327 os::Printer::log("No closing brace in Mesh Texture Coordinates Array found in x file", ELL_WARNING); 1327 os::Printer::log("No closing brace in Mesh Texture Coordinates Array found in x file", ELL_WARNING);
1328 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1328 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1329 return false; 1329 return false;
1330 } 1330 }
1331 1331
1332 return true; 1332 return true;
1333} 1333}
1334 1334
1335 1335
1336bool CXMeshFileLoader::parseDataObjectMeshVertexColors(SXMesh &mesh) 1336bool CXMeshFileLoader::parseDataObjectMeshVertexColors(SXMesh &mesh)
1337{ 1337{
1338#ifdef _XREADER_DEBUG 1338#ifdef _XREADER_DEBUG
1339 os::Printer::log("CXFileReader: reading mesh vertex colors", ELL_DEBUG); 1339 os::Printer::log("CXFileReader: reading mesh vertex colors", ELL_DEBUG);
1340#endif 1340#endif
1341 1341
1342 if (!readHeadOfDataObject()) 1342 if (!readHeadOfDataObject())
1343 { 1343 {
1344 os::Printer::log("No opening brace for Mesh Vertex Colors found in x file", ELL_WARNING); 1344 os::Printer::log("No opening brace for Mesh Vertex Colors found in x file", ELL_WARNING);
1345 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1345 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1346 return false; 1346 return false;
1347 } 1347 }
1348 1348
1349 mesh.HasVertexColors=true; 1349 mesh.HasVertexColors=true;
1350 const u32 nColors = readInt(); 1350 const u32 nColors = readInt();
1351 for (u32 i=0; i<nColors; ++i) 1351 for (u32 i=0; i<nColors; ++i)
1352 { 1352 {
1353 const u32 Index=readInt(); 1353 const u32 Index=readInt();
1354 if (Index>=mesh.Vertices.size()) 1354 if (Index>=mesh.Vertices.size())
1355 { 1355 {
1356 os::Printer::log("index value in parseDataObjectMeshVertexColors out of bounds", ELL_WARNING); 1356 os::Printer::log("index value in parseDataObjectMeshVertexColors out of bounds", ELL_WARNING);
1357 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1357 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1358 return false; 1358 return false;
1359 } 1359 }
1360 readRGBA(mesh.Vertices[Index].Color); 1360 readRGBA(mesh.Vertices[Index].Color);
1361 checkForOneFollowingSemicolons(); 1361 checkForOneFollowingSemicolons();
1362 } 1362 }
1363 1363
1364 if (!checkForOneFollowingSemicolons()) 1364 if (!checkForOneFollowingSemicolons())
1365 { 1365 {
1366 os::Printer::log("No finishing semicolon in Mesh Vertex Colors Array found in x file", ELL_WARNING); 1366 os::Printer::log("No finishing semicolon in Mesh Vertex Colors Array found in x file", ELL_WARNING);
1367 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1367 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1368 } 1368 }
1369 1369
1370 if (!checkForClosingBrace()) 1370 if (!checkForClosingBrace())
1371 { 1371 {
1372 os::Printer::log("No closing brace in Mesh Texture Coordinates Array found in x file", ELL_WARNING); 1372 os::Printer::log("No closing brace in Mesh Texture Coordinates Array found in x file", ELL_WARNING);
1373 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1373 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1374 return false; 1374 return false;
1375 } 1375 }
1376 1376
1377 return true; 1377 return true;
1378} 1378}
1379 1379
1380 1380
1381bool CXMeshFileLoader::parseDataObjectMeshMaterialList(SXMesh &mesh) 1381bool CXMeshFileLoader::parseDataObjectMeshMaterialList(SXMesh &mesh)
1382{ 1382{
1383#ifdef _XREADER_DEBUG 1383#ifdef _XREADER_DEBUG
1384 os::Printer::log("CXFileReader: Reading mesh material list", ELL_DEBUG); 1384 os::Printer::log("CXFileReader: Reading mesh material list", ELL_DEBUG);
1385#endif 1385#endif
1386 1386
1387 if (!readHeadOfDataObject()) 1387 if (!readHeadOfDataObject())
1388 { 1388 {
1389 os::Printer::log("No opening brace in Mesh Material List found in x file", ELL_WARNING); 1389 os::Printer::log("No opening brace in Mesh Material List found in x file", ELL_WARNING);
1390 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1390 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1391 return false; 1391 return false;
1392 } 1392 }
1393 1393
1394 // read material count 1394 // read material count
1395 mesh.Materials.reallocate(readInt()); 1395 mesh.Materials.reallocate(readInt());
1396 1396
1397 // read non triangulated face material index count 1397 // read non triangulated face material index count
1398 const u32 nFaceIndices = readInt(); 1398 const u32 nFaceIndices = readInt();
1399 1399
1400 // There seems to be a compact representation of "all faces the same material" 1400 // There seems to be a compact representation of "all faces the same material"
1401 // being represented as 1;1;0;; which means 1 material, 1 face with first material 1401 // being represented as 1;1;0;; which means 1 material, 1 face with first material
1402 // all the other faces have to obey then, so check is disabled 1402 // all the other faces have to obey then, so check is disabled
1403 //if (nFaceIndices != mesh.IndexCountPerFace.size()) 1403 //if (nFaceIndices != mesh.IndexCountPerFace.size())
1404 // os::Printer::log("Index count per face not equal to face material index count in x file.", ELL_WARNING); 1404 // os::Printer::log("Index count per face not equal to face material index count in x file.", ELL_WARNING);
1405 1405
1406 // read non triangulated face indices and create triangulated ones 1406 // read non triangulated face indices and create triangulated ones
1407 mesh.FaceMaterialIndices.set_used( mesh.Indices.size() / 3); 1407 mesh.FaceMaterialIndices.set_used( mesh.Indices.size() / 3);
1408 u32 triangulatedindex = 0; 1408 u32 triangulatedindex = 0;
1409 u32 ind = 0; 1409 u32 ind = 0;
1410 for (u32 tfi=0; tfi<mesh.IndexCountPerFace.size(); ++tfi) 1410 for (u32 tfi=0; tfi<mesh.IndexCountPerFace.size(); ++tfi)
1411 { 1411 {
1412 if (tfi<nFaceIndices) 1412 if (tfi<nFaceIndices)
1413 ind = readInt(); 1413 ind = readInt();
1414 const u32 fc = mesh.IndexCountPerFace[tfi]/3; 1414 const u32 fc = mesh.IndexCountPerFace[tfi]/3;
1415 for (u32 k=0; k<fc; ++k) 1415 for (u32 k=0; k<fc; ++k)
1416 mesh.FaceMaterialIndices[triangulatedindex++] = ind; 1416 mesh.FaceMaterialIndices[triangulatedindex++] = ind;
1417 } 1417 }
1418 1418
1419 // in version 03.02, the face indices end with two semicolons. 1419 // in version 03.02, the face indices end with two semicolons.
1420 // commented out version check, as version 03.03 exported from blender also has 2 semicolons 1420 // commented out version check, as version 03.03 exported from blender also has 2 semicolons
1421 if (!BinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2) 1421 if (!BinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
1422 { 1422 {
1423 if (P[0] == ';') 1423 if (P[0] == ';')
1424 ++P; 1424 ++P;
1425 } 1425 }
1426 1426
1427 // read following data objects 1427 // read following data objects
1428 1428
1429 while(true) 1429 while(true)
1430 { 1430 {
1431 core::stringc objectName = getNextToken(); 1431 core::stringc objectName = getNextToken();
1432 1432
1433 if (objectName.size() == 0) 1433 if (objectName.size() == 0)
1434 { 1434 {
1435 os::Printer::log("Unexpected ending found in Mesh Material list in .x file.", ELL_WARNING); 1435 os::Printer::log("Unexpected ending found in Mesh Material list in .x file.", ELL_WARNING);
1436 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1436 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1437 return false; 1437 return false;
1438 } 1438 }
1439 else 1439 else
1440 if (objectName == "}") 1440 if (objectName == "}")
1441 { 1441 {
1442 break; // material list finished 1442 break; // material list finished
1443 } 1443 }
1444 else 1444 else
1445 if (objectName == "{") 1445 if (objectName == "{")
1446 { 1446 {
1447 // template materials now available thanks to joeWright 1447 // template materials now available thanks to joeWright
1448 objectName = getNextToken(); 1448 objectName = getNextToken();
1449 for (u32 i=0; i<TemplateMaterials.size(); ++i) 1449 for (u32 i=0; i<TemplateMaterials.size(); ++i)
1450 if (TemplateMaterials[i].Name == objectName) 1450 if (TemplateMaterials[i].Name == objectName)
1451 mesh.Materials.push_back(TemplateMaterials[i].Material); 1451 mesh.Materials.push_back(TemplateMaterials[i].Material);
1452 getNextToken(); // skip } 1452 getNextToken(); // skip }
1453 } 1453 }
1454 else 1454 else
1455 if (objectName == "Material") 1455 if (objectName == "Material")
1456 { 1456 {
1457 mesh.Materials.push_back(video::SMaterial()); 1457 mesh.Materials.push_back(video::SMaterial());
1458 if (!parseDataObjectMaterial(mesh.Materials.getLast())) 1458 if (!parseDataObjectMaterial(mesh.Materials.getLast()))
1459 return false; 1459 return false;
1460 } 1460 }
1461 else 1461 else
1462 if (objectName == ";") 1462 if (objectName == ";")
1463 { 1463 {
1464 // ignore 1464 // ignore
1465 } 1465 }
1466 else 1466 else
1467 { 1467 {
1468 os::Printer::log("Unknown data object in material list in x file", objectName.c_str(), ELL_WARNING); 1468 os::Printer::log("Unknown data object in material list in x file", objectName.c_str(), ELL_WARNING);
1469 if (!parseUnknownDataObject()) 1469 if (!parseUnknownDataObject())
1470 return false; 1470 return false;
1471 } 1471 }
1472 } 1472 }
1473 return true; 1473 return true;
1474} 1474}
1475 1475
1476 1476
1477bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material) 1477bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material)
1478{ 1478{
1479#ifdef _XREADER_DEBUG 1479#ifdef _XREADER_DEBUG
1480 os::Printer::log("CXFileReader: Reading mesh material", ELL_DEBUG); 1480 os::Printer::log("CXFileReader: Reading mesh material", ELL_DEBUG);
1481#endif 1481#endif
1482 1482
1483 if (!readHeadOfDataObject()) 1483 if (!readHeadOfDataObject())
1484 { 1484 {
1485 os::Printer::log("No opening brace in Mesh Material found in .x file", ELL_WARNING); 1485 os::Printer::log("No opening brace in Mesh Material found in .x file", ELL_WARNING);
1486 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1486 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1487 return false; 1487 return false;
1488 } 1488 }
1489 1489
1490 // read RGBA 1490 // read RGBA
1491 readRGBA(material.DiffuseColor); checkForOneFollowingSemicolons(); 1491 readRGBA(material.DiffuseColor); checkForOneFollowingSemicolons();
1492 1492
1493 // read power 1493 // read power
1494 material.Shininess = readFloat(); 1494 material.Shininess = readFloat();
1495 1495
1496 // read specular 1496 // read specular
1497 readRGB(material.SpecularColor); checkForOneFollowingSemicolons(); 1497 readRGB(material.SpecularColor); checkForOneFollowingSemicolons();
1498 1498
1499 // read emissive 1499 // read emissive
1500 readRGB(material.EmissiveColor); checkForOneFollowingSemicolons(); 1500 readRGB(material.EmissiveColor); checkForOneFollowingSemicolons();
1501 1501
1502 // read other data objects 1502 // read other data objects
1503 int textureLayer=0; 1503 int textureLayer=0;
1504 while(true) 1504 while(true)
1505 { 1505 {
1506 core::stringc objectName = getNextToken(); 1506 core::stringc objectName = getNextToken();
1507 1507
1508 if (objectName.size() == 0) 1508 if (objectName.size() == 0)
1509 { 1509 {
1510 os::Printer::log("Unexpected ending found in Mesh Material in .x file.", ELL_WARNING); 1510 os::Printer::log("Unexpected ending found in Mesh Material in .x file.", ELL_WARNING);
1511 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1511 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1512 return false; 1512 return false;
1513 } 1513 }
1514 else 1514 else
1515 if (objectName == "}") 1515 if (objectName == "}")
1516 { 1516 {
1517 break; // material finished 1517 break; // material finished
1518 } 1518 }
1519 else 1519 else
1520 if (objectName.equals_ignore_case("TextureFilename")) 1520 if (objectName.equals_ignore_case("TextureFilename"))
1521 { 1521 {
1522 // some exporters write "TextureFileName" instead. 1522 // some exporters write "TextureFileName" instead.
1523 core::stringc TextureFileName; 1523 core::stringc TextureFileName;
1524 if (!parseDataObjectTextureFilename(TextureFileName)) 1524 if (!parseDataObjectTextureFilename(TextureFileName))
1525 return false; 1525 return false;
1526 1526
1527 // original name 1527 // original name
1528 if (FileSystem->existFile(TextureFileName)) 1528 if (FileSystem->existFile(TextureFileName))
1529 material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName)); 1529 material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName));
1530 // mesh path 1530 // mesh path
1531 else 1531 else
1532 { 1532 {
1533 TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName); 1533 TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName);
1534 if (FileSystem->existFile(TextureFileName)) 1534 if (FileSystem->existFile(TextureFileName))
1535 material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName)); 1535 material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName));
1536 // working directory 1536 // working directory
1537 else 1537 else
1538 material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName))); 1538 material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName)));
1539 } 1539 }
1540 ++textureLayer; 1540 ++textureLayer;
1541 if (textureLayer==2) 1541 if (textureLayer==2)
1542 material.MaterialType=video::EMT_LIGHTMAP; 1542 material.MaterialType=video::EMT_LIGHTMAP;
1543 } 1543 }
1544 else 1544 else
1545 if (objectName.equals_ignore_case("NormalmapFilename")) 1545 if (objectName.equals_ignore_case("NormalmapFilename"))
1546 { 1546 {
1547 // some exporters write "NormalmapFileName" instead. 1547 // some exporters write "NormalmapFileName" instead.
1548 core::stringc TextureFileName; 1548 core::stringc TextureFileName;
1549 if (!parseDataObjectTextureFilename(TextureFileName)) 1549 if (!parseDataObjectTextureFilename(TextureFileName))
1550 return false; 1550 return false;
1551 1551
1552 // original name 1552 // original name
1553 if (FileSystem->existFile(TextureFileName)) 1553 if (FileSystem->existFile(TextureFileName))
1554 material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName)); 1554 material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName));
1555 // mesh path 1555 // mesh path
1556 else 1556 else
1557 { 1557 {
1558 TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName); 1558 TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName);
1559 if (FileSystem->existFile(TextureFileName)) 1559 if (FileSystem->existFile(TextureFileName))
1560 material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName)); 1560 material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName));
1561 // working directory 1561 // working directory
1562 else 1562 else
1563 material.setTexture(1, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName))); 1563 material.setTexture(1, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName)));
1564 } 1564 }
1565 if (textureLayer==1) 1565 if (textureLayer==1)
1566 ++textureLayer; 1566 ++textureLayer;
1567 } 1567 }
1568 else 1568 else
1569 { 1569 {
1570 os::Printer::log("Unknown data object in material in .x file", objectName.c_str(), ELL_WARNING); 1570 os::Printer::log("Unknown data object in material in .x file", objectName.c_str(), ELL_WARNING);
1571 if (!parseUnknownDataObject()) 1571 if (!parseUnknownDataObject())
1572 return false; 1572 return false;
1573 } 1573 }
1574 } 1574 }
1575 1575
1576 return true; 1576 return true;
1577} 1577}
1578 1578
1579 1579
1580bool CXMeshFileLoader::parseDataObjectAnimationSet() 1580bool CXMeshFileLoader::parseDataObjectAnimationSet()
1581{ 1581{
1582#ifdef _XREADER_DEBUG 1582#ifdef _XREADER_DEBUG
1583 os::Printer::log("CXFileReader: Reading animation set", ELL_DEBUG); 1583 os::Printer::log("CXFileReader: Reading animation set", ELL_DEBUG);
1584#endif 1584#endif
1585 1585
1586 core::stringc AnimationName; 1586 core::stringc AnimationName;
1587 1587
1588 if (!readHeadOfDataObject(&AnimationName)) 1588 if (!readHeadOfDataObject(&AnimationName))
1589 { 1589 {
1590 os::Printer::log("No opening brace in Animation Set found in x file", ELL_WARNING); 1590 os::Printer::log("No opening brace in Animation Set found in x file", ELL_WARNING);
1591 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1591 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1592 return false; 1592 return false;
1593 } 1593 }
1594 os::Printer::log("Reading animationset ", AnimationName, ELL_DEBUG); 1594 os::Printer::log("Reading animationset ", AnimationName, ELL_DEBUG);
1595 1595
1596 while(true) 1596 while(true)
1597 { 1597 {
1598 core::stringc objectName = getNextToken(); 1598 core::stringc objectName = getNextToken();
1599 1599
1600 if (objectName.size() == 0) 1600 if (objectName.size() == 0)
1601 { 1601 {
1602 os::Printer::log("Unexpected ending found in Animation set in x file.", ELL_WARNING); 1602 os::Printer::log("Unexpected ending found in Animation set in x file.", ELL_WARNING);
1603 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1603 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1604 return false; 1604 return false;
1605 } 1605 }
1606 else 1606 else
1607 if (objectName == "}") 1607 if (objectName == "}")
1608 { 1608 {
1609 break; // animation set finished 1609 break; // animation set finished
1610 } 1610 }
1611 else 1611 else
1612 if (objectName == "Animation") 1612 if (objectName == "Animation")
1613 { 1613 {
1614 if (!parseDataObjectAnimation()) 1614 if (!parseDataObjectAnimation())
1615 return false; 1615 return false;
1616 } 1616 }
1617 else 1617 else
1618 { 1618 {
1619 os::Printer::log("Unknown data object in animation set in x file", objectName.c_str(), ELL_WARNING); 1619 os::Printer::log("Unknown data object in animation set in x file", objectName.c_str(), ELL_WARNING);
1620 if (!parseUnknownDataObject()) 1620 if (!parseUnknownDataObject())
1621 return false; 1621 return false;
1622 } 1622 }
1623 } 1623 }
1624 return true; 1624 return true;
1625} 1625}
1626 1626
1627 1627
1628bool CXMeshFileLoader::parseDataObjectAnimation() 1628bool CXMeshFileLoader::parseDataObjectAnimation()
1629{ 1629{
1630#ifdef _XREADER_DEBUG 1630#ifdef _XREADER_DEBUG
1631 os::Printer::log("CXFileReader: reading animation", ELL_DEBUG); 1631 os::Printer::log("CXFileReader: reading animation", ELL_DEBUG);
1632#endif 1632#endif
1633 1633
1634 if (!readHeadOfDataObject()) 1634 if (!readHeadOfDataObject())
1635 { 1635 {
1636 os::Printer::log("No opening brace in Animation found in x file", ELL_WARNING); 1636 os::Printer::log("No opening brace in Animation found in x file", ELL_WARNING);
1637 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1637 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1638 return false; 1638 return false;
1639 } 1639 }
1640 1640
1641 //anim.closed = true; 1641 //anim.closed = true;
1642 //anim.linearPositionQuality = true; 1642 //anim.linearPositionQuality = true;
1643 CSkinnedMesh::SJoint animationDump; 1643 CSkinnedMesh::SJoint animationDump;
1644 1644
1645 core::stringc FrameName; 1645 core::stringc FrameName;
1646 1646
1647 while(true) 1647 while(true)
1648 { 1648 {
1649 core::stringc objectName = getNextToken(); 1649 core::stringc objectName = getNextToken();
1650 1650
1651 if (objectName.size() == 0) 1651 if (objectName.size() == 0)
1652 { 1652 {
1653 os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); 1653 os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING);
1654 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1654 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1655 return false; 1655 return false;
1656 } 1656 }
1657 else 1657 else
1658 if (objectName == "}") 1658 if (objectName == "}")
1659 { 1659 {
1660 break; // animation finished 1660 break; // animation finished
1661 } 1661 }
1662 else 1662 else
1663 if (objectName == "AnimationKey") 1663 if (objectName == "AnimationKey")
1664 { 1664 {
1665 if (!parseDataObjectAnimationKey(&animationDump)) 1665 if (!parseDataObjectAnimationKey(&animationDump))
1666 return false; 1666 return false;
1667 } 1667 }
1668 else 1668 else
1669 if (objectName == "AnimationOptions") 1669 if (objectName == "AnimationOptions")
1670 { 1670 {
1671 //TODO: parse options. 1671 //TODO: parse options.
1672 if (!parseUnknownDataObject()) 1672 if (!parseUnknownDataObject())
1673 return false; 1673 return false;
1674 } 1674 }
1675 else 1675 else
1676 if (objectName == "{") 1676 if (objectName == "{")
1677 { 1677 {
1678 // read frame name 1678 // read frame name
1679 FrameName = getNextToken(); 1679 FrameName = getNextToken();
1680 1680
1681 if (!checkForClosingBrace()) 1681 if (!checkForClosingBrace())
1682 { 1682 {
1683 os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); 1683 os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING);
1684 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1684 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1685 return false; 1685 return false;
1686 } 1686 }
1687 } 1687 }
1688 else 1688 else
1689 { 1689 {
1690 os::Printer::log("Unknown data object in animation in x file", objectName.c_str(), ELL_WARNING); 1690 os::Printer::log("Unknown data object in animation in x file", objectName.c_str(), ELL_WARNING);
1691 if (!parseUnknownDataObject()) 1691 if (!parseUnknownDataObject())
1692 return false; 1692 return false;
1693 } 1693 }
1694 } 1694 }
1695 1695
1696 if (FrameName.size() != 0) 1696 if (FrameName.size() != 0)
1697 { 1697 {
1698#ifdef _XREADER_DEBUG 1698#ifdef _XREADER_DEBUG
1699 os::Printer::log("frame name", FrameName.c_str(), ELL_DEBUG); 1699 os::Printer::log("frame name", FrameName.c_str(), ELL_DEBUG);
1700#endif 1700#endif
1701 CSkinnedMesh::SJoint *joint=0; 1701 CSkinnedMesh::SJoint *joint=0;
1702 1702
1703 u32 n; 1703 u32 n;
1704 for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n) 1704 for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
1705 { 1705 {
1706 if (AnimatedMesh->getAllJoints()[n]->Name==FrameName) 1706 if (AnimatedMesh->getAllJoints()[n]->Name==FrameName)
1707 { 1707 {
1708 joint=AnimatedMesh->getAllJoints()[n]; 1708 joint=AnimatedMesh->getAllJoints()[n];
1709 break; 1709 break;
1710 } 1710 }
1711 } 1711 }
1712 1712
1713 if (!joint) 1713 if (!joint)
1714 { 1714 {
1715#ifdef _XREADER_DEBUG 1715#ifdef _XREADER_DEBUG
1716 os::Printer::log("creating joint for animation ", FrameName.c_str(), ELL_DEBUG); 1716 os::Printer::log("creating joint for animation ", FrameName.c_str(), ELL_DEBUG);
1717#endif 1717#endif
1718 joint=AnimatedMesh->addJoint(0); 1718 joint=AnimatedMesh->addJoint(0);
1719 joint->Name=FrameName; 1719 joint->Name=FrameName;
1720 } 1720 }
1721 1721
1722 joint->PositionKeys.reallocate(joint->PositionKeys.size()+animationDump.PositionKeys.size()); 1722 joint->PositionKeys.reallocate(joint->PositionKeys.size()+animationDump.PositionKeys.size());
1723 for (n=0; n<animationDump.PositionKeys.size(); ++n) 1723 for (n=0; n<animationDump.PositionKeys.size(); ++n)
1724 { 1724 {
1725 joint->PositionKeys.push_back(animationDump.PositionKeys[n]); 1725 joint->PositionKeys.push_back(animationDump.PositionKeys[n]);
1726 } 1726 }
1727 1727
1728 joint->ScaleKeys.reallocate(joint->ScaleKeys.size()+animationDump.ScaleKeys.size()); 1728 joint->ScaleKeys.reallocate(joint->ScaleKeys.size()+animationDump.ScaleKeys.size());
1729 for (n=0; n<animationDump.ScaleKeys.size(); ++n) 1729 for (n=0; n<animationDump.ScaleKeys.size(); ++n)
1730 { 1730 {
1731 joint->ScaleKeys.push_back(animationDump.ScaleKeys[n]); 1731 joint->ScaleKeys.push_back(animationDump.ScaleKeys[n]);
1732 } 1732 }
1733 1733
1734 joint->RotationKeys.reallocate(joint->RotationKeys.size()+animationDump.RotationKeys.size()); 1734 joint->RotationKeys.reallocate(joint->RotationKeys.size()+animationDump.RotationKeys.size());
1735 for (n=0; n<animationDump.RotationKeys.size(); ++n) 1735 for (n=0; n<animationDump.RotationKeys.size(); ++n)
1736 { 1736 {
1737 joint->RotationKeys.push_back(animationDump.RotationKeys[n]); 1737 joint->RotationKeys.push_back(animationDump.RotationKeys[n]);
1738 } 1738 }
1739 } 1739 }
1740 else 1740 else
1741 os::Printer::log("joint name was never given", ELL_WARNING); 1741 os::Printer::log("joint name was never given", ELL_WARNING);
1742 1742
1743 return true; 1743 return true;
1744} 1744}
1745 1745
1746 1746
1747bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) 1747bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint)
1748{ 1748{
1749#ifdef _XREADER_DEBUG 1749#ifdef _XREADER_DEBUG
1750 os::Printer::log("CXFileReader: reading animation key", ELL_DEBUG); 1750 os::Printer::log("CXFileReader: reading animation key", ELL_DEBUG);
1751#endif 1751#endif
1752 1752
1753 if (!readHeadOfDataObject()) 1753 if (!readHeadOfDataObject())
1754 { 1754 {
1755 os::Printer::log("No opening brace in Animation Key found in x file", ELL_WARNING); 1755 os::Printer::log("No opening brace in Animation Key found in x file", ELL_WARNING);
1756 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1756 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1757 return false; 1757 return false;
1758 } 1758 }
1759 1759
1760 // read key type 1760 // read key type
1761 1761
1762 const u32 keyType = readInt(); 1762 const u32 keyType = readInt();
1763 1763
1764 if (keyType > 4) 1764 if (keyType > 4)
1765 { 1765 {
1766 os::Printer::log("Unknown key type found in Animation Key in x file", ELL_WARNING); 1766 os::Printer::log("Unknown key type found in Animation Key in x file", ELL_WARNING);
1767 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1767 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1768 return false; 1768 return false;
1769 } 1769 }
1770 1770
1771 // read number of keys 1771 // read number of keys
1772 const u32 numberOfKeys = readInt(); 1772 const u32 numberOfKeys = readInt();
1773 1773
1774 // eat the semicolon after the "0". if there are keys present, readInt() 1774 // eat the semicolon after the "0". if there are keys present, readInt()
1775 // does this for us. If there aren't, we need to do it explicitly 1775 // does this for us. If there aren't, we need to do it explicitly
1776 if (numberOfKeys == 0) 1776 if (numberOfKeys == 0)
1777 checkForOneFollowingSemicolons(); 1777 checkForOneFollowingSemicolons();
1778 1778
1779 for (u32 i=0; i<numberOfKeys; ++i) 1779 for (u32 i=0; i<numberOfKeys; ++i)
1780 { 1780 {
1781 // read time 1781 // read time
1782 const f32 time = (f32)readInt(); 1782 const f32 time = (f32)readInt();
1783 1783
1784 // read keys 1784 // read keys
1785 switch(keyType) 1785 switch(keyType)
1786 { 1786 {
1787 case 0: //rotation 1787 case 0: //rotation
1788 { 1788 {
1789 //read quaternions 1789 //read quaternions
1790 1790
1791 // read count 1791 // read count
1792 if (readInt() != 4) 1792 if (readInt() != 4)
1793 { 1793 {
1794 os::Printer::log("Expected 4 numbers in animation key in x file", ELL_WARNING); 1794 os::Printer::log("Expected 4 numbers in animation key in x file", ELL_WARNING);
1795 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1795 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1796 return false; 1796 return false;
1797 } 1797 }
1798 1798
1799 f32 W = -readFloat(); 1799 f32 W = -readFloat();
1800 f32 X = -readFloat(); 1800 f32 X = -readFloat();
1801 f32 Y = -readFloat(); 1801 f32 Y = -readFloat();
1802 f32 Z = -readFloat(); 1802 f32 Z = -readFloat();
1803 1803
1804 if (!checkForTwoFollowingSemicolons()) 1804 if (!checkForTwoFollowingSemicolons())
1805 { 1805 {
1806 os::Printer::log("No finishing semicolon after quaternion animation key in x file", ELL_WARNING); 1806 os::Printer::log("No finishing semicolon after quaternion animation key in x file", ELL_WARNING);
1807 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1807 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1808 } 1808 }
1809 1809
1810 ISkinnedMesh::SRotationKey *key=AnimatedMesh->addRotationKey(joint); 1810 ISkinnedMesh::SRotationKey *key=AnimatedMesh->addRotationKey(joint);
1811 key->frame=time; 1811 key->frame=time;
1812 key->rotation.set(X,Y,Z,W); 1812 key->rotation.set(X,Y,Z,W);
1813 } 1813 }
1814 break; 1814 break;
1815 case 1: //scale 1815 case 1: //scale
1816 case 2: //position 1816 case 2: //position
1817 { 1817 {
1818 // read vectors 1818 // read vectors
1819 1819
1820 // read count 1820 // read count
1821 if (readInt() != 3) 1821 if (readInt() != 3)
1822 { 1822 {
1823 os::Printer::log("Expected 3 numbers in animation key in x file", ELL_WARNING); 1823 os::Printer::log("Expected 3 numbers in animation key in x file", ELL_WARNING);
1824 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1824 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1825 return false; 1825 return false;
1826 } 1826 }
1827 1827
1828 core::vector3df vector; 1828 core::vector3df vector;
1829 readVector3(vector); 1829 readVector3(vector);
1830 1830
1831 if (!checkForTwoFollowingSemicolons()) 1831 if (!checkForTwoFollowingSemicolons())
1832 { 1832 {
1833 os::Printer::log("No finishing semicolon after vector animation key in x file", ELL_WARNING); 1833 os::Printer::log("No finishing semicolon after vector animation key in x file", ELL_WARNING);
1834 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1834 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1835 } 1835 }
1836 1836
1837 if (keyType==2) 1837 if (keyType==2)
1838 { 1838 {
1839 ISkinnedMesh::SPositionKey *key=AnimatedMesh->addPositionKey(joint); 1839 ISkinnedMesh::SPositionKey *key=AnimatedMesh->addPositionKey(joint);
1840 key->frame=time; 1840 key->frame=time;
1841 key->position=vector; 1841 key->position=vector;
1842 } 1842 }
1843 else 1843 else
1844 { 1844 {
1845 ISkinnedMesh::SScaleKey *key=AnimatedMesh->addScaleKey(joint); 1845 ISkinnedMesh::SScaleKey *key=AnimatedMesh->addScaleKey(joint);
1846 key->frame=time; 1846 key->frame=time;
1847 key->scale=vector; 1847 key->scale=vector;
1848 } 1848 }
1849 } 1849 }
1850 break; 1850 break;
1851 case 3: 1851 case 3:
1852 case 4: 1852 case 4:
1853 { 1853 {
1854 // read matrix 1854 // read matrix
1855 1855
1856 // read count 1856 // read count
1857 if (readInt() != 16) 1857 if (readInt() != 16)
1858 { 1858 {
1859 os::Printer::log("Expected 16 numbers in animation key in x file", ELL_WARNING); 1859 os::Printer::log("Expected 16 numbers in animation key in x file", ELL_WARNING);
1860 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1860 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1861 return false; 1861 return false;
1862 } 1862 }
1863 1863
1864 // read matrix 1864 // read matrix
1865 core::matrix4 mat(core::matrix4::EM4CONST_NOTHING); 1865 core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
1866 readMatrix(mat); 1866 readMatrix(mat);
1867 1867
1868 //mat=joint->LocalMatrix*mat; 1868 //mat=joint->LocalMatrix*mat;
1869 1869
1870 if (!checkForOneFollowingSemicolons()) 1870 if (!checkForOneFollowingSemicolons())
1871 { 1871 {
1872 os::Printer::log("No finishing semicolon after matrix animation key in x file", ELL_WARNING); 1872 os::Printer::log("No finishing semicolon after matrix animation key in x file", ELL_WARNING);
1873 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1873 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1874 } 1874 }
1875 1875
1876 //core::vector3df rotation = mat.getRotationDegrees(); 1876 //core::vector3df rotation = mat.getRotationDegrees();
1877 1877
1878 ISkinnedMesh::SRotationKey *keyR=AnimatedMesh->addRotationKey(joint); 1878 ISkinnedMesh::SRotationKey *keyR=AnimatedMesh->addRotationKey(joint);
1879 keyR->frame=time; 1879 keyR->frame=time;
1880 1880
1881 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from mat to mat.getTransposed() for downward compatibility. 1881 // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from mat to mat.getTransposed() for downward compatibility.
1882 // Not tested so far if this was correct or wrong before quaternion fix! 1882 // Not tested so far if this was correct or wrong before quaternion fix!
1883 keyR->rotation= core::quaternion(mat.getTransposed()); 1883 keyR->rotation= core::quaternion(mat.getTransposed());
1884 1884
1885 ISkinnedMesh::SPositionKey *keyP=AnimatedMesh->addPositionKey(joint); 1885 ISkinnedMesh::SPositionKey *keyP=AnimatedMesh->addPositionKey(joint);
1886 keyP->frame=time; 1886 keyP->frame=time;
1887 keyP->position=mat.getTranslation(); 1887 keyP->position=mat.getTranslation();
1888 1888
1889/* 1889/*
1890 core::vector3df scale=mat.getScale(); 1890 core::vector3df scale=mat.getScale();
1891 1891
1892 if (scale.X==0) 1892 if (scale.X==0)
1893 scale.X=1; 1893 scale.X=1;
1894 if (scale.Y==0) 1894 if (scale.Y==0)
1895 scale.Y=1; 1895 scale.Y=1;
1896 if (scale.Z==0) 1896 if (scale.Z==0)
1897 scale.Z=1; 1897 scale.Z=1;
1898 ISkinnedMesh::SScaleKey *keyS=AnimatedMesh->addScaleKey(joint); 1898 ISkinnedMesh::SScaleKey *keyS=AnimatedMesh->addScaleKey(joint);
1899 keyS->frame=time; 1899 keyS->frame=time;
1900 keyS->scale=scale; 1900 keyS->scale=scale;
1901*/ 1901*/
1902 } 1902 }
1903 break; 1903 break;
1904 } // end switch 1904 } // end switch
1905 } 1905 }
1906 1906
1907 if (!checkForOneFollowingSemicolons()) 1907 if (!checkForOneFollowingSemicolons())
1908 --P; 1908 --P;
1909 1909
1910 if (!checkForClosingBrace()) 1910 if (!checkForClosingBrace())
1911 { 1911 {
1912 os::Printer::log("No closing brace in animation key in x file", ELL_WARNING); 1912 os::Printer::log("No closing brace in animation key in x file", ELL_WARNING);
1913 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1913 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1914 return false; 1914 return false;
1915 } 1915 }
1916 1916
1917 return true; 1917 return true;
1918} 1918}
1919 1919
1920 1920
1921bool CXMeshFileLoader::parseDataObjectTextureFilename(core::stringc& texturename) 1921bool CXMeshFileLoader::parseDataObjectTextureFilename(core::stringc& texturename)
1922{ 1922{
1923#ifdef _XREADER_DEBUG 1923#ifdef _XREADER_DEBUG
1924 os::Printer::log("CXFileReader: reading texture filename", ELL_DEBUG); 1924 os::Printer::log("CXFileReader: reading texture filename", ELL_DEBUG);
1925#endif 1925#endif
1926 1926
1927 if (!readHeadOfDataObject()) 1927 if (!readHeadOfDataObject())
1928 { 1928 {
1929 os::Printer::log("No opening brace in Texture filename found in x file", ELL_WARNING); 1929 os::Printer::log("No opening brace in Texture filename found in x file", ELL_WARNING);
1930 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1930 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1931 return false; 1931 return false;
1932 } 1932 }
1933 1933
1934 if (!getNextTokenAsString(texturename)) 1934 if (!getNextTokenAsString(texturename))
1935 { 1935 {
1936 os::Printer::log("Unknown syntax while reading texture filename string in x file", ELL_WARNING); 1936 os::Printer::log("Unknown syntax while reading texture filename string in x file", ELL_WARNING);
1937 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1937 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1938 return false; 1938 return false;
1939 } 1939 }
1940 1940
1941 if (!checkForClosingBrace()) 1941 if (!checkForClosingBrace())
1942 { 1942 {
1943 os::Printer::log("No closing brace in Texture filename found in x file", ELL_WARNING); 1943 os::Printer::log("No closing brace in Texture filename found in x file", ELL_WARNING);
1944 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); 1944 os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
1945 return false; 1945 return false;
1946 } 1946 }
1947 1947
1948 return true; 1948 return true;
1949} 1949}
1950 1950
1951 1951
1952bool CXMeshFileLoader::parseUnknownDataObject() 1952bool CXMeshFileLoader::parseUnknownDataObject()
1953{ 1953{
1954 // find opening delimiter 1954 // find opening delimiter
1955 while(true) 1955 while(true)
1956 { 1956 {
1957 core::stringc t = getNextToken(); 1957 core::stringc t = getNextToken();
1958 1958
1959 if (t.size() == 0) 1959 if (t.size() == 0)
1960 return false; 1960 return false;
1961 1961
1962 if (t == "{") 1962 if (t == "{")
1963 break; 1963 break;
1964 } 1964 }
1965 1965
1966 u32 counter = 1; 1966 u32 counter = 1;
1967 1967
1968 // parse until closing delimiter 1968 // parse until closing delimiter
1969 1969
1970 while(counter) 1970 while(counter)
1971 { 1971 {
1972 core::stringc t = getNextToken(); 1972 core::stringc t = getNextToken();
1973 1973
1974 if (t.size() == 0) 1974 if (t.size() == 0)
1975 return false; 1975 return false;
1976 1976
1977 if (t == "{") 1977 if (t == "{")
1978 ++counter; 1978 ++counter;
1979 else 1979 else
1980 if (t == "}") 1980 if (t == "}")
1981 --counter; 1981 --counter;
1982 } 1982 }
1983 1983
1984 return true; 1984 return true;
1985} 1985}
1986 1986
1987 1987
1988//! checks for closing curly brace, returns false if not there 1988//! checks for closing curly brace, returns false if not there
1989bool CXMeshFileLoader::checkForClosingBrace() 1989bool CXMeshFileLoader::checkForClosingBrace()
1990{ 1990{
1991 return (getNextToken() == "}"); 1991 return (getNextToken() == "}");
1992} 1992}
1993 1993
1994 1994
1995//! checks for one following semicolon, returns false if not there 1995//! checks for one following semicolon, returns false if not there
1996bool CXMeshFileLoader::checkForOneFollowingSemicolons() 1996bool CXMeshFileLoader::checkForOneFollowingSemicolons()
1997{ 1997{
1998 if (BinaryFormat) 1998 if (BinaryFormat)
1999 return true; 1999 return true;
2000 2000
2001 if (getNextToken() == ";") 2001 if (getNextToken() == ";")
2002 return true; 2002 return true;
2003 else 2003 else
2004 { 2004 {
2005 --P; 2005 --P;
2006 return false; 2006 return false;
2007 } 2007 }
2008} 2008}
2009 2009
2010 2010
2011//! checks for two following semicolons, returns false if they are not there 2011//! checks for two following semicolons, returns false if they are not there
2012bool CXMeshFileLoader::checkForTwoFollowingSemicolons() 2012bool CXMeshFileLoader::checkForTwoFollowingSemicolons()
2013{ 2013{
2014 if (BinaryFormat) 2014 if (BinaryFormat)
2015 return true; 2015 return true;
2016 2016
2017 for (u32 k=0; k<2; ++k) 2017 for (u32 k=0; k<2; ++k)
2018 { 2018 {
2019 if (getNextToken() != ";") 2019 if (getNextToken() != ";")
2020 { 2020 {
2021 --P; 2021 --P;
2022 return false; 2022 return false;
2023 } 2023 }
2024 } 2024 }
2025 2025
2026 return true; 2026 return true;
2027} 2027}
2028 2028
2029 2029
2030//! reads header of dataobject including the opening brace. 2030//! reads header of dataobject including the opening brace.
2031//! returns false if error happened, and writes name of object 2031//! returns false if error happened, and writes name of object
2032//! if there is one 2032//! if there is one
2033bool CXMeshFileLoader::readHeadOfDataObject(core::stringc* outname) 2033bool CXMeshFileLoader::readHeadOfDataObject(core::stringc* outname)
2034{ 2034{
2035 core::stringc nameOrBrace = getNextToken(); 2035 core::stringc nameOrBrace = getNextToken();
2036 if (nameOrBrace != "{") 2036 if (nameOrBrace != "{")
2037 { 2037 {
2038 if (outname) 2038 if (outname)
2039 (*outname) = nameOrBrace; 2039 (*outname) = nameOrBrace;
2040 2040
2041 if (getNextToken() != "{") 2041 if (getNextToken() != "{")
2042 return false; 2042 return false;
2043 } 2043 }
2044 2044
2045 return true; 2045 return true;
2046} 2046}
2047 2047
2048 2048
2049//! returns next parseable token. Returns empty string if no token there 2049//! returns next parseable token. Returns empty string if no token there
2050core::stringc CXMeshFileLoader::getNextToken() 2050core::stringc CXMeshFileLoader::getNextToken()
2051{ 2051{
2052 core::stringc s; 2052 core::stringc s;
2053 2053
2054 // process binary-formatted file 2054 // process binary-formatted file
2055 if (BinaryFormat) 2055 if (BinaryFormat)
2056 { 2056 {
2057 // in binary mode it will only return NAME and STRING token 2057 // in binary mode it will only return NAME and STRING token
2058 // and (correctly) skip over other tokens. 2058 // and (correctly) skip over other tokens.
2059 2059
2060 s16 tok = readBinWord(); 2060 s16 tok = readBinWord();
2061 u32 len; 2061 u32 len;
2062 2062
2063 // standalone tokens 2063 // standalone tokens
2064 switch (tok) { 2064 switch (tok) {
2065 case 1: 2065 case 1:
2066 // name token 2066 // name token
2067 len = readBinDWord(); 2067 len = readBinDWord();
2068 s = core::stringc(P, len); 2068 s = core::stringc(P, len);
2069 P += len; 2069 P += len;
2070 return s; 2070 return s;
2071 case 2: 2071 case 2:
2072 // string token 2072 // string token
2073 len = readBinDWord(); 2073 len = readBinDWord();
2074 s = core::stringc(P, len); 2074 s = core::stringc(P, len);
2075 P += (len + 2); 2075 P += (len + 2);
2076 return s; 2076 return s;
2077 case 3: 2077 case 3:
2078 // integer token 2078 // integer token
2079 P += 4; 2079 P += 4;
2080 return "<integer>"; 2080 return "<integer>";
2081 case 5: 2081 case 5:
2082 // GUID token 2082 // GUID token
2083 P += 16; 2083 P += 16;
2084 return "<guid>"; 2084 return "<guid>";
2085 case 6: 2085 case 6:
2086 len = readBinDWord(); 2086 len = readBinDWord();
2087 P += (len * 4); 2087 P += (len * 4);
2088 return "<int_list>"; 2088 return "<int_list>";
2089 case 7: 2089 case 7:
2090 len = readBinDWord(); 2090 len = readBinDWord();
2091 P += (len * FloatSize); 2091 P += (len * FloatSize);
2092 return "<flt_list>"; 2092 return "<flt_list>";
2093 case 0x0a: 2093 case 0x0a:
2094 return "{"; 2094 return "{";
2095 case 0x0b: 2095 case 0x0b:
2096 return "}"; 2096 return "}";
2097 case 0x0c: 2097 case 0x0c:
2098 return "("; 2098 return "(";
2099 case 0x0d: 2099 case 0x0d:
2100 return ")"; 2100 return ")";
2101 case 0x0e: 2101 case 0x0e:
2102 return "["; 2102 return "[";
2103 case 0x0f: 2103 case 0x0f:
2104 return "]"; 2104 return "]";
2105 case 0x10: 2105 case 0x10:
2106 return "<"; 2106 return "<";
2107 case 0x11: 2107 case 0x11:
2108 return ">"; 2108 return ">";
2109 case 0x12: 2109 case 0x12:
2110 return "."; 2110 return ".";
2111 case 0x13: 2111 case 0x13:
2112 return ","; 2112 return ",";
2113 case 0x14: 2113 case 0x14:
2114 return ";"; 2114 return ";";
2115 case 0x1f: 2115 case 0x1f:
2116 return "template"; 2116 return "template";
2117 case 0x28: 2117 case 0x28:
2118 return "WORD"; 2118 return "WORD";
2119 case 0x29: 2119 case 0x29:
2120 return "DWORD"; 2120 return "DWORD";
2121 case 0x2a: 2121 case 0x2a:
2122 return "FLOAT"; 2122 return "FLOAT";
2123 case 0x2b: 2123 case 0x2b:
2124 return "DOUBLE"; 2124 return "DOUBLE";
2125 case 0x2c: 2125 case 0x2c:
2126 return "CHAR"; 2126 return "CHAR";
2127 case 0x2d: 2127 case 0x2d:
2128 return "UCHAR"; 2128 return "UCHAR";
2129 case 0x2e: 2129 case 0x2e:
2130 return "SWORD"; 2130 return "SWORD";
2131 case 0x2f: 2131 case 0x2f:
2132 return "SDWORD"; 2132 return "SDWORD";
2133 case 0x30: 2133 case 0x30:
2134 return "void"; 2134 return "void";
2135 case 0x31: 2135 case 0x31:
2136 return "string"; 2136 return "string";
2137 case 0x32: 2137 case 0x32:
2138 return "unicode"; 2138 return "unicode";
2139 case 0x33: 2139 case 0x33:
2140 return "cstring"; 2140 return "cstring";
2141 case 0x34: 2141 case 0x34:
2142 return "array"; 2142 return "array";
2143 } 2143 }
2144 } 2144 }
2145 // process text-formatted file 2145 // process text-formatted file
2146 else 2146 else
2147 { 2147 {
2148 findNextNoneWhiteSpace(); 2148 findNextNoneWhiteSpace();
2149 2149
2150 if (P >= End) 2150 if (P >= End)
2151 return s; 2151 return s;
2152 2152
2153 while((P < End) && !core::isspace(P[0])) 2153 while((P < End) && !core::isspace(P[0]))
2154 { 2154 {
2155 // either keep token delimiters when already holding a token, or return if first valid char 2155 // either keep token delimiters when already holding a token, or return if first valid char
2156 if (P[0]==';' || P[0]=='}' || P[0]=='{' || P[0]==',') 2156 if (P[0]==';' || P[0]=='}' || P[0]=='{' || P[0]==',')
2157 { 2157 {
2158 if (!s.size()) 2158 if (!s.size())
2159 { 2159 {
2160 s.append(P[0]); 2160 s.append(P[0]);
2161 ++P; 2161 ++P;
2162 } 2162 }
2163 break; // stop for delimiter 2163 break; // stop for delimiter
2164 } 2164 }
2165 s.append(P[0]); 2165 s.append(P[0]);
2166 ++P; 2166 ++P;
2167 } 2167 }
2168 } 2168 }
2169 return s; 2169 return s;
2170} 2170}
2171 2171
2172 2172
2173//! places pointer to next begin of a token, which must be a number, 2173//! places pointer to next begin of a token, which must be a number,
2174// and ignores comments 2174// and ignores comments
2175void CXMeshFileLoader::findNextNoneWhiteSpaceNumber() 2175void CXMeshFileLoader::findNextNoneWhiteSpaceNumber()
2176{ 2176{
2177 if (BinaryFormat) 2177 if (BinaryFormat)
2178 return; 2178 return;
2179 2179
2180 while((P < End) && (P[0] != '-') && (P[0] != '.') && 2180 while((P < End) && (P[0] != '-') && (P[0] != '.') &&
2181 !( core::isdigit(P[0]))) 2181 !( core::isdigit(P[0])))
2182 { 2182 {
2183 // check if this is a comment 2183 // check if this is a comment
2184 if ((P[0] == '/' && P[1] == '/') || P[0] == '#') 2184 if ((P[0] == '/' && P[1] == '/') || P[0] == '#')
2185 readUntilEndOfLine(); 2185 readUntilEndOfLine();
2186 else 2186 else
2187 ++P; 2187 ++P;
2188 } 2188 }
2189} 2189}
2190 2190
2191 2191
2192// places pointer to next begin of a token, and ignores comments 2192// places pointer to next begin of a token, and ignores comments
2193void CXMeshFileLoader::findNextNoneWhiteSpace() 2193void CXMeshFileLoader::findNextNoneWhiteSpace()
2194{ 2194{
2195 if (BinaryFormat) 2195 if (BinaryFormat)
2196 return; 2196 return;
2197 2197
2198 while(true) 2198 while(true)
2199 { 2199 {
2200 while((P < End) && core::isspace(P[0])) 2200 while((P < End) && core::isspace(P[0]))
2201 { 2201 {
2202 if (*P=='\n') 2202 if (*P=='\n')
2203 ++Line; 2203 ++Line;
2204 ++P; 2204 ++P;
2205 } 2205 }
2206 2206
2207 if (P >= End) 2207 if (P >= End)
2208 return; 2208 return;
2209 2209
2210 // check if this is a comment 2210 // check if this is a comment
2211 if ((P[0] == '/' && P[1] == '/') || 2211 if ((P[0] == '/' && P[1] == '/') ||
2212 P[0] == '#') 2212 P[0] == '#')
2213 readUntilEndOfLine(); 2213 readUntilEndOfLine();
2214 else 2214 else
2215 break; 2215 break;
2216 } 2216 }
2217} 2217}
2218 2218
2219 2219
2220//! reads a x file style string 2220//! reads a x file style string
2221bool CXMeshFileLoader::getNextTokenAsString(core::stringc& out) 2221bool CXMeshFileLoader::getNextTokenAsString(core::stringc& out)
2222{ 2222{
2223 if (BinaryFormat) 2223 if (BinaryFormat)
2224 { 2224 {
2225 out=getNextToken(); 2225 out=getNextToken();
2226 return true; 2226 return true;
2227 } 2227 }
2228 findNextNoneWhiteSpace(); 2228 findNextNoneWhiteSpace();
2229 2229
2230 if (P >= End) 2230 if (P >= End)
2231 return false; 2231 return false;
2232 2232
2233 if (P[0] != '"') 2233 if (P[0] != '"')
2234 return false; 2234 return false;
2235 ++P; 2235 ++P;
2236 2236
2237 while(P < End && P[0]!='"') 2237 while(P < End && P[0]!='"')
2238 { 2238 {
2239 out.append(P[0]); 2239 out.append(P[0]);
2240 ++P; 2240 ++P;
2241 } 2241 }
2242 2242
2243 if ( P[1] != ';' || P[0] != '"') 2243 if ( P[1] != ';' || P[0] != '"')
2244 return false; 2244 return false;
2245 P+=2; 2245 P+=2;
2246 2246
2247 return true; 2247 return true;
2248} 2248}
2249 2249
2250 2250
2251void CXMeshFileLoader::readUntilEndOfLine() 2251void CXMeshFileLoader::readUntilEndOfLine()
2252{ 2252{
2253 if (BinaryFormat) 2253 if (BinaryFormat)
2254 return; 2254 return;
2255 2255
2256 while(P < End) 2256 while(P < End)
2257 { 2257 {
2258 if (P[0] == '\n' || P[0] == '\r') 2258 if (P[0] == '\n' || P[0] == '\r')
2259 { 2259 {
2260 ++P; 2260 ++P;
2261 ++Line; 2261 ++Line;
2262 return; 2262 return;
2263 } 2263 }
2264 2264
2265 ++P; 2265 ++P;
2266 } 2266 }
2267} 2267}
2268 2268
2269 2269
2270u16 CXMeshFileLoader::readBinWord() 2270u16 CXMeshFileLoader::readBinWord()
2271{ 2271{
2272#ifdef __BIG_ENDIAN__ 2272#ifdef __BIG_ENDIAN__
2273 const u16 tmp = os::Byteswap::byteswap(*(u16 *)P); 2273 const u16 tmp = os::Byteswap::byteswap(*(u16 *)P);
2274#else 2274#else
2275 const u16 tmp = *(u16 *)P; 2275 const u16 tmp = *(u16 *)P;
2276#endif 2276#endif
2277 P += 2; 2277 P += 2;
2278 return tmp; 2278 return tmp;
2279} 2279}
2280 2280
2281 2281
2282u32 CXMeshFileLoader::readBinDWord() 2282u32 CXMeshFileLoader::readBinDWord()
2283{ 2283{
2284#ifdef __BIG_ENDIAN__ 2284#ifdef __BIG_ENDIAN__
2285 const u32 tmp = os::Byteswap::byteswap(*(u32 *)P); 2285 const u32 tmp = os::Byteswap::byteswap(*(u32 *)P);
2286#else 2286#else
2287 const u32 tmp = *(u32 *)P; 2287 const u32 tmp = *(u32 *)P;
2288#endif 2288#endif
2289 P += 4; 2289 P += 4;
2290 return tmp; 2290 return tmp;
2291} 2291}
2292 2292
2293 2293
2294u32 CXMeshFileLoader::readInt() 2294u32 CXMeshFileLoader::readInt()
2295{ 2295{
2296 if (BinaryFormat) 2296 if (BinaryFormat)
2297 { 2297 {
2298 if (!BinaryNumCount) 2298 if (!BinaryNumCount)
2299 { 2299 {
2300 const u16 tmp = readBinWord(); // 0x06 or 0x03 2300 const u16 tmp = readBinWord(); // 0x06 or 0x03
2301 if (tmp == 0x06) 2301 if (tmp == 0x06)
2302 BinaryNumCount = readBinDWord(); 2302 BinaryNumCount = readBinDWord();
2303 else 2303 else
2304 BinaryNumCount = 1; // single int 2304 BinaryNumCount = 1; // single int
2305 } 2305 }
2306 --BinaryNumCount; 2306 --BinaryNumCount;
2307 return readBinDWord(); 2307 return readBinDWord();
2308 } 2308 }
2309 else 2309 else
2310 { 2310 {
2311 findNextNoneWhiteSpaceNumber(); 2311 findNextNoneWhiteSpaceNumber();
2312 return core::strtoul10(P, &P); 2312 return core::strtoul10(P, &P);
2313 } 2313 }
2314} 2314}
2315 2315
2316 2316
2317f32 CXMeshFileLoader::readFloat() 2317f32 CXMeshFileLoader::readFloat()
2318{ 2318{
2319 if (BinaryFormat) 2319 if (BinaryFormat)
2320 { 2320 {
2321 if (!BinaryNumCount) 2321 if (!BinaryNumCount)
2322 { 2322 {
2323 const u16 tmp = readBinWord(); // 0x07 or 0x42 2323 const u16 tmp = readBinWord(); // 0x07 or 0x42
2324 if (tmp == 0x07) 2324 if (tmp == 0x07)
2325 BinaryNumCount = readBinDWord(); 2325 BinaryNumCount = readBinDWord();
2326 else 2326 else
2327 BinaryNumCount = 1; // single int 2327 BinaryNumCount = 1; // single int
2328 } 2328 }
2329 --BinaryNumCount; 2329 --BinaryNumCount;
2330 if (FloatSize == 8) 2330 if (FloatSize == 8)
2331 { 2331 {
2332#ifdef __BIG_ENDIAN__ 2332#ifdef __BIG_ENDIAN__
2333 //TODO: Check if data is properly converted here 2333 //TODO: Check if data is properly converted here
2334 f32 ctmp[2]; 2334 f32 ctmp[2];
2335 ctmp[1] = os::Byteswap::byteswap(*(f32*)P); 2335 ctmp[1] = os::Byteswap::byteswap(*(f32*)P);
2336 ctmp[0] = os::Byteswap::byteswap(*(f32*)P+4); 2336 ctmp[0] = os::Byteswap::byteswap(*(f32*)P+4);
2337 const f32 tmp = (f32)(*(f64*)(void*)ctmp); 2337 const f32 tmp = (f32)(*(f64*)(void*)ctmp);
2338#else 2338#else
2339 const f32 tmp = (f32)(*(f64 *)P); 2339 const f32 tmp = (f32)(*(f64 *)P);
2340#endif 2340#endif
2341 P += 8; 2341 P += 8;
2342 return tmp; 2342 return tmp;
2343 } 2343 }
2344 else 2344 else
2345 { 2345 {
2346#ifdef __BIG_ENDIAN__ 2346#ifdef __BIG_ENDIAN__
2347 const f32 tmp = os::Byteswap::byteswap(*(f32 *)P); 2347 const f32 tmp = os::Byteswap::byteswap(*(f32 *)P);
2348#else 2348#else
2349 const f32 tmp = *(f32 *)P; 2349 const f32 tmp = *(f32 *)P;
2350#endif 2350#endif
2351 P += 4; 2351 P += 4;
2352 return tmp; 2352 return tmp;
2353 } 2353 }
2354 } 2354 }
2355 findNextNoneWhiteSpaceNumber(); 2355 findNextNoneWhiteSpaceNumber();
2356 f32 ftmp; 2356 f32 ftmp;
2357 P = core::fast_atof_move(P, ftmp); 2357 P = core::fast_atof_move(P, ftmp);
2358 return ftmp; 2358 return ftmp;
2359} 2359}
2360 2360
2361 2361
2362// read 2-dimensional vector. Stops at semicolon after second value for text file format 2362// read 2-dimensional vector. Stops at semicolon after second value for text file format
2363bool CXMeshFileLoader::readVector2(core::vector2df& vec) 2363bool CXMeshFileLoader::readVector2(core::vector2df& vec)
2364{ 2364{
2365 vec.X = readFloat(); 2365 vec.X = readFloat();
2366 vec.Y = readFloat(); 2366 vec.Y = readFloat();
2367 return true; 2367 return true;
2368} 2368}
2369 2369
2370 2370
2371// read 3-dimensional vector. Stops at semicolon after third value for text file format 2371// read 3-dimensional vector. Stops at semicolon after third value for text file format
2372bool CXMeshFileLoader::readVector3(core::vector3df& vec) 2372bool CXMeshFileLoader::readVector3(core::vector3df& vec)
2373{ 2373{
2374 vec.X = readFloat(); 2374 vec.X = readFloat();
2375 vec.Y = readFloat(); 2375 vec.Y = readFloat();
2376 vec.Z = readFloat(); 2376 vec.Z = readFloat();
2377 return true; 2377 return true;
2378} 2378}
2379 2379
2380 2380
2381// read color without alpha value. Stops after second semicolon after blue value 2381// read color without alpha value. Stops after second semicolon after blue value
2382bool CXMeshFileLoader::readRGB(video::SColor& color) 2382bool CXMeshFileLoader::readRGB(video::SColor& color)
2383{ 2383{
2384 video::SColorf tmpColor; 2384 video::SColorf tmpColor;
2385 tmpColor.r = readFloat(); 2385 tmpColor.r = readFloat();
2386 tmpColor.g = readFloat(); 2386 tmpColor.g = readFloat();
2387 tmpColor.b = readFloat(); 2387 tmpColor.b = readFloat();
2388 color = tmpColor.toSColor(); 2388 color = tmpColor.toSColor();
2389 return checkForOneFollowingSemicolons(); 2389 return checkForOneFollowingSemicolons();
2390} 2390}
2391 2391
2392 2392
2393// read color with alpha value. Stops after second semicolon after blue value 2393// read color with alpha value. Stops after second semicolon after blue value
2394bool CXMeshFileLoader::readRGBA(video::SColor& color) 2394bool CXMeshFileLoader::readRGBA(video::SColor& color)
2395{ 2395{
2396 video::SColorf tmpColor; 2396 video::SColorf tmpColor;
2397 tmpColor.r = readFloat(); 2397 tmpColor.r = readFloat();
2398 tmpColor.g = readFloat(); 2398 tmpColor.g = readFloat();
2399 tmpColor.b = readFloat(); 2399 tmpColor.b = readFloat();
2400 tmpColor.a = readFloat(); 2400 tmpColor.a = readFloat();
2401 color = tmpColor.toSColor(); 2401 color = tmpColor.toSColor();
2402 return checkForOneFollowingSemicolons(); 2402 return checkForOneFollowingSemicolons();
2403} 2403}
2404 2404
2405 2405
2406// read matrix from list of floats 2406// read matrix from list of floats
2407bool CXMeshFileLoader::readMatrix(core::matrix4& mat) 2407bool CXMeshFileLoader::readMatrix(core::matrix4& mat)
2408{ 2408{
2409 for (u32 i=0; i<16; ++i) 2409 for (u32 i=0; i<16; ++i)
2410 mat[i] = readFloat(); 2410 mat[i] = readFloat();
2411 return checkForOneFollowingSemicolons(); 2411 return checkForOneFollowingSemicolons();
2412} 2412}
2413 2413
2414 2414
2415} // end namespace scene 2415} // end namespace scene
2416} // end namespace irr 2416} // end namespace irr
2417 2417
2418#endif // _IRR_COMPILE_WITH_X_LOADER_ 2418#endif // _IRR_COMPILE_WITH_X_LOADER_
2419 2419