diff options
author | David Walter Seikel | 2013-01-13 18:54:10 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 18:54:10 +1000 |
commit | 959831f4ef5a3e797f576c3de08cd65032c997ad (patch) | |
tree | e7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshFileLoader.cpp | |
parent | Add info about changes to Irrlicht. (diff) | |
download | SledjHamr-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 '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshFileLoader.cpp | 1108 |
1 files changed, 554 insertions, 554 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshFileLoader.cpp index 6478aaf..8729b7d 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshFileLoader.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshFileLoader.cpp | |||
@@ -1,554 +1,554 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #include "IrrCompileConfig.h" | 5 | #include "IrrCompileConfig.h" |
6 | #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ | 6 | #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ |
7 | 7 | ||
8 | #include "CIrrMeshFileLoader.h" | 8 | #include "CIrrMeshFileLoader.h" |
9 | #include "os.h" | 9 | #include "os.h" |
10 | #include "IXMLReader.h" | 10 | #include "IXMLReader.h" |
11 | #include "SAnimatedMesh.h" | 11 | #include "SAnimatedMesh.h" |
12 | #include "fast_atof.h" | 12 | #include "fast_atof.h" |
13 | #include "IReadFile.h" | 13 | #include "IReadFile.h" |
14 | #include "IAttributes.h" | 14 | #include "IAttributes.h" |
15 | #include "IMeshSceneNode.h" | 15 | #include "IMeshSceneNode.h" |
16 | #include "CDynamicMeshBuffer.h" | 16 | #include "CDynamicMeshBuffer.h" |
17 | #include "SMeshBufferLightMap.h" | 17 | #include "SMeshBufferLightMap.h" |
18 | 18 | ||
19 | namespace irr | 19 | namespace irr |
20 | { | 20 | { |
21 | namespace scene | 21 | namespace scene |
22 | { | 22 | { |
23 | 23 | ||
24 | 24 | ||
25 | //! Constructor | 25 | //! Constructor |
26 | CIrrMeshFileLoader::CIrrMeshFileLoader(scene::ISceneManager* smgr, | 26 | CIrrMeshFileLoader::CIrrMeshFileLoader(scene::ISceneManager* smgr, |
27 | io::IFileSystem* fs) | 27 | io::IFileSystem* fs) |
28 | : SceneManager(smgr), FileSystem(fs) | 28 | : SceneManager(smgr), FileSystem(fs) |
29 | { | 29 | { |
30 | 30 | ||
31 | #ifdef _DEBUG | 31 | #ifdef _DEBUG |
32 | setDebugName("CIrrMeshFileLoader"); | 32 | setDebugName("CIrrMeshFileLoader"); |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | } | 35 | } |
36 | 36 | ||
37 | 37 | ||
38 | //! Returns true if the file maybe is able to be loaded by this class. | 38 | //! Returns true if the file maybe is able to be loaded by this class. |
39 | /** This decision should be based only on the file extension (e.g. ".cob") */ | 39 | /** This decision should be based only on the file extension (e.g. ".cob") */ |
40 | bool CIrrMeshFileLoader::isALoadableFileExtension(const io::path& filename) const | 40 | bool CIrrMeshFileLoader::isALoadableFileExtension(const io::path& filename) const |
41 | { | 41 | { |
42 | return core::hasFileExtension ( filename, "xml", "irrmesh" ); | 42 | return core::hasFileExtension ( filename, "xml", "irrmesh" ); |
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
46 | //! creates/loads an animated mesh from the file. | 46 | //! creates/loads an animated mesh from the file. |
47 | //! \return Pointer to the created mesh. Returns 0 if loading failed. | 47 | //! \return Pointer to the created mesh. Returns 0 if loading failed. |
48 | //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). | 48 | //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). |
49 | //! See IReferenceCounted::drop() for more information. | 49 | //! See IReferenceCounted::drop() for more information. |
50 | IAnimatedMesh* CIrrMeshFileLoader::createMesh(io::IReadFile* file) | 50 | IAnimatedMesh* CIrrMeshFileLoader::createMesh(io::IReadFile* file) |
51 | { | 51 | { |
52 | io::IXMLReader* reader = FileSystem->createXMLReader(file); | 52 | io::IXMLReader* reader = FileSystem->createXMLReader(file); |
53 | if (!reader) | 53 | if (!reader) |
54 | return 0; | 54 | return 0; |
55 | 55 | ||
56 | // read until mesh section, skip other parts | 56 | // read until mesh section, skip other parts |
57 | 57 | ||
58 | const core::stringc meshTagName = "mesh"; | 58 | const core::stringc meshTagName = "mesh"; |
59 | IAnimatedMesh* mesh = 0; | 59 | IAnimatedMesh* mesh = 0; |
60 | 60 | ||
61 | while(reader->read()) | 61 | while(reader->read()) |
62 | { | 62 | { |
63 | if (reader->getNodeType() == io::EXN_ELEMENT) | 63 | if (reader->getNodeType() == io::EXN_ELEMENT) |
64 | { | 64 | { |
65 | if (meshTagName == reader->getNodeName()) | 65 | if (meshTagName == reader->getNodeName()) |
66 | { | 66 | { |
67 | mesh = readMesh(reader); | 67 | mesh = readMesh(reader); |
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | else | 70 | else |
71 | skipSection(reader, true); // unknown section | 71 | skipSection(reader, true); // unknown section |
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | reader->drop(); | 75 | reader->drop(); |
76 | 76 | ||
77 | return mesh; | 77 | return mesh; |
78 | } | 78 | } |
79 | 79 | ||
80 | 80 | ||
81 | //! reads a mesh sections and creates a mesh from it | 81 | //! reads a mesh sections and creates a mesh from it |
82 | IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader) | 82 | IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader) |
83 | { | 83 | { |
84 | SAnimatedMesh* animatedmesh = new SAnimatedMesh(); | 84 | SAnimatedMesh* animatedmesh = new SAnimatedMesh(); |
85 | SMesh* mesh = new SMesh(); | 85 | SMesh* mesh = new SMesh(); |
86 | 86 | ||
87 | animatedmesh->addMesh(mesh); | 87 | animatedmesh->addMesh(mesh); |
88 | mesh->drop(); | 88 | mesh->drop(); |
89 | 89 | ||
90 | core::stringc bbSectionName = "boundingBox"; | 90 | core::stringc bbSectionName = "boundingBox"; |
91 | core::stringc bufferSectionName = "buffer"; | 91 | core::stringc bufferSectionName = "buffer"; |
92 | core::stringc meshSectionName = "mesh"; | 92 | core::stringc meshSectionName = "mesh"; |
93 | 93 | ||
94 | if (!reader->isEmptyElement()) | 94 | if (!reader->isEmptyElement()) |
95 | while(reader->read()) | 95 | while(reader->read()) |
96 | { | 96 | { |
97 | if (reader->getNodeType() == io::EXN_ELEMENT) | 97 | if (reader->getNodeType() == io::EXN_ELEMENT) |
98 | { | 98 | { |
99 | const wchar_t* nodeName = reader->getNodeName(); | 99 | const wchar_t* nodeName = reader->getNodeName(); |
100 | if (bbSectionName == nodeName) | 100 | if (bbSectionName == nodeName) |
101 | { | 101 | { |
102 | // inside a bounding box, ignore it for now because | 102 | // inside a bounding box, ignore it for now because |
103 | // we are calculating this anyway ourselves later. | 103 | // we are calculating this anyway ourselves later. |
104 | } | 104 | } |
105 | else | 105 | else |
106 | if (bufferSectionName == nodeName) | 106 | if (bufferSectionName == nodeName) |
107 | { | 107 | { |
108 | // we've got a mesh buffer | 108 | // we've got a mesh buffer |
109 | 109 | ||
110 | IMeshBuffer* buffer = readMeshBuffer(reader); | 110 | IMeshBuffer* buffer = readMeshBuffer(reader); |
111 | if (buffer) | 111 | if (buffer) |
112 | { | 112 | { |
113 | mesh->addMeshBuffer(buffer); | 113 | mesh->addMeshBuffer(buffer); |
114 | buffer->drop(); | 114 | buffer->drop(); |
115 | } | 115 | } |
116 | } | 116 | } |
117 | else | 117 | else |
118 | skipSection(reader, true); // unknown section | 118 | skipSection(reader, true); // unknown section |
119 | 119 | ||
120 | } // end if node type is element | 120 | } // end if node type is element |
121 | else | 121 | else |
122 | if (reader->getNodeType() == io::EXN_ELEMENT_END) | 122 | if (reader->getNodeType() == io::EXN_ELEMENT_END) |
123 | { | 123 | { |
124 | if (meshSectionName == reader->getNodeName()) | 124 | if (meshSectionName == reader->getNodeName()) |
125 | { | 125 | { |
126 | // end of mesh section reached, cancel out | 126 | // end of mesh section reached, cancel out |
127 | break; | 127 | break; |
128 | } | 128 | } |
129 | } | 129 | } |
130 | } // end while reader->read(); | 130 | } // end while reader->read(); |
131 | 131 | ||
132 | mesh->recalculateBoundingBox(); | 132 | mesh->recalculateBoundingBox(); |
133 | animatedmesh->recalculateBoundingBox(); | 133 | animatedmesh->recalculateBoundingBox(); |
134 | 134 | ||
135 | return animatedmesh; | 135 | return animatedmesh; |
136 | } | 136 | } |
137 | 137 | ||
138 | 138 | ||
139 | //! reads a mesh sections and creates a mesh buffer from it | 139 | //! reads a mesh sections and creates a mesh buffer from it |
140 | IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) | 140 | IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) |
141 | { | 141 | { |
142 | CDynamicMeshBuffer* buffer = 0; | 142 | CDynamicMeshBuffer* buffer = 0; |
143 | 143 | ||
144 | core::stringc verticesSectionName = "vertices"; | 144 | core::stringc verticesSectionName = "vertices"; |
145 | core::stringc bbSectionName = "boundingBox"; | 145 | core::stringc bbSectionName = "boundingBox"; |
146 | core::stringc materialSectionName = "material"; | 146 | core::stringc materialSectionName = "material"; |
147 | core::stringc indicesSectionName = "indices"; | 147 | core::stringc indicesSectionName = "indices"; |
148 | core::stringc bufferSectionName = "buffer"; | 148 | core::stringc bufferSectionName = "buffer"; |
149 | 149 | ||
150 | bool insideVertexSection = false; | 150 | bool insideVertexSection = false; |
151 | bool insideIndexSection = false; | 151 | bool insideIndexSection = false; |
152 | 152 | ||
153 | int vertexCount = 0; | 153 | int vertexCount = 0; |
154 | int indexCount = 0; | 154 | int indexCount = 0; |
155 | 155 | ||
156 | video::SMaterial material; | 156 | video::SMaterial material; |
157 | 157 | ||
158 | if (!reader->isEmptyElement()) | 158 | if (!reader->isEmptyElement()) |
159 | while(reader->read()) | 159 | while(reader->read()) |
160 | { | 160 | { |
161 | if (reader->getNodeType() == io::EXN_ELEMENT) | 161 | if (reader->getNodeType() == io::EXN_ELEMENT) |
162 | { | 162 | { |
163 | const wchar_t* nodeName = reader->getNodeName(); | 163 | const wchar_t* nodeName = reader->getNodeName(); |
164 | if (bbSectionName == nodeName) | 164 | if (bbSectionName == nodeName) |
165 | { | 165 | { |
166 | // inside a bounding box, ignore it for now because | 166 | // inside a bounding box, ignore it for now because |
167 | // we are calculating this anyway ourselves later. | 167 | // we are calculating this anyway ourselves later. |
168 | } | 168 | } |
169 | else | 169 | else |
170 | if (materialSectionName == nodeName) | 170 | if (materialSectionName == nodeName) |
171 | { | 171 | { |
172 | //we've got a material | 172 | //we've got a material |
173 | 173 | ||
174 | io::IAttributes* attributes = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); | 174 | io::IAttributes* attributes = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); |
175 | attributes->read(reader, true, L"material"); | 175 | attributes->read(reader, true, L"material"); |
176 | 176 | ||
177 | SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes(material, attributes); | 177 | SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes(material, attributes); |
178 | attributes->drop(); | 178 | attributes->drop(); |
179 | } | 179 | } |
180 | else | 180 | else |
181 | if (verticesSectionName == nodeName) | 181 | if (verticesSectionName == nodeName) |
182 | { | 182 | { |
183 | // vertices section | 183 | // vertices section |
184 | 184 | ||
185 | const core::stringc vertexTypeName1 = "standard"; | 185 | const core::stringc vertexTypeName1 = "standard"; |
186 | const core::stringc vertexTypeName2 = "2tcoords"; | 186 | const core::stringc vertexTypeName2 = "2tcoords"; |
187 | const core::stringc vertexTypeName3 = "tangents"; | 187 | const core::stringc vertexTypeName3 = "tangents"; |
188 | 188 | ||
189 | const wchar_t* vertexType = reader->getAttributeValue(L"type"); | 189 | const wchar_t* vertexType = reader->getAttributeValue(L"type"); |
190 | vertexCount = reader->getAttributeValueAsInt(L"vertexCount"); | 190 | vertexCount = reader->getAttributeValueAsInt(L"vertexCount"); |
191 | 191 | ||
192 | insideVertexSection = true; | 192 | insideVertexSection = true; |
193 | 193 | ||
194 | video::E_INDEX_TYPE itype = (vertexCount > 65536)?irr::video::EIT_32BIT:irr::video::EIT_16BIT; | 194 | video::E_INDEX_TYPE itype = (vertexCount > 65536)?irr::video::EIT_32BIT:irr::video::EIT_16BIT; |
195 | if (vertexTypeName1 == vertexType) | 195 | if (vertexTypeName1 == vertexType) |
196 | { | 196 | { |
197 | buffer = new CDynamicMeshBuffer(irr::video::EVT_STANDARD, itype); | 197 | buffer = new CDynamicMeshBuffer(irr::video::EVT_STANDARD, itype); |
198 | 198 | ||
199 | } | 199 | } |
200 | else | 200 | else |
201 | if (vertexTypeName2 == vertexType) | 201 | if (vertexTypeName2 == vertexType) |
202 | { | 202 | { |
203 | buffer = new CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, itype); | 203 | buffer = new CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, itype); |
204 | } | 204 | } |
205 | else | 205 | else |
206 | if (vertexTypeName3 == vertexType) | 206 | if (vertexTypeName3 == vertexType) |
207 | { | 207 | { |
208 | buffer = new CDynamicMeshBuffer(irr::video::EVT_TANGENTS, itype); | 208 | buffer = new CDynamicMeshBuffer(irr::video::EVT_TANGENTS, itype); |
209 | } | 209 | } |
210 | buffer->getVertexBuffer().reallocate(vertexCount); | 210 | buffer->getVertexBuffer().reallocate(vertexCount); |
211 | buffer->Material = material; | 211 | buffer->Material = material; |
212 | } | 212 | } |
213 | else | 213 | else |
214 | if (indicesSectionName == nodeName) | 214 | if (indicesSectionName == nodeName) |
215 | { | 215 | { |
216 | // indices section | 216 | // indices section |
217 | 217 | ||
218 | indexCount = reader->getAttributeValueAsInt(L"indexCount"); | 218 | indexCount = reader->getAttributeValueAsInt(L"indexCount"); |
219 | insideIndexSection = true; | 219 | insideIndexSection = true; |
220 | } | 220 | } |
221 | 221 | ||
222 | } // end if node type is element | 222 | } // end if node type is element |
223 | else | 223 | else |
224 | if (reader->getNodeType() == io::EXN_TEXT) | 224 | if (reader->getNodeType() == io::EXN_TEXT) |
225 | { | 225 | { |
226 | // read vertex data | 226 | // read vertex data |
227 | if (insideVertexSection) | 227 | if (insideVertexSection) |
228 | { | 228 | { |
229 | readMeshBuffer(reader, vertexCount, buffer); | 229 | readMeshBuffer(reader, vertexCount, buffer); |
230 | insideVertexSection = false; | 230 | insideVertexSection = false; |
231 | 231 | ||
232 | } // end reading vertex array | 232 | } // end reading vertex array |
233 | else | 233 | else |
234 | if (insideIndexSection) | 234 | if (insideIndexSection) |
235 | { | 235 | { |
236 | readIndices(reader, indexCount, buffer->getIndexBuffer()); | 236 | readIndices(reader, indexCount, buffer->getIndexBuffer()); |
237 | insideIndexSection = false; | 237 | insideIndexSection = false; |
238 | } | 238 | } |
239 | 239 | ||
240 | } // end if node type is text | 240 | } // end if node type is text |
241 | else | 241 | else |
242 | if (reader->getNodeType() == io::EXN_ELEMENT_END) | 242 | if (reader->getNodeType() == io::EXN_ELEMENT_END) |
243 | { | 243 | { |
244 | if (bufferSectionName == reader->getNodeName()) | 244 | if (bufferSectionName == reader->getNodeName()) |
245 | { | 245 | { |
246 | // end of buffer section reached, cancel out | 246 | // end of buffer section reached, cancel out |
247 | break; | 247 | break; |
248 | } | 248 | } |
249 | } | 249 | } |
250 | } // end while reader->read(); | 250 | } // end while reader->read(); |
251 | 251 | ||
252 | if (buffer) | 252 | if (buffer) |
253 | buffer->recalculateBoundingBox(); | 253 | buffer->recalculateBoundingBox(); |
254 | 254 | ||
255 | return buffer; | 255 | return buffer; |
256 | } | 256 | } |
257 | 257 | ||
258 | 258 | ||
259 | //! read indices | 259 | //! read indices |
260 | void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices) | 260 | void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices) |
261 | { | 261 | { |
262 | indices.reallocate(indexCount); | 262 | indices.reallocate(indexCount); |
263 | 263 | ||
264 | core::stringc data = reader->getNodeData(); | 264 | core::stringc data = reader->getNodeData(); |
265 | const c8* p = &data[0]; | 265 | const c8* p = &data[0]; |
266 | 266 | ||
267 | for (int i=0; i<indexCount && *p; ++i) | 267 | for (int i=0; i<indexCount && *p; ++i) |
268 | { | 268 | { |
269 | findNextNoneWhiteSpace(&p); | 269 | findNextNoneWhiteSpace(&p); |
270 | indices.push_back(readInt(&p)); | 270 | indices.push_back(readInt(&p)); |
271 | } | 271 | } |
272 | } | 272 | } |
273 | 273 | ||
274 | 274 | ||
275 | void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, CDynamicMeshBuffer* sbuffer) | 275 | void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, CDynamicMeshBuffer* sbuffer) |
276 | { | 276 | { |
277 | core::stringc data = reader->getNodeData(); | 277 | core::stringc data = reader->getNodeData(); |
278 | const c8* p = &data[0]; | 278 | const c8* p = &data[0]; |
279 | scene::IVertexBuffer& Vertices = sbuffer->getVertexBuffer(); | 279 | scene::IVertexBuffer& Vertices = sbuffer->getVertexBuffer(); |
280 | video::E_VERTEX_TYPE vType = Vertices.getType(); | 280 | video::E_VERTEX_TYPE vType = Vertices.getType(); |
281 | 281 | ||
282 | if (sbuffer) | 282 | if (sbuffer) |
283 | { | 283 | { |
284 | for (int i=0; i<vertexCount && *p; ++i) | 284 | for (int i=0; i<vertexCount && *p; ++i) |
285 | { | 285 | { |
286 | switch(vType) | 286 | switch(vType) |
287 | { | 287 | { |
288 | case video::EVT_STANDARD: | 288 | case video::EVT_STANDARD: |
289 | { | 289 | { |
290 | video::S3DVertex vtx; | 290 | video::S3DVertex vtx; |
291 | // position | 291 | // position |
292 | 292 | ||
293 | findNextNoneWhiteSpace(&p); | 293 | findNextNoneWhiteSpace(&p); |
294 | vtx.Pos.X = readFloat(&p); | 294 | vtx.Pos.X = readFloat(&p); |
295 | findNextNoneWhiteSpace(&p); | 295 | findNextNoneWhiteSpace(&p); |
296 | vtx.Pos.Y = readFloat(&p); | 296 | vtx.Pos.Y = readFloat(&p); |
297 | findNextNoneWhiteSpace(&p); | 297 | findNextNoneWhiteSpace(&p); |
298 | vtx.Pos.Z = readFloat(&p); | 298 | vtx.Pos.Z = readFloat(&p); |
299 | 299 | ||
300 | // normal | 300 | // normal |
301 | 301 | ||
302 | findNextNoneWhiteSpace(&p); | 302 | findNextNoneWhiteSpace(&p); |
303 | vtx.Normal.X = readFloat(&p); | 303 | vtx.Normal.X = readFloat(&p); |
304 | findNextNoneWhiteSpace(&p); | 304 | findNextNoneWhiteSpace(&p); |
305 | vtx.Normal.Y = readFloat(&p); | 305 | vtx.Normal.Y = readFloat(&p); |
306 | findNextNoneWhiteSpace(&p); | 306 | findNextNoneWhiteSpace(&p); |
307 | vtx.Normal.Z = readFloat(&p); | 307 | vtx.Normal.Z = readFloat(&p); |
308 | 308 | ||
309 | // color | 309 | // color |
310 | 310 | ||
311 | u32 col; | 311 | u32 col; |
312 | findNextNoneWhiteSpace(&p); | 312 | findNextNoneWhiteSpace(&p); |
313 | sscanf(p, "%08x", &col); | 313 | sscanf(p, "%08x", &col); |
314 | vtx.Color.set(col); | 314 | vtx.Color.set(col); |
315 | skipCurrentNoneWhiteSpace(&p); | 315 | skipCurrentNoneWhiteSpace(&p); |
316 | 316 | ||
317 | // tcoord1 | 317 | // tcoord1 |
318 | 318 | ||
319 | findNextNoneWhiteSpace(&p); | 319 | findNextNoneWhiteSpace(&p); |
320 | vtx.TCoords.X = readFloat(&p); | 320 | vtx.TCoords.X = readFloat(&p); |
321 | findNextNoneWhiteSpace(&p); | 321 | findNextNoneWhiteSpace(&p); |
322 | vtx.TCoords.Y = readFloat(&p); | 322 | vtx.TCoords.Y = readFloat(&p); |
323 | 323 | ||
324 | Vertices.push_back(vtx); | 324 | Vertices.push_back(vtx); |
325 | } | 325 | } |
326 | break; | 326 | break; |
327 | case video::EVT_2TCOORDS: | 327 | case video::EVT_2TCOORDS: |
328 | { | 328 | { |
329 | video::S3DVertex2TCoords vtx; | 329 | video::S3DVertex2TCoords vtx; |
330 | // position | 330 | // position |
331 | 331 | ||
332 | findNextNoneWhiteSpace(&p); | 332 | findNextNoneWhiteSpace(&p); |
333 | vtx.Pos.X = readFloat(&p); | 333 | vtx.Pos.X = readFloat(&p); |
334 | findNextNoneWhiteSpace(&p); | 334 | findNextNoneWhiteSpace(&p); |
335 | vtx.Pos.Y = readFloat(&p); | 335 | vtx.Pos.Y = readFloat(&p); |
336 | findNextNoneWhiteSpace(&p); | 336 | findNextNoneWhiteSpace(&p); |
337 | vtx.Pos.Z = readFloat(&p); | 337 | vtx.Pos.Z = readFloat(&p); |
338 | 338 | ||
339 | // normal | 339 | // normal |
340 | 340 | ||
341 | findNextNoneWhiteSpace(&p); | 341 | findNextNoneWhiteSpace(&p); |
342 | vtx.Normal.X = readFloat(&p); | 342 | vtx.Normal.X = readFloat(&p); |
343 | findNextNoneWhiteSpace(&p); | 343 | findNextNoneWhiteSpace(&p); |
344 | vtx.Normal.Y = readFloat(&p); | 344 | vtx.Normal.Y = readFloat(&p); |
345 | findNextNoneWhiteSpace(&p); | 345 | findNextNoneWhiteSpace(&p); |
346 | vtx.Normal.Z = readFloat(&p); | 346 | vtx.Normal.Z = readFloat(&p); |
347 | 347 | ||
348 | // color | 348 | // color |
349 | 349 | ||
350 | u32 col; | 350 | u32 col; |
351 | findNextNoneWhiteSpace(&p); | 351 | findNextNoneWhiteSpace(&p); |
352 | sscanf(p, "%08x", &col); | 352 | sscanf(p, "%08x", &col); |
353 | vtx.Color.set(col); | 353 | vtx.Color.set(col); |
354 | skipCurrentNoneWhiteSpace(&p); | 354 | skipCurrentNoneWhiteSpace(&p); |
355 | 355 | ||
356 | // tcoord1 | 356 | // tcoord1 |
357 | 357 | ||
358 | findNextNoneWhiteSpace(&p); | 358 | findNextNoneWhiteSpace(&p); |
359 | vtx.TCoords.X = readFloat(&p); | 359 | vtx.TCoords.X = readFloat(&p); |
360 | findNextNoneWhiteSpace(&p); | 360 | findNextNoneWhiteSpace(&p); |
361 | vtx.TCoords.Y = readFloat(&p); | 361 | vtx.TCoords.Y = readFloat(&p); |
362 | 362 | ||
363 | // tcoord2 | 363 | // tcoord2 |
364 | 364 | ||
365 | findNextNoneWhiteSpace(&p); | 365 | findNextNoneWhiteSpace(&p); |
366 | vtx.TCoords2.X = readFloat(&p); | 366 | vtx.TCoords2.X = readFloat(&p); |
367 | findNextNoneWhiteSpace(&p); | 367 | findNextNoneWhiteSpace(&p); |
368 | vtx.TCoords2.Y = readFloat(&p); | 368 | vtx.TCoords2.Y = readFloat(&p); |
369 | 369 | ||
370 | Vertices.push_back(vtx); | 370 | Vertices.push_back(vtx); |
371 | } | 371 | } |
372 | break; | 372 | break; |
373 | 373 | ||
374 | case video::EVT_TANGENTS: | 374 | case video::EVT_TANGENTS: |
375 | { | 375 | { |
376 | video::S3DVertexTangents vtx; | 376 | video::S3DVertexTangents vtx; |
377 | // position | 377 | // position |
378 | 378 | ||
379 | findNextNoneWhiteSpace(&p); | 379 | findNextNoneWhiteSpace(&p); |
380 | vtx.Pos.X = readFloat(&p); | 380 | vtx.Pos.X = readFloat(&p); |
381 | findNextNoneWhiteSpace(&p); | 381 | findNextNoneWhiteSpace(&p); |
382 | vtx.Pos.Y = readFloat(&p); | 382 | vtx.Pos.Y = readFloat(&p); |
383 | findNextNoneWhiteSpace(&p); | 383 | findNextNoneWhiteSpace(&p); |
384 | vtx.Pos.Z = readFloat(&p); | 384 | vtx.Pos.Z = readFloat(&p); |
385 | 385 | ||
386 | // normal | 386 | // normal |
387 | 387 | ||
388 | findNextNoneWhiteSpace(&p); | 388 | findNextNoneWhiteSpace(&p); |
389 | vtx.Normal.X = readFloat(&p); | 389 | vtx.Normal.X = readFloat(&p); |
390 | findNextNoneWhiteSpace(&p); | 390 | findNextNoneWhiteSpace(&p); |
391 | vtx.Normal.Y = readFloat(&p); | 391 | vtx.Normal.Y = readFloat(&p); |
392 | findNextNoneWhiteSpace(&p); | 392 | findNextNoneWhiteSpace(&p); |
393 | vtx.Normal.Z = readFloat(&p); | 393 | vtx.Normal.Z = readFloat(&p); |
394 | 394 | ||
395 | // color | 395 | // color |
396 | 396 | ||
397 | u32 col; | 397 | u32 col; |
398 | findNextNoneWhiteSpace(&p); | 398 | findNextNoneWhiteSpace(&p); |
399 | sscanf(p, "%08x", &col); | 399 | sscanf(p, "%08x", &col); |
400 | vtx.Color.set(col); | 400 | vtx.Color.set(col); |
401 | skipCurrentNoneWhiteSpace(&p); | 401 | skipCurrentNoneWhiteSpace(&p); |
402 | 402 | ||
403 | // tcoord1 | 403 | // tcoord1 |
404 | 404 | ||
405 | findNextNoneWhiteSpace(&p); | 405 | findNextNoneWhiteSpace(&p); |
406 | vtx.TCoords.X = readFloat(&p); | 406 | vtx.TCoords.X = readFloat(&p); |
407 | findNextNoneWhiteSpace(&p); | 407 | findNextNoneWhiteSpace(&p); |
408 | vtx.TCoords.Y = readFloat(&p); | 408 | vtx.TCoords.Y = readFloat(&p); |
409 | 409 | ||
410 | // tangent | 410 | // tangent |
411 | 411 | ||
412 | findNextNoneWhiteSpace(&p); | 412 | findNextNoneWhiteSpace(&p); |
413 | vtx.Tangent.X = readFloat(&p); | 413 | vtx.Tangent.X = readFloat(&p); |
414 | findNextNoneWhiteSpace(&p); | 414 | findNextNoneWhiteSpace(&p); |
415 | vtx.Tangent.Y = readFloat(&p); | 415 | vtx.Tangent.Y = readFloat(&p); |
416 | findNextNoneWhiteSpace(&p); | 416 | findNextNoneWhiteSpace(&p); |
417 | vtx.Tangent.Z = readFloat(&p); | 417 | vtx.Tangent.Z = readFloat(&p); |
418 | 418 | ||
419 | // binormal | 419 | // binormal |
420 | 420 | ||
421 | findNextNoneWhiteSpace(&p); | 421 | findNextNoneWhiteSpace(&p); |
422 | vtx.Binormal.X = readFloat(&p); | 422 | vtx.Binormal.X = readFloat(&p); |
423 | findNextNoneWhiteSpace(&p); | 423 | findNextNoneWhiteSpace(&p); |
424 | vtx.Binormal.Y = readFloat(&p); | 424 | vtx.Binormal.Y = readFloat(&p); |
425 | findNextNoneWhiteSpace(&p); | 425 | findNextNoneWhiteSpace(&p); |
426 | vtx.Binormal.Z = readFloat(&p); | 426 | vtx.Binormal.Z = readFloat(&p); |
427 | 427 | ||
428 | Vertices.push_back(vtx); | 428 | Vertices.push_back(vtx); |
429 | } | 429 | } |
430 | break; | 430 | break; |
431 | }; | 431 | }; |
432 | 432 | ||
433 | } | 433 | } |
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | 437 | ||
438 | //! skips an (unknown) section in the irrmesh document | 438 | //! skips an (unknown) section in the irrmesh document |
439 | void CIrrMeshFileLoader::skipSection(io::IXMLReader* reader, bool reportSkipping) | 439 | void CIrrMeshFileLoader::skipSection(io::IXMLReader* reader, bool reportSkipping) |
440 | { | 440 | { |
441 | #ifdef _DEBUG | 441 | #ifdef _DEBUG |
442 | os::Printer::log("irrMesh skipping section", core::stringc(reader->getNodeName()).c_str()); | 442 | os::Printer::log("irrMesh skipping section", core::stringc(reader->getNodeName()).c_str()); |
443 | #endif | 443 | #endif |
444 | 444 | ||
445 | // skip if this element is empty anyway. | 445 | // skip if this element is empty anyway. |
446 | if (reader->isEmptyElement()) | 446 | if (reader->isEmptyElement()) |
447 | return; | 447 | return; |
448 | 448 | ||
449 | // read until we've reached the last element in this section | 449 | // read until we've reached the last element in this section |
450 | u32 tagCounter = 1; | 450 | u32 tagCounter = 1; |
451 | 451 | ||
452 | while(tagCounter && reader->read()) | 452 | while(tagCounter && reader->read()) |
453 | { | 453 | { |
454 | if (reader->getNodeType() == io::EXN_ELEMENT && | 454 | if (reader->getNodeType() == io::EXN_ELEMENT && |
455 | !reader->isEmptyElement()) | 455 | !reader->isEmptyElement()) |
456 | { | 456 | { |
457 | #ifdef _DEBUG | 457 | #ifdef _DEBUG |
458 | if (reportSkipping) | 458 | if (reportSkipping) |
459 | os::Printer::log("irrMesh unknown element:", core::stringc(reader->getNodeName()).c_str()); | 459 | os::Printer::log("irrMesh unknown element:", core::stringc(reader->getNodeName()).c_str()); |
460 | #endif | 460 | #endif |
461 | 461 | ||
462 | ++tagCounter; | 462 | ++tagCounter; |
463 | } | 463 | } |
464 | else | 464 | else |
465 | if (reader->getNodeType() == io::EXN_ELEMENT_END) | 465 | if (reader->getNodeType() == io::EXN_ELEMENT_END) |
466 | --tagCounter; | 466 | --tagCounter; |
467 | } | 467 | } |
468 | } | 468 | } |
469 | 469 | ||
470 | 470 | ||
471 | //! parses a float from a char pointer and moves the pointer | 471 | //! parses a float from a char pointer and moves the pointer |
472 | //! to the end of the parsed float | 472 | //! to the end of the parsed float |
473 | inline f32 CIrrMeshFileLoader::readFloat(const c8** p) | 473 | inline f32 CIrrMeshFileLoader::readFloat(const c8** p) |
474 | { | 474 | { |
475 | f32 ftmp; | 475 | f32 ftmp; |
476 | *p = core::fast_atof_move(*p, ftmp); | 476 | *p = core::fast_atof_move(*p, ftmp); |
477 | return ftmp; | 477 | return ftmp; |
478 | } | 478 | } |
479 | 479 | ||
480 | 480 | ||
481 | //! parses an int from a char pointer and moves the pointer to | 481 | //! parses an int from a char pointer and moves the pointer to |
482 | //! the end of the parsed float | 482 | //! the end of the parsed float |
483 | inline s32 CIrrMeshFileLoader::readInt(const c8** p) | 483 | inline s32 CIrrMeshFileLoader::readInt(const c8** p) |
484 | { | 484 | { |
485 | return (s32)readFloat(p); | 485 | return (s32)readFloat(p); |
486 | } | 486 | } |
487 | 487 | ||
488 | 488 | ||
489 | //! places pointer to next begin of a token | 489 | //! places pointer to next begin of a token |
490 | void CIrrMeshFileLoader::skipCurrentNoneWhiteSpace(const c8** start) | 490 | void CIrrMeshFileLoader::skipCurrentNoneWhiteSpace(const c8** start) |
491 | { | 491 | { |
492 | const c8* p = *start; | 492 | const c8* p = *start; |
493 | 493 | ||
494 | while(*p && !(*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) | 494 | while(*p && !(*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) |
495 | ++p; | 495 | ++p; |
496 | 496 | ||
497 | // TODO: skip comments <!-- --> | 497 | // TODO: skip comments <!-- --> |
498 | 498 | ||
499 | *start = p; | 499 | *start = p; |
500 | } | 500 | } |
501 | 501 | ||
502 | //! places pointer to next begin of a token | 502 | //! places pointer to next begin of a token |
503 | void CIrrMeshFileLoader::findNextNoneWhiteSpace(const c8** start) | 503 | void CIrrMeshFileLoader::findNextNoneWhiteSpace(const c8** start) |
504 | { | 504 | { |
505 | const c8* p = *start; | 505 | const c8* p = *start; |
506 | 506 | ||
507 | while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) | 507 | while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) |
508 | ++p; | 508 | ++p; |
509 | 509 | ||
510 | // TODO: skip comments <!-- --> | 510 | // TODO: skip comments <!-- --> |
511 | 511 | ||
512 | *start = p; | 512 | *start = p; |
513 | } | 513 | } |
514 | 514 | ||
515 | 515 | ||
516 | //! reads floats from inside of xml element until end of xml element | 516 | //! reads floats from inside of xml element until end of xml element |
517 | void CIrrMeshFileLoader::readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count) | 517 | void CIrrMeshFileLoader::readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count) |
518 | { | 518 | { |
519 | if (reader->isEmptyElement()) | 519 | if (reader->isEmptyElement()) |
520 | return; | 520 | return; |
521 | 521 | ||
522 | while(reader->read()) | 522 | while(reader->read()) |
523 | { | 523 | { |
524 | // TODO: check for comments inside the element | 524 | // TODO: check for comments inside the element |
525 | // and ignore them. | 525 | // and ignore them. |
526 | 526 | ||
527 | if (reader->getNodeType() == io::EXN_TEXT) | 527 | if (reader->getNodeType() == io::EXN_TEXT) |
528 | { | 528 | { |
529 | // parse float data | 529 | // parse float data |
530 | core::stringc data = reader->getNodeData(); | 530 | core::stringc data = reader->getNodeData(); |
531 | const c8* p = &data[0]; | 531 | const c8* p = &data[0]; |
532 | 532 | ||
533 | for (u32 i=0; i<count; ++i) | 533 | for (u32 i=0; i<count; ++i) |
534 | { | 534 | { |
535 | findNextNoneWhiteSpace(&p); | 535 | findNextNoneWhiteSpace(&p); |
536 | if (*p) | 536 | if (*p) |
537 | floats[i] = readFloat(&p); | 537 | floats[i] = readFloat(&p); |
538 | else | 538 | else |
539 | floats[i] = 0.0f; | 539 | floats[i] = 0.0f; |
540 | } | 540 | } |
541 | } | 541 | } |
542 | else | 542 | else |
543 | if (reader->getNodeType() == io::EXN_ELEMENT_END) | 543 | if (reader->getNodeType() == io::EXN_ELEMENT_END) |
544 | break; // end parsing text | 544 | break; // end parsing text |
545 | } | 545 | } |
546 | } | 546 | } |
547 | 547 | ||
548 | 548 | ||
549 | 549 | ||
550 | 550 | ||
551 | } // end namespace scene | 551 | } // end namespace scene |
552 | } // end namespace irr | 552 | } // end namespace irr |
553 | 553 | ||
554 | #endif // _IRR_COMPILE_WITH_IRR_MESH_LOADER_ | 554 | #endif // _IRR_COMPILE_WITH_IRR_MESH_LOADER_ |