aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshWriter.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshWriter.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshWriter.cpp
new file mode 100644
index 0000000..2f7f9bd
--- /dev/null
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshWriter.cpp
@@ -0,0 +1,315 @@
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
5#include "IrrCompileConfig.h"
6
7#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
8
9#include "CIrrMeshWriter.h"
10#include "os.h"
11#include "IWriteFile.h"
12#include "IXMLWriter.h"
13#include "IMesh.h"
14#include "IAttributes.h"
15
16namespace irr
17{
18namespace scene
19{
20
21
22CIrrMeshWriter::CIrrMeshWriter(video::IVideoDriver* driver,
23 io::IFileSystem* fs)
24 : FileSystem(fs), VideoDriver(driver), Writer(0)
25{
26 #ifdef _DEBUG
27 setDebugName("CIrrMeshWriter");
28 #endif
29
30 if (VideoDriver)
31 VideoDriver->grab();
32
33 if (FileSystem)
34 FileSystem->grab();
35}
36
37
38CIrrMeshWriter::~CIrrMeshWriter()
39{
40 if (VideoDriver)
41 VideoDriver->drop();
42
43 if (FileSystem)
44 FileSystem->drop();
45}
46
47
48//! Returns the type of the mesh writer
49EMESH_WRITER_TYPE CIrrMeshWriter::getType() const
50{
51 return EMWT_IRR_MESH;
52}
53
54
55//! writes a mesh
56bool CIrrMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
57{
58 if (!file)
59 return false;
60
61 Writer = FileSystem->createXMLWriter(file);
62
63 if (!Writer)
64 {
65 os::Printer::log("Could not write file", file->getFileName());
66 return false;
67 }
68
69 os::Printer::log("Writing mesh", file->getFileName());
70
71 // write IRR MESH header
72
73 Writer->writeXMLHeader();
74
75 Writer->writeElement(L"mesh", false,
76 L"xmlns", L"http://irrlicht.sourceforge.net/IRRMESH_09_2007",
77 L"version", L"1.0");
78 Writer->writeLineBreak();
79
80 // add some informational comment. Add a space after and before the comment
81 // tags so that some braindead xml parsers (AS anyone?) are able to parse this too.
82
83 core::stringw infoComment = L" This file contains a static mesh in the Irrlicht Engine format with ";
84 infoComment += core::stringw(mesh->getMeshBufferCount());
85 infoComment += L" materials.";
86
87 Writer->writeComment(infoComment.c_str());
88 Writer->writeLineBreak();
89
90 // write mesh bounding box
91
92 writeBoundingBox(mesh->getBoundingBox());
93 Writer->writeLineBreak();
94
95 // write mesh buffers
96
97 for (int i=0; i<(int)mesh->getMeshBufferCount(); ++i)
98 {
99 scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i);
100 if (buffer)
101 {
102 writeMeshBuffer(buffer);
103 Writer->writeLineBreak();
104 }
105 }
106
107 Writer->writeClosingTag(L"mesh");
108
109 Writer->drop();
110 return true;
111}
112
113
114void CIrrMeshWriter::writeBoundingBox(const core::aabbox3df& box)
115{
116 Writer->writeElement(L"boundingBox", true,
117 L"minEdge", getVectorAsStringLine(box.MinEdge).c_str(),
118 L"maxEdge", getVectorAsStringLine(box.MaxEdge).c_str());
119}
120
121
122core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector3df& v) const
123{
124 core::stringw str;
125
126 str = core::stringw(v.X);
127 str += L" ";
128 str += core::stringw(v.Y);
129 str += L" ";
130 str += core::stringw(v.Z);
131
132 return str;
133}
134
135
136core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector2df& v) const
137{
138 core::stringw str;
139
140 str = core::stringw(v.X);
141 str += L" ";
142 str += core::stringw(v.Y);
143
144 return str;
145}
146
147
148void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
149{
150 Writer->writeElement(L"buffer", false);
151 Writer->writeLineBreak();
152
153 // write bounding box
154
155 writeBoundingBox(buffer->getBoundingBox());
156 Writer->writeLineBreak();
157
158 // write material
159
160 writeMaterial(buffer->getMaterial());
161
162 // write vertices
163
164 const core::stringw vertexTypeStr = video::sBuiltInVertexTypeNames[buffer->getVertexType()];
165
166 Writer->writeElement(L"vertices", false,
167 L"type", vertexTypeStr.c_str(),
168 L"vertexCount", core::stringw(buffer->getVertexCount()).c_str());
169
170 Writer->writeLineBreak();
171
172 u32 vertexCount = buffer->getVertexCount();
173
174 switch(buffer->getVertexType())
175 {
176 case video::EVT_STANDARD:
177 {
178 video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
179 for (u32 j=0; j<vertexCount; ++j)
180 {
181 core::stringw str = getVectorAsStringLine(vtx[j].Pos);
182 str += L" ";
183 str += getVectorAsStringLine(vtx[j].Normal);
184
185 char tmp[12];
186 sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getGreen(), vtx[j].Color.getBlue());
187 str += tmp;
188
189 str += getVectorAsStringLine(vtx[j].TCoords);
190
191 Writer->writeText(str.c_str());
192 Writer->writeLineBreak();
193 }
194 }
195 break;
196 case video::EVT_2TCOORDS:
197 {
198 video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
199 for (u32 j=0; j<vertexCount; ++j)
200 {
201 core::stringw str = getVectorAsStringLine(vtx[j].Pos);
202 str += L" ";
203 str += getVectorAsStringLine(vtx[j].Normal);
204
205 char tmp[12];
206 sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getGreen(), vtx[j].Color.getBlue());
207 str += tmp;
208
209 str += getVectorAsStringLine(vtx[j].TCoords);
210 str += L" ";
211 str += getVectorAsStringLine(vtx[j].TCoords2);
212
213 Writer->writeText(str.c_str());
214 Writer->writeLineBreak();
215 }
216 }
217 break;
218 case video::EVT_TANGENTS:
219 {
220 video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
221 for (u32 j=0; j<vertexCount; ++j)
222 {
223 core::stringw str = getVectorAsStringLine(vtx[j].Pos);
224 str += L" ";
225 str += getVectorAsStringLine(vtx[j].Normal);
226
227 char tmp[12];
228 sprintf(tmp, " %02x%02x%02x%02x ", vtx[j].Color.getAlpha(), vtx[j].Color.getRed(), vtx[j].Color.getGreen(), vtx[j].Color.getBlue());
229 str += tmp;
230
231 str += getVectorAsStringLine(vtx[j].TCoords);
232 str += L" ";
233 str += getVectorAsStringLine(vtx[j].Tangent);
234 str += L" ";
235 str += getVectorAsStringLine(vtx[j].Binormal);
236
237 Writer->writeText(str.c_str());
238 Writer->writeLineBreak();
239 }
240 }
241 break;
242 }
243
244 Writer->writeClosingTag(L"vertices");
245 Writer->writeLineBreak();
246
247 // write indices
248
249 Writer->writeElement(L"indices", false,
250 L"indexCount", core::stringw(buffer->getIndexCount()).c_str());
251
252 Writer->writeLineBreak();
253
254 int indexCount = (int)buffer->getIndexCount();
255
256 video::E_INDEX_TYPE iType = buffer->getIndexType();
257
258 const u16* idx16 = buffer->getIndices();
259 const u32* idx32 = (u32*) buffer->getIndices();
260 const int maxIndicesPerLine = 25;
261
262 for (int i=0; i<indexCount; ++i)
263 {
264 if(iType == video::EIT_16BIT)
265 {
266 core::stringw str((int)idx16[i]);
267 Writer->writeText(str.c_str());
268 }
269 else
270 {
271 core::stringw str((int)idx32[i]);
272 Writer->writeText(str.c_str());
273 }
274
275 if (i % maxIndicesPerLine != maxIndicesPerLine)
276 {
277 if (i % maxIndicesPerLine == maxIndicesPerLine-1)
278 Writer->writeLineBreak();
279 else
280 Writer->writeText(L" ");
281 }
282 }
283
284 if ((indexCount-1) % maxIndicesPerLine != maxIndicesPerLine-1)
285 Writer->writeLineBreak();
286
287 Writer->writeClosingTag(L"indices");
288 Writer->writeLineBreak();
289
290 // close buffer tag
291
292 Writer->writeClosingTag(L"buffer");
293}
294
295
296void CIrrMeshWriter::writeMaterial(const video::SMaterial& material)
297{
298 // simply use irrlichts built-in attribute serialization capabilities here:
299
300 io::IAttributes* attributes =
301 VideoDriver->createAttributesFromMaterial(material);
302
303 if (attributes)
304 {
305 attributes->write(Writer, false, L"material");
306 attributes->drop();
307 }
308}
309
310
311} // end namespace
312} // end namespace
313
314#endif
315