aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp373
1 files changed, 373 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp
new file mode 100644
index 0000000..6969731
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp
@@ -0,0 +1,373 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4// This file was written by Jonas Petersen and modified by Nikolaus Gebhardt.
5// See CLMTSMeshFileLoder.h for details.
6/*
7
8CLMTSMeshFileLoader.cpp
9
10LMTSMeshFileLoader
11Written by Jonas Petersen (a.k.a. jox)
12
13Version 1.5 - 15 March 2005
14
15Get the latest version here: http://development.mindfloaters.de/
16
17This class allows loading meshes with lightmaps (*.lmts + *.tga files) that were created
18using Pulsar LMTools by Lord Trancos (http://www.geocities.com/dxlab/index_en.html)
19
20Notes:
21- This version does not support user data in the *.lmts files, but still loads those files (by skipping the extra data).
22
23License:
24--------
25
26It's free. You are encouraged to give me credit if you use it in your software.
27
28Version History:
29----------------
30
31Version 1.5 - 15 March 2005
32- Did a better cleanup. No memory leaks in case of an loading error.
33- Added "#include <stdio.h>" for sprintf.
34
35Version 1.4 - 12 March 2005
36- Fixed bug in texture and subset loading code that would possibly cause crash.
37- Fixed memory cleanup to avoid leak when loading more then one mesh
38- Used the irrlicht Logger instead of cerr to output warnings and errors.
39 For this I had to change the constructor
40 from:
41 CLMTSMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver)
42 to:
43 CLMTSMeshFileLoader(IrrlichtDevice* device)
44
45Version 1.3 - 15 February 2005
46- Fixed bug that prevented loading more than one different lmts files.
47- Removed unnecessary "#include <os.h>".
48- Added "std::" in front of "cerr". This was necessary for Visual Studio .NET,
49 I hope it's not disturbing other compilers.
50- Added warning message when a texture can not be loaded.
51- Changed the documentation a bit (minor).
52
53Version 1.2
54- To avoid confusion I skipped version 1.2 because the website was offering
55version 1.2 even though it was only version 1.1. Sorry about that.
56
57Version 1.1 - 29 July 2004
58- Added setTexturePath() function
59- Minor improvements
60
61Version 1.0 - 29 July 2004
62- Initial release
63
64
65*/
66//////////////////////////////////////////////////////////////////////
67
68#include "IrrCompileConfig.h"
69#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
70
71#include "SMeshBufferLightMap.h"
72#include "SAnimatedMesh.h"
73#include "SMeshBuffer.h"
74#include "irrString.h"
75#include "IReadFile.h"
76#include "IAttributes.h"
77#include "ISceneManager.h"
78#include "CLMTSMeshFileLoader.h"
79#include "os.h"
80
81namespace irr
82{
83namespace scene
84{
85
86CLMTSMeshFileLoader::CLMTSMeshFileLoader(io::IFileSystem* fs,
87 video::IVideoDriver* driver, io::IAttributes* parameters)
88 : Textures(0), Subsets(0), Triangles(0),
89 Parameters(parameters), Driver(driver), FileSystem(fs), FlipEndianess(false)
90{
91 #ifdef _DEBUG
92 setDebugName("CLMTSMeshFileLoader");
93 #endif
94
95 if (Driver)
96 Driver->grab();
97
98 if (FileSystem)
99 FileSystem->grab();
100}
101
102
103CLMTSMeshFileLoader::~CLMTSMeshFileLoader()
104{
105 cleanup();
106
107 if (Driver)
108 Driver->drop();
109
110 if (FileSystem)
111 FileSystem->drop();
112}
113
114
115void CLMTSMeshFileLoader::cleanup()
116{
117 delete [] Textures;
118 Textures = 0;
119 delete [] Subsets;
120 Subsets = 0;
121 delete [] Triangles;
122 Triangles = 0;
123}
124
125
126bool CLMTSMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
127{
128 return core::hasFileExtension ( filename, "lmts" );
129}
130
131
132IAnimatedMesh* CLMTSMeshFileLoader::createMesh(io::IReadFile* file)
133{
134 u32 i;
135 u32 id;
136
137 // HEADER
138
139 file->read(&Header, sizeof(SLMTSHeader));
140 if (Header.MagicID == 0x4C4D5354)
141 {
142 FlipEndianess = true;
143 Header.MagicID = os::Byteswap::byteswap(Header.MagicID);
144 Header.Version = os::Byteswap::byteswap(Header.Version);
145 Header.HeaderSize = os::Byteswap::byteswap(Header.HeaderSize);
146 Header.TextureCount = os::Byteswap::byteswap(Header.TextureCount);
147 Header.SubsetCount = os::Byteswap::byteswap(Header.SubsetCount);
148 Header.TriangleCount = os::Byteswap::byteswap(Header.TriangleCount);
149 Header.SubsetSize = os::Byteswap::byteswap(Header.SubsetSize);
150 Header.VertexSize = os::Byteswap::byteswap(Header.VertexSize);
151 }
152 if (Header.MagicID != 0x53544D4C) { // "LMTS"
153 os::Printer::log("LMTS ERROR: wrong header magic id!", ELL_ERROR);
154 return 0;
155 }
156
157 //Skip any User Data (arbitrary app specific data)
158
159 const s32 userSize = Header.HeaderSize - sizeof(SLMTSHeader);
160 if (userSize>0)
161 file->seek(userSize,true);
162
163 // TEXTURES
164
165 file->read(&id, sizeof(u32));
166 if (FlipEndianess)
167 id = os::Byteswap::byteswap(id);
168 if (id != 0x54584554) { // "TEXT"
169 os::Printer::log("LMTS ERROR: wrong texture magic id!", ELL_ERROR);
170 return 0;
171 }
172
173 Textures = new SLMTSTextureInfoEntry[Header.TextureCount];
174
175 file->read(Textures, sizeof(SLMTSTextureInfoEntry)*Header.TextureCount);
176 if (FlipEndianess)
177 {
178 for (i=0; i<Header.TextureCount; ++i)
179 Textures[i].Flags = os::Byteswap::byteswap(Textures[i].Flags);
180 }
181
182 // SUBSETS
183
184 file->read(&id, sizeof(u32));
185 if (FlipEndianess)
186 id = os::Byteswap::byteswap(id);
187 if (id != 0x53425553) // "SUBS"
188 {
189 os::Printer::log("LMTS ERROR: wrong subset magic id!", ELL_ERROR);
190 cleanup();
191 return 0;
192 }
193
194 Subsets = new SLMTSSubsetInfoEntry[Header.SubsetCount];
195 const s32 subsetUserSize = Header.SubsetSize - sizeof(SLMTSSubsetInfoEntry);
196
197 for (i=0; i<Header.SubsetCount; ++i)
198 {
199 file->read(&Subsets[i], sizeof(SLMTSSubsetInfoEntry));
200 if (FlipEndianess)
201 {
202 Subsets[i].Offset = os::Byteswap::byteswap(Subsets[i].Offset);
203 Subsets[i].Count = os::Byteswap::byteswap(Subsets[i].Count);
204 Subsets[i].TextID1 = os::Byteswap::byteswap(Subsets[i].TextID1);
205 Subsets[i].TextID2 = os::Byteswap::byteswap(Subsets[i].TextID2);
206 }
207 if (subsetUserSize>0)
208 file->seek(subsetUserSize,true);
209 }
210
211 // TRIANGLES
212
213 file->read(&id, sizeof(u32));
214 if (FlipEndianess)
215 id = os::Byteswap::byteswap(id);
216 if (id != 0x53495254) // "TRIS"
217 {
218 os::Printer::log("LMTS ERROR: wrong triangle magic id!", ELL_ERROR);
219 cleanup();
220 return 0;
221 }
222
223 Triangles = new SLMTSTriangleDataEntry[(Header.TriangleCount*3)];
224 const s32 triUserSize = Header.VertexSize - sizeof(SLMTSTriangleDataEntry);
225
226 for (i=0; i<(Header.TriangleCount*3); ++i)
227 {
228 file->read(&Triangles[i], sizeof(SLMTSTriangleDataEntry));
229 if (FlipEndianess)
230 {
231 Triangles[i].X = os::Byteswap::byteswap(Triangles[i].X);
232 Triangles[i].Y = os::Byteswap::byteswap(Triangles[i].Y);
233 Triangles[i].Z = os::Byteswap::byteswap(Triangles[i].Z);
234 Triangles[i].U1 = os::Byteswap::byteswap(Triangles[i].U1);
235 Triangles[i].V1 = os::Byteswap::byteswap(Triangles[i].U2);
236 Triangles[i].U2 = os::Byteswap::byteswap(Triangles[i].V1);
237 Triangles[i].V2 = os::Byteswap::byteswap(Triangles[i].V2);
238 }
239 if (triUserSize>0)
240 file->seek(triUserSize,true);
241 }
242
243 /////////////////////////////////////////////////////////////////
244
245 SMesh* mesh = new SMesh();
246
247 constructMesh(mesh);
248
249 loadTextures(mesh);
250
251 cleanup();
252
253 SAnimatedMesh* am = new SAnimatedMesh();
254 am->Type = EAMT_LMTS; // not unknown to irrlicht anymore
255
256 am->addMesh(mesh);
257 am->recalculateBoundingBox();
258 mesh->drop();
259 return am;
260}
261
262
263void CLMTSMeshFileLoader::constructMesh(SMesh* mesh)
264{
265 for (s32 i=0; i<Header.SubsetCount; ++i)
266 {
267 scene::SMeshBufferLightMap* meshBuffer = new scene::SMeshBufferLightMap();
268
269 // EMT_LIGHTMAP_M2/EMT_LIGHTMAP_M4 also possible
270 meshBuffer->Material.MaterialType = video::EMT_LIGHTMAP;
271 meshBuffer->Material.Wireframe = false;
272 meshBuffer->Material.Lighting = false;
273
274 mesh->addMeshBuffer(meshBuffer);
275
276 const u32 offs = Subsets[i].Offset * 3;
277
278 for (u32 sc=0; sc<Subsets[i].Count; sc++)
279 {
280 const u32 idx = meshBuffer->getVertexCount();
281
282 for (u32 vu=0; vu<3; ++vu)
283 {
284 const SLMTSTriangleDataEntry& v = Triangles[offs+(3*sc)+vu];
285 meshBuffer->Vertices.push_back(
286 video::S3DVertex2TCoords(
287 v.X, v.Y, v.Z,
288 video::SColor(255,255,255,255),
289 v.U1, v.V1, v.U2, v.V2));
290 }
291 const core::vector3df normal = core::plane3df(
292 meshBuffer->Vertices[idx].Pos,
293 meshBuffer->Vertices[idx+1].Pos,
294 meshBuffer->Vertices[idx+2].Pos).Normal;
295
296 meshBuffer->Vertices[idx].Normal = normal;
297 meshBuffer->Vertices[idx+1].Normal = normal;
298 meshBuffer->Vertices[idx+2].Normal = normal;
299
300 meshBuffer->Indices.push_back(idx);
301 meshBuffer->Indices.push_back(idx+1);
302 meshBuffer->Indices.push_back(idx+2);
303 }
304 meshBuffer->drop();
305 }
306
307 for (u32 j=0; j<mesh->MeshBuffers.size(); ++j)
308 mesh->MeshBuffers[j]->recalculateBoundingBox();
309
310 mesh->recalculateBoundingBox();
311}
312
313
314void CLMTSMeshFileLoader::loadTextures(SMesh* mesh)
315{
316 if (!Driver || !FileSystem)
317 return;
318
319 // load textures
320
321 // a little too much space, but won't matter here
322 core::array<video::ITexture*> tex;
323 tex.reallocate(Header.TextureCount);
324 core::array<video::ITexture*> lig;
325 lig.reallocate(Header.TextureCount);
326 core::array<u32> id2id;
327 id2id.reallocate(Header.TextureCount);
328
329 const core::stringc Path = Parameters->getAttributeAsString(LMTS_TEXTURE_PATH);
330
331 core::stringc s;
332 for (u32 t=0; t<Header.TextureCount; ++t)
333 {
334 video::ITexture* tmptex = 0;
335 s = Path;
336 s.append(Textures[t].Filename);
337
338 if (FileSystem->existFile(s))
339 tmptex = Driver->getTexture(s);
340 else
341 os::Printer::log("LMTS WARNING: Texture does not exist", s.c_str(), ELL_WARNING);
342
343 if (Textures[t].Flags & 0x01)
344 {
345 id2id.push_back(lig.size());
346 lig.push_back(tmptex);
347 }
348 else
349 {
350 id2id.push_back(tex.size());
351 tex.push_back(tmptex);
352 }
353 }
354
355 // attach textures to materials.
356
357 for (u32 i=0; i<Header.SubsetCount; ++i)
358 {
359 if (Subsets[i].TextID1 < Header.TextureCount && id2id[Subsets[i].TextID1] < tex.size())
360 mesh->getMeshBuffer(i)->getMaterial().setTexture(0, tex[id2id[Subsets[i].TextID1]]);
361 if (Subsets[i].TextID2 < Header.TextureCount && id2id[Subsets[i].TextID2] < lig.size())
362 mesh->getMeshBuffer(i)->getMaterial().setTexture(1, lig[id2id[Subsets[i].TextID2]]);
363
364 if (!mesh->getMeshBuffer(i)->getMaterial().getTexture(1))
365 mesh->getMeshBuffer(i)->getMaterial().MaterialType = video::EMT_SOLID;
366 }
367}
368
369
370} // end namespace scene
371} // end namespace irr
372
373#endif // _IRR_COMPILE_WITH_LMTS_LOADER_