diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp | 2210 |
1 files changed, 1105 insertions, 1105 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp index 3d8769e..399e342 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CB3DMeshFileLoader.cpp | |||
@@ -1,1105 +1,1105 @@ | |||
1 | // Copyright (C) 2006-2012 Luke Hoschke | 1 | // Copyright (C) 2006-2012 Luke Hoschke |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | // B3D Mesh loader | 5 | // B3D Mesh loader |
6 | // File format designed by Mark Sibly for the Blitz3D engine and has been | 6 | // File format designed by Mark Sibly for the Blitz3D engine and has been |
7 | // declared public domain | 7 | // declared public domain |
8 | 8 | ||
9 | #include "IrrCompileConfig.h" | 9 | #include "IrrCompileConfig.h" |
10 | #ifdef _IRR_COMPILE_WITH_B3D_LOADER_ | 10 | #ifdef _IRR_COMPILE_WITH_B3D_LOADER_ |
11 | 11 | ||
12 | #include "CB3DMeshFileLoader.h" | 12 | #include "CB3DMeshFileLoader.h" |
13 | 13 | ||
14 | #include "IVideoDriver.h" | 14 | #include "IVideoDriver.h" |
15 | #include "IFileSystem.h" | 15 | #include "IFileSystem.h" |
16 | #include "os.h" | 16 | #include "os.h" |
17 | 17 | ||
18 | #ifdef _DEBUG | 18 | #ifdef _DEBUG |
19 | #define _B3D_READER_DEBUG | 19 | #define _B3D_READER_DEBUG |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | namespace irr | 22 | namespace irr |
23 | { | 23 | { |
24 | namespace scene | 24 | namespace scene |
25 | { | 25 | { |
26 | 26 | ||
27 | //! Constructor | 27 | //! Constructor |
28 | CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr) | 28 | CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr) |
29 | : SceneManager(smgr), AnimatedMesh(0), B3DFile(0), NormalsInFile(false), | 29 | : SceneManager(smgr), AnimatedMesh(0), B3DFile(0), NormalsInFile(false), |
30 | HasVertexColors(false), ShowWarning(true) | 30 | HasVertexColors(false), ShowWarning(true) |
31 | { | 31 | { |
32 | #ifdef _DEBUG | 32 | #ifdef _DEBUG |
33 | setDebugName("CB3DMeshFileLoader"); | 33 | setDebugName("CB3DMeshFileLoader"); |
34 | #endif | 34 | #endif |
35 | } | 35 | } |
36 | 36 | ||
37 | 37 | ||
38 | //! returns true if the file maybe is able to be loaded by this class | 38 | //! returns true if the file maybe is able to be loaded by this class |
39 | //! based on the file extension (e.g. ".bsp") | 39 | //! based on the file extension (e.g. ".bsp") |
40 | bool CB3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const | 40 | bool CB3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const |
41 | { | 41 | { |
42 | return core::hasFileExtension ( filename, "b3d" ); | 42 | return core::hasFileExtension ( filename, "b3d" ); |
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
46 | //! creates/loads an animated mesh from the file. | 46 | //! creates/loads an animated mesh from the file. |
47 | //! \return Pointer to the created mesh. Returns 0 if loading failed. | 47 | //! \return Pointer to the created mesh. Returns 0 if loading failed. |
48 | //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). | 48 | //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). |
49 | //! See IReferenceCounted::drop() for more information. | 49 | //! See IReferenceCounted::drop() for more information. |
50 | IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f) | 50 | IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f) |
51 | { | 51 | { |
52 | if (!f) | 52 | if (!f) |
53 | return 0; | 53 | return 0; |
54 | 54 | ||
55 | B3DFile = f; | 55 | B3DFile = f; |
56 | AnimatedMesh = new scene::CSkinnedMesh(); | 56 | AnimatedMesh = new scene::CSkinnedMesh(); |
57 | ShowWarning = true; // If true a warning is issued if too many textures are used | 57 | ShowWarning = true; // If true a warning is issued if too many textures are used |
58 | VerticesStart=0; | 58 | VerticesStart=0; |
59 | 59 | ||
60 | if ( load() ) | 60 | if ( load() ) |
61 | { | 61 | { |
62 | AnimatedMesh->finalize(); | 62 | AnimatedMesh->finalize(); |
63 | } | 63 | } |
64 | else | 64 | else |
65 | { | 65 | { |
66 | AnimatedMesh->drop(); | 66 | AnimatedMesh->drop(); |
67 | AnimatedMesh = 0; | 67 | AnimatedMesh = 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | return AnimatedMesh; | 70 | return AnimatedMesh; |
71 | } | 71 | } |
72 | 72 | ||
73 | 73 | ||
74 | bool CB3DMeshFileLoader::load() | 74 | bool CB3DMeshFileLoader::load() |
75 | { | 75 | { |
76 | B3dStack.clear(); | 76 | B3dStack.clear(); |
77 | 77 | ||
78 | NormalsInFile=false; | 78 | NormalsInFile=false; |
79 | HasVertexColors=false; | 79 | HasVertexColors=false; |
80 | 80 | ||
81 | //------ Get header ------ | 81 | //------ Get header ------ |
82 | 82 | ||
83 | SB3dChunkHeader header; | 83 | SB3dChunkHeader header; |
84 | B3DFile->read(&header, sizeof(header)); | 84 | B3DFile->read(&header, sizeof(header)); |
85 | #ifdef __BIG_ENDIAN__ | 85 | #ifdef __BIG_ENDIAN__ |
86 | header.size = os::Byteswap::byteswap(header.size); | 86 | header.size = os::Byteswap::byteswap(header.size); |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | if ( strncmp( header.name, "BB3D", 4 ) != 0 ) | 89 | if ( strncmp( header.name, "BB3D", 4 ) != 0 ) |
90 | { | 90 | { |
91 | os::Printer::log("File is not a b3d file. Loading failed (No header found)", B3DFile->getFileName(), ELL_ERROR); | 91 | os::Printer::log("File is not a b3d file. Loading failed (No header found)", B3DFile->getFileName(), ELL_ERROR); |
92 | return false; | 92 | return false; |
93 | } | 93 | } |
94 | 94 | ||
95 | // Add main chunk... | 95 | // Add main chunk... |
96 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); | 96 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); |
97 | 97 | ||
98 | // Get file version, but ignore it, as it's not important with b3d files... | 98 | // Get file version, but ignore it, as it's not important with b3d files... |
99 | s32 fileVersion; | 99 | s32 fileVersion; |
100 | B3DFile->read(&fileVersion, sizeof(fileVersion)); | 100 | B3DFile->read(&fileVersion, sizeof(fileVersion)); |
101 | #ifdef __BIG_ENDIAN__ | 101 | #ifdef __BIG_ENDIAN__ |
102 | fileVersion = os::Byteswap::byteswap(fileVersion); | 102 | fileVersion = os::Byteswap::byteswap(fileVersion); |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | //------ Read main chunk ------ | 105 | //------ Read main chunk ------ |
106 | 106 | ||
107 | while ( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos() ) | 107 | while ( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos() ) |
108 | { | 108 | { |
109 | B3DFile->read(&header, sizeof(header)); | 109 | B3DFile->read(&header, sizeof(header)); |
110 | #ifdef __BIG_ENDIAN__ | 110 | #ifdef __BIG_ENDIAN__ |
111 | header.size = os::Byteswap::byteswap(header.size); | 111 | header.size = os::Byteswap::byteswap(header.size); |
112 | #endif | 112 | #endif |
113 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); | 113 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); |
114 | 114 | ||
115 | if ( strncmp( B3dStack.getLast().name, "TEXS", 4 ) == 0 ) | 115 | if ( strncmp( B3dStack.getLast().name, "TEXS", 4 ) == 0 ) |
116 | { | 116 | { |
117 | if (!readChunkTEXS()) | 117 | if (!readChunkTEXS()) |
118 | return false; | 118 | return false; |
119 | } | 119 | } |
120 | else if ( strncmp( B3dStack.getLast().name, "BRUS", 4 ) == 0 ) | 120 | else if ( strncmp( B3dStack.getLast().name, "BRUS", 4 ) == 0 ) |
121 | { | 121 | { |
122 | if (!readChunkBRUS()) | 122 | if (!readChunkBRUS()) |
123 | return false; | 123 | return false; |
124 | } | 124 | } |
125 | else if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) | 125 | else if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) |
126 | { | 126 | { |
127 | if (!readChunkNODE((CSkinnedMesh::SJoint*)0) ) | 127 | if (!readChunkNODE((CSkinnedMesh::SJoint*)0) ) |
128 | return false; | 128 | return false; |
129 | } | 129 | } |
130 | else | 130 | else |
131 | { | 131 | { |
132 | os::Printer::log("Unknown chunk found in mesh base - skipping"); | 132 | os::Printer::log("Unknown chunk found in mesh base - skipping"); |
133 | B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); | 133 | B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); |
134 | B3dStack.erase(B3dStack.size()-1); | 134 | B3dStack.erase(B3dStack.size()-1); |
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
138 | B3dStack.clear(); | 138 | B3dStack.clear(); |
139 | 139 | ||
140 | BaseVertices.clear(); | 140 | BaseVertices.clear(); |
141 | AnimatedVertices_VertexID.clear(); | 141 | AnimatedVertices_VertexID.clear(); |
142 | AnimatedVertices_BufferID.clear(); | 142 | AnimatedVertices_BufferID.clear(); |
143 | 143 | ||
144 | Materials.clear(); | 144 | Materials.clear(); |
145 | Textures.clear(); | 145 | Textures.clear(); |
146 | 146 | ||
147 | return true; | 147 | return true; |
148 | } | 148 | } |
149 | 149 | ||
150 | 150 | ||
151 | bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) | 151 | bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) |
152 | { | 152 | { |
153 | CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint); | 153 | CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint); |
154 | readString(joint->Name); | 154 | readString(joint->Name); |
155 | 155 | ||
156 | #ifdef _B3D_READER_DEBUG | 156 | #ifdef _B3D_READER_DEBUG |
157 | core::stringc logStr; | 157 | core::stringc logStr; |
158 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 158 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
159 | logStr += "-"; | 159 | logStr += "-"; |
160 | logStr += "read ChunkNODE"; | 160 | logStr += "read ChunkNODE"; |
161 | os::Printer::log(logStr.c_str(), joint->Name.c_str()); | 161 | os::Printer::log(logStr.c_str(), joint->Name.c_str()); |
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | f32 position[3], scale[3], rotation[4]; | 164 | f32 position[3], scale[3], rotation[4]; |
165 | 165 | ||
166 | readFloats(position, 3); | 166 | readFloats(position, 3); |
167 | readFloats(scale, 3); | 167 | readFloats(scale, 3); |
168 | readFloats(rotation, 4); | 168 | readFloats(rotation, 4); |
169 | 169 | ||
170 | joint->Animatedposition = core::vector3df(position[0],position[1],position[2]) ; | 170 | joint->Animatedposition = core::vector3df(position[0],position[1],position[2]) ; |
171 | joint->Animatedscale = core::vector3df(scale[0],scale[1],scale[2]); | 171 | joint->Animatedscale = core::vector3df(scale[0],scale[1],scale[2]); |
172 | joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]); | 172 | joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]); |
173 | 173 | ||
174 | //Build LocalMatrix: | 174 | //Build LocalMatrix: |
175 | 175 | ||
176 | core::matrix4 positionMatrix; | 176 | core::matrix4 positionMatrix; |
177 | positionMatrix.setTranslation( joint->Animatedposition ); | 177 | positionMatrix.setTranslation( joint->Animatedposition ); |
178 | core::matrix4 scaleMatrix; | 178 | core::matrix4 scaleMatrix; |
179 | scaleMatrix.setScale( joint->Animatedscale ); | 179 | scaleMatrix.setScale( joint->Animatedscale ); |
180 | core::matrix4 rotationMatrix; | 180 | core::matrix4 rotationMatrix; |
181 | joint->Animatedrotation.getMatrix_transposed(rotationMatrix); | 181 | joint->Animatedrotation.getMatrix_transposed(rotationMatrix); |
182 | 182 | ||
183 | joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix; | 183 | joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix; |
184 | 184 | ||
185 | if (inJoint) | 185 | if (inJoint) |
186 | joint->GlobalMatrix = inJoint->GlobalMatrix * joint->LocalMatrix; | 186 | joint->GlobalMatrix = inJoint->GlobalMatrix * joint->LocalMatrix; |
187 | else | 187 | else |
188 | joint->GlobalMatrix = joint->LocalMatrix; | 188 | joint->GlobalMatrix = joint->LocalMatrix; |
189 | 189 | ||
190 | while(B3dStack.getLast().startposition + B3dStack.getLast().length > B3DFile->getPos()) // this chunk repeats | 190 | while(B3dStack.getLast().startposition + B3dStack.getLast().length > B3DFile->getPos()) // this chunk repeats |
191 | { | 191 | { |
192 | SB3dChunkHeader header; | 192 | SB3dChunkHeader header; |
193 | B3DFile->read(&header, sizeof(header)); | 193 | B3DFile->read(&header, sizeof(header)); |
194 | #ifdef __BIG_ENDIAN__ | 194 | #ifdef __BIG_ENDIAN__ |
195 | header.size = os::Byteswap::byteswap(header.size); | 195 | header.size = os::Byteswap::byteswap(header.size); |
196 | #endif | 196 | #endif |
197 | 197 | ||
198 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); | 198 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); |
199 | 199 | ||
200 | if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) | 200 | if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) |
201 | { | 201 | { |
202 | if (!readChunkNODE(joint)) | 202 | if (!readChunkNODE(joint)) |
203 | return false; | 203 | return false; |
204 | } | 204 | } |
205 | else if ( strncmp( B3dStack.getLast().name, "MESH", 4 ) == 0 ) | 205 | else if ( strncmp( B3dStack.getLast().name, "MESH", 4 ) == 0 ) |
206 | { | 206 | { |
207 | VerticesStart=BaseVertices.size(); | 207 | VerticesStart=BaseVertices.size(); |
208 | if (!readChunkMESH(joint)) | 208 | if (!readChunkMESH(joint)) |
209 | return false; | 209 | return false; |
210 | } | 210 | } |
211 | else if ( strncmp( B3dStack.getLast().name, "BONE", 4 ) == 0 ) | 211 | else if ( strncmp( B3dStack.getLast().name, "BONE", 4 ) == 0 ) |
212 | { | 212 | { |
213 | if (!readChunkBONE(joint)) | 213 | if (!readChunkBONE(joint)) |
214 | return false; | 214 | return false; |
215 | } | 215 | } |
216 | else if ( strncmp( B3dStack.getLast().name, "KEYS", 4 ) == 0 ) | 216 | else if ( strncmp( B3dStack.getLast().name, "KEYS", 4 ) == 0 ) |
217 | { | 217 | { |
218 | if(!readChunkKEYS(joint)) | 218 | if(!readChunkKEYS(joint)) |
219 | return false; | 219 | return false; |
220 | } | 220 | } |
221 | else if ( strncmp( B3dStack.getLast().name, "ANIM", 4 ) == 0 ) | 221 | else if ( strncmp( B3dStack.getLast().name, "ANIM", 4 ) == 0 ) |
222 | { | 222 | { |
223 | if (!readChunkANIM()) | 223 | if (!readChunkANIM()) |
224 | return false; | 224 | return false; |
225 | } | 225 | } |
226 | else | 226 | else |
227 | { | 227 | { |
228 | os::Printer::log("Unknown chunk found in node chunk - skipping"); | 228 | os::Printer::log("Unknown chunk found in node chunk - skipping"); |
229 | B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); | 229 | B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); |
230 | B3dStack.erase(B3dStack.size()-1); | 230 | B3dStack.erase(B3dStack.size()-1); |
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | B3dStack.erase(B3dStack.size()-1); | 234 | B3dStack.erase(B3dStack.size()-1); |
235 | 235 | ||
236 | return true; | 236 | return true; |
237 | } | 237 | } |
238 | 238 | ||
239 | 239 | ||
240 | bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) | 240 | bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) |
241 | { | 241 | { |
242 | #ifdef _B3D_READER_DEBUG | 242 | #ifdef _B3D_READER_DEBUG |
243 | core::stringc logStr; | 243 | core::stringc logStr; |
244 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 244 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
245 | logStr += "-"; | 245 | logStr += "-"; |
246 | logStr += "read ChunkMESH"; | 246 | logStr += "read ChunkMESH"; |
247 | os::Printer::log(logStr.c_str()); | 247 | os::Printer::log(logStr.c_str()); |
248 | #endif | 248 | #endif |
249 | 249 | ||
250 | s32 brushID; | 250 | s32 brushID; |
251 | B3DFile->read(&brushID, sizeof(brushID)); | 251 | B3DFile->read(&brushID, sizeof(brushID)); |
252 | #ifdef __BIG_ENDIAN__ | 252 | #ifdef __BIG_ENDIAN__ |
253 | brushID = os::Byteswap::byteswap(brushID); | 253 | brushID = os::Byteswap::byteswap(brushID); |
254 | #endif | 254 | #endif |
255 | 255 | ||
256 | NormalsInFile=false; | 256 | NormalsInFile=false; |
257 | HasVertexColors=false; | 257 | HasVertexColors=false; |
258 | 258 | ||
259 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats | 259 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats |
260 | { | 260 | { |
261 | SB3dChunkHeader header; | 261 | SB3dChunkHeader header; |
262 | B3DFile->read(&header, sizeof(header)); | 262 | B3DFile->read(&header, sizeof(header)); |
263 | #ifdef __BIG_ENDIAN__ | 263 | #ifdef __BIG_ENDIAN__ |
264 | header.size = os::Byteswap::byteswap(header.size); | 264 | header.size = os::Byteswap::byteswap(header.size); |
265 | #endif | 265 | #endif |
266 | 266 | ||
267 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); | 267 | B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); |
268 | 268 | ||
269 | if ( strncmp( B3dStack.getLast().name, "VRTS", 4 ) == 0 ) | 269 | if ( strncmp( B3dStack.getLast().name, "VRTS", 4 ) == 0 ) |
270 | { | 270 | { |
271 | if (!readChunkVRTS(inJoint)) | 271 | if (!readChunkVRTS(inJoint)) |
272 | return false; | 272 | return false; |
273 | } | 273 | } |
274 | else if ( strncmp( B3dStack.getLast().name, "TRIS", 4 ) == 0 ) | 274 | else if ( strncmp( B3dStack.getLast().name, "TRIS", 4 ) == 0 ) |
275 | { | 275 | { |
276 | scene::SSkinMeshBuffer *meshBuffer = AnimatedMesh->addMeshBuffer(); | 276 | scene::SSkinMeshBuffer *meshBuffer = AnimatedMesh->addMeshBuffer(); |
277 | 277 | ||
278 | if (brushID!=-1) | 278 | if (brushID!=-1) |
279 | { | 279 | { |
280 | loadTextures(Materials[brushID]); | 280 | loadTextures(Materials[brushID]); |
281 | meshBuffer->Material=Materials[brushID].Material; | 281 | meshBuffer->Material=Materials[brushID].Material; |
282 | } | 282 | } |
283 | 283 | ||
284 | if(readChunkTRIS(meshBuffer,AnimatedMesh->getMeshBuffers().size()-1, VerticesStart)==false) | 284 | if(readChunkTRIS(meshBuffer,AnimatedMesh->getMeshBuffers().size()-1, VerticesStart)==false) |
285 | return false; | 285 | return false; |
286 | 286 | ||
287 | if (!NormalsInFile) | 287 | if (!NormalsInFile) |
288 | { | 288 | { |
289 | s32 i; | 289 | s32 i; |
290 | 290 | ||
291 | for ( i=0; i<(s32)meshBuffer->Indices.size(); i+=3) | 291 | for ( i=0; i<(s32)meshBuffer->Indices.size(); i+=3) |
292 | { | 292 | { |
293 | core::plane3df p(meshBuffer->getVertex(meshBuffer->Indices[i+0])->Pos, | 293 | core::plane3df p(meshBuffer->getVertex(meshBuffer->Indices[i+0])->Pos, |
294 | meshBuffer->getVertex(meshBuffer->Indices[i+1])->Pos, | 294 | meshBuffer->getVertex(meshBuffer->Indices[i+1])->Pos, |
295 | meshBuffer->getVertex(meshBuffer->Indices[i+2])->Pos); | 295 | meshBuffer->getVertex(meshBuffer->Indices[i+2])->Pos); |
296 | 296 | ||
297 | meshBuffer->getVertex(meshBuffer->Indices[i+0])->Normal += p.Normal; | 297 | meshBuffer->getVertex(meshBuffer->Indices[i+0])->Normal += p.Normal; |
298 | meshBuffer->getVertex(meshBuffer->Indices[i+1])->Normal += p.Normal; | 298 | meshBuffer->getVertex(meshBuffer->Indices[i+1])->Normal += p.Normal; |
299 | meshBuffer->getVertex(meshBuffer->Indices[i+2])->Normal += p.Normal; | 299 | meshBuffer->getVertex(meshBuffer->Indices[i+2])->Normal += p.Normal; |
300 | } | 300 | } |
301 | 301 | ||
302 | for ( i = 0; i<(s32)meshBuffer->getVertexCount(); ++i ) | 302 | for ( i = 0; i<(s32)meshBuffer->getVertexCount(); ++i ) |
303 | { | 303 | { |
304 | meshBuffer->getVertex(i)->Normal.normalize(); | 304 | meshBuffer->getVertex(i)->Normal.normalize(); |
305 | BaseVertices[VerticesStart+i].Normal=meshBuffer->getVertex(i)->Normal; | 305 | BaseVertices[VerticesStart+i].Normal=meshBuffer->getVertex(i)->Normal; |
306 | } | 306 | } |
307 | } | 307 | } |
308 | } | 308 | } |
309 | else | 309 | else |
310 | { | 310 | { |
311 | os::Printer::log("Unknown chunk found in mesh - skipping"); | 311 | os::Printer::log("Unknown chunk found in mesh - skipping"); |
312 | B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); | 312 | B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); |
313 | B3dStack.erase(B3dStack.size()-1); | 313 | B3dStack.erase(B3dStack.size()-1); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ||
317 | B3dStack.erase(B3dStack.size()-1); | 317 | B3dStack.erase(B3dStack.size()-1); |
318 | 318 | ||
319 | return true; | 319 | return true; |
320 | } | 320 | } |
321 | 321 | ||
322 | 322 | ||
323 | /* | 323 | /* |
324 | VRTS: | 324 | VRTS: |
325 | int flags ;1=normal values present, 2=rgba values present | 325 | int flags ;1=normal values present, 2=rgba values present |
326 | int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 | 326 | int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 |
327 | but we only support 3 | 327 | but we only support 3 |
328 | int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 | 328 | int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 |
329 | { | 329 | { |
330 | float x,y,z ;always present | 330 | float x,y,z ;always present |
331 | float nx,ny,nz ;vertex normal: present if (flags&1) | 331 | float nx,ny,nz ;vertex normal: present if (flags&1) |
332 | float red,green,blue,alpha ;vertex color: present if (flags&2) | 332 | float red,green,blue,alpha ;vertex color: present if (flags&2) |
333 | float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords | 333 | float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords |
334 | } | 334 | } |
335 | */ | 335 | */ |
336 | bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint) | 336 | bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint) |
337 | { | 337 | { |
338 | #ifdef _B3D_READER_DEBUG | 338 | #ifdef _B3D_READER_DEBUG |
339 | core::stringc logStr; | 339 | core::stringc logStr; |
340 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 340 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
341 | logStr += "-"; | 341 | logStr += "-"; |
342 | logStr += "ChunkVRTS"; | 342 | logStr += "ChunkVRTS"; |
343 | os::Printer::log(logStr.c_str()); | 343 | os::Printer::log(logStr.c_str()); |
344 | #endif | 344 | #endif |
345 | 345 | ||
346 | const s32 max_tex_coords = 3; | 346 | const s32 max_tex_coords = 3; |
347 | s32 flags, tex_coord_sets, tex_coord_set_size; | 347 | s32 flags, tex_coord_sets, tex_coord_set_size; |
348 | 348 | ||
349 | B3DFile->read(&flags, sizeof(flags)); | 349 | B3DFile->read(&flags, sizeof(flags)); |
350 | B3DFile->read(&tex_coord_sets, sizeof(tex_coord_sets)); | 350 | B3DFile->read(&tex_coord_sets, sizeof(tex_coord_sets)); |
351 | B3DFile->read(&tex_coord_set_size, sizeof(tex_coord_set_size)); | 351 | B3DFile->read(&tex_coord_set_size, sizeof(tex_coord_set_size)); |
352 | #ifdef __BIG_ENDIAN__ | 352 | #ifdef __BIG_ENDIAN__ |
353 | flags = os::Byteswap::byteswap(flags); | 353 | flags = os::Byteswap::byteswap(flags); |
354 | tex_coord_sets = os::Byteswap::byteswap(tex_coord_sets); | 354 | tex_coord_sets = os::Byteswap::byteswap(tex_coord_sets); |
355 | tex_coord_set_size = os::Byteswap::byteswap(tex_coord_set_size); | 355 | tex_coord_set_size = os::Byteswap::byteswap(tex_coord_set_size); |
356 | #endif | 356 | #endif |
357 | 357 | ||
358 | if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong | 358 | if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong |
359 | { | 359 | { |
360 | os::Printer::log("tex_coord_sets or tex_coord_set_size too big", B3DFile->getFileName(), ELL_ERROR); | 360 | os::Printer::log("tex_coord_sets or tex_coord_set_size too big", B3DFile->getFileName(), ELL_ERROR); |
361 | return false; | 361 | return false; |
362 | } | 362 | } |
363 | 363 | ||
364 | //------ Allocate Memory, for speed -----------// | 364 | //------ Allocate Memory, for speed -----------// |
365 | 365 | ||
366 | s32 numberOfReads = 3; | 366 | s32 numberOfReads = 3; |
367 | 367 | ||
368 | if (flags & 1) | 368 | if (flags & 1) |
369 | { | 369 | { |
370 | NormalsInFile = true; | 370 | NormalsInFile = true; |
371 | numberOfReads += 3; | 371 | numberOfReads += 3; |
372 | } | 372 | } |
373 | if (flags & 2) | 373 | if (flags & 2) |
374 | { | 374 | { |
375 | numberOfReads += 4; | 375 | numberOfReads += 4; |
376 | HasVertexColors=true; | 376 | HasVertexColors=true; |
377 | } | 377 | } |
378 | 378 | ||
379 | numberOfReads += tex_coord_sets*tex_coord_set_size; | 379 | numberOfReads += tex_coord_sets*tex_coord_set_size; |
380 | 380 | ||
381 | const s32 memoryNeeded = (B3dStack.getLast().length / sizeof(f32)) / numberOfReads; | 381 | const s32 memoryNeeded = (B3dStack.getLast().length / sizeof(f32)) / numberOfReads; |
382 | 382 | ||
383 | BaseVertices.reallocate(memoryNeeded + BaseVertices.size() + 1); | 383 | BaseVertices.reallocate(memoryNeeded + BaseVertices.size() + 1); |
384 | AnimatedVertices_VertexID.reallocate(memoryNeeded + AnimatedVertices_VertexID.size() + 1); | 384 | AnimatedVertices_VertexID.reallocate(memoryNeeded + AnimatedVertices_VertexID.size() + 1); |
385 | 385 | ||
386 | //--------------------------------------------// | 386 | //--------------------------------------------// |
387 | 387 | ||
388 | while( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats | 388 | while( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats |
389 | { | 389 | { |
390 | f32 position[3]; | 390 | f32 position[3]; |
391 | f32 normal[3]={0.f, 0.f, 0.f}; | 391 | f32 normal[3]={0.f, 0.f, 0.f}; |
392 | f32 color[4]={1.0f, 1.0f, 1.0f, 1.0f}; | 392 | f32 color[4]={1.0f, 1.0f, 1.0f, 1.0f}; |
393 | f32 tex_coords[max_tex_coords][4]; | 393 | f32 tex_coords[max_tex_coords][4]; |
394 | 394 | ||
395 | readFloats(position, 3); | 395 | readFloats(position, 3); |
396 | 396 | ||
397 | if (flags & 1) | 397 | if (flags & 1) |
398 | readFloats(normal, 3); | 398 | readFloats(normal, 3); |
399 | if (flags & 2) | 399 | if (flags & 2) |
400 | readFloats(color, 4); | 400 | readFloats(color, 4); |
401 | 401 | ||
402 | for (s32 i=0; i<tex_coord_sets; ++i) | 402 | for (s32 i=0; i<tex_coord_sets; ++i) |
403 | readFloats(tex_coords[i], tex_coord_set_size); | 403 | readFloats(tex_coords[i], tex_coord_set_size); |
404 | 404 | ||
405 | f32 tu=0.0f, tv=0.0f; | 405 | f32 tu=0.0f, tv=0.0f; |
406 | if (tex_coord_sets >= 1 && tex_coord_set_size >= 2) | 406 | if (tex_coord_sets >= 1 && tex_coord_set_size >= 2) |
407 | { | 407 | { |
408 | tu=tex_coords[0][0]; | 408 | tu=tex_coords[0][0]; |
409 | tv=tex_coords[0][1]; | 409 | tv=tex_coords[0][1]; |
410 | } | 410 | } |
411 | 411 | ||
412 | f32 tu2=0.0f, tv2=0.0f; | 412 | f32 tu2=0.0f, tv2=0.0f; |
413 | if (tex_coord_sets>1 && tex_coord_set_size>1) | 413 | if (tex_coord_sets>1 && tex_coord_set_size>1) |
414 | { | 414 | { |
415 | tu2=tex_coords[1][0]; | 415 | tu2=tex_coords[1][0]; |
416 | tv2=tex_coords[1][1]; | 416 | tv2=tex_coords[1][1]; |
417 | } | 417 | } |
418 | 418 | ||
419 | // Create Vertex... | 419 | // Create Vertex... |
420 | video::S3DVertex2TCoords Vertex(position[0], position[1], position[2], | 420 | video::S3DVertex2TCoords Vertex(position[0], position[1], position[2], |
421 | normal[0], normal[1], normal[2], | 421 | normal[0], normal[1], normal[2], |
422 | video::SColorf(color[0], color[1], color[2], color[3]).toSColor(), | 422 | video::SColorf(color[0], color[1], color[2], color[3]).toSColor(), |
423 | tu, tv, tu2, tv2); | 423 | tu, tv, tu2, tv2); |
424 | 424 | ||
425 | // Transform the Vertex position by nested node... | 425 | // Transform the Vertex position by nested node... |
426 | inJoint->GlobalMatrix.transformVect(Vertex.Pos); | 426 | inJoint->GlobalMatrix.transformVect(Vertex.Pos); |
427 | inJoint->GlobalMatrix.rotateVect(Vertex.Normal); | 427 | inJoint->GlobalMatrix.rotateVect(Vertex.Normal); |
428 | 428 | ||
429 | //Add it... | 429 | //Add it... |
430 | BaseVertices.push_back(Vertex); | 430 | BaseVertices.push_back(Vertex); |
431 | 431 | ||
432 | AnimatedVertices_VertexID.push_back(-1); | 432 | AnimatedVertices_VertexID.push_back(-1); |
433 | AnimatedVertices_BufferID.push_back(-1); | 433 | AnimatedVertices_BufferID.push_back(-1); |
434 | } | 434 | } |
435 | 435 | ||
436 | B3dStack.erase(B3dStack.size()-1); | 436 | B3dStack.erase(B3dStack.size()-1); |
437 | 437 | ||
438 | return true; | 438 | return true; |
439 | } | 439 | } |
440 | 440 | ||
441 | 441 | ||
442 | bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 meshBufferID, s32 vertices_Start) | 442 | bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 meshBufferID, s32 vertices_Start) |
443 | { | 443 | { |
444 | #ifdef _B3D_READER_DEBUG | 444 | #ifdef _B3D_READER_DEBUG |
445 | core::stringc logStr; | 445 | core::stringc logStr; |
446 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 446 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
447 | logStr += "-"; | 447 | logStr += "-"; |
448 | logStr += "ChunkTRIS"; | 448 | logStr += "ChunkTRIS"; |
449 | os::Printer::log(logStr.c_str()); | 449 | os::Printer::log(logStr.c_str()); |
450 | #endif | 450 | #endif |
451 | 451 | ||
452 | bool showVertexWarning=false; | 452 | bool showVertexWarning=false; |
453 | 453 | ||
454 | s32 triangle_brush_id; // Note: Irrlicht can't have different brushes for each triangle (using a workaround) | 454 | s32 triangle_brush_id; // Note: Irrlicht can't have different brushes for each triangle (using a workaround) |
455 | B3DFile->read(&triangle_brush_id, sizeof(triangle_brush_id)); | 455 | B3DFile->read(&triangle_brush_id, sizeof(triangle_brush_id)); |
456 | #ifdef __BIG_ENDIAN__ | 456 | #ifdef __BIG_ENDIAN__ |
457 | triangle_brush_id = os::Byteswap::byteswap(triangle_brush_id); | 457 | triangle_brush_id = os::Byteswap::byteswap(triangle_brush_id); |
458 | #endif | 458 | #endif |
459 | 459 | ||
460 | SB3dMaterial *B3dMaterial; | 460 | SB3dMaterial *B3dMaterial; |
461 | 461 | ||
462 | if (triangle_brush_id != -1) | 462 | if (triangle_brush_id != -1) |
463 | { | 463 | { |
464 | loadTextures(Materials[triangle_brush_id]); | 464 | loadTextures(Materials[triangle_brush_id]); |
465 | B3dMaterial = &Materials[triangle_brush_id]; | 465 | B3dMaterial = &Materials[triangle_brush_id]; |
466 | meshBuffer->Material = B3dMaterial->Material; | 466 | meshBuffer->Material = B3dMaterial->Material; |
467 | } | 467 | } |
468 | else | 468 | else |
469 | B3dMaterial = 0; | 469 | B3dMaterial = 0; |
470 | 470 | ||
471 | const s32 memoryNeeded = B3dStack.getLast().length / sizeof(s32); | 471 | const s32 memoryNeeded = B3dStack.getLast().length / sizeof(s32); |
472 | meshBuffer->Indices.reallocate(memoryNeeded + meshBuffer->Indices.size() + 1); | 472 | meshBuffer->Indices.reallocate(memoryNeeded + meshBuffer->Indices.size() + 1); |
473 | 473 | ||
474 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats | 474 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats |
475 | { | 475 | { |
476 | s32 vertex_id[3]; | 476 | s32 vertex_id[3]; |
477 | 477 | ||
478 | B3DFile->read(vertex_id, 3*sizeof(s32)); | 478 | B3DFile->read(vertex_id, 3*sizeof(s32)); |
479 | #ifdef __BIG_ENDIAN__ | 479 | #ifdef __BIG_ENDIAN__ |
480 | vertex_id[0] = os::Byteswap::byteswap(vertex_id[0]); | 480 | vertex_id[0] = os::Byteswap::byteswap(vertex_id[0]); |
481 | vertex_id[1] = os::Byteswap::byteswap(vertex_id[1]); | 481 | vertex_id[1] = os::Byteswap::byteswap(vertex_id[1]); |
482 | vertex_id[2] = os::Byteswap::byteswap(vertex_id[2]); | 482 | vertex_id[2] = os::Byteswap::byteswap(vertex_id[2]); |
483 | #endif | 483 | #endif |
484 | 484 | ||
485 | //Make Ids global: | 485 | //Make Ids global: |
486 | vertex_id[0] += vertices_Start; | 486 | vertex_id[0] += vertices_Start; |
487 | vertex_id[1] += vertices_Start; | 487 | vertex_id[1] += vertices_Start; |
488 | vertex_id[2] += vertices_Start; | 488 | vertex_id[2] += vertices_Start; |
489 | 489 | ||
490 | for(s32 i=0; i<3; ++i) | 490 | for(s32 i=0; i<3; ++i) |
491 | { | 491 | { |
492 | if ((u32)vertex_id[i] >= AnimatedVertices_VertexID.size()) | 492 | if ((u32)vertex_id[i] >= AnimatedVertices_VertexID.size()) |
493 | { | 493 | { |
494 | os::Printer::log("Illegal vertex index found", B3DFile->getFileName(), ELL_ERROR); | 494 | os::Printer::log("Illegal vertex index found", B3DFile->getFileName(), ELL_ERROR); |
495 | return false; | 495 | return false; |
496 | } | 496 | } |
497 | 497 | ||
498 | if (AnimatedVertices_VertexID[ vertex_id[i] ] != -1) | 498 | if (AnimatedVertices_VertexID[ vertex_id[i] ] != -1) |
499 | { | 499 | { |
500 | if ( AnimatedVertices_BufferID[ vertex_id[i] ] != (s32)meshBufferID ) //If this vertex is linked in a different meshbuffer | 500 | if ( AnimatedVertices_BufferID[ vertex_id[i] ] != (s32)meshBufferID ) //If this vertex is linked in a different meshbuffer |
501 | { | 501 | { |
502 | AnimatedVertices_VertexID[ vertex_id[i] ] = -1; | 502 | AnimatedVertices_VertexID[ vertex_id[i] ] = -1; |
503 | AnimatedVertices_BufferID[ vertex_id[i] ] = -1; | 503 | AnimatedVertices_BufferID[ vertex_id[i] ] = -1; |
504 | showVertexWarning=true; | 504 | showVertexWarning=true; |
505 | } | 505 | } |
506 | } | 506 | } |
507 | if (AnimatedVertices_VertexID[ vertex_id[i] ] == -1) //If this vertex is not in the meshbuffer | 507 | if (AnimatedVertices_VertexID[ vertex_id[i] ] == -1) //If this vertex is not in the meshbuffer |
508 | { | 508 | { |
509 | //Check for lightmapping: | 509 | //Check for lightmapping: |
510 | if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2df(0.f,0.f)) | 510 | if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2df(0.f,0.f)) |
511 | meshBuffer->convertTo2TCoords(); //Will only affect the meshbuffer the first time this is called | 511 | meshBuffer->convertTo2TCoords(); //Will only affect the meshbuffer the first time this is called |
512 | 512 | ||
513 | //Add the vertex to the meshbuffer: | 513 | //Add the vertex to the meshbuffer: |
514 | if (meshBuffer->VertexType == video::EVT_STANDARD) | 514 | if (meshBuffer->VertexType == video::EVT_STANDARD) |
515 | meshBuffer->Vertices_Standard.push_back( BaseVertices[ vertex_id[i] ] ); | 515 | meshBuffer->Vertices_Standard.push_back( BaseVertices[ vertex_id[i] ] ); |
516 | else | 516 | else |
517 | meshBuffer->Vertices_2TCoords.push_back(BaseVertices[ vertex_id[i] ] ); | 517 | meshBuffer->Vertices_2TCoords.push_back(BaseVertices[ vertex_id[i] ] ); |
518 | 518 | ||
519 | //create vertex id to meshbuffer index link: | 519 | //create vertex id to meshbuffer index link: |
520 | AnimatedVertices_VertexID[ vertex_id[i] ] = meshBuffer->getVertexCount()-1; | 520 | AnimatedVertices_VertexID[ vertex_id[i] ] = meshBuffer->getVertexCount()-1; |
521 | AnimatedVertices_BufferID[ vertex_id[i] ] = meshBufferID; | 521 | AnimatedVertices_BufferID[ vertex_id[i] ] = meshBufferID; |
522 | 522 | ||
523 | if (B3dMaterial) | 523 | if (B3dMaterial) |
524 | { | 524 | { |
525 | // Apply Material/Color/etc... | 525 | // Apply Material/Color/etc... |
526 | video::S3DVertex *Vertex=meshBuffer->getVertex(meshBuffer->getVertexCount()-1); | 526 | video::S3DVertex *Vertex=meshBuffer->getVertex(meshBuffer->getVertexCount()-1); |
527 | 527 | ||
528 | if (!HasVertexColors) | 528 | if (!HasVertexColors) |
529 | Vertex->Color=B3dMaterial->Material.DiffuseColor; | 529 | Vertex->Color=B3dMaterial->Material.DiffuseColor; |
530 | else if (Vertex->Color.getAlpha() == 255) | 530 | else if (Vertex->Color.getAlpha() == 255) |
531 | Vertex->Color.setAlpha( (s32)(B3dMaterial->alpha * 255.0f) ); | 531 | Vertex->Color.setAlpha( (s32)(B3dMaterial->alpha * 255.0f) ); |
532 | 532 | ||
533 | // Use texture's scale | 533 | // Use texture's scale |
534 | if (B3dMaterial->Textures[0]) | 534 | if (B3dMaterial->Textures[0]) |
535 | { | 535 | { |
536 | Vertex->TCoords.X *= B3dMaterial->Textures[0]->Xscale; | 536 | Vertex->TCoords.X *= B3dMaterial->Textures[0]->Xscale; |
537 | Vertex->TCoords.Y *= B3dMaterial->Textures[0]->Yscale; | 537 | Vertex->TCoords.Y *= B3dMaterial->Textures[0]->Yscale; |
538 | } | 538 | } |
539 | /* | 539 | /* |
540 | if (B3dMaterial->Textures[1]) | 540 | if (B3dMaterial->Textures[1]) |
541 | { | 541 | { |
542 | Vertex->TCoords2.X *=B3dMaterial->Textures[1]->Xscale; | 542 | Vertex->TCoords2.X *=B3dMaterial->Textures[1]->Xscale; |
543 | Vertex->TCoords2.Y *=B3dMaterial->Textures[1]->Yscale; | 543 | Vertex->TCoords2.Y *=B3dMaterial->Textures[1]->Yscale; |
544 | } | 544 | } |
545 | */ | 545 | */ |
546 | } | 546 | } |
547 | } | 547 | } |
548 | } | 548 | } |
549 | 549 | ||
550 | meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[0] ] ); | 550 | meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[0] ] ); |
551 | meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[1] ] ); | 551 | meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[1] ] ); |
552 | meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[2] ] ); | 552 | meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[2] ] ); |
553 | } | 553 | } |
554 | 554 | ||
555 | B3dStack.erase(B3dStack.size()-1); | 555 | B3dStack.erase(B3dStack.size()-1); |
556 | 556 | ||
557 | if (showVertexWarning) | 557 | if (showVertexWarning) |
558 | os::Printer::log("B3dMeshLoader: Warning, different meshbuffers linking to the same vertex, this will cause problems with animated meshes"); | 558 | os::Printer::log("B3dMeshLoader: Warning, different meshbuffers linking to the same vertex, this will cause problems with animated meshes"); |
559 | 559 | ||
560 | return true; | 560 | return true; |
561 | } | 561 | } |
562 | 562 | ||
563 | 563 | ||
564 | bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint) | 564 | bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint) |
565 | { | 565 | { |
566 | #ifdef _B3D_READER_DEBUG | 566 | #ifdef _B3D_READER_DEBUG |
567 | core::stringc logStr; | 567 | core::stringc logStr; |
568 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 568 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
569 | logStr += "-"; | 569 | logStr += "-"; |
570 | logStr += "read ChunkBONE"; | 570 | logStr += "read ChunkBONE"; |
571 | os::Printer::log(logStr.c_str()); | 571 | os::Printer::log(logStr.c_str()); |
572 | #endif | 572 | #endif |
573 | 573 | ||
574 | if (B3dStack.getLast().length > 8) | 574 | if (B3dStack.getLast().length > 8) |
575 | { | 575 | { |
576 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats | 576 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats |
577 | { | 577 | { |
578 | u32 globalVertexID; | 578 | u32 globalVertexID; |
579 | f32 strength; | 579 | f32 strength; |
580 | B3DFile->read(&globalVertexID, sizeof(globalVertexID)); | 580 | B3DFile->read(&globalVertexID, sizeof(globalVertexID)); |
581 | B3DFile->read(&strength, sizeof(strength)); | 581 | B3DFile->read(&strength, sizeof(strength)); |
582 | #ifdef __BIG_ENDIAN__ | 582 | #ifdef __BIG_ENDIAN__ |
583 | globalVertexID = os::Byteswap::byteswap(globalVertexID); | 583 | globalVertexID = os::Byteswap::byteswap(globalVertexID); |
584 | strength = os::Byteswap::byteswap(strength); | 584 | strength = os::Byteswap::byteswap(strength); |
585 | #endif | 585 | #endif |
586 | globalVertexID += VerticesStart; | 586 | globalVertexID += VerticesStart; |
587 | 587 | ||
588 | if (AnimatedVertices_VertexID[globalVertexID]==-1) | 588 | if (AnimatedVertices_VertexID[globalVertexID]==-1) |
589 | { | 589 | { |
590 | os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)"); | 590 | os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)"); |
591 | } | 591 | } |
592 | else if (strength >0) | 592 | else if (strength >0) |
593 | { | 593 | { |
594 | CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(inJoint); | 594 | CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(inJoint); |
595 | weight->strength=strength; | 595 | weight->strength=strength; |
596 | //Find the meshbuffer and Vertex index from the Global Vertex ID: | 596 | //Find the meshbuffer and Vertex index from the Global Vertex ID: |
597 | weight->vertex_id = AnimatedVertices_VertexID[globalVertexID]; | 597 | weight->vertex_id = AnimatedVertices_VertexID[globalVertexID]; |
598 | weight->buffer_id = AnimatedVertices_BufferID[globalVertexID]; | 598 | weight->buffer_id = AnimatedVertices_BufferID[globalVertexID]; |
599 | } | 599 | } |
600 | } | 600 | } |
601 | } | 601 | } |
602 | 602 | ||
603 | B3dStack.erase(B3dStack.size()-1); | 603 | B3dStack.erase(B3dStack.size()-1); |
604 | return true; | 604 | return true; |
605 | } | 605 | } |
606 | 606 | ||
607 | 607 | ||
608 | bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint) | 608 | bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint) |
609 | { | 609 | { |
610 | #ifdef _B3D_READER_DEBUG | 610 | #ifdef _B3D_READER_DEBUG |
611 | // Only print first, that's just too much output otherwise | 611 | // Only print first, that's just too much output otherwise |
612 | if ( !inJoint || (inJoint->PositionKeys.empty() && inJoint->ScaleKeys.empty() && inJoint->RotationKeys.empty()) ) | 612 | if ( !inJoint || (inJoint->PositionKeys.empty() && inJoint->ScaleKeys.empty() && inJoint->RotationKeys.empty()) ) |
613 | { | 613 | { |
614 | core::stringc logStr; | 614 | core::stringc logStr; |
615 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 615 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
616 | logStr += "-"; | 616 | logStr += "-"; |
617 | logStr += "read ChunkKEYS"; | 617 | logStr += "read ChunkKEYS"; |
618 | os::Printer::log(logStr.c_str()); | 618 | os::Printer::log(logStr.c_str()); |
619 | } | 619 | } |
620 | #endif | 620 | #endif |
621 | 621 | ||
622 | s32 flags; | 622 | s32 flags; |
623 | B3DFile->read(&flags, sizeof(flags)); | 623 | B3DFile->read(&flags, sizeof(flags)); |
624 | #ifdef __BIG_ENDIAN__ | 624 | #ifdef __BIG_ENDIAN__ |
625 | flags = os::Byteswap::byteswap(flags); | 625 | flags = os::Byteswap::byteswap(flags); |
626 | #endif | 626 | #endif |
627 | 627 | ||
628 | CSkinnedMesh::SPositionKey *oldPosKey=0; | 628 | CSkinnedMesh::SPositionKey *oldPosKey=0; |
629 | core::vector3df oldPos[2]; | 629 | core::vector3df oldPos[2]; |
630 | CSkinnedMesh::SScaleKey *oldScaleKey=0; | 630 | CSkinnedMesh::SScaleKey *oldScaleKey=0; |
631 | core::vector3df oldScale[2]; | 631 | core::vector3df oldScale[2]; |
632 | CSkinnedMesh::SRotationKey *oldRotKey=0; | 632 | CSkinnedMesh::SRotationKey *oldRotKey=0; |
633 | core::quaternion oldRot[2]; | 633 | core::quaternion oldRot[2]; |
634 | bool isFirst[3]={true,true,true}; | 634 | bool isFirst[3]={true,true,true}; |
635 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats | 635 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats |
636 | { | 636 | { |
637 | s32 frame; | 637 | s32 frame; |
638 | 638 | ||
639 | B3DFile->read(&frame, sizeof(frame)); | 639 | B3DFile->read(&frame, sizeof(frame)); |
640 | #ifdef __BIG_ENDIAN__ | 640 | #ifdef __BIG_ENDIAN__ |
641 | frame = os::Byteswap::byteswap(frame); | 641 | frame = os::Byteswap::byteswap(frame); |
642 | #endif | 642 | #endif |
643 | 643 | ||
644 | // Add key frames, frames in Irrlicht are zero-based | 644 | // Add key frames, frames in Irrlicht are zero-based |
645 | f32 data[4]; | 645 | f32 data[4]; |
646 | if (flags & 1) | 646 | if (flags & 1) |
647 | { | 647 | { |
648 | readFloats(data, 3); | 648 | readFloats(data, 3); |
649 | if ((oldPosKey!=0) && (oldPos[0]==oldPos[1])) | 649 | if ((oldPosKey!=0) && (oldPos[0]==oldPos[1])) |
650 | { | 650 | { |
651 | const core::vector3df pos(data[0], data[1], data[2]); | 651 | const core::vector3df pos(data[0], data[1], data[2]); |
652 | if (oldPos[1]==pos) | 652 | if (oldPos[1]==pos) |
653 | oldPosKey->frame = (f32)frame-1; | 653 | oldPosKey->frame = (f32)frame-1; |
654 | else | 654 | else |
655 | { | 655 | { |
656 | oldPos[0]=oldPos[1]; | 656 | oldPos[0]=oldPos[1]; |
657 | oldPosKey=AnimatedMesh->addPositionKey(inJoint); | 657 | oldPosKey=AnimatedMesh->addPositionKey(inJoint); |
658 | oldPosKey->frame = (f32)frame-1; | 658 | oldPosKey->frame = (f32)frame-1; |
659 | oldPos[1].set(oldPosKey->position.set(pos)); | 659 | oldPos[1].set(oldPosKey->position.set(pos)); |
660 | } | 660 | } |
661 | } | 661 | } |
662 | else if (oldPosKey==0 && isFirst[0]) | 662 | else if (oldPosKey==0 && isFirst[0]) |
663 | { | 663 | { |
664 | oldPosKey=AnimatedMesh->addPositionKey(inJoint); | 664 | oldPosKey=AnimatedMesh->addPositionKey(inJoint); |
665 | oldPosKey->frame = (f32)frame-1; | 665 | oldPosKey->frame = (f32)frame-1; |
666 | oldPos[0].set(oldPosKey->position.set(data[0], data[1], data[2])); | 666 | oldPos[0].set(oldPosKey->position.set(data[0], data[1], data[2])); |
667 | oldPosKey=0; | 667 | oldPosKey=0; |
668 | isFirst[0]=false; | 668 | isFirst[0]=false; |
669 | } | 669 | } |
670 | else | 670 | else |
671 | { | 671 | { |
672 | if (oldPosKey!=0) | 672 | if (oldPosKey!=0) |
673 | oldPos[0]=oldPos[1]; | 673 | oldPos[0]=oldPos[1]; |
674 | oldPosKey=AnimatedMesh->addPositionKey(inJoint); | 674 | oldPosKey=AnimatedMesh->addPositionKey(inJoint); |
675 | oldPosKey->frame = (f32)frame-1; | 675 | oldPosKey->frame = (f32)frame-1; |
676 | oldPos[1].set(oldPosKey->position.set(data[0], data[1], data[2])); | 676 | oldPos[1].set(oldPosKey->position.set(data[0], data[1], data[2])); |
677 | } | 677 | } |
678 | } | 678 | } |
679 | if (flags & 2) | 679 | if (flags & 2) |
680 | { | 680 | { |
681 | readFloats(data, 3); | 681 | readFloats(data, 3); |
682 | if ((oldScaleKey!=0) && (oldScale[0]==oldScale[1])) | 682 | if ((oldScaleKey!=0) && (oldScale[0]==oldScale[1])) |
683 | { | 683 | { |
684 | const core::vector3df scale(data[0], data[1], data[2]); | 684 | const core::vector3df scale(data[0], data[1], data[2]); |
685 | if (oldScale[1]==scale) | 685 | if (oldScale[1]==scale) |
686 | oldScaleKey->frame = (f32)frame-1; | 686 | oldScaleKey->frame = (f32)frame-1; |
687 | else | 687 | else |
688 | { | 688 | { |
689 | oldScale[0]=oldScale[1]; | 689 | oldScale[0]=oldScale[1]; |
690 | oldScaleKey=AnimatedMesh->addScaleKey(inJoint); | 690 | oldScaleKey=AnimatedMesh->addScaleKey(inJoint); |
691 | oldScaleKey->frame = (f32)frame-1; | 691 | oldScaleKey->frame = (f32)frame-1; |
692 | oldScale[1].set(oldScaleKey->scale.set(scale)); | 692 | oldScale[1].set(oldScaleKey->scale.set(scale)); |
693 | } | 693 | } |
694 | } | 694 | } |
695 | else if (oldScaleKey==0 && isFirst[1]) | 695 | else if (oldScaleKey==0 && isFirst[1]) |
696 | { | 696 | { |
697 | oldScaleKey=AnimatedMesh->addScaleKey(inJoint); | 697 | oldScaleKey=AnimatedMesh->addScaleKey(inJoint); |
698 | oldScaleKey->frame = (f32)frame-1; | 698 | oldScaleKey->frame = (f32)frame-1; |
699 | oldScale[0].set(oldScaleKey->scale.set(data[0], data[1], data[2])); | 699 | oldScale[0].set(oldScaleKey->scale.set(data[0], data[1], data[2])); |
700 | oldScaleKey=0; | 700 | oldScaleKey=0; |
701 | isFirst[1]=false; | 701 | isFirst[1]=false; |
702 | } | 702 | } |
703 | else | 703 | else |
704 | { | 704 | { |
705 | if (oldScaleKey!=0) | 705 | if (oldScaleKey!=0) |
706 | oldScale[0]=oldScale[1]; | 706 | oldScale[0]=oldScale[1]; |
707 | oldScaleKey=AnimatedMesh->addScaleKey(inJoint); | 707 | oldScaleKey=AnimatedMesh->addScaleKey(inJoint); |
708 | oldScaleKey->frame = (f32)frame-1; | 708 | oldScaleKey->frame = (f32)frame-1; |
709 | oldScale[1].set(oldScaleKey->scale.set(data[0], data[1], data[2])); | 709 | oldScale[1].set(oldScaleKey->scale.set(data[0], data[1], data[2])); |
710 | } | 710 | } |
711 | } | 711 | } |
712 | if (flags & 4) | 712 | if (flags & 4) |
713 | { | 713 | { |
714 | readFloats(data, 4); | 714 | readFloats(data, 4); |
715 | if ((oldRotKey!=0) && (oldRot[0]==oldRot[1])) | 715 | if ((oldRotKey!=0) && (oldRot[0]==oldRot[1])) |
716 | { | 716 | { |
717 | // meant to be in this order since b3d stores W first | 717 | // meant to be in this order since b3d stores W first |
718 | const core::quaternion rot(data[1], data[2], data[3], data[0]); | 718 | const core::quaternion rot(data[1], data[2], data[3], data[0]); |
719 | if (oldRot[1]==rot) | 719 | if (oldRot[1]==rot) |
720 | oldRotKey->frame = (f32)frame-1; | 720 | oldRotKey->frame = (f32)frame-1; |
721 | else | 721 | else |
722 | { | 722 | { |
723 | oldRot[0]=oldRot[1]; | 723 | oldRot[0]=oldRot[1]; |
724 | oldRotKey=AnimatedMesh->addRotationKey(inJoint); | 724 | oldRotKey=AnimatedMesh->addRotationKey(inJoint); |
725 | oldRotKey->frame = (f32)frame-1; | 725 | oldRotKey->frame = (f32)frame-1; |
726 | oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); | 726 | oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); |
727 | } | 727 | } |
728 | } | 728 | } |
729 | else if (oldRotKey==0 && isFirst[2]) | 729 | else if (oldRotKey==0 && isFirst[2]) |
730 | { | 730 | { |
731 | oldRotKey=AnimatedMesh->addRotationKey(inJoint); | 731 | oldRotKey=AnimatedMesh->addRotationKey(inJoint); |
732 | oldRotKey->frame = (f32)frame-1; | 732 | oldRotKey->frame = (f32)frame-1; |
733 | // meant to be in this order since b3d stores W first | 733 | // meant to be in this order since b3d stores W first |
734 | oldRot[0].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); | 734 | oldRot[0].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); |
735 | oldRotKey=0; | 735 | oldRotKey=0; |
736 | isFirst[2]=false; | 736 | isFirst[2]=false; |
737 | } | 737 | } |
738 | else | 738 | else |
739 | { | 739 | { |
740 | if (oldRotKey!=0) | 740 | if (oldRotKey!=0) |
741 | oldRot[0]=oldRot[1]; | 741 | oldRot[0]=oldRot[1]; |
742 | oldRotKey=AnimatedMesh->addRotationKey(inJoint); | 742 | oldRotKey=AnimatedMesh->addRotationKey(inJoint); |
743 | oldRotKey->frame = (f32)frame-1; | 743 | oldRotKey->frame = (f32)frame-1; |
744 | // meant to be in this order since b3d stores W first | 744 | // meant to be in this order since b3d stores W first |
745 | oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); | 745 | oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); |
746 | } | 746 | } |
747 | } | 747 | } |
748 | } | 748 | } |
749 | 749 | ||
750 | B3dStack.erase(B3dStack.size()-1); | 750 | B3dStack.erase(B3dStack.size()-1); |
751 | return true; | 751 | return true; |
752 | } | 752 | } |
753 | 753 | ||
754 | 754 | ||
755 | bool CB3DMeshFileLoader::readChunkANIM() | 755 | bool CB3DMeshFileLoader::readChunkANIM() |
756 | { | 756 | { |
757 | #ifdef _B3D_READER_DEBUG | 757 | #ifdef _B3D_READER_DEBUG |
758 | core::stringc logStr; | 758 | core::stringc logStr; |
759 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 759 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
760 | logStr += "-"; | 760 | logStr += "-"; |
761 | logStr += "read ChunkANIM"; | 761 | logStr += "read ChunkANIM"; |
762 | os::Printer::log(logStr.c_str()); | 762 | os::Printer::log(logStr.c_str()); |
763 | #endif | 763 | #endif |
764 | 764 | ||
765 | s32 animFlags; //not stored\used | 765 | s32 animFlags; //not stored\used |
766 | s32 animFrames;//not stored\used | 766 | s32 animFrames;//not stored\used |
767 | f32 animFPS; //not stored\used | 767 | f32 animFPS; //not stored\used |
768 | 768 | ||
769 | B3DFile->read(&animFlags, sizeof(s32)); | 769 | B3DFile->read(&animFlags, sizeof(s32)); |
770 | B3DFile->read(&animFrames, sizeof(s32)); | 770 | B3DFile->read(&animFrames, sizeof(s32)); |
771 | readFloats(&animFPS, 1); | 771 | readFloats(&animFPS, 1); |
772 | if (animFPS>0.f) | 772 | if (animFPS>0.f) |
773 | AnimatedMesh->setAnimationSpeed(animFPS); | 773 | AnimatedMesh->setAnimationSpeed(animFPS); |
774 | os::Printer::log("FPS", io::path((double)animFPS), ELL_DEBUG); | 774 | os::Printer::log("FPS", io::path((double)animFPS), ELL_DEBUG); |
775 | 775 | ||
776 | #ifdef __BIG_ENDIAN__ | 776 | #ifdef __BIG_ENDIAN__ |
777 | animFlags = os::Byteswap::byteswap(animFlags); | 777 | animFlags = os::Byteswap::byteswap(animFlags); |
778 | animFrames = os::Byteswap::byteswap(animFrames); | 778 | animFrames = os::Byteswap::byteswap(animFrames); |
779 | #endif | 779 | #endif |
780 | 780 | ||
781 | B3dStack.erase(B3dStack.size()-1); | 781 | B3dStack.erase(B3dStack.size()-1); |
782 | return true; | 782 | return true; |
783 | } | 783 | } |
784 | 784 | ||
785 | 785 | ||
786 | bool CB3DMeshFileLoader::readChunkTEXS() | 786 | bool CB3DMeshFileLoader::readChunkTEXS() |
787 | { | 787 | { |
788 | #ifdef _B3D_READER_DEBUG | 788 | #ifdef _B3D_READER_DEBUG |
789 | core::stringc logStr; | 789 | core::stringc logStr; |
790 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 790 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
791 | logStr += "-"; | 791 | logStr += "-"; |
792 | logStr += "read ChunkTEXS"; | 792 | logStr += "read ChunkTEXS"; |
793 | os::Printer::log(logStr.c_str()); | 793 | os::Printer::log(logStr.c_str()); |
794 | #endif | 794 | #endif |
795 | 795 | ||
796 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats | 796 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats |
797 | { | 797 | { |
798 | Textures.push_back(SB3dTexture()); | 798 | Textures.push_back(SB3dTexture()); |
799 | SB3dTexture& B3dTexture = Textures.getLast(); | 799 | SB3dTexture& B3dTexture = Textures.getLast(); |
800 | 800 | ||
801 | readString(B3dTexture.TextureName); | 801 | readString(B3dTexture.TextureName); |
802 | B3dTexture.TextureName.replace('\\','/'); | 802 | B3dTexture.TextureName.replace('\\','/'); |
803 | #ifdef _B3D_READER_DEBUG | 803 | #ifdef _B3D_READER_DEBUG |
804 | os::Printer::log("read Texture", B3dTexture.TextureName.c_str()); | 804 | os::Printer::log("read Texture", B3dTexture.TextureName.c_str()); |
805 | #endif | 805 | #endif |
806 | 806 | ||
807 | B3DFile->read(&B3dTexture.Flags, sizeof(s32)); | 807 | B3DFile->read(&B3dTexture.Flags, sizeof(s32)); |
808 | B3DFile->read(&B3dTexture.Blend, sizeof(s32)); | 808 | B3DFile->read(&B3dTexture.Blend, sizeof(s32)); |
809 | #ifdef __BIG_ENDIAN__ | 809 | #ifdef __BIG_ENDIAN__ |
810 | B3dTexture.Flags = os::Byteswap::byteswap(B3dTexture.Flags); | 810 | B3dTexture.Flags = os::Byteswap::byteswap(B3dTexture.Flags); |
811 | B3dTexture.Blend = os::Byteswap::byteswap(B3dTexture.Blend); | 811 | B3dTexture.Blend = os::Byteswap::byteswap(B3dTexture.Blend); |
812 | #endif | 812 | #endif |
813 | #ifdef _B3D_READER_DEBUG | 813 | #ifdef _B3D_READER_DEBUG |
814 | os::Printer::log("Flags", core::stringc(B3dTexture.Flags).c_str()); | 814 | os::Printer::log("Flags", core::stringc(B3dTexture.Flags).c_str()); |
815 | os::Printer::log("Blend", core::stringc(B3dTexture.Blend).c_str()); | 815 | os::Printer::log("Blend", core::stringc(B3dTexture.Blend).c_str()); |
816 | #endif | 816 | #endif |
817 | readFloats(&B3dTexture.Xpos, 1); | 817 | readFloats(&B3dTexture.Xpos, 1); |
818 | readFloats(&B3dTexture.Ypos, 1); | 818 | readFloats(&B3dTexture.Ypos, 1); |
819 | readFloats(&B3dTexture.Xscale, 1); | 819 | readFloats(&B3dTexture.Xscale, 1); |
820 | readFloats(&B3dTexture.Yscale, 1); | 820 | readFloats(&B3dTexture.Yscale, 1); |
821 | readFloats(&B3dTexture.Angle, 1); | 821 | readFloats(&B3dTexture.Angle, 1); |
822 | } | 822 | } |
823 | 823 | ||
824 | B3dStack.erase(B3dStack.size()-1); | 824 | B3dStack.erase(B3dStack.size()-1); |
825 | 825 | ||
826 | return true; | 826 | return true; |
827 | } | 827 | } |
828 | 828 | ||
829 | 829 | ||
830 | bool CB3DMeshFileLoader::readChunkBRUS() | 830 | bool CB3DMeshFileLoader::readChunkBRUS() |
831 | { | 831 | { |
832 | #ifdef _B3D_READER_DEBUG | 832 | #ifdef _B3D_READER_DEBUG |
833 | core::stringc logStr; | 833 | core::stringc logStr; |
834 | for ( u32 i=1; i < B3dStack.size(); ++i ) | 834 | for ( u32 i=1; i < B3dStack.size(); ++i ) |
835 | logStr += "-"; | 835 | logStr += "-"; |
836 | logStr += "read ChunkBRUS"; | 836 | logStr += "read ChunkBRUS"; |
837 | os::Printer::log(logStr.c_str()); | 837 | os::Printer::log(logStr.c_str()); |
838 | #endif | 838 | #endif |
839 | 839 | ||
840 | u32 n_texs; | 840 | u32 n_texs; |
841 | B3DFile->read(&n_texs, sizeof(u32)); | 841 | B3DFile->read(&n_texs, sizeof(u32)); |
842 | #ifdef __BIG_ENDIAN__ | 842 | #ifdef __BIG_ENDIAN__ |
843 | n_texs = os::Byteswap::byteswap(n_texs); | 843 | n_texs = os::Byteswap::byteswap(n_texs); |
844 | #endif | 844 | #endif |
845 | 845 | ||
846 | // number of texture ids read for Irrlicht | 846 | // number of texture ids read for Irrlicht |
847 | const u32 num_textures = core::min_(n_texs, video::MATERIAL_MAX_TEXTURES); | 847 | const u32 num_textures = core::min_(n_texs, video::MATERIAL_MAX_TEXTURES); |
848 | // number of bytes to skip (for ignored texture ids) | 848 | // number of bytes to skip (for ignored texture ids) |
849 | const u32 n_texs_offset = (num_textures<n_texs)?(n_texs-num_textures):0; | 849 | const u32 n_texs_offset = (num_textures<n_texs)?(n_texs-num_textures):0; |
850 | 850 | ||
851 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats | 851 | while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats |
852 | { | 852 | { |
853 | // This is what blitz basic calls a brush, like a Irrlicht Material | 853 | // This is what blitz basic calls a brush, like a Irrlicht Material |
854 | 854 | ||
855 | core::stringc name; | 855 | core::stringc name; |
856 | readString(name); | 856 | readString(name); |
857 | #ifdef _B3D_READER_DEBUG | 857 | #ifdef _B3D_READER_DEBUG |
858 | os::Printer::log("read Material", name); | 858 | os::Printer::log("read Material", name); |
859 | #endif | 859 | #endif |
860 | Materials.push_back(SB3dMaterial()); | 860 | Materials.push_back(SB3dMaterial()); |
861 | SB3dMaterial& B3dMaterial=Materials.getLast(); | 861 | SB3dMaterial& B3dMaterial=Materials.getLast(); |
862 | 862 | ||
863 | readFloats(&B3dMaterial.red, 1); | 863 | readFloats(&B3dMaterial.red, 1); |
864 | readFloats(&B3dMaterial.green, 1); | 864 | readFloats(&B3dMaterial.green, 1); |
865 | readFloats(&B3dMaterial.blue, 1); | 865 | readFloats(&B3dMaterial.blue, 1); |
866 | readFloats(&B3dMaterial.alpha, 1); | 866 | readFloats(&B3dMaterial.alpha, 1); |
867 | readFloats(&B3dMaterial.shininess, 1); | 867 | readFloats(&B3dMaterial.shininess, 1); |
868 | 868 | ||
869 | B3DFile->read(&B3dMaterial.blend, sizeof(B3dMaterial.blend)); | 869 | B3DFile->read(&B3dMaterial.blend, sizeof(B3dMaterial.blend)); |
870 | B3DFile->read(&B3dMaterial.fx, sizeof(B3dMaterial.fx)); | 870 | B3DFile->read(&B3dMaterial.fx, sizeof(B3dMaterial.fx)); |
871 | #ifdef __BIG_ENDIAN__ | 871 | #ifdef __BIG_ENDIAN__ |
872 | B3dMaterial.blend = os::Byteswap::byteswap(B3dMaterial.blend); | 872 | B3dMaterial.blend = os::Byteswap::byteswap(B3dMaterial.blend); |
873 | B3dMaterial.fx = os::Byteswap::byteswap(B3dMaterial.fx); | 873 | B3dMaterial.fx = os::Byteswap::byteswap(B3dMaterial.fx); |
874 | #endif | 874 | #endif |
875 | #ifdef _B3D_READER_DEBUG | 875 | #ifdef _B3D_READER_DEBUG |
876 | os::Printer::log("Blend", core::stringc(B3dMaterial.blend).c_str()); | 876 | os::Printer::log("Blend", core::stringc(B3dMaterial.blend).c_str()); |
877 | os::Printer::log("FX", core::stringc(B3dMaterial.fx).c_str()); | 877 | os::Printer::log("FX", core::stringc(B3dMaterial.fx).c_str()); |
878 | #endif | 878 | #endif |
879 | 879 | ||
880 | u32 i; | 880 | u32 i; |
881 | for (i=0; i<num_textures; ++i) | 881 | for (i=0; i<num_textures; ++i) |
882 | { | 882 | { |
883 | s32 texture_id=-1; | 883 | s32 texture_id=-1; |
884 | B3DFile->read(&texture_id, sizeof(s32)); | 884 | B3DFile->read(&texture_id, sizeof(s32)); |
885 | #ifdef __BIG_ENDIAN__ | 885 | #ifdef __BIG_ENDIAN__ |
886 | texture_id = os::Byteswap::byteswap(texture_id); | 886 | texture_id = os::Byteswap::byteswap(texture_id); |
887 | #endif | 887 | #endif |
888 | //--- Get pointers to the texture, based on the IDs --- | 888 | //--- Get pointers to the texture, based on the IDs --- |
889 | if ((u32)texture_id < Textures.size()) | 889 | if ((u32)texture_id < Textures.size()) |
890 | { | 890 | { |
891 | B3dMaterial.Textures[i]=&Textures[texture_id]; | 891 | B3dMaterial.Textures[i]=&Textures[texture_id]; |
892 | #ifdef _B3D_READER_DEBUG | 892 | #ifdef _B3D_READER_DEBUG |
893 | os::Printer::log("Layer", core::stringc(i).c_str()); | 893 | os::Printer::log("Layer", core::stringc(i).c_str()); |
894 | os::Printer::log("using texture", Textures[texture_id].TextureName.c_str()); | 894 | os::Printer::log("using texture", Textures[texture_id].TextureName.c_str()); |
895 | #endif | 895 | #endif |
896 | } | 896 | } |
897 | else | 897 | else |
898 | B3dMaterial.Textures[i]=0; | 898 | B3dMaterial.Textures[i]=0; |
899 | } | 899 | } |
900 | // skip other texture ids | 900 | // skip other texture ids |
901 | for (i=0; i<n_texs_offset; ++i) | 901 | for (i=0; i<n_texs_offset; ++i) |
902 | { | 902 | { |
903 | s32 texture_id=-1; | 903 | s32 texture_id=-1; |
904 | B3DFile->read(&texture_id, sizeof(s32)); | 904 | B3DFile->read(&texture_id, sizeof(s32)); |
905 | #ifdef __BIG_ENDIAN__ | 905 | #ifdef __BIG_ENDIAN__ |
906 | texture_id = os::Byteswap::byteswap(texture_id); | 906 | texture_id = os::Byteswap::byteswap(texture_id); |
907 | #endif | 907 | #endif |
908 | if (ShowWarning && (texture_id != -1) && (n_texs>video::MATERIAL_MAX_TEXTURES)) | 908 | if (ShowWarning && (texture_id != -1) && (n_texs>video::MATERIAL_MAX_TEXTURES)) |
909 | { | 909 | { |
910 | os::Printer::log("Too many textures used in one material", B3DFile->getFileName(), ELL_WARNING); | 910 | os::Printer::log("Too many textures used in one material", B3DFile->getFileName(), ELL_WARNING); |
911 | ShowWarning = false; | 911 | ShowWarning = false; |
912 | } | 912 | } |
913 | } | 913 | } |
914 | 914 | ||
915 | //Fixes problems when the lightmap is on the first texture: | 915 | //Fixes problems when the lightmap is on the first texture: |
916 | if (B3dMaterial.Textures[0] != 0) | 916 | if (B3dMaterial.Textures[0] != 0) |
917 | { | 917 | { |
918 | if (B3dMaterial.Textures[0]->Flags & 65536) // 65536 = secondary UV | 918 | if (B3dMaterial.Textures[0]->Flags & 65536) // 65536 = secondary UV |
919 | { | 919 | { |
920 | SB3dTexture *TmpTexture; | 920 | SB3dTexture *TmpTexture; |
921 | TmpTexture = B3dMaterial.Textures[1]; | 921 | TmpTexture = B3dMaterial.Textures[1]; |
922 | B3dMaterial.Textures[1] = B3dMaterial.Textures[0]; | 922 | B3dMaterial.Textures[1] = B3dMaterial.Textures[0]; |
923 | B3dMaterial.Textures[0] = TmpTexture; | 923 | B3dMaterial.Textures[0] = TmpTexture; |
924 | } | 924 | } |
925 | } | 925 | } |
926 | 926 | ||
927 | //If a preceeding texture slot is empty move the others down: | 927 | //If a preceeding texture slot is empty move the others down: |
928 | for (i=num_textures; i>0; --i) | 928 | for (i=num_textures; i>0; --i) |
929 | { | 929 | { |
930 | for (u32 j=i-1; j<num_textures-1; ++j) | 930 | for (u32 j=i-1; j<num_textures-1; ++j) |
931 | { | 931 | { |
932 | if (B3dMaterial.Textures[j+1] != 0 && B3dMaterial.Textures[j] == 0) | 932 | if (B3dMaterial.Textures[j+1] != 0 && B3dMaterial.Textures[j] == 0) |
933 | { | 933 | { |
934 | B3dMaterial.Textures[j] = B3dMaterial.Textures[j+1]; | 934 | B3dMaterial.Textures[j] = B3dMaterial.Textures[j+1]; |
935 | B3dMaterial.Textures[j+1] = 0; | 935 | B3dMaterial.Textures[j+1] = 0; |
936 | } | 936 | } |
937 | } | 937 | } |
938 | } | 938 | } |
939 | 939 | ||
940 | //------ Convert blitz flags/blend to irrlicht ------- | 940 | //------ Convert blitz flags/blend to irrlicht ------- |
941 | 941 | ||
942 | //Two textures: | 942 | //Two textures: |
943 | if (B3dMaterial.Textures[1]) | 943 | if (B3dMaterial.Textures[1]) |
944 | { | 944 | { |
945 | if (B3dMaterial.alpha==1.f) | 945 | if (B3dMaterial.alpha==1.f) |
946 | { | 946 | { |
947 | if (B3dMaterial.Textures[1]->Blend == 5) //(Multiply 2) | 947 | if (B3dMaterial.Textures[1]->Blend == 5) //(Multiply 2) |
948 | B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP_M2; | 948 | B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP_M2; |
949 | else | 949 | else |
950 | B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP; | 950 | B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP; |
951 | B3dMaterial.Material.Lighting = false; | 951 | B3dMaterial.Material.Lighting = false; |
952 | } | 952 | } |
953 | else | 953 | else |
954 | { | 954 | { |
955 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; | 955 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; |
956 | B3dMaterial.Material.ZWriteEnable = false; | 956 | B3dMaterial.Material.ZWriteEnable = false; |
957 | } | 957 | } |
958 | } | 958 | } |
959 | else if (B3dMaterial.Textures[0]) //One texture: | 959 | else if (B3dMaterial.Textures[0]) //One texture: |
960 | { | 960 | { |
961 | // Flags & 0x1 is usual SOLID, 0x8 is mipmap (handled before) | 961 | // Flags & 0x1 is usual SOLID, 0x8 is mipmap (handled before) |
962 | if (B3dMaterial.Textures[0]->Flags & 0x2) //(Alpha mapped) | 962 | if (B3dMaterial.Textures[0]->Flags & 0x2) //(Alpha mapped) |
963 | { | 963 | { |
964 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; | 964 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; |
965 | B3dMaterial.Material.ZWriteEnable = false; | 965 | B3dMaterial.Material.ZWriteEnable = false; |
966 | } | 966 | } |
967 | else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked) | 967 | else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked) |
968 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture | 968 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture |
969 | else if (B3dMaterial.Textures[0]->Flags & 0x40) | 969 | else if (B3dMaterial.Textures[0]->Flags & 0x40) |
970 | B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; | 970 | B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; |
971 | else if (B3dMaterial.Textures[0]->Flags & 0x80) | 971 | else if (B3dMaterial.Textures[0]->Flags & 0x80) |
972 | B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; // TODO: Should be cube map | 972 | B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; // TODO: Should be cube map |
973 | else if (B3dMaterial.alpha == 1.f) | 973 | else if (B3dMaterial.alpha == 1.f) |
974 | B3dMaterial.Material.MaterialType = video::EMT_SOLID; | 974 | B3dMaterial.Material.MaterialType = video::EMT_SOLID; |
975 | else | 975 | else |
976 | { | 976 | { |
977 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; | 977 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; |
978 | B3dMaterial.Material.ZWriteEnable = false; | 978 | B3dMaterial.Material.ZWriteEnable = false; |
979 | } | 979 | } |
980 | } | 980 | } |
981 | else //No texture: | 981 | else //No texture: |
982 | { | 982 | { |
983 | if (B3dMaterial.alpha == 1.f) | 983 | if (B3dMaterial.alpha == 1.f) |
984 | B3dMaterial.Material.MaterialType = video::EMT_SOLID; | 984 | B3dMaterial.Material.MaterialType = video::EMT_SOLID; |
985 | else | 985 | else |
986 | { | 986 | { |
987 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; | 987 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; |
988 | B3dMaterial.Material.ZWriteEnable = false; | 988 | B3dMaterial.Material.ZWriteEnable = false; |
989 | } | 989 | } |
990 | } | 990 | } |
991 | 991 | ||
992 | B3dMaterial.Material.DiffuseColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor(); | 992 | B3dMaterial.Material.DiffuseColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor(); |
993 | B3dMaterial.Material.ColorMaterial=video::ECM_NONE; | 993 | B3dMaterial.Material.ColorMaterial=video::ECM_NONE; |
994 | 994 | ||
995 | //------ Material fx ------ | 995 | //------ Material fx ------ |
996 | 996 | ||
997 | if (B3dMaterial.fx & 1) //full-bright | 997 | if (B3dMaterial.fx & 1) //full-bright |
998 | { | 998 | { |
999 | B3dMaterial.Material.AmbientColor = video::SColor(255, 255, 255, 255); | 999 | B3dMaterial.Material.AmbientColor = video::SColor(255, 255, 255, 255); |
1000 | B3dMaterial.Material.Lighting = false; | 1000 | B3dMaterial.Material.Lighting = false; |
1001 | } | 1001 | } |
1002 | else | 1002 | else |
1003 | B3dMaterial.Material.AmbientColor = B3dMaterial.Material.DiffuseColor; | 1003 | B3dMaterial.Material.AmbientColor = B3dMaterial.Material.DiffuseColor; |
1004 | 1004 | ||
1005 | if (B3dMaterial.fx & 2) //use vertex colors instead of brush color | 1005 | if (B3dMaterial.fx & 2) //use vertex colors instead of brush color |
1006 | B3dMaterial.Material.ColorMaterial=video::ECM_DIFFUSE_AND_AMBIENT; | 1006 | B3dMaterial.Material.ColorMaterial=video::ECM_DIFFUSE_AND_AMBIENT; |
1007 | 1007 | ||
1008 | if (B3dMaterial.fx & 4) //flatshaded | 1008 | if (B3dMaterial.fx & 4) //flatshaded |
1009 | B3dMaterial.Material.GouraudShading = false; | 1009 | B3dMaterial.Material.GouraudShading = false; |
1010 | 1010 | ||
1011 | if (B3dMaterial.fx & 16) //disable backface culling | 1011 | if (B3dMaterial.fx & 16) //disable backface culling |
1012 | B3dMaterial.Material.BackfaceCulling = false; | 1012 | B3dMaterial.Material.BackfaceCulling = false; |
1013 | 1013 | ||
1014 | if (B3dMaterial.fx & 32) //force vertex alpha-blending | 1014 | if (B3dMaterial.fx & 32) //force vertex alpha-blending |
1015 | { | 1015 | { |
1016 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; | 1016 | B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; |
1017 | B3dMaterial.Material.ZWriteEnable = false; | 1017 | B3dMaterial.Material.ZWriteEnable = false; |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | B3dMaterial.Material.Shininess = B3dMaterial.shininess; | 1020 | B3dMaterial.Material.Shininess = B3dMaterial.shininess; |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | B3dStack.erase(B3dStack.size()-1); | 1023 | B3dStack.erase(B3dStack.size()-1); |
1024 | 1024 | ||
1025 | return true; | 1025 | return true; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | 1028 | ||
1029 | void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const | 1029 | void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const |
1030 | { | 1030 | { |
1031 | const bool previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT); | 1031 | const bool previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT); |
1032 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true); | 1032 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true); |
1033 | 1033 | ||
1034 | // read texture from disk | 1034 | // read texture from disk |
1035 | // note that mipmaps might be disabled by Flags & 0x8 | 1035 | // note that mipmaps might be disabled by Flags & 0x8 |
1036 | const bool doMipMaps = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); | 1036 | const bool doMipMaps = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); |
1037 | 1037 | ||
1038 | for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) | 1038 | for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) |
1039 | { | 1039 | { |
1040 | SB3dTexture* B3dTexture = material.Textures[i]; | 1040 | SB3dTexture* B3dTexture = material.Textures[i]; |
1041 | if (B3dTexture && B3dTexture->TextureName.size() && !material.Material.getTexture(i)) | 1041 | if (B3dTexture && B3dTexture->TextureName.size() && !material.Material.getTexture(i)) |
1042 | { | 1042 | { |
1043 | if (!SceneManager->getParameters()->getAttributeAsBool(B3D_LOADER_IGNORE_MIPMAP_FLAG)) | 1043 | if (!SceneManager->getParameters()->getAttributeAsBool(B3D_LOADER_IGNORE_MIPMAP_FLAG)) |
1044 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, (B3dTexture->Flags & 0x8) ? true:false); | 1044 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, (B3dTexture->Flags & 0x8) ? true:false); |
1045 | { | 1045 | { |
1046 | video::ITexture* tex = 0; | 1046 | video::ITexture* tex = 0; |
1047 | io::IFileSystem* fs = SceneManager->getFileSystem(); | 1047 | io::IFileSystem* fs = SceneManager->getFileSystem(); |
1048 | io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) ); | 1048 | io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) ); |
1049 | if ( texnameWithUserPath.size() ) | 1049 | if ( texnameWithUserPath.size() ) |
1050 | { | 1050 | { |
1051 | texnameWithUserPath += '/'; | 1051 | texnameWithUserPath += '/'; |
1052 | texnameWithUserPath += B3dTexture->TextureName; | 1052 | texnameWithUserPath += B3dTexture->TextureName; |
1053 | } | 1053 | } |
1054 | if (fs->existFile(texnameWithUserPath)) | 1054 | if (fs->existFile(texnameWithUserPath)) |
1055 | tex = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath); | 1055 | tex = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath); |
1056 | else if (fs->existFile(B3dTexture->TextureName)) | 1056 | else if (fs->existFile(B3dTexture->TextureName)) |
1057 | tex = SceneManager->getVideoDriver()->getTexture(B3dTexture->TextureName); | 1057 | tex = SceneManager->getVideoDriver()->getTexture(B3dTexture->TextureName); |
1058 | else if (fs->existFile(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName))) | 1058 | else if (fs->existFile(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName))) |
1059 | tex = SceneManager->getVideoDriver()->getTexture(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName)); | 1059 | tex = SceneManager->getVideoDriver()->getTexture(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName)); |
1060 | else | 1060 | else |
1061 | tex = SceneManager->getVideoDriver()->getTexture(fs->getFileBasename(B3dTexture->TextureName)); | 1061 | tex = SceneManager->getVideoDriver()->getTexture(fs->getFileBasename(B3dTexture->TextureName)); |
1062 | 1062 | ||
1063 | material.Material.setTexture(i, tex); | 1063 | material.Material.setTexture(i, tex); |
1064 | } | 1064 | } |
1065 | if (material.Textures[i]->Flags & 0x10) // Clamp U | 1065 | if (material.Textures[i]->Flags & 0x10) // Clamp U |
1066 | material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP; | 1066 | material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP; |
1067 | if (material.Textures[i]->Flags & 0x20) // Clamp V | 1067 | if (material.Textures[i]->Flags & 0x20) // Clamp V |
1068 | material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP; | 1068 | material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP; |
1069 | } | 1069 | } |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, doMipMaps); | 1072 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, doMipMaps); |
1073 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, previous32BitTextureFlag); | 1073 | SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, previous32BitTextureFlag); |
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | 1076 | ||
1077 | void CB3DMeshFileLoader::readString(core::stringc& newstring) | 1077 | void CB3DMeshFileLoader::readString(core::stringc& newstring) |
1078 | { | 1078 | { |
1079 | newstring=""; | 1079 | newstring=""; |
1080 | while (B3DFile->getPos() <= B3DFile->getSize()) | 1080 | while (B3DFile->getPos() <= B3DFile->getSize()) |
1081 | { | 1081 | { |
1082 | c8 character; | 1082 | c8 character; |
1083 | B3DFile->read(&character, sizeof(character)); | 1083 | B3DFile->read(&character, sizeof(character)); |
1084 | if (character==0) | 1084 | if (character==0) |
1085 | return; | 1085 | return; |
1086 | newstring.append(character); | 1086 | newstring.append(character); |
1087 | } | 1087 | } |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | 1090 | ||
1091 | void CB3DMeshFileLoader::readFloats(f32* vec, u32 count) | 1091 | void CB3DMeshFileLoader::readFloats(f32* vec, u32 count) |
1092 | { | 1092 | { |
1093 | B3DFile->read(vec, count*sizeof(f32)); | 1093 | B3DFile->read(vec, count*sizeof(f32)); |
1094 | #ifdef __BIG_ENDIAN__ | 1094 | #ifdef __BIG_ENDIAN__ |
1095 | for (u32 n=0; n<count; ++n) | 1095 | for (u32 n=0; n<count; ++n) |
1096 | vec[n] = os::Byteswap::byteswap(vec[n]); | 1096 | vec[n] = os::Byteswap::byteswap(vec[n]); |
1097 | #endif | 1097 | #endif |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | } // end namespace scene | 1100 | } // end namespace scene |
1101 | } // end namespace irr | 1101 | } // end namespace irr |
1102 | 1102 | ||
1103 | 1103 | ||
1104 | #endif // _IRR_COMPILE_WITH_B3D_LOADER_ | 1104 | #endif // _IRR_COMPILE_WITH_B3D_LOADER_ |
1105 | 1105 | ||