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