.irrMesh writer implementation finished
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@927 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
71a1e46d7b
commit
8a3a2a2ad5
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -14,13 +14,15 @@ 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
|
//! class to write meshes, implementing a IrrMesh (.irrmesh, .xml) writer
|
||||||
merged out to the Irrlicht Engine */
|
/** This writer implementation has been originally developed for irrEdit and then
|
||||||
class CIrrMeshWriter : public IMeshWriter
|
merged out to the Irrlicht Engine */
|
||||||
{
|
class CIrrMeshWriter : public IMeshWriter
|
||||||
public:
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
CIrrMeshWriter(irr::video::IVideoDriver* driver, irr::io::IFileSystem* fs);
|
CIrrMeshWriter(irr::video::IVideoDriver* driver, irr::io::IFileSystem* fs);
|
||||||
virtual ~CIrrMeshWriter();
|
virtual ~CIrrMeshWriter();
|
||||||
|
@ -31,13 +33,24 @@ public:
|
||||||
//! writes a mesh
|
//! writes a mesh
|
||||||
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE);
|
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
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;
|
io::IFileSystem* FileSystem;
|
||||||
video::IVideoDriver* VideoDriver;
|
video::IVideoDriver* VideoDriver;
|
||||||
io::IXMLWriter* Writer;
|
io::IXMLWriter* Writer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
Loading…
Reference in New Issue