irrlicht/source/Irrlicht/CPLYMeshWriter.cpp

184 lines
4.3 KiB
C++

// Copyright (C) 2008-2009 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_