diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CIrrMeshWriter.cpp | 315 |
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 | |||
16 | namespace irr | ||
17 | { | ||
18 | namespace scene | ||
19 | { | ||
20 | |||
21 | |||
22 | CIrrMeshWriter::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 | |||
38 | CIrrMeshWriter::~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 | ||
49 | EMESH_WRITER_TYPE CIrrMeshWriter::getType() const | ||
50 | { | ||
51 | return EMWT_IRR_MESH; | ||
52 | } | ||
53 | |||
54 | |||
55 | //! writes a mesh | ||
56 | bool 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 | |||
114 | void 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 | |||
122 | core::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 | |||
136 | core::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 | |||
148 | void 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 | |||
296 | void 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 | |||