aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.cpp
blob: c9f05c89c42ecca258b37567eaf2f40d4eb5130c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright (C) 2008-2012 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#include "IrrCompileConfig.h" 

#ifdef _IRR_COMPILE_WITH_PLY_WRITER_

#include "CPLYMeshWriter.h"
#include "os.h"
#include "IMesh.h"
#include "IMeshBuffer.h"
#include "IWriteFile.h"

namespace irr
{
namespace scene
{

CPLYMeshWriter::CPLYMeshWriter()
{
	#ifdef _DEBUG
	setDebugName("CPLYMeshWriter");
	#endif
}


//! Returns the type of the mesh writer
EMESH_WRITER_TYPE CPLYMeshWriter::getType() const
{
	return EMWT_PLY;
}

//! writes a mesh
bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	if (!file || !mesh)
		return false;

	os::Printer::log("Writing mesh", file->getFileName());

	// write PLY header
	core::stringc header = 
        	"ply\n"
		"format ascii 1.0\n" 
		"comment Irrlicht Engine ";
	header +=  IRRLICHT_SDK_VERSION;

	// get vertex and triangle counts
	u32 VertexCount   = 0;
	u32 TriangleCount = 0;

	for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
	{
		VertexCount   += mesh->getMeshBuffer(i)->getVertexCount();
		TriangleCount += mesh->getMeshBuffer(i)->getIndexCount() / 3;
	}

	// vertex definition
	header += "\nelement vertex ";
	header += VertexCount;

	header += "\n"
		"property float x\n"
		"property float y\n"
		"property float z\n"
		"property float nx\n"
		"property float ny\n"
		"property float nz\n";
	// todo: writer flags for extended (r,g,b,u,v) and non-standard (alpha,u1,uv,tx,ty,tz) properties
	//	"property uchar red\n"
	//	"property uchar green\n"
	//	"property uchar blue\n"
	//	"property uchar alpha\n"
	//	"property float u\n"
	//	"property float v\n";
	//	"property float u1\n
	//	"property float v1\n"
	//	"property float tx\n"
	//	"property float ty\n"
	//	"property float tz\n"

	// face definition

	header += "element face ";
	header += TriangleCount;
	header += "\n" 
		"property list uchar int vertex_indices\n"
		"end_header\n";

	// write header
	file->write(header.c_str(), header.size());

	// write vertices

	c8 outLine[1024];

	for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
	{
		scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
		for (u32 j=0; j < mb->getVertexCount(); ++j)
		{
			const core::vector3df& pos = mb->getPosition(j);
			const core::vector3df& n   = mb->getNormal(j);
//			const core::vector2df& tc  = mb->getTCoords(j);

			u8 *buf  = (u8*)mb->getVertices();
			switch(mb->getVertexType())
			{
			case video::EVT_STANDARD:
				buf += sizeof(video::S3DVertex)*j;
				break;
			case video::EVT_2TCOORDS:
				buf += sizeof(video::S3DVertex2TCoords)*j;
				break;
			case video::EVT_TANGENTS:
				buf += sizeof(video::S3DVertexTangents)*j;
				break;
			}
//			video::SColor &col = ( (video::S3DVertex*)buf )->Color;

			// x y z nx ny nz red green blue alpha u v [u1 v1 | tx ty tz]\n
			snprintf(outLine, 1024, 
				"%f %f %f %f %f %f\n",// %u %u %u %u %f %f\n", 
				pos.X, pos.Z, pos.Y, // Y and Z are flipped
				n.X, n.Z, n.Y); 
				/*col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha(), 
				tc.X, tc.Y);*/

			// write the line
			file->write(outLine, strlen(outLine));
		}
	}

	// index of the first vertex in the current mesh buffer
	u32 StartOffset = 0;

	// write triangles
	for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
	{
		scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
		for (u32 j=0; j < mb->getIndexCount(); j+=3)
		{
			// y and z are flipped so triangles are reversed
			u32 a=StartOffset, 
			    b=StartOffset, 
			    c=StartOffset;

			switch(mb->getIndexType())
			{
			case video::EIT_16BIT:
				a += mb->getIndices()[j+0];
				c += mb->getIndices()[j+1];
				b += mb->getIndices()[j+2];
				break;
			case video::EIT_32BIT:
				a += ((u32*)mb->getIndices()) [j+0];
				c += ((u32*)mb->getIndices()) [j+0];
				b += ((u32*)mb->getIndices()) [j+0];
				break;
			}

			// count a b c\n
			snprintf(outLine, 1024, "3 %u %u %u\n", a, b, c);
			// write the line
			file->write(outLine, strlen(outLine));
		}

		// increment offset
		StartOffset += mb->getVertexCount();
	}

	// all done!
	

	return true;
}

} // end namespace
} // end namespace

#endif // _IRR_COMPILE_WITH_PLY_WRITER_