Reworked collada exporter somewhat so it no longer breaks the xml schema:

- blinn attributes have to ordered on writing 
- there is no flow="OUT" in accessor - param so I removed it (maybe that was from an older collada version?)
- material-name is without #
- input attribute is called offset not idx 
Also a little cleanup to avoid redundant code.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3817 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2011-06-07 19:11:28 +00:00
parent 23bb72ab6a
commit dabb165279
2 changed files with 117 additions and 159 deletions

View File

@ -79,7 +79,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"version", L"1.4.1");
Writer->writeLineBreak();
// write asset data
// write asset data
Writer->writeElement(L"asset", false);
Writer->writeLineBreak();
@ -165,92 +165,90 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
io::IAttributes* attributes = VideoDriver->createAttributesFromMaterial(
mesh->getMeshBuffer(i)->getMaterial());
u32 count = attributes->getAttributeCount();
for (u32 attridx=0; attridx<count; ++attridx)
// attributes must be written in fixed order
core::stringc str;
s32 attridx = attributes->findAttribute("Emissive");
if ( attridx >= 0 )
{
core::stringc str = attributes->getAttributeName(attridx);
if (str=="Emissive")
{
Writer->writeElement(L"emission", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
Writer->writeElement(L"emission", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"emission");
Writer->writeLineBreak();
}
else
if (str=="Ambient")
{
Writer->writeElement(L"ambient", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"emission");
Writer->writeLineBreak();
}
attridx = attributes->findAttribute("Ambient");
if ( attridx >= 0 )
{
Writer->writeElement(L"ambient", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"ambient");
Writer->writeLineBreak();
}
else
if (str=="Diffuse")
{
Writer->writeElement(L"diffuse", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"ambient");
Writer->writeLineBreak();
}
attridx = attributes->findAttribute("Diffuse");
if ( attridx >= 0 )
{
Writer->writeElement(L"diffuse", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"diffuse");
Writer->writeLineBreak();
}
else
if (str=="Specular")
{
Writer->writeElement(L"specular", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"diffuse");
Writer->writeLineBreak();
}
attridx = attributes->findAttribute("Specular");
if ( attridx >= 0 )
{
Writer->writeElement(L"specular", false);
Writer->writeLineBreak();
Writer->writeElement(L"color", false);
Writer->writeLineBreak();
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
str = attributes->getAttributeAsString(attridx);
str.replace(',',' ');
Writer->writeText(core::stringw(str.c_str()).c_str());
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"specular");
Writer->writeLineBreak();
}
else
if (str=="Shininess")
{
Writer->writeElement(L"shininess", false);
Writer->writeLineBreak();
Writer->writeElement(L"float", false);
Writer->writeLineBreak();
Writer->writeClosingTag(L"color");
Writer->writeLineBreak();
Writer->writeClosingTag(L"specular");
Writer->writeLineBreak();
}
attridx = attributes->findAttribute("Shininess");
if ( attridx >= 0 )
{
Writer->writeElement(L"shininess", false);
Writer->writeLineBreak();
Writer->writeElement(L"float", false);
Writer->writeLineBreak();
Writer->writeText(core::stringw(attributes->getAttributeAsString(attridx).c_str()).c_str());
Writer->writeText(core::stringw(attributes->getAttributeAsString(attridx).c_str()).c_str());
Writer->writeClosingTag(L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"shininess");
Writer->writeLineBreak();
}
Writer->writeClosingTag(L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"shininess");
Writer->writeLineBreak();
}
attributes->drop();
@ -332,14 +330,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Pos.X;
str += " ";
str += vtx[j].Pos.Y;
str += " ";
str += vtx[j].Pos.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Pos).c_str());
Writer->writeLineBreak();
}
}
@ -349,14 +340,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Pos.X;
str += " ";
str += vtx[j].Pos.Y;
str += " ";
str += vtx[j].Pos.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Pos).c_str());
Writer->writeLineBreak();
}
}
@ -366,14 +350,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Pos.X;
str += " ";
str += vtx[j].Pos.Y;
str += " ";
str += vtx[j].Pos.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Pos).c_str());
Writer->writeLineBreak();
}
}
@ -439,12 +416,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords.X;
str += " ";
str += vtx[j].TCoords.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords).c_str());
Writer->writeLineBreak();
}
}
@ -454,12 +426,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords.X;
str += " ";
str += vtx[j].TCoords.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords).c_str());
Writer->writeLineBreak();
}
}
@ -469,12 +436,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords.X;
str += " ";
str += vtx[j].TCoords.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords).c_str());
Writer->writeLineBreak();
}
}
@ -494,9 +456,9 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"count", vertexCountStr.c_str(), L"stride", L"2");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"accessor");
@ -538,14 +500,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Normal.X;
str += " ";
str += vtx[j].Normal.Y;
str += " ";
str += vtx[j].Normal.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Normal).c_str());
Writer->writeLineBreak();
}
}
@ -555,14 +510,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Normal.X;
str += " ";
str += vtx[j].Normal.Y;
str += " ";
str += vtx[j].Normal.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Normal).c_str());
Writer->writeLineBreak();
}
}
@ -572,14 +520,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].Normal.X;
str += " ";
str += vtx[j].Normal.Y;
str += " ";
str += vtx[j].Normal.Z;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].Normal).c_str());
Writer->writeLineBreak();
}
}
@ -599,11 +540,11 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"count", vertexCountStr.c_str(), L"stride", L"3");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"accessor");
@ -649,12 +590,7 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
for (u32 j=0; j<vertexCount; ++j)
{
core::stringw str;
str += vtx[j].TCoords2.X;
str += " ";
str += vtx[j].TCoords2.Y;
Writer->writeText(str.c_str());
Writer->writeText(toString(vtx[j].TCoords2).c_str());
Writer->writeLineBreak();
}
}
@ -677,9 +613,9 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
L"count", vertexCountStr.c_str(), L"stride", L"2");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float");
Writer->writeLineBreak();
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float", L"flow", L"OUT");
Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float");
Writer->writeLineBreak();
Writer->writeClosingTag(L"accessor");
@ -715,18 +651,18 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
const u32 polyCount = buffer->getIndexCount() / 3;
core::stringw strPolyCount(polyCount);
core::stringw strMat = "#mat";
core::stringw strMat = "mat";
strMat += i;
Writer->writeElement(L"triangles", false, L"count", strPolyCount.c_str(),
L"material", strMat.c_str());
Writer->writeLineBreak();
Writer->writeElement(L"input", true, L"semantic", L"VERTEX", L"source", L"#mesh-Vtx", L"idx", L"0");
Writer->writeElement(L"input", true, L"semantic", L"VERTEX", L"source", L"#mesh-Vtx", L"offset", L"0");
Writer->writeLineBreak();
Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", L"#mesh-TexCoord0", L"idx", L"1");
Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", L"#mesh-TexCoord0", L"offset", L"1");
Writer->writeLineBreak();
Writer->writeElement(L"input", true, L"semantic", L"NORMAL", L"source", L"#mesh-Normal", L"idx", L"2");
Writer->writeElement(L"input", true, L"semantic", L"NORMAL", L"source", L"#mesh-Normal", L"offset", L"2");
Writer->writeLineBreak();
bool has2ndTexCoords = hasSecondTextureCoordinates(buffer->getVertexType());
@ -823,6 +759,25 @@ bool CColladaMeshWriter::hasSecondTextureCoordinates(video::E_VERTEX_TYPE type)
return type == video::EVT_2TCOORDS;
}
irr::core::stringw CColladaMeshWriter::toString(const irr::core::vector3df& vec) const
{
core::stringw str;
str += vec.X;
str += " ";
str += vec.Y;
str += " ";
str += vec.Z;
return str;
}
irr::core::stringw CColladaMeshWriter::toString(const irr::core::vector2df& vec) const
{
core::stringw str;
str += vec.X;
str += " ";
str += vec.Y;
return str;
}
} // end namespace
} // end namespace

View File

@ -35,9 +35,12 @@ public:
//! writes a mesh
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE);
protected:
bool hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const;
inline irr::core::stringw toString(const irr::core::vector3df& vec) const;
inline irr::core::stringw toString(const irr::core::vector2df& vec) const;
struct SComponentGlobalStartPos
{