aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp1764
1 files changed, 882 insertions, 882 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp
index 7044721..b993d9a 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CMY3DMeshFileLoader.cpp
@@ -1,882 +1,882 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4// 4//
5// This file was originally written by ZDimitor. 5// This file was originally written by ZDimitor.
6 6
7//----------------------------------------------------------------------------- 7//-----------------------------------------------------------------------------
8// This tool created by ZDimitor everyone can use it as wants 8// This tool created by ZDimitor everyone can use it as wants
9//----------------------------------------------------------------------------- 9//-----------------------------------------------------------------------------
10 10
11#include "IrrCompileConfig.h" 11#include "IrrCompileConfig.h"
12#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_ 12#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
13 13
14#include "CMY3DMeshFileLoader.h" 14#include "CMY3DMeshFileLoader.h"
15 15
16#include "SAnimatedMesh.h" 16#include "SAnimatedMesh.h"
17#include "SMeshBuffer.h" 17#include "SMeshBuffer.h"
18#include "IReadFile.h" 18#include "IReadFile.h"
19#include "IAttributes.h" 19#include "IAttributes.h"
20 20
21#include "CMY3DHelper.h" 21#include "CMY3DHelper.h"
22#include "os.h" 22#include "os.h"
23 23
24// v3.15 - May 16, 2005 24// v3.15 - May 16, 2005
25 25
26namespace irr 26namespace irr
27{ 27{
28namespace scene 28namespace scene
29{ 29{
30 30
31static const u32 MY3D_ID = 0x4d593344; 31static const u32 MY3D_ID = 0x4d593344;
32static const u16 MY3D_VER = 0x0003; 32static const u16 MY3D_VER = 0x0003;
33static const u16 MY3D_SCENE_HEADER_ID = 0x1000; 33static const u16 MY3D_SCENE_HEADER_ID = 0x1000;
34static const u16 MY3D_MAT_LIST_ID = 0x2000; 34static const u16 MY3D_MAT_LIST_ID = 0x2000;
35static const u16 MY3D_MAT_HEADER_ID = 0x2100; 35static const u16 MY3D_MAT_HEADER_ID = 0x2100;
36static const u16 MY3D_TEX_FNAME_ID = 0x2101; 36static const u16 MY3D_TEX_FNAME_ID = 0x2101;
37static const u16 MY3D_TEXDATA_HEADER_ID = 0x2501; 37static const u16 MY3D_TEXDATA_HEADER_ID = 0x2501;
38static const u16 MY3D_TEXDATA_RLE_HEADER_ID = 0x2502; 38static const u16 MY3D_TEXDATA_RLE_HEADER_ID = 0x2502;
39static const u16 MY3D_MESH_LIST_ID = 0x3000; 39static const u16 MY3D_MESH_LIST_ID = 0x3000;
40static const u16 MY3D_MESH_HEADER_ID = 0x3100; 40static const u16 MY3D_MESH_HEADER_ID = 0x3100;
41static const u16 MY3D_VERTS_ID = 0x3101; 41static const u16 MY3D_VERTS_ID = 0x3101;
42static const u16 MY3D_FACES_ID = 0x3102; 42static const u16 MY3D_FACES_ID = 0x3102;
43static const u16 MY3D_TVERTS_ID = 0x3103; 43static const u16 MY3D_TVERTS_ID = 0x3103;
44static const u16 MY3D_TFACES_ID = 0x3104; 44static const u16 MY3D_TFACES_ID = 0x3104;
45static const u16 MY3D_FILE_END_ID = 0xFFFF; 45static const u16 MY3D_FILE_END_ID = 0xFFFF;
46 46
47static const unsigned long MY3D_TEXDATA_COMPR_NONE_ID = 0x4e4f4e45; 47static const unsigned long MY3D_TEXDATA_COMPR_NONE_ID = 0x4e4f4e45;
48static const unsigned long MY3D_TEXDATA_COMPR_SIMPLE_ID = 0x53494d50; 48static const unsigned long MY3D_TEXDATA_COMPR_SIMPLE_ID = 0x53494d50;
49static const unsigned long MY3D_TEXDATA_COMPR_RLE_ID = 0x20524c45; 49static const unsigned long MY3D_TEXDATA_COMPR_RLE_ID = 0x20524c45;
50 50
51static const unsigned long MY3D_PIXEL_FORMAT_24 = 0x5f32345f; 51static const unsigned long MY3D_PIXEL_FORMAT_24 = 0x5f32345f;
52static const unsigned long MY3D_PIXEL_FORMAT_16 = 0x5f31365f; 52static const unsigned long MY3D_PIXEL_FORMAT_16 = 0x5f31365f;
53 53
54CMY3DMeshFileLoader::CMY3DMeshFileLoader(ISceneManager* scmgr, io::IFileSystem* fs) 54CMY3DMeshFileLoader::CMY3DMeshFileLoader(ISceneManager* scmgr, io::IFileSystem* fs)
55 : SceneManager(scmgr), FileSystem(fs) 55 : SceneManager(scmgr), FileSystem(fs)
56{ 56{
57 #ifdef _DEBUG 57 #ifdef _DEBUG
58 setDebugName("CMY3DMeshFileLoader"); 58 setDebugName("CMY3DMeshFileLoader");
59 #endif 59 #endif
60 60
61 if (FileSystem) 61 if (FileSystem)
62 FileSystem->grab(); 62 FileSystem->grab();
63} 63}
64 64
65 65
66CMY3DMeshFileLoader::~CMY3DMeshFileLoader() 66CMY3DMeshFileLoader::~CMY3DMeshFileLoader()
67{ 67{
68 if (FileSystem) 68 if (FileSystem)
69 FileSystem->drop(); 69 FileSystem->drop();
70} 70}
71 71
72 72
73bool CMY3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 73bool CMY3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
74{ 74{
75 return core::hasFileExtension ( filename, "my3d" ); 75 return core::hasFileExtension ( filename, "my3d" );
76} 76}
77 77
78 78
79IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file) 79IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
80{ 80{
81 MaterialEntry.clear(); 81 MaterialEntry.clear();
82 MeshBufferEntry.clear(); 82 MeshBufferEntry.clear();
83 ChildNodes.clear(); 83 ChildNodes.clear();
84 84
85 // working directory (from which we load the scene) 85 // working directory (from which we load the scene)
86 core::stringc filepath = FileSystem->getFileDir(file->getFileName()); 86 core::stringc filepath = FileSystem->getFileDir(file->getFileName());
87 if (filepath==".") 87 if (filepath==".")
88 filepath=""; 88 filepath="";
89 else 89 else
90 filepath.append("/"); 90 filepath.append("/");
91 91
92 // read file into memory 92 // read file into memory
93 SMyFileHeader fileHeader; 93 SMyFileHeader fileHeader;
94 file->read(&fileHeader, sizeof(SMyFileHeader)); 94 file->read(&fileHeader, sizeof(SMyFileHeader));
95#ifdef __BIG_ENDIAN__ 95#ifdef __BIG_ENDIAN__
96 fileHeader.MyId = os::Byteswap::byteswap(fileHeader.MyId); 96 fileHeader.MyId = os::Byteswap::byteswap(fileHeader.MyId);
97 fileHeader.Ver = os::Byteswap::byteswap(fileHeader.Ver); 97 fileHeader.Ver = os::Byteswap::byteswap(fileHeader.Ver);
98#endif 98#endif
99 99
100 if (fileHeader.MyId!=MY3D_ID || fileHeader.Ver!=MY3D_VER) 100 if (fileHeader.MyId!=MY3D_ID || fileHeader.Ver!=MY3D_VER)
101 { 101 {
102 os::Printer::log("Bad MY3D file header, loading failed!", ELL_ERROR); 102 os::Printer::log("Bad MY3D file header, loading failed!", ELL_ERROR);
103 return 0; 103 return 0;
104 } 104 }
105 105
106 u16 id; 106 u16 id;
107 107
108 file->read(&id, sizeof(id)); 108 file->read(&id, sizeof(id));
109#ifdef __BIG_ENDIAN__ 109#ifdef __BIG_ENDIAN__
110 id = os::Byteswap::byteswap(id); 110 id = os::Byteswap::byteswap(id);
111#endif 111#endif
112 112
113 if (id!=MY3D_SCENE_HEADER_ID) 113 if (id!=MY3D_SCENE_HEADER_ID)
114 { 114 {
115 os::Printer::log("Cannot find MY3D_SCENE_HEADER_ID, loading failed!", ELL_ERROR); 115 os::Printer::log("Cannot find MY3D_SCENE_HEADER_ID, loading failed!", ELL_ERROR);
116 return 0; 116 return 0;
117 } 117 }
118 118
119 SMySceneHeader sceneHeader; 119 SMySceneHeader sceneHeader;
120 file->read(&sceneHeader, sizeof(SMySceneHeader)); 120 file->read(&sceneHeader, sizeof(SMySceneHeader));
121#ifdef __BIG_ENDIAN__ 121#ifdef __BIG_ENDIAN__
122 sceneHeader.MaterialCount = os::Byteswap::byteswap(sceneHeader.MaterialCount); 122 sceneHeader.MaterialCount = os::Byteswap::byteswap(sceneHeader.MaterialCount);
123 sceneHeader.MeshCount = os::Byteswap::byteswap(sceneHeader.MeshCount); 123 sceneHeader.MeshCount = os::Byteswap::byteswap(sceneHeader.MeshCount);
124#endif 124#endif
125 125
126 file->read(&id, sizeof(id)); 126 file->read(&id, sizeof(id));
127#ifdef __BIG_ENDIAN__ 127#ifdef __BIG_ENDIAN__
128 id = os::Byteswap::byteswap(id); 128 id = os::Byteswap::byteswap(id);
129#endif 129#endif
130 130
131 if (id!=MY3D_MAT_LIST_ID) 131 if (id!=MY3D_MAT_LIST_ID)
132 { 132 {
133 os::Printer::log("Can not find MY3D_MAT_LIST_ID, loading failed!", ELL_ERROR); 133 os::Printer::log("Can not find MY3D_MAT_LIST_ID, loading failed!", ELL_ERROR);
134 return 0; 134 return 0;
135 } 135 }
136 136
137 core::stringc texturePath = 137 core::stringc texturePath =
138 SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH); 138 SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH);
139 139
140 file->read(&id, sizeof(id)); 140 file->read(&id, sizeof(id));
141#ifdef __BIG_ENDIAN__ 141#ifdef __BIG_ENDIAN__
142 id = os::Byteswap::byteswap(id); 142 id = os::Byteswap::byteswap(id);
143#endif 143#endif
144 144
145 c8 namebuf[256]; 145 c8 namebuf[256];
146 for (s32 m=0; m<sceneHeader.MaterialCount; ++m) 146 for (s32 m=0; m<sceneHeader.MaterialCount; ++m)
147 { 147 {
148 if (id != MY3D_MAT_HEADER_ID) 148 if (id != MY3D_MAT_HEADER_ID)
149 { 149 {
150 os::Printer::log("Cannot find MY3D_MAT_HEADER_ID, loading failed!", ELL_ERROR); 150 os::Printer::log("Cannot find MY3D_MAT_HEADER_ID, loading failed!", ELL_ERROR);
151 return 0; 151 return 0;
152 } 152 }
153 153
154 // read material header 154 // read material header
155 MaterialEntry.push_back(SMyMaterialEntry()); 155 MaterialEntry.push_back(SMyMaterialEntry());
156 SMyMaterialEntry& me=MaterialEntry.getLast(); 156 SMyMaterialEntry& me=MaterialEntry.getLast();
157 file->read(&(me.Header), sizeof(SMyMaterialHeader)); 157 file->read(&(me.Header), sizeof(SMyMaterialHeader));
158 158
159 // read next identificator 159 // read next identificator
160 file->read(&id, sizeof(id)); 160 file->read(&id, sizeof(id));
161#ifdef __BIG_ENDIAN__ 161#ifdef __BIG_ENDIAN__
162 id = os::Byteswap::byteswap(id); 162 id = os::Byteswap::byteswap(id);
163#endif 163#endif
164 164
165 bool gotLightMap=false, gotMainMap=false; 165 bool gotLightMap=false, gotMainMap=false;
166 166
167 for (u32 t=0; t<me.Header.TextureCount; ++t) 167 for (u32 t=0; t<me.Header.TextureCount; ++t)
168 { 168 {
169 if (id==MY3D_TEX_FNAME_ID) 169 if (id==MY3D_TEX_FNAME_ID)
170 file->read(namebuf, 256); 170 file->read(namebuf, 256);
171 else 171 else
172 { 172 {
173 me.Texture2 = readEmbeddedLightmap(file, namebuf); 173 me.Texture2 = readEmbeddedLightmap(file, namebuf);
174 if (!me.Texture2) 174 if (!me.Texture2)
175 return 0; 175 return 0;
176 gotLightMap = true; 176 gotLightMap = true;
177 } 177 }
178 178
179 const core::stringc name(namebuf); 179 const core::stringc name(namebuf);
180 const s32 pos = name.findLast('.'); 180 const s32 pos = name.findLast('.');
181 const core::stringc LightingMapStr = "LightingMap"; 181 const core::stringc LightingMapStr = "LightingMap";
182 const s32 ls = LightingMapStr.size(); 182 const s32 ls = LightingMapStr.size();
183 const bool isSubString = (LightingMapStr == name.subString(core::max_(0, (pos - ls)), ls)); 183 const bool isSubString = (LightingMapStr == name.subString(core::max_(0, (pos - ls)), ls));
184 if ((isSubString || (name[pos-1]=='m' && 184 if ((isSubString || (name[pos-1]=='m' &&
185 name[pos-2]=='l' && name[pos-3]=='_')) && 185 name[pos-2]=='l' && name[pos-3]=='_')) &&
186 !gotLightMap) 186 !gotLightMap)
187 { 187 {
188 const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); 188 const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
189 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); 189 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
190 190
191 me.Texture2FileName = texturePath.size() ? texturePath : filepath; 191 me.Texture2FileName = texturePath.size() ? texturePath : filepath;
192 me.Texture2FileName.append("Lightmaps/"); 192 me.Texture2FileName.append("Lightmaps/");
193 me.Texture2FileName.append(name); 193 me.Texture2FileName.append(name);
194 194
195 if (name.size()) 195 if (name.size())
196 me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName); 196 me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName);
197 197
198 me.MaterialType = video::EMT_LIGHTMAP_M2; 198 me.MaterialType = video::EMT_LIGHTMAP_M2;
199 gotLightMap = true; 199 gotLightMap = true;
200 200
201 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); 201 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
202 } 202 }
203 else 203 else
204 if (!gotLightMap && gotMainMap) 204 if (!gotLightMap && gotMainMap)
205 { 205 {
206 me.Texture2FileName = texturePath.size() ? texturePath : filepath; 206 me.Texture2FileName = texturePath.size() ? texturePath : filepath;
207 me.Texture2FileName.append(name); 207 me.Texture2FileName.append(name);
208 208
209 if (name.size()) 209 if (name.size())
210 me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName); 210 me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName);
211 211
212 me.MaterialType = video::EMT_REFLECTION_2_LAYER; 212 me.MaterialType = video::EMT_REFLECTION_2_LAYER;
213 } 213 }
214 else 214 else
215 if (!gotMainMap && !gotLightMap) 215 if (!gotMainMap && !gotLightMap)
216 { 216 {
217 me.Texture1FileName = filepath; 217 me.Texture1FileName = filepath;
218 me.Texture1FileName.append(name); 218 me.Texture1FileName.append(name);
219 if (name.size()) 219 if (name.size())
220 me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName); 220 me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName);
221 221
222 gotMainMap = true; 222 gotMainMap = true;
223 me.MaterialType = video::EMT_SOLID; 223 me.MaterialType = video::EMT_SOLID;
224 } 224 }
225 else 225 else
226 if (gotLightMap) 226 if (gotLightMap)
227 { 227 {
228 me.MaterialType = video::EMT_LIGHTMAP_M2; 228 me.MaterialType = video::EMT_LIGHTMAP_M2;
229 } 229 }
230 230
231 file->read(&id, sizeof(id)); 231 file->read(&id, sizeof(id));
232#ifdef __BIG_ENDIAN__ 232#ifdef __BIG_ENDIAN__
233 id = os::Byteswap::byteswap(id); 233 id = os::Byteswap::byteswap(id);
234#endif 234#endif
235 } 235 }
236 236
237 // override material types based on their names 237 // override material types based on their names
238 if (!strncmp(me.Header.Name, "AlphaChannel-", 13)) 238 if (!strncmp(me.Header.Name, "AlphaChannel-", 13))
239 me.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; 239 me.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
240 else 240 else
241 if (!strncmp(me.Header.Name, "SphereMap-", 10)) 241 if (!strncmp(me.Header.Name, "SphereMap-", 10))
242 me.MaterialType = video::EMT_SPHERE_MAP; 242 me.MaterialType = video::EMT_SPHERE_MAP;
243 } 243 }
244 244
245 // loading meshes 245 // loading meshes
246 246
247 if (id!=MY3D_MESH_LIST_ID) 247 if (id!=MY3D_MESH_LIST_ID)
248 { 248 {
249 os::Printer::log("Can not find MY3D_MESH_LIST_ID, loading failed!", ELL_ERROR); 249 os::Printer::log("Can not find MY3D_MESH_LIST_ID, loading failed!", ELL_ERROR);
250 return 0; 250 return 0;
251 } 251 }
252 252
253 file->read(&id, sizeof(id)); 253 file->read(&id, sizeof(id));
254#ifdef __BIG_ENDIAN__ 254#ifdef __BIG_ENDIAN__
255 id = os::Byteswap::byteswap(id); 255 id = os::Byteswap::byteswap(id);
256#endif 256#endif
257 257
258 for (s32 mesh_id=0; mesh_id<sceneHeader.MeshCount; mesh_id++) 258 for (s32 mesh_id=0; mesh_id<sceneHeader.MeshCount; mesh_id++)
259 { 259 {
260 // Warning!!! In some cases MY3D exporter uncorrectly calculates 260 // Warning!!! In some cases MY3D exporter uncorrectly calculates
261 // MeshCount (it's a problem, has to be solved) thats why 261 // MeshCount (it's a problem, has to be solved) thats why
262 // i added this code line 262 // i added this code line
263 if (id!=MY3D_MESH_HEADER_ID) 263 if (id!=MY3D_MESH_HEADER_ID)
264 break; 264 break;
265 265
266 if (id!=MY3D_MESH_HEADER_ID) 266 if (id!=MY3D_MESH_HEADER_ID)
267 { 267 {
268 os::Printer::log("Can not find MY3D_MESH_HEADER_ID, loading failed!", ELL_ERROR); 268 os::Printer::log("Can not find MY3D_MESH_HEADER_ID, loading failed!", ELL_ERROR);
269 return 0; 269 return 0;
270 } 270 }
271 271
272 SMyMeshHeader meshHeader; 272 SMyMeshHeader meshHeader;
273 file->read(&meshHeader, sizeof(SMyMeshHeader)); 273 file->read(&meshHeader, sizeof(SMyMeshHeader));
274 274
275 core::array <SMyVertex> Vertex; 275 core::array <SMyVertex> Vertex;
276 core::array <SMyFace> Face; 276 core::array <SMyFace> Face;
277 core::array <SMyTVertex> TVertex1, TVertex2; 277 core::array <SMyTVertex> TVertex1, TVertex2;
278 core::array <SMyFace> TFace1, TFace2; 278 core::array <SMyFace> TFace1, TFace2;
279 279
280 s32 vertsNum=0; 280 s32 vertsNum=0;
281 s32 facesNum=0; 281 s32 facesNum=0;
282 282
283 // vertices 283 // vertices
284 file->read(&id, sizeof(id)); 284 file->read(&id, sizeof(id));
285#ifdef __BIG_ENDIAN__ 285#ifdef __BIG_ENDIAN__
286 id = os::Byteswap::byteswap(id); 286 id = os::Byteswap::byteswap(id);
287#endif 287#endif
288 if (id!=MY3D_VERTS_ID) 288 if (id!=MY3D_VERTS_ID)
289 { 289 {
290 os::Printer::log("Can not find MY3D_VERTS_ID, loading failed!", ELL_ERROR); 290 os::Printer::log("Can not find MY3D_VERTS_ID, loading failed!", ELL_ERROR);
291 return 0; 291 return 0;
292 } 292 }
293 293
294 file->read(&vertsNum, sizeof(vertsNum)); 294 file->read(&vertsNum, sizeof(vertsNum));
295 Vertex.set_used(vertsNum); 295 Vertex.set_used(vertsNum);
296 file->read(Vertex.pointer(), sizeof(SMyVertex)*vertsNum); 296 file->read(Vertex.pointer(), sizeof(SMyVertex)*vertsNum);
297 297
298 // faces 298 // faces
299 file->read(&id, sizeof(id)); 299 file->read(&id, sizeof(id));
300#ifdef __BIG_ENDIAN__ 300#ifdef __BIG_ENDIAN__
301 id = os::Byteswap::byteswap(id); 301 id = os::Byteswap::byteswap(id);
302#endif 302#endif
303 if (id!=MY3D_FACES_ID) 303 if (id!=MY3D_FACES_ID)
304 { 304 {
305 os::Printer::log("Can not find MY3D_FACES_ID, loading failed!", ELL_ERROR); 305 os::Printer::log("Can not find MY3D_FACES_ID, loading failed!", ELL_ERROR);
306 return 0; 306 return 0;
307 } 307 }
308 308
309 file->read(&facesNum, sizeof(facesNum)); 309 file->read(&facesNum, sizeof(facesNum));
310 Face.set_used(facesNum); 310 Face.set_used(facesNum);
311 file->read(Face.pointer(), sizeof(SMyFace)*facesNum); 311 file->read(Face.pointer(), sizeof(SMyFace)*facesNum);
312 312
313 // reading texture channels 313 // reading texture channels
314 for (s32 tex=0; tex<(s32)meshHeader.TChannelCnt; tex++) 314 for (s32 tex=0; tex<(s32)meshHeader.TChannelCnt; tex++)
315 { 315 {
316 // Max 2 texture channels allowed (but in format .my3d can be more) 316 // Max 2 texture channels allowed (but in format .my3d can be more)
317 s32 tVertsNum=0, tFacesNum=0; 317 s32 tVertsNum=0, tFacesNum=0;
318 318
319 // reading texture coords 319 // reading texture coords
320 file->read(&id, sizeof(id)); 320 file->read(&id, sizeof(id));
321#ifdef __BIG_ENDIAN__ 321#ifdef __BIG_ENDIAN__
322 id = os::Byteswap::byteswap(id); 322 id = os::Byteswap::byteswap(id);
323#endif 323#endif
324 324
325 if (id!=MY3D_TVERTS_ID) 325 if (id!=MY3D_TVERTS_ID)
326 { 326 {
327 core::stringc msg="Can not find MY3D_TVERTS_ID ("; 327 core::stringc msg="Can not find MY3D_TVERTS_ID (";
328 msg.append(core::stringc(tex)); 328 msg.append(core::stringc(tex));
329 msg.append("texture channel), loading failed!"); 329 msg.append("texture channel), loading failed!");
330 os::Printer::log(msg.c_str(), ELL_ERROR); 330 os::Printer::log(msg.c_str(), ELL_ERROR);
331 return 0; 331 return 0;
332 } 332 }
333 333
334 file->read(&tVertsNum, sizeof(tVertsNum)); 334 file->read(&tVertsNum, sizeof(tVertsNum));
335 335
336 if (tex==0) 336 if (tex==0)
337 { 337 {
338 // 1st texture channel 338 // 1st texture channel
339 TVertex1.set_used(tVertsNum); 339 TVertex1.set_used(tVertsNum);
340 file->read(TVertex1.pointer(), sizeof(SMyTVertex)*tVertsNum); 340 file->read(TVertex1.pointer(), sizeof(SMyTVertex)*tVertsNum);
341 } 341 }
342 else 342 else
343 if (tex==1) 343 if (tex==1)
344 { 344 {
345 // 2nd texture channel 345 // 2nd texture channel
346 TVertex2.set_used(tVertsNum); 346 TVertex2.set_used(tVertsNum);
347 file->read(TVertex2.pointer(), sizeof(SMyTVertex)*tVertsNum); 347 file->read(TVertex2.pointer(), sizeof(SMyTVertex)*tVertsNum);
348 } 348 }
349 else 349 else
350 { 350 {
351 // skip other texture channels 351 // skip other texture channels
352 file->seek(file->getPos()+sizeof(SMyTVertex)*tVertsNum); 352 file->seek(file->getPos()+sizeof(SMyTVertex)*tVertsNum);
353 } 353 }
354 354
355 // reading texture faces 355 // reading texture faces
356 file->read(&id, sizeof(id)); 356 file->read(&id, sizeof(id));
357#ifdef __BIG_ENDIAN__ 357#ifdef __BIG_ENDIAN__
358 id = os::Byteswap::byteswap(id); 358 id = os::Byteswap::byteswap(id);
359#endif 359#endif
360 360
361 if (id!=MY3D_TFACES_ID) 361 if (id!=MY3D_TFACES_ID)
362 { 362 {
363 core::stringc msg="Can not find MY3D_TFACES_ID ("; 363 core::stringc msg="Can not find MY3D_TFACES_ID (";
364 msg.append(core::stringc(tex)); 364 msg.append(core::stringc(tex));
365 msg.append("texture channel), loading failed!"); 365 msg.append("texture channel), loading failed!");
366 os::Printer::log(msg.c_str(), ELL_ERROR); 366 os::Printer::log(msg.c_str(), ELL_ERROR);
367 return 0; 367 return 0;
368 } 368 }
369 369
370 file->read(&tFacesNum, sizeof(tFacesNum)); 370 file->read(&tFacesNum, sizeof(tFacesNum));
371 371
372 if (tex==0) 372 if (tex==0)
373 { 373 {
374 // 1st texture channel 374 // 1st texture channel
375 TFace1.set_used(tFacesNum); 375 TFace1.set_used(tFacesNum);
376 file->read(TFace1.pointer(), sizeof(SMyFace)*tFacesNum); 376 file->read(TFace1.pointer(), sizeof(SMyFace)*tFacesNum);
377 } 377 }
378 else if (tex==1) 378 else if (tex==1)
379 { 379 {
380 // 2nd texture channel 380 // 2nd texture channel
381 TFace2.set_used(tFacesNum); 381 TFace2.set_used(tFacesNum);
382 file->read(TFace2.pointer(), sizeof(SMyFace)*tFacesNum); 382 file->read(TFace2.pointer(), sizeof(SMyFace)*tFacesNum);
383 } 383 }
384 else 384 else
385 { 385 {
386 // skip other texture channels 386 // skip other texture channels
387 file->seek(file->getPos()+sizeof(SMyFace)*tFacesNum); 387 file->seek(file->getPos()+sizeof(SMyFace)*tFacesNum);
388 } 388 }
389 } 389 }
390 390
391 // trying to find material 391 // trying to find material
392 392
393 SMyMaterialEntry* matEnt = getMaterialEntryByIndex(meshHeader.MatIndex); 393 SMyMaterialEntry* matEnt = getMaterialEntryByIndex(meshHeader.MatIndex);
394 394
395 // creating geometry for the mesh 395 // creating geometry for the mesh
396 396
397 // trying to find mesh buffer for this material 397 // trying to find mesh buffer for this material
398 SMeshBufferLightMap* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex); 398 SMeshBufferLightMap* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex);
399 399
400 if (!buffer || 400 if (!buffer ||
401 (buffer->Vertices.size()+vertsNum) > SceneManager->getVideoDriver()->getMaximalPrimitiveCount()) 401 (buffer->Vertices.size()+vertsNum) > SceneManager->getVideoDriver()->getMaximalPrimitiveCount())
402 { 402 {
403 // creating new mesh buffer for this material 403 // creating new mesh buffer for this material
404 buffer = new scene::SMeshBufferLightMap(); 404 buffer = new scene::SMeshBufferLightMap();
405 405
406 buffer->Material.MaterialType = video::EMT_LIGHTMAP_M2; // EMT_LIGHTMAP_M4 also possible 406 buffer->Material.MaterialType = video::EMT_LIGHTMAP_M2; // EMT_LIGHTMAP_M4 also possible
407 buffer->Material.Wireframe = false; 407 buffer->Material.Wireframe = false;
408 buffer->Material.Lighting = false; 408 buffer->Material.Lighting = false;
409 409
410 if (matEnt) 410 if (matEnt)
411 { 411 {
412 buffer->Material.MaterialType = matEnt->MaterialType; 412 buffer->Material.MaterialType = matEnt->MaterialType;
413 413
414 if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER) 414 if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER)
415 { 415 {
416 buffer->Material.Lighting = true; 416 buffer->Material.Lighting = true;
417 buffer->Material.setTexture(1, matEnt->Texture1); 417 buffer->Material.setTexture(1, matEnt->Texture1);
418 buffer->Material.setTexture(0, matEnt->Texture2); 418 buffer->Material.setTexture(0, matEnt->Texture2);
419 } 419 }
420 else 420 else
421 { 421 {
422 buffer->Material.setTexture(0, matEnt->Texture1); 422 buffer->Material.setTexture(0, matEnt->Texture1);
423 buffer->Material.setTexture(1, matEnt->Texture2); 423 buffer->Material.setTexture(1, matEnt->Texture2);
424 } 424 }
425 425
426 if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) 426 if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
427 { 427 {
428 buffer->Material.BackfaceCulling = true; 428 buffer->Material.BackfaceCulling = true;
429 buffer->Material.Lighting = true; 429 buffer->Material.Lighting = true;
430 } 430 }
431 else 431 else
432 if (buffer->Material.MaterialType == video::EMT_SPHERE_MAP) 432 if (buffer->Material.MaterialType == video::EMT_SPHERE_MAP)
433 { 433 {
434 buffer->Material.Lighting = true; 434 buffer->Material.Lighting = true;
435 } 435 }
436 436
437 buffer->Material.AmbientColor = video::SColor( 437 buffer->Material.AmbientColor = video::SColor(
438 matEnt->Header.AmbientColor.A, matEnt->Header.AmbientColor.R, 438 matEnt->Header.AmbientColor.A, matEnt->Header.AmbientColor.R,
439 matEnt->Header.AmbientColor.G, matEnt->Header.AmbientColor.B 439 matEnt->Header.AmbientColor.G, matEnt->Header.AmbientColor.B
440 ); 440 );
441 buffer->Material.DiffuseColor = video::SColor( 441 buffer->Material.DiffuseColor = video::SColor(
442 matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, 442 matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R,
443 matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B 443 matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B
444 ); 444 );
445 buffer->Material.EmissiveColor = video::SColor( 445 buffer->Material.EmissiveColor = video::SColor(
446 matEnt->Header.EmissiveColor.A, matEnt->Header.EmissiveColor.R, 446 matEnt->Header.EmissiveColor.A, matEnt->Header.EmissiveColor.R,
447 matEnt->Header.EmissiveColor.G, matEnt->Header.EmissiveColor.B 447 matEnt->Header.EmissiveColor.G, matEnt->Header.EmissiveColor.B
448 ); 448 );
449 buffer->Material.SpecularColor = video::SColor( 449 buffer->Material.SpecularColor = video::SColor(
450 matEnt->Header.SpecularColor.A, matEnt->Header.SpecularColor.R, 450 matEnt->Header.SpecularColor.A, matEnt->Header.SpecularColor.R,
451 matEnt->Header.SpecularColor.G, matEnt->Header.SpecularColor.B 451 matEnt->Header.SpecularColor.G, matEnt->Header.SpecularColor.B
452 ); 452 );
453 } 453 }
454 else 454 else
455 { 455 {
456 buffer->Material.setTexture(0, 0); 456 buffer->Material.setTexture(0, 0);
457 buffer->Material.setTexture(1, 0); 457 buffer->Material.setTexture(1, 0);
458 458
459 buffer->Material.AmbientColor = video::SColor(255, 255, 255, 255); 459 buffer->Material.AmbientColor = video::SColor(255, 255, 255, 255);
460 buffer->Material.DiffuseColor = video::SColor(255, 255, 255, 255); 460 buffer->Material.DiffuseColor = video::SColor(255, 255, 255, 255);
461 buffer->Material.EmissiveColor = video::SColor(0, 0, 0, 0); 461 buffer->Material.EmissiveColor = video::SColor(0, 0, 0, 0);
462 buffer->Material.SpecularColor = video::SColor(0, 0, 0, 0); 462 buffer->Material.SpecularColor = video::SColor(0, 0, 0, 0);
463 } 463 }
464 464
465 if (matEnt && matEnt->Header.Transparency!=0) 465 if (matEnt && matEnt->Header.Transparency!=0)
466 { 466 {
467 if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER ) 467 if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER )
468 { 468 {
469 buffer->Material.MaterialType = video::EMT_TRANSPARENT_REFLECTION_2_LAYER; 469 buffer->Material.MaterialType = video::EMT_TRANSPARENT_REFLECTION_2_LAYER;
470 buffer->Material.Lighting = true; 470 buffer->Material.Lighting = true;
471 buffer->Material.BackfaceCulling = true; 471 buffer->Material.BackfaceCulling = true;
472 } 472 }
473 else 473 else
474 { 474 {
475 buffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; 475 buffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
476 buffer->Material.Lighting = false; 476 buffer->Material.Lighting = false;
477 buffer->Material.BackfaceCulling = false; 477 buffer->Material.BackfaceCulling = false;
478 } 478 }
479 } 479 }
480 else if ( 480 else if (
481 !buffer->Material.getTexture(1) && 481 !buffer->Material.getTexture(1) &&
482 buffer->Material.MaterialType != video::EMT_TRANSPARENT_ALPHA_CHANNEL && 482 buffer->Material.MaterialType != video::EMT_TRANSPARENT_ALPHA_CHANNEL &&
483 buffer->Material.MaterialType != video::EMT_SPHERE_MAP) 483 buffer->Material.MaterialType != video::EMT_SPHERE_MAP)
484 { 484 {
485 buffer->Material.MaterialType = video::EMT_SOLID; 485 buffer->Material.MaterialType = video::EMT_SOLID;
486 buffer->Material.Lighting = true; 486 buffer->Material.Lighting = true;
487 } 487 }
488 488
489 MeshBufferEntry.push_back( 489 MeshBufferEntry.push_back(
490 SMyMeshBufferEntry(meshHeader.MatIndex, buffer)); 490 SMyMeshBufferEntry(meshHeader.MatIndex, buffer));
491 } 491 }
492 492
493 video::S3DVertex2TCoords VertexA, VertexB, VertexC; 493 video::S3DVertex2TCoords VertexA, VertexB, VertexC;
494 494
495 // vertices (A, B, C) color 495 // vertices (A, B, C) color
496 video::SColor vert_color; 496 video::SColor vert_color;
497 if (matEnt && 497 if (matEnt &&
498 (buffer->Material.MaterialType == video::EMT_TRANSPARENT_VERTEX_ALPHA || 498 (buffer->Material.MaterialType == video::EMT_TRANSPARENT_VERTEX_ALPHA ||
499 buffer->Material.MaterialType == video::EMT_TRANSPARENT_REFLECTION_2_LAYER)) 499 buffer->Material.MaterialType == video::EMT_TRANSPARENT_REFLECTION_2_LAYER))
500 { 500 {
501 video::SColor color( 501 video::SColor color(
502 matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, 502 matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R,
503 matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B); 503 matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B);
504 504
505 vert_color = color.getInterpolated(video::SColor(0,0,0,0), 505 vert_color = color.getInterpolated(video::SColor(0,0,0,0),
506 1-matEnt->Header.Transparency); 506 1-matEnt->Header.Transparency);
507 } 507 }
508 else 508 else
509 { 509 {
510 vert_color = buffer->Material.DiffuseColor; 510 vert_color = buffer->Material.DiffuseColor;
511 } 511 }
512 512
513 VertexA.Color = VertexB.Color = VertexC.Color = vert_color; 513 VertexA.Color = VertexB.Color = VertexC.Color = vert_color;
514 514
515 if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) 515 if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
516 { 516 {
517 buffer->Indices.reallocate(buffer->Indices.size()+6*facesNum); 517 buffer->Indices.reallocate(buffer->Indices.size()+6*facesNum);
518 buffer->Vertices.reallocate(buffer->Vertices.size()+6*facesNum); 518 buffer->Vertices.reallocate(buffer->Vertices.size()+6*facesNum);
519 } 519 }
520 else 520 else
521 { 521 {
522 buffer->Indices.reallocate(buffer->Indices.size()+3*facesNum); 522 buffer->Indices.reallocate(buffer->Indices.size()+3*facesNum);
523 buffer->Vertices.reallocate(buffer->Vertices.size()+3*facesNum); 523 buffer->Vertices.reallocate(buffer->Vertices.size()+3*facesNum);
524 } 524 }
525 for (int f=0; f<facesNum; f++) 525 for (int f=0; f<facesNum; f++)
526 { 526 {
527 // vertex A 527 // vertex A
528 528
529 VertexA.Pos.X = Vertex[Face[f].C].Coord.X; 529 VertexA.Pos.X = Vertex[Face[f].C].Coord.X;
530 VertexA.Pos.Y = Vertex[Face[f].C].Coord.Y; 530 VertexA.Pos.Y = Vertex[Face[f].C].Coord.Y;
531 VertexA.Pos.Z = Vertex[Face[f].C].Coord.Z; 531 VertexA.Pos.Z = Vertex[Face[f].C].Coord.Z;
532 532
533 VertexA.Normal.X = Vertex[Face[f].C].Normal.X; 533 VertexA.Normal.X = Vertex[Face[f].C].Normal.X;
534 VertexA.Normal.Y = Vertex[Face[f].C].Normal.Y; 534 VertexA.Normal.Y = Vertex[Face[f].C].Normal.Y;
535 VertexA.Normal.Z = Vertex[Face[f].C].Normal.Z; 535 VertexA.Normal.Z = Vertex[Face[f].C].Normal.Z;
536 536
537 if (meshHeader.TChannelCnt>0) 537 if (meshHeader.TChannelCnt>0)
538 { 538 {
539 VertexA.TCoords.X = TVertex1[TFace1[f].C].TCoord.X; 539 VertexA.TCoords.X = TVertex1[TFace1[f].C].TCoord.X;
540 VertexA.TCoords.Y = TVertex1[TFace1[f].C].TCoord.Y; 540 VertexA.TCoords.Y = TVertex1[TFace1[f].C].TCoord.Y;
541 } 541 }
542 542
543 if (meshHeader.TChannelCnt>1) 543 if (meshHeader.TChannelCnt>1)
544 { 544 {
545 VertexA.TCoords2.X = TVertex2[TFace2[f].C].TCoord.X; 545 VertexA.TCoords2.X = TVertex2[TFace2[f].C].TCoord.X;
546 VertexA.TCoords2.Y = TVertex2[TFace2[f].C].TCoord.Y; 546 VertexA.TCoords2.Y = TVertex2[TFace2[f].C].TCoord.Y;
547 } 547 }
548 548
549 // vertex B 549 // vertex B
550 550
551 VertexB.Pos.X = Vertex[Face[f].B].Coord.X; 551 VertexB.Pos.X = Vertex[Face[f].B].Coord.X;
552 VertexB.Pos.Y = Vertex[Face[f].B].Coord.Y; 552 VertexB.Pos.Y = Vertex[Face[f].B].Coord.Y;
553 VertexB.Pos.Z = Vertex[Face[f].B].Coord.Z; 553 VertexB.Pos.Z = Vertex[Face[f].B].Coord.Z;
554 554
555 VertexB.Normal.X = Vertex[Face[f].B].Normal.X; 555 VertexB.Normal.X = Vertex[Face[f].B].Normal.X;
556 VertexB.Normal.Y = Vertex[Face[f].B].Normal.Y; 556 VertexB.Normal.Y = Vertex[Face[f].B].Normal.Y;
557 VertexB.Normal.Z = Vertex[Face[f].B].Normal.Z; 557 VertexB.Normal.Z = Vertex[Face[f].B].Normal.Z;
558 558
559 if (meshHeader.TChannelCnt>0) 559 if (meshHeader.TChannelCnt>0)
560 { 560 {
561 VertexB.TCoords.X = TVertex1[TFace1[f].B].TCoord.X; 561 VertexB.TCoords.X = TVertex1[TFace1[f].B].TCoord.X;
562 VertexB.TCoords.Y = TVertex1[TFace1[f].B].TCoord.Y; 562 VertexB.TCoords.Y = TVertex1[TFace1[f].B].TCoord.Y;
563 } 563 }
564 564
565 if (meshHeader.TChannelCnt>1) 565 if (meshHeader.TChannelCnt>1)
566 { 566 {
567 VertexB.TCoords2.X = TVertex2[TFace2[f].B].TCoord.X; 567 VertexB.TCoords2.X = TVertex2[TFace2[f].B].TCoord.X;
568 VertexB.TCoords2.Y = TVertex2[TFace2[f].B].TCoord.Y; 568 VertexB.TCoords2.Y = TVertex2[TFace2[f].B].TCoord.Y;
569 } 569 }
570 570
571 // vertex C 571 // vertex C
572 572
573 VertexC.Pos.X = Vertex[Face[f].A].Coord.X; 573 VertexC.Pos.X = Vertex[Face[f].A].Coord.X;
574 VertexC.Pos.Y = Vertex[Face[f].A].Coord.Y; 574 VertexC.Pos.Y = Vertex[Face[f].A].Coord.Y;
575 VertexC.Pos.Z = Vertex[Face[f].A].Coord.Z; 575 VertexC.Pos.Z = Vertex[Face[f].A].Coord.Z;
576 576
577 VertexC.Normal.X = Vertex[Face[f].A].Normal.X; 577 VertexC.Normal.X = Vertex[Face[f].A].Normal.X;
578 VertexC.Normal.Y = Vertex[Face[f].A].Normal.Y; 578 VertexC.Normal.Y = Vertex[Face[f].A].Normal.Y;
579 VertexC.Normal.Z = Vertex[Face[f].A].Normal.Z; 579 VertexC.Normal.Z = Vertex[Face[f].A].Normal.Z;
580 580
581 if (meshHeader.TChannelCnt>0) 581 if (meshHeader.TChannelCnt>0)
582 { 582 {
583 VertexC.TCoords.X = TVertex1[TFace1[f].A].TCoord.X; 583 VertexC.TCoords.X = TVertex1[TFace1[f].A].TCoord.X;
584 VertexC.TCoords.Y = TVertex1[TFace1[f].A].TCoord.Y; 584 VertexC.TCoords.Y = TVertex1[TFace1[f].A].TCoord.Y;
585 } 585 }
586 if (meshHeader.TChannelCnt>1) 586 if (meshHeader.TChannelCnt>1)
587 { 587 {
588 VertexC.TCoords2.X = TVertex2[TFace2[f].A].TCoord.X; 588 VertexC.TCoords2.X = TVertex2[TFace2[f].A].TCoord.X;
589 VertexC.TCoords2.Y = TVertex2[TFace2[f].A].TCoord.Y; 589 VertexC.TCoords2.Y = TVertex2[TFace2[f].A].TCoord.Y;
590 } 590 }
591 591
592 // store 3d data in mesh buffer 592 // store 3d data in mesh buffer
593 593
594 buffer->Indices.push_back(buffer->Vertices.size()); 594 buffer->Indices.push_back(buffer->Vertices.size());
595 buffer->Vertices.push_back(VertexA); 595 buffer->Vertices.push_back(VertexA);
596 596
597 buffer->Indices.push_back(buffer->Vertices.size()); 597 buffer->Indices.push_back(buffer->Vertices.size());
598 buffer->Vertices.push_back(VertexB); 598 buffer->Vertices.push_back(VertexB);
599 599
600 buffer->Indices.push_back(buffer->Vertices.size()); 600 buffer->Indices.push_back(buffer->Vertices.size());
601 buffer->Vertices.push_back(VertexC); 601 buffer->Vertices.push_back(VertexC);
602 602
603 //***************************************************************** 603 //*****************************************************************
604 // !!!!!! W A R N I N G !!!!!!! 604 // !!!!!! W A R N I N G !!!!!!!
605 //***************************************************************** 605 //*****************************************************************
606 // For materials with alpha channel we duplicate all faces. 606 // For materials with alpha channel we duplicate all faces.
607 // This has be done for proper lighting calculation of the back faces. 607 // This has be done for proper lighting calculation of the back faces.
608 // So you must remember this while you creating your models !!!!! 608 // So you must remember this while you creating your models !!!!!
609 //***************************************************************** 609 //*****************************************************************
610 // !!!!!! W A R N I N G !!!!!!! 610 // !!!!!! W A R N I N G !!!!!!!
611 //***************************************************************** 611 //*****************************************************************
612 612
613 if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) 613 if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
614 { 614 {
615 VertexA.Normal = core::vector3df(-VertexA.Normal.X, -VertexA.Normal.Y, -VertexA.Normal.Z); 615 VertexA.Normal = core::vector3df(-VertexA.Normal.X, -VertexA.Normal.Y, -VertexA.Normal.Z);
616 VertexB.Normal = core::vector3df(-VertexB.Normal.X, -VertexB.Normal.Y, -VertexB.Normal.Z); 616 VertexB.Normal = core::vector3df(-VertexB.Normal.X, -VertexB.Normal.Y, -VertexB.Normal.Z);
617 VertexC.Normal = core::vector3df(-VertexC.Normal.X, -VertexC.Normal.Y, -VertexC.Normal.Z); 617 VertexC.Normal = core::vector3df(-VertexC.Normal.X, -VertexC.Normal.Y, -VertexC.Normal.Z);
618 618
619 buffer->Indices.push_back(buffer->Vertices.size()); 619 buffer->Indices.push_back(buffer->Vertices.size());
620 buffer->Vertices.push_back(VertexC); 620 buffer->Vertices.push_back(VertexC);
621 621
622 buffer->Indices.push_back(buffer->Vertices.size()); 622 buffer->Indices.push_back(buffer->Vertices.size());
623 buffer->Vertices.push_back(VertexB); 623 buffer->Vertices.push_back(VertexB);
624 624
625 buffer->Indices.push_back(buffer->Vertices.size()); 625 buffer->Indices.push_back(buffer->Vertices.size());
626 buffer->Vertices.push_back(VertexA); 626 buffer->Vertices.push_back(VertexA);
627 } 627 }
628 } 628 }
629 file->read(&id, sizeof(id)); 629 file->read(&id, sizeof(id));
630#ifdef __BIG_ENDIAN__ 630#ifdef __BIG_ENDIAN__
631 id = os::Byteswap::byteswap(id); 631 id = os::Byteswap::byteswap(id);
632#endif 632#endif
633 } 633 }
634 634
635 // creating mesh 635 // creating mesh
636 SMesh* mesh = new SMesh(); 636 SMesh* mesh = new SMesh();
637 637
638 for (u32 num=0; num<MeshBufferEntry.size(); ++num) 638 for (u32 num=0; num<MeshBufferEntry.size(); ++num)
639 { 639 {
640 SMeshBufferLightMap* buffer = MeshBufferEntry[num].MeshBuffer; 640 SMeshBufferLightMap* buffer = MeshBufferEntry[num].MeshBuffer;
641 641
642 if (!buffer) 642 if (!buffer)
643 continue; 643 continue;
644 644
645 mesh->addMeshBuffer(buffer); 645 mesh->addMeshBuffer(buffer);
646 646
647 buffer->recalculateBoundingBox(); 647 buffer->recalculateBoundingBox();
648 buffer->drop(); 648 buffer->drop();
649 } 649 }
650 650
651 mesh->recalculateBoundingBox(); 651 mesh->recalculateBoundingBox();
652 652
653 if (id != MY3D_FILE_END_ID) 653 if (id != MY3D_FILE_END_ID)
654 os::Printer::log("Loading finished, but can not find MY3D_FILE_END_ID token.", ELL_WARNING); 654 os::Printer::log("Loading finished, but can not find MY3D_FILE_END_ID token.", ELL_WARNING);
655 655
656 SAnimatedMesh* am = new SAnimatedMesh(); 656 SAnimatedMesh* am = new SAnimatedMesh();
657 657
658 am->addMesh(mesh); 658 am->addMesh(mesh);
659 mesh->drop(); 659 mesh->drop();
660 am->recalculateBoundingBox(); 660 am->recalculateBoundingBox();
661 661
662 return am; 662 return am;
663} 663}
664 664
665 665
666video::ITexture* CMY3DMeshFileLoader::readEmbeddedLightmap(io::IReadFile* file, char* namebuf) 666video::ITexture* CMY3DMeshFileLoader::readEmbeddedLightmap(io::IReadFile* file, char* namebuf)
667{ 667{
668 static int LightMapIndex=0; 668 static int LightMapIndex=0;
669 u16 id; 669 u16 id;
670 file->read(&id, sizeof(id)); 670 file->read(&id, sizeof(id));
671#ifdef __BIG_ENDIAN__ 671#ifdef __BIG_ENDIAN__
672 id = os::Byteswap::byteswap(id); 672 id = os::Byteswap::byteswap(id);
673#endif 673#endif
674 if (id!=MY3D_TEXDATA_HEADER_ID) 674 if (id!=MY3D_TEXDATA_HEADER_ID)
675 { 675 {
676 os::Printer::log("Can not find MY3D_TEXDATA_HEADER_ID, loading failed!", ELL_ERROR); 676 os::Printer::log("Can not find MY3D_TEXDATA_HEADER_ID, loading failed!", ELL_ERROR);
677 return 0; 677 return 0;
678 } 678 }
679 679
680 SMyTexDataHeader texDataHeader; 680 SMyTexDataHeader texDataHeader;
681 681
682 file->read(&texDataHeader, sizeof(SMyTexDataHeader)); 682 file->read(&texDataHeader, sizeof(SMyTexDataHeader));
683 683
684 strcpy(texDataHeader.Name, namebuf); 684 strcpy(texDataHeader.Name, namebuf);
685 685
686 char LightMapName[255]; 686 char LightMapName[255];
687 sprintf(LightMapName,"My3D.Lightmap.%d",++LightMapIndex); 687 sprintf(LightMapName,"My3D.Lightmap.%d",++LightMapIndex);
688 688
689 core::stringc pixFormatStr; 689 core::stringc pixFormatStr;
690 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) 690 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24)
691 pixFormatStr = "24bit,"; 691 pixFormatStr = "24bit,";
692 else 692 else
693 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_16) 693 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_16)
694 pixFormatStr = "16bit,"; 694 pixFormatStr = "16bit,";
695 else 695 else
696 { 696 {
697 core::stringc msg="Unknown format of image data ("; 697 core::stringc msg="Unknown format of image data (";
698 msg.append(LightMapName); 698 msg.append(LightMapName);
699 msg.append("), loading failed!"); 699 msg.append("), loading failed!");
700 os::Printer::log(msg.c_str(), ELL_ERROR); 700 os::Printer::log(msg.c_str(), ELL_ERROR);
701 return 0; 701 return 0;
702 } 702 }
703 703
704 if (texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_NONE_ID && 704 if (texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_NONE_ID &&
705 texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_RLE_ID && 705 texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_RLE_ID &&
706 texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_SIMPLE_ID ) 706 texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_SIMPLE_ID )
707 { 707 {
708 os::Printer::log("Unknown method of compression image data, loading failed!", ELL_ERROR); 708 os::Printer::log("Unknown method of compression image data, loading failed!", ELL_ERROR);
709 return 0; 709 return 0;
710 } 710 }
711 711
712 const u32 num_pixels = texDataHeader.Width*texDataHeader.Height; 712 const u32 num_pixels = texDataHeader.Width*texDataHeader.Height;
713 713
714 void* data = 0; 714 void* data = 0;
715 715
716 if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_NONE_ID) 716 if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_NONE_ID)
717 { 717 {
718 // none compressed image data 718 // none compressed image data
719 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) 719 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24)
720 { 720 {
721 data = (void*) new SMyPixelColor24[num_pixels]; 721 data = (void*) new SMyPixelColor24[num_pixels];
722 file->read(data, sizeof(SMyPixelColor24)*num_pixels); 722 file->read(data, sizeof(SMyPixelColor24)*num_pixels);
723 } 723 }
724 else 724 else
725 { 725 {
726 data = (void*) new SMyPixelColor16[num_pixels]; 726 data = (void*) new SMyPixelColor16[num_pixels];
727 file->read(data, sizeof(SMyPixelColor16)*num_pixels); 727 file->read(data, sizeof(SMyPixelColor16)*num_pixels);
728 } 728 }
729 } 729 }
730 else 730 else
731 if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_RLE_ID) 731 if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_RLE_ID)
732 { 732 {
733 // read RLE header identificator 733 // read RLE header identificator
734 file->read(&id, sizeof(id)); 734 file->read(&id, sizeof(id));
735#ifdef __BIG_ENDIAN__ 735#ifdef __BIG_ENDIAN__
736 id = os::Byteswap::byteswap(id); 736 id = os::Byteswap::byteswap(id);
737#endif 737#endif
738 if (id!=MY3D_TEXDATA_RLE_HEADER_ID) 738 if (id!=MY3D_TEXDATA_RLE_HEADER_ID)
739 { 739 {
740 os::Printer::log("Can not find MY3D_TEXDATA_RLE_HEADER_ID, loading failed!", ELL_ERROR); 740 os::Printer::log("Can not find MY3D_TEXDATA_RLE_HEADER_ID, loading failed!", ELL_ERROR);
741 return 0; 741 return 0;
742 } 742 }
743 743
744 // read RLE header 744 // read RLE header
745 SMyRLEHeader rleHeader; 745 SMyRLEHeader rleHeader;
746 file->read(&rleHeader, sizeof(SMyRLEHeader)); 746 file->read(&rleHeader, sizeof(SMyRLEHeader));
747 747
748 //allocate memory for input and output buffers 748 //allocate memory for input and output buffers
749 void *input_buffer = (void*) new unsigned char[rleHeader.nEncodedBytes]; 749 void *input_buffer = (void*) new unsigned char[rleHeader.nEncodedBytes];
750 void *output_buffer = (void*) new unsigned char[rleHeader.nDecodedBytes]; 750 void *output_buffer = (void*) new unsigned char[rleHeader.nDecodedBytes];
751 751
752 // read encoded data 752 // read encoded data
753 file->read(input_buffer, rleHeader.nEncodedBytes); 753 file->read(input_buffer, rleHeader.nEncodedBytes);
754 754
755 // decode data 755 // decode data
756 data = 0;//(void*) new unsigned char[rleHeader.nDecodedBytes]; 756 data = 0;//(void*) new unsigned char[rleHeader.nDecodedBytes];
757 s32 decodedBytes = core::rle_decode( 757 s32 decodedBytes = core::rle_decode(
758 (unsigned char*)input_buffer, rleHeader.nEncodedBytes, 758 (unsigned char*)input_buffer, rleHeader.nEncodedBytes,
759 (unsigned char*)output_buffer, rleHeader.nDecodedBytes); 759 (unsigned char*)output_buffer, rleHeader.nDecodedBytes);
760 760
761 if (decodedBytes!=(s32)rleHeader.nDecodedBytes) 761 if (decodedBytes!=(s32)rleHeader.nDecodedBytes)
762 { 762 {
763 os::Printer::log("Error extracting data from RLE compression, loading failed!", ELL_ERROR); 763 os::Printer::log("Error extracting data from RLE compression, loading failed!", ELL_ERROR);
764 return 0; 764 return 0;
765 } 765 }
766 766
767 // free input buffer 767 // free input buffer
768 delete [] (unsigned char*)input_buffer; 768 delete [] (unsigned char*)input_buffer;
769 769
770 // here decoded data 770 // here decoded data
771 data = output_buffer; 771 data = output_buffer;
772 } 772 }
773 else if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_SIMPLE_ID) 773 else if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_SIMPLE_ID)
774 { 774 {
775 // simple compressed image data 775 // simple compressed image data
776 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) 776 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24)
777 data = (void*) new SMyPixelColor24[num_pixels]; 777 data = (void*) new SMyPixelColor24[num_pixels];
778 else 778 else
779 data = (void*) new SMyPixelColor16[num_pixels]; 779 data = (void*) new SMyPixelColor16[num_pixels];
780 780
781 u32 nReadedPixels=0, nToRead=0; 781 u32 nReadedPixels=0, nToRead=0;
782 while (true) 782 while (true)
783 { 783 {
784 file->read(&nToRead, sizeof(nToRead)); 784 file->read(&nToRead, sizeof(nToRead));
785 785
786 if ((nReadedPixels+nToRead) > num_pixels) 786 if ((nReadedPixels+nToRead) > num_pixels)
787 break; 787 break;
788 788
789 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) 789 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24)
790 { 790 {
791 SMyPixelColor24 col24; 791 SMyPixelColor24 col24;
792 file->read(&col24, sizeof(SMyPixelColor24)); 792 file->read(&col24, sizeof(SMyPixelColor24));
793 for (u32 p=0; p<nToRead; p++) 793 for (u32 p=0; p<nToRead; p++)
794 { 794 {
795 ((SMyPixelColor24*)data)[nReadedPixels+p] = 795 ((SMyPixelColor24*)data)[nReadedPixels+p] =
796 SMyPixelColor24(col24.r, col24.g, col24.b); 796 SMyPixelColor24(col24.r, col24.g, col24.b);
797 } 797 }
798 } 798 }
799 else 799 else
800 { 800 {
801 SMyPixelColor16 col16; 801 SMyPixelColor16 col16;
802 file->read(&col16, sizeof(SMyPixelColor16)); 802 file->read(&col16, sizeof(SMyPixelColor16));
803 for (u32 p=0; p<nToRead; p++) 803 for (u32 p=0; p<nToRead; p++)
804 ((SMyPixelColor16*)data)[nReadedPixels+p].argb = col16.argb; 804 ((SMyPixelColor16*)data)[nReadedPixels+p].argb = col16.argb;
805 } 805 }
806 806
807 nReadedPixels+=nToRead; 807 nReadedPixels+=nToRead;
808 808
809 if (nReadedPixels >= num_pixels) 809 if (nReadedPixels >= num_pixels)
810 break; 810 break;
811 } 811 }
812 812
813 if (nReadedPixels != num_pixels) 813 if (nReadedPixels != num_pixels)
814 { 814 {
815 os::Printer::log("Image data seems to be corrupted, loading failed!", ELL_ERROR); 815 os::Printer::log("Image data seems to be corrupted, loading failed!", ELL_ERROR);
816 return 0; 816 return 0;
817 } 817 }
818 } 818 }
819 819
820 //! Creates a software image from a byte array. 820 //! Creates a software image from a byte array.
821 video::IImage* light_img = 0; 821 video::IImage* light_img = 0;
822 822
823 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) 823 if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24)
824 { 824 {
825 // 24 bit lightmap format 825 // 24 bit lightmap format
826 light_img = SceneManager->getVideoDriver()->createImageFromData( 826 light_img = SceneManager->getVideoDriver()->createImageFromData(
827 video::ECF_R8G8B8, 827 video::ECF_R8G8B8,
828 core::dimension2d<u32>(texDataHeader.Width, texDataHeader.Height), 828 core::dimension2d<u32>(texDataHeader.Width, texDataHeader.Height),
829 data, true); 829 data, true);
830 } 830 }
831 else 831 else
832 { 832 {
833 // 16 bit lightmap format 833 // 16 bit lightmap format
834 light_img = SceneManager->getVideoDriver()->createImageFromData( 834 light_img = SceneManager->getVideoDriver()->createImageFromData(
835 video::ECF_A1R5G5B5, 835 video::ECF_A1R5G5B5,
836 core::dimension2d<u32>(texDataHeader.Width, texDataHeader.Height), 836 core::dimension2d<u32>(texDataHeader.Width, texDataHeader.Height),
837 data, true); 837 data, true);
838 } 838 }
839 839
840 const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); 840 const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
841 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); 841 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
842 video::ITexture* lmtex = SceneManager->getVideoDriver()->addTexture(LightMapName, light_img); 842 video::ITexture* lmtex = SceneManager->getVideoDriver()->addTexture(LightMapName, light_img);
843 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); 843 SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
844 844
845 light_img->drop(); 845 light_img->drop();
846 return lmtex; 846 return lmtex;
847} 847}
848 848
849 849
850CMY3DMeshFileLoader::SMyMaterialEntry* CMY3DMeshFileLoader::getMaterialEntryByIndex(u32 matInd) 850CMY3DMeshFileLoader::SMyMaterialEntry* CMY3DMeshFileLoader::getMaterialEntryByIndex(u32 matInd)
851{ 851{
852 for (u32 m=0; m<MaterialEntry.size(); ++m) 852 for (u32 m=0; m<MaterialEntry.size(); ++m)
853 if (MaterialEntry[m].Header.Index == matInd) 853 if (MaterialEntry[m].Header.Index == matInd)
854 return &MaterialEntry[m]; 854 return &MaterialEntry[m];
855 855
856 return 0; 856 return 0;
857} 857}
858 858
859 859
860 860
861SMeshBufferLightMap* CMY3DMeshFileLoader::getMeshBufferByMaterialIndex(u32 matInd) 861SMeshBufferLightMap* CMY3DMeshFileLoader::getMeshBufferByMaterialIndex(u32 matInd)
862{ 862{
863 for (u32 m=0; m<MeshBufferEntry.size(); ++m) 863 for (u32 m=0; m<MeshBufferEntry.size(); ++m)
864 { 864 {
865 if (MeshBufferEntry[m].MaterialIndex == (s32)matInd) 865 if (MeshBufferEntry[m].MaterialIndex == (s32)matInd)
866 return MeshBufferEntry[m].MeshBuffer; 866 return MeshBufferEntry[m].MeshBuffer;
867 } 867 }
868 return 0; 868 return 0;
869} 869}
870 870
871 871
872const core::array<ISceneNode*>& CMY3DMeshFileLoader::getChildNodes() const 872const core::array<ISceneNode*>& CMY3DMeshFileLoader::getChildNodes() const
873{ 873{
874 return ChildNodes; 874 return ChildNodes;
875} 875}
876 876
877 877
878} // end namespace scnene 878} // end namespace scnene
879} // end namespace irr 879} // end namespace irr
880 880
881#endif // _IRR_COMPILE_WITH_MY3D_LOADER_ 881#endif // _IRR_COMPILE_WITH_MY3D_LOADER_
882 882