aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp
new file mode 100644
index 0000000..bf9ffb3
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp
@@ -0,0 +1,253 @@
1// Copyright (C) 2007-2012 Christian Stehno
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_STL_LOADER_
8
9#include "CSTLMeshFileLoader.h"
10#include "SMesh.h"
11#include "SMeshBuffer.h"
12#include "SAnimatedMesh.h"
13#include "IReadFile.h"
14#include "fast_atof.h"
15#include "coreutil.h"
16#include "os.h"
17
18namespace irr
19{
20namespace scene
21{
22
23
24//! returns true if the file maybe is able to be loaded by this class
25//! based on the file extension (e.g. ".bsp")
26bool CSTLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
27{
28 return core::hasFileExtension ( filename, "stl" );
29}
30
31
32
33//! creates/loads an animated mesh from the file.
34//! \return Pointer to the created mesh. Returns 0 if loading failed.
35//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
36//! See IReferenceCounted::drop() for more information.
37IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file)
38{
39 const long filesize = file->getSize();
40 if (filesize < 6) // we need a header
41 return 0;
42
43 SMesh* mesh = new SMesh();
44 SMeshBuffer* meshBuffer = new SMeshBuffer();
45 mesh->addMeshBuffer(meshBuffer);
46 meshBuffer->drop();
47
48 core::vector3df vertex[3];
49 core::vector3df normal;
50
51 bool binary = false;
52 core::stringc token;
53 if (getNextToken(file, token) != "solid")
54 binary = true;
55 // read/skip header
56 u32 binFaceCount = 0;
57 if (binary)
58 {
59 file->seek(80);
60 file->read(&binFaceCount, 4);
61#ifdef __BIG_ENDIAN__
62 binFaceCount = os::Byteswap::byteswap(binFaceCount);
63#endif
64 }
65 else
66 goNextLine(file);
67
68 u16 attrib=0;
69 token.reserve(32);
70
71 while (file->getPos() < filesize)
72 {
73 if (!binary)
74 {
75 if (getNextToken(file, token) != "facet")
76 {
77 if (token=="endsolid")
78 break;
79 mesh->drop();
80 return 0;
81 }
82 if (getNextToken(file, token) != "normal")
83 {
84 mesh->drop();
85 return 0;
86 }
87 }
88 getNextVector(file, normal, binary);
89 if (!binary)
90 {
91 if (getNextToken(file, token) != "outer")
92 {
93 mesh->drop();
94 return 0;
95 }
96 if (getNextToken(file, token) != "loop")
97 {
98 mesh->drop();
99 return 0;
100 }
101 }
102 for (u32 i=0; i<3; ++i)
103 {
104 if (!binary)
105 {
106 if (getNextToken(file, token) != "vertex")
107 {
108 mesh->drop();
109 return 0;
110 }
111 }
112 getNextVector(file, vertex[i], binary);
113 }
114 if (!binary)
115 {
116 if (getNextToken(file, token) != "endloop")
117 {
118 mesh->drop();
119 return 0;
120 }
121 if (getNextToken(file, token) != "endfacet")
122 {
123 mesh->drop();
124 return 0;
125 }
126 }
127 else
128 {
129 file->read(&attrib, 2);
130#ifdef __BIG_ENDIAN__
131 attrib = os::Byteswap::byteswap(attrib);
132#endif
133 }
134
135 SMeshBuffer* mb = reinterpret_cast<SMeshBuffer*>(mesh->getMeshBuffer(mesh->getMeshBufferCount()-1));
136 u32 vCount = mb->getVertexCount();
137 video::SColor color(0xffffffff);
138 if (attrib & 0x8000)
139 color = video::A1R5G5B5toA8R8G8B8(attrib);
140 if (normal==core::vector3df())
141 normal=core::plane3df(vertex[2],vertex[1],vertex[0]).Normal;
142 mb->Vertices.push_back(video::S3DVertex(vertex[2],normal,color, core::vector2df()));
143 mb->Vertices.push_back(video::S3DVertex(vertex[1],normal,color, core::vector2df()));
144 mb->Vertices.push_back(video::S3DVertex(vertex[0],normal,color, core::vector2df()));
145 mb->Indices.push_back(vCount);
146 mb->Indices.push_back(vCount+1);
147 mb->Indices.push_back(vCount+2);
148 } // end while (file->getPos() < filesize)
149 mesh->getMeshBuffer(0)->recalculateBoundingBox();
150
151 // Create the Animated mesh if there's anything in the mesh
152 SAnimatedMesh* pAM = 0;
153 if ( 0 != mesh->getMeshBufferCount() )
154 {
155 mesh->recalculateBoundingBox();
156 pAM = new SAnimatedMesh();
157 pAM->Type = EAMT_OBJ;
158 pAM->addMesh(mesh);
159 pAM->recalculateBoundingBox();
160 }
161
162 mesh->drop();
163
164 return pAM;
165}
166
167
168//! Read 3d vector of floats
169void CSTLMeshFileLoader::getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const
170{
171 if (binary)
172 {
173 file->read(&vec.X, 4);
174 file->read(&vec.Y, 4);
175 file->read(&vec.Z, 4);
176#ifdef __BIG_ENDIAN__
177 vec.X = os::Byteswap::byteswap(vec.X);
178 vec.Y = os::Byteswap::byteswap(vec.Y);
179 vec.Z = os::Byteswap::byteswap(vec.Z);
180#endif
181 }
182 else
183 {
184 goNextWord(file);
185 core::stringc tmp;
186
187 getNextToken(file, tmp);
188 core::fast_atof_move(tmp.c_str(), vec.X);
189 getNextToken(file, tmp);
190 core::fast_atof_move(tmp.c_str(), vec.Y);
191 getNextToken(file, tmp);
192 core::fast_atof_move(tmp.c_str(), vec.Z);
193 }
194 vec.X=-vec.X;
195}
196
197
198//! Read next word
199const core::stringc& CSTLMeshFileLoader::getNextToken(io::IReadFile* file, core::stringc& token) const
200{
201 goNextWord(file);
202 u8 c;
203 token = "";
204 while(file->getPos() != file->getSize())
205 {
206 file->read(&c, 1);
207 // found it, so leave
208 if (core::isspace(c))
209 break;
210 token.append(c);
211 }
212 return token;
213}
214
215
216//! skip to next word
217void CSTLMeshFileLoader::goNextWord(io::IReadFile* file) const
218{
219 u8 c;
220 while(file->getPos() != file->getSize())
221 {
222 file->read(&c, 1);
223 // found it, so leave
224 if (!core::isspace(c))
225 {
226 file->seek(-1, true);
227 break;
228 }
229 }
230}
231
232
233//! Read until line break is reached and stop at the next non-space character
234void CSTLMeshFileLoader::goNextLine(io::IReadFile* file) const
235{
236 u8 c;
237 // look for newline characters
238 while(file->getPos() != file->getSize())
239 {
240 file->read(&c, 1);
241 // found it, so leave
242 if (c=='\n' || c=='\r')
243 break;
244 }
245}
246
247
248} // end namespace scene
249} // end namespace irr
250
251
252#endif // _IRR_COMPILE_WITH_STL_LOADER_
253