aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp
new file mode 100644
index 0000000..099f2aa
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp
@@ -0,0 +1,232 @@
1// Copyright (C) 2010-2012 Gaz Davidson / Joseph Ellis
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "IrrCompileConfig.h"
6
7#ifdef _IRR_COMPILE_WITH_SMF_LOADER_
8
9#include "CSMFMeshFileLoader.h"
10#include "SAnimatedMesh.h"
11#include "SMeshBuffer.h"
12#include "IReadFile.h"
13#include "coreutil.h"
14#include "os.h"
15#include "IVideoDriver.h"
16
17namespace irr
18{
19namespace scene
20{
21
22CSMFMeshFileLoader::CSMFMeshFileLoader(video::IVideoDriver* driver)
23: Driver(driver)
24{
25}
26
27//! Returns true if the file might be loaded by this class.
28bool CSMFMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
29{
30 return core::hasFileExtension(filename, "smf");
31}
32
33//! Creates/loads an animated mesh from the file.
34IAnimatedMesh* CSMFMeshFileLoader::createMesh(io::IReadFile* file)
35{
36 // create empty mesh
37 SMesh *mesh = new SMesh();
38
39 // load file
40 u16 version;
41 u8 flags;
42 s32 limbCount;
43 s32 i;
44
45 io::BinaryFile::read(file, version);
46 io::BinaryFile::read(file, flags);
47 io::BinaryFile::read(file, limbCount);
48
49 // load mesh data
50 core::matrix4 identity;
51 for (i=0; i < limbCount; ++i)
52 loadLimb(file, mesh, identity);
53
54 // recalculate buffer bounding boxes
55 for (i=0; i < (s32)mesh->getMeshBufferCount(); ++i)
56 mesh->getMeshBuffer(i)->recalculateBoundingBox();
57
58 mesh->recalculateBoundingBox();
59 SAnimatedMesh *am = new SAnimatedMesh();
60 am->addMesh(mesh);
61 mesh->drop();
62 am->recalculateBoundingBox();
63
64 return am;
65}
66
67void CSMFMeshFileLoader::loadLimb(io::IReadFile* file, SMesh* mesh, const core::matrix4 &parentTransformation)
68{
69 core::matrix4 transformation;
70
71 // limb transformation
72 core::vector3df translate, rotate, scale;
73 io::BinaryFile::read(file, translate);
74 io::BinaryFile::read(file, rotate);
75 io::BinaryFile::read(file, scale);
76
77 transformation.setTranslation(translate);
78 transformation.setRotationDegrees(rotate);
79 transformation.setScale(scale);
80
81 transformation = parentTransformation * transformation;
82
83 core::stringc textureName, textureGroupName;
84
85 // texture information
86 io::BinaryFile::read(file, textureGroupName);
87 io::BinaryFile::read(file, textureName);
88
89 // attempt to load texture using known formats
90 video::ITexture* texture = 0;
91
92 const c8* extensions[] = {".jpg", ".png", ".tga", ".bmp", 0};
93
94 for (const c8 **ext = extensions; !texture && *ext; ++ext)
95 {
96 texture = Driver->getTexture(textureName + *ext);
97 if (texture)
98 textureName = textureName + *ext;
99 }
100 // find the correct mesh buffer
101 u32 i;
102 for (i=0; i<mesh->MeshBuffers.size(); ++i)
103 if (mesh->MeshBuffers[i]->getMaterial().TextureLayer[0].Texture == texture)
104 break;
105
106 // create mesh buffer if none was found
107 if (i == mesh->MeshBuffers.size())
108 {
109 CMeshBuffer<video::S3DVertex>* mb = new CMeshBuffer<video::S3DVertex>();
110 mb->Material.TextureLayer[0].Texture = texture;
111
112 // horribly hacky way to do this, maybe it's in the flags?
113 if (core::hasFileExtension(textureName, "tga", "png"))
114 mb->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
115 else
116 mb->Material.MaterialType = video::EMT_SOLID;
117
118 mesh->MeshBuffers.push_back(mb);
119 }
120
121 CMeshBuffer<video::S3DVertex>* mb = (CMeshBuffer<video::S3DVertex>*)mesh->MeshBuffers[i];
122
123 u16 vertexCount, firstVertex = mb->getVertexCount();
124
125 io::BinaryFile::read(file, vertexCount);
126 mb->Vertices.reallocate(mb->Vertices.size() + vertexCount);
127
128 // add vertices and set positions
129 for (i=0; i<vertexCount; ++i)
130 {
131 core::vector3df pos;
132 io::BinaryFile::read(file, pos);
133 transformation.transformVect(pos);
134 video::S3DVertex vert;
135 vert.Color = 0xFFFFFFFF;
136 vert.Pos = pos;
137 mb->Vertices.push_back(vert);
138 }
139
140 // set vertex normals
141 for (i=0; i < vertexCount; ++i)
142 {
143 core::vector3df normal;
144 io::BinaryFile::read(file, normal);
145 transformation.rotateVect(normal);
146 mb->Vertices[firstVertex + i].Normal = normal;
147 }
148 // set texture coordinates
149
150 for (i=0; i < vertexCount; ++i)
151 {
152 core::vector2df tcoords;
153 io::BinaryFile::read(file, tcoords);
154 mb->Vertices[firstVertex + i].TCoords = tcoords;
155 }
156
157 // triangles
158 u32 triangleCount;
159 // vertexCount used as temporary
160 io::BinaryFile::read(file, vertexCount);
161 triangleCount=3*vertexCount;
162 mb->Indices.reallocate(mb->Indices.size() + triangleCount);
163
164 for (i=0; i < triangleCount; ++i)
165 {
166 u16 index;
167 io::BinaryFile::read(file, index);
168 mb->Indices.push_back(firstVertex + index);
169 }
170
171 // read limbs
172 s32 limbCount;
173 io::BinaryFile::read(file, limbCount);
174
175 for (s32 l=0; l < limbCount; ++l)
176 loadLimb(file, mesh, transformation);
177}
178
179} // namespace scene
180
181// todo: at some point in the future let's move these to a place where everyone can use them.
182namespace io
183{
184
185#if _BIGENDIAN
186#define _SYSTEM_BIG_ENDIAN_ (true)
187#else
188#define _SYSTEM_BIG_ENDIAN_ (false)
189#endif
190
191template <class T>
192void BinaryFile::read(io::IReadFile* file, T &out, bool bigEndian)
193{
194 file->read((void*)&out, sizeof(out));
195 if (bigEndian != (_SYSTEM_BIG_ENDIAN_))
196 out = os::Byteswap::byteswap(out);
197}
198
199//! reads a 3d vector from the file, moving the file pointer along
200void BinaryFile::read(io::IReadFile* file, core::vector3df &outVector2d, bool bigEndian)
201{
202 BinaryFile::read(file, outVector2d.X, bigEndian);
203 BinaryFile::read(file, outVector2d.Y, bigEndian);
204 BinaryFile::read(file, outVector2d.Z, bigEndian);
205}
206
207//! reads a 2d vector from the file, moving the file pointer along
208void BinaryFile::read(io::IReadFile* file, core::vector2df &outVector2d, bool bigEndian)
209{
210 BinaryFile::read(file, outVector2d.X, bigEndian);
211 BinaryFile::read(file, outVector2d.Y, bigEndian);
212}
213
214//! reads a null terminated string from the file, moving the file pointer along
215void BinaryFile::read(io::IReadFile* file, core::stringc &outString, bool bigEndian)
216{
217 c8 c;
218 file->read((void*)&c, 1);
219
220 while (c)
221 {
222 outString += c;
223 file->read((void*)&c, 1);
224 }
225}
226
227} // namespace io
228
229} // namespace irr
230
231#endif // compile with SMF loader
232