mirror of
https://github.com/minetest/irrlicht.git
synced 2024-09-07 05:10:19 +02:00
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6000 dfc29bdd-3216-0410-991c-e03cc46cb475
221 lines
5.1 KiB
C++
221 lines
5.1 KiB
C++
// 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";
|
|
|
|
if (flags & scene::EMWF_WRITE_BINARY)
|
|
{
|
|
#ifdef __BIG_ENDIAN__
|
|
header += "format binary_big_endian 1.0\n";
|
|
#else
|
|
header += "format binary_little_endian 1.0\n";
|
|
#endif
|
|
}
|
|
else
|
|
header += "format ascii 1.0\n";
|
|
|
|
header += "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"
|
|
"property float s\n"
|
|
"property float t\n"
|
|
"property uchar red\n"
|
|
"property uchar green\n"
|
|
"property uchar blue\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)
|
|
{
|
|
const scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
|
|
u32 vertexSize = 0;
|
|
switch(mb->getVertexType())
|
|
{
|
|
case video::EVT_STANDARD:
|
|
vertexSize = sizeof(video::S3DVertex);
|
|
break;
|
|
case video::EVT_2TCOORDS:
|
|
vertexSize = sizeof(video::S3DVertex2TCoords);
|
|
break;
|
|
case video::EVT_TANGENTS:
|
|
vertexSize = sizeof(video::S3DVertexTangents);
|
|
break;
|
|
}
|
|
u8 *vertices = (u8*)mb->getVertices() ;
|
|
|
|
for (u32 j=0; j < mb->getVertexCount(); ++j)
|
|
{
|
|
u8 *buf = vertices + j * vertexSize;
|
|
const video::S3DVertex* vertex = ( (video::S3DVertex*)buf );
|
|
const core::vector3df& pos = vertex->Pos;
|
|
const core::vector3df& n = vertex->Normal;
|
|
const core::vector2df& uv = vertex->TCoords;
|
|
const video::SColor& color = vertex->Color;
|
|
|
|
if (flags & scene::EMWF_WRITE_BINARY)
|
|
{
|
|
// Y and Z are flipped
|
|
file->write(&pos.X, 4);
|
|
file->write(&pos.Z, 4);
|
|
file->write(&pos.Y, 4);
|
|
|
|
file->write(&n.X, 4);
|
|
file->write(&n.Z, 4);
|
|
file->write(&n.Y, 4);
|
|
|
|
file->write(&uv, 8);
|
|
|
|
const u32 r = color.getRed(), g = color.getGreen(), b = color.getBlue();
|
|
file->write(&r, 1);
|
|
file->write(&g, 1);
|
|
file->write(&b, 1);
|
|
}
|
|
else
|
|
{
|
|
// x y z nx ny nz u v red green blue [u1 v1 | tx ty tz]\n
|
|
snprintf_irr(outLine, 1024,
|
|
"%f %f %f %f %f %f %f %f %d %d %d\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,
|
|
uv.X, uv.Y,
|
|
color.getRed(), color.getGreen(), color.getBlue());
|
|
|
|
file->write(outLine, strlen(outLine));
|
|
}
|
|
}
|
|
}
|
|
|
|
// index of the first vertex in the current mesh buffer
|
|
u32 StartOffset = 0;
|
|
|
|
// write triangles
|
|
const unsigned char nbIndicesParFace = 3;
|
|
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;
|
|
u32 b=StartOffset;
|
|
u32 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+1];
|
|
b += ((u32*)mb->getIndices()) [j+2];
|
|
break;
|
|
}
|
|
|
|
if (flags & scene::EMWF_WRITE_BINARY)
|
|
{
|
|
file->write(&nbIndicesParFace, 1);
|
|
file->write(&a, 4);
|
|
file->write(&b, 4);
|
|
file->write(&c, 4);
|
|
}
|
|
else
|
|
{
|
|
// count a b c\n
|
|
snprintf_irr(outLine, 1024, "3 %u %u %u\n", a, b, c);
|
|
file->write(outLine, strlen(outLine));
|
|
}
|
|
}
|
|
|
|
// increment offset
|
|
StartOffset += mb->getVertexCount();
|
|
}
|
|
|
|
// all done!
|
|
return true;
|
|
}
|
|
|
|
} // end namespace
|
|
} // end namespace
|
|
|
|
#endif // _IRR_COMPILE_WITH_PLY_WRITER_
|
|
|