~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/CSMFMeshFileLoader.cpp

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2010-2011 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
 
 
17
namespace irr
 
18
{
 
19
namespace scene
 
20
{
 
21
 
 
22
CSMFMeshFileLoader::CSMFMeshFileLoader(video::IVideoDriver* driver)
 
23
: Driver(driver)
 
24
{
 
25
}
 
26
 
 
27
//! Returns true if the file might be loaded by this class.
 
28
bool 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.
 
34
IAnimatedMesh* 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
 
 
67
void 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.
 
182
namespace io
 
183
{
 
184
 
 
185
#if _BIGENDIAN
 
186
#define _SYSTEM_BIG_ENDIAN_ (true)
 
187
#else
 
188
#define _SYSTEM_BIG_ENDIAN_ (false)
 
189
#endif
 
190
 
 
191
template <class T>
 
192
void 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
 
200
void 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
 
208
void 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
 
215
void 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