.irrMesh writer implementation finished

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@927 dfc29bdd-3216-0410-991c-e03cc46cb475
master
irrlicht 2007-09-08 15:26:47 +00:00
parent 71a1e46d7b
commit 8a3a2a2ad5
5 changed files with 277 additions and 30 deletions

View File

@ -155,14 +155,16 @@ public:
//! Reads attributes from a xml file. //! Reads attributes from a xml file.
//! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'.
//! \param elementName: The surrounding element name. If it is null, the default one, "attributes" will be taken.
//! If set to false, the first appearing list of attributes are read. //! If set to false, the first appearing list of attributes are read.
virtual bool read(irr::io::IXMLReader* reader, bool readCurrentElementOnly=false) = 0; virtual bool read(irr::io::IXMLReader* reader, bool readCurrentElementOnly=false, const wchar_t* elementName=0) = 0;
//! Write these attributes into a xml file //! Write these attributes into a xml file
//! \param writer: The XML writer to write to //! \param writer: The XML writer to write to
//! \param writeXMLHeader: Writes a header to the XML file, required if at the beginning of the file //! \param writeXMLHeader: Writes a header to the XML file, required if at the beginning of the file
//! \param elementName: The surrounding element name. If it is null, the default one, "attributes" will be taken.
//! and you haven't already written one with writer->writeXMLHeader() //! and you haven't already written one with writer->writeXMLHeader()
virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false) = 0; virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false, const wchar_t* elementName=0) = 0;
/* /*

View File

@ -1378,14 +1378,17 @@ void CAttributes::setAttribute(s32 index, void* userPointer)
//! Reads attributes from a xml file. //! Reads attributes from a xml file.
//! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'.
//! IF set to false, the first appearing list attributes are read. //! IF set to false, the first appearing list attributes are read.
bool CAttributes::read(irr::io::IXMLReader* reader, bool readCurrentElementOnly) bool CAttributes::read(irr::io::IXMLReader* reader, bool readCurrentElementOnly,
const wchar_t* nonDefaultElementName)
{ {
if (!reader) if (!reader)
return false; return false;
clear(); clear();
const core::stringw elementName = L"attributes"; core::stringw elementName = L"attributes";
if (nonDefaultElementName)
elementName = nonDefaultElementName;
if (readCurrentElementOnly) if (readCurrentElementOnly)
{ {
@ -1542,7 +1545,8 @@ void CAttributes::readAttributeFromXML(io::IXMLReader* reader)
} }
//! Write these attributes into a xml file //! Write these attributes into a xml file
bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader) bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader,
const wchar_t* nonDefaultElementName)
{ {
if (!writer) if (!writer)
return false; return false;
@ -1550,7 +1554,11 @@ bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader)
if (writeXMLHeader) if (writeXMLHeader)
writer->writeXMLHeader(); writer->writeXMLHeader();
writer->writeElement(L"attributes", false); core::stringw elementName = L"attributes";
if (nonDefaultElementName)
elementName = nonDefaultElementName;
writer->writeElement(elementName.c_str(), false);
writer->writeLineBreak(); writer->writeLineBreak();
s32 i=0; s32 i=0;
@ -1594,7 +1602,7 @@ bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader)
writer->writeLineBreak(); writer->writeLineBreak();
} }
writer->writeClosingTag(L"attributes"); writer->writeClosingTag(elementName.c_str());
writer->writeLineBreak(); writer->writeLineBreak();
return true; return true;

View File

@ -62,10 +62,11 @@ public:
//! Reads attributes from a xml file. //! Reads attributes from a xml file.
//! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'.
//! IF set to false, the first appearing list attributes are read. //! IF set to false, the first appearing list attributes are read.
virtual bool read(irr::io::IXMLReader* reader, bool readCurrentElementOnly=false); virtual bool read(irr::io::IXMLReader* reader, bool readCurrentElementOnly=false,
const wchar_t* nonDefaultElementName = 0);
//! Write these attributes into a xml file //! Write these attributes into a xml file
virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false); virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false, const wchar_t* nonDefaultElementName=0);
/* /*

View File

@ -59,20 +59,243 @@ bool CIrrMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
Writer->writeXMLHeader(); Writer->writeXMLHeader();
Writer->writeElement(L"irrmesh", false, Writer->writeElement(L"mesh", false,
L"xmlns", L"http://irrlicht.sourceforge.net/IRRMESH_08_2007", L"xmlns", L"http://irrlicht.sourceforge.net/IRRMESH_09_2007",
L"version", L"1.0"); L"version", L"1.0");
Writer->writeLineBreak(); Writer->writeLineBreak();
// write mesh // add some informational comment. Add a space after and before the comment
// tags so that some braindead xml parsers (AS anyone?) are able to parse this too.
// TODO: implement core::stringw infoComment = L" This file contains a static mesh in the Irrlicht Engine format with ";
infoComment += core::stringw(mesh->getMeshBufferCount());
infoComment += L" materials.";
Writer->writeComment(infoComment.c_str());
Writer->writeLineBreak();
// write mesh bounding box
writeBoundingBox(mesh->getBoundingBox());
Writer->writeLineBreak();
// write mesh buffers
for (int i=0; i<(int)mesh->getMeshBufferCount(); ++i)
{
irr::scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i);
if (buffer)
{
writeMeshBuffer(buffer);
Writer->writeLineBreak();
}
}
Writer->writeClosingTag(L"mesh");
Writer->drop(); Writer->drop();
return true; return true;
} }
void CIrrMeshWriter::writeBoundingBox(const core::aabbox3df& box)
{
Writer->writeElement(L"boundingBox", true,
L"minEdge", getVectorAsStringLine(box.MinEdge).c_str(),
L"maxEdge", getVectorAsStringLine(box.MaxEdge).c_str() );
}
core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector3df& v)
{
core::stringw str;
str = core::stringw(v.X);
str += L" ";
str += core::stringw(v.Y);
str += L" ";
str += core::stringw(v.Z);
return str;
}
core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector2df& v)
{
core::stringw str;
str = core::stringw(v.X);
str += L" ";
str += core::stringw(v.Y);
return str;
}
void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
{
Writer->writeElement(L"buffer", false);
Writer->writeLineBreak();
// write bounding box
writeBoundingBox(buffer->getBoundingBox());
Writer->writeLineBreak();
// write material
writeMaterial(buffer->getMaterial());
// write vertices
const wchar_t* vertexTypeStr;
switch(buffer->getVertexType())
{
case video::EVT_STANDARD:
vertexTypeStr = L"standard";
break;
case video::EVT_TANGENTS:
vertexTypeStr = L"tangents";
break;
case video::EVT_2TCOORDS:
default:
vertexTypeStr = L"2tcoords";
break;
}
Writer->writeElement(L"vertices", false,
L"type", vertexTypeStr,
L"vertexCount", core::stringw(buffer->getVertexCount()).c_str());
Writer->writeLineBreak();
int vertexCount = (int)buffer->getVertexCount();
switch(buffer->getVertexType())
{
case video::EVT_STANDARD:
{
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (int j=0; j<vertexCount; ++j)
{
core::stringw str = getVectorAsStringLine(vtx[j].Pos);
str += L" ";
str += getVectorAsStringLine(vtx[j].Normal);
char tmp[12];
sprintf(tmp, " %08x ", vtx[j].Color);
str += tmp;
str += getVectorAsStringLine(vtx[j].TCoords);
Writer->writeText(str.c_str());
Writer->writeLineBreak();
}
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (int j=0; j<vertexCount; ++j)
{
core::stringw str = getVectorAsStringLine(vtx[j].Pos);
str += L" ";
str += getVectorAsStringLine(vtx[j].Normal);
char tmp[12];
sprintf(tmp, " %08x ", vtx[j].Color);
str += tmp;
str += getVectorAsStringLine(vtx[j].TCoords);
str += L" ";
str += getVectorAsStringLine(vtx[j].TCoords2);
Writer->writeText(str.c_str());
Writer->writeLineBreak();
}
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (int j=0; j<vertexCount; ++j)
{
core::stringw str = getVectorAsStringLine(vtx[j].Pos);
str += L" ";
str += getVectorAsStringLine(vtx[j].Normal);
char tmp[12];
sprintf(tmp, " %08x ", vtx[j].Color);
str += tmp;
str += getVectorAsStringLine(vtx[j].TCoords);
str += L" ";
str += getVectorAsStringLine(vtx[j].Tangent);
str += L" ";
str += getVectorAsStringLine(vtx[j].Binormal);
Writer->writeText(str.c_str());
Writer->writeLineBreak();
}
}
break;
}
Writer->writeClosingTag(L"vertices");
Writer->writeLineBreak();
// write indices
Writer->writeElement(L"indices", false,
L"indexCount", core::stringw(buffer->getIndexCount()).c_str());
Writer->writeLineBreak();
int indexCount = (int)buffer->getIndexCount();
const u16* idx = buffer->getIndices();
const int maxIndicesPerLine = 25;
for (int i=0; i<indexCount; ++i)
{
core::stringw str((int)idx[i]);
Writer->writeText(str.c_str());
if (i % maxIndicesPerLine != maxIndicesPerLine)
{
if (i % maxIndicesPerLine == maxIndicesPerLine-1)
Writer->writeLineBreak();
else
Writer->writeText(L" ");
}
}
if ((indexCount-1) % maxIndicesPerLine != maxIndicesPerLine-1)
Writer->writeLineBreak();
Writer->writeClosingTag(L"indices");
Writer->writeLineBreak();
// close buffer tag
Writer->writeClosingTag(L"buffer");
}
void CIrrMeshWriter::writeMaterial(const video::SMaterial& material)
{
// simply use irrlichts built-in attribute serialization capabilities here:
irr::io::IAttributes* attributes =
VideoDriver->createAttributesFromMaterial(material);
if (attributes)
{
attributes->write(Writer, false, L"material");
attributes->drop();
}
}
} // end namespace } // end namespace
} // end namespace } // end namespace

View File

@ -14,30 +14,43 @@ namespace io
} }
namespace scene namespace scene
{ {
class IMeshBuffer;
//! class to write meshes, implementing a IrrMesh (.irrmesh, .xml) writer
/** This writer implementation has been originally developed for irrEdit and then
merged out to the Irrlicht Engine */
class CIrrMeshWriter : public IMeshWriter
{
public:
CIrrMeshWriter(irr::video::IVideoDriver* driver, irr::io::IFileSystem* fs); //! class to write meshes, implementing a IrrMesh (.irrmesh, .xml) writer
virtual ~CIrrMeshWriter(); /** This writer implementation has been originally developed for irrEdit and then
merged out to the Irrlicht Engine */
class CIrrMeshWriter : public IMeshWriter
{
public:
//! Returns the type of the mesh writer CIrrMeshWriter(irr::video::IVideoDriver* driver, irr::io::IFileSystem* fs);
virtual EMESH_WRITER_TYPE getType() const; virtual ~CIrrMeshWriter();
//! writes a mesh //! Returns the type of the mesh writer
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); virtual EMESH_WRITER_TYPE getType() const;
protected: //! writes a mesh
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE);
io::IFileSystem* FileSystem; protected:
video::IVideoDriver* VideoDriver;
io::IXMLWriter* Writer;
};
void writeBoundingBox(const core::aabbox3df& box);
void writeMeshBuffer(const scene::IMeshBuffer* buffer);
void writeMaterial(const video::SMaterial& material);
core::stringw getVectorAsStringLine(const core::vector3df& v);
core::stringw getVectorAsStringLine(const core::vector2df& v);
// member variables:
io::IFileSystem* FileSystem;
video::IVideoDriver* VideoDriver;
io::IXMLWriter* Writer;
};
} // end namespace } // end namespace
} // end namespace } // end namespace