// 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_