- Colladawriter now exports materials per node when those are used in Irrlicht

- Colladawriter now writing matrices for node transformations as old solution did not work with CDummyTransformationSceneNode's.
- Colladawriter no longer create an extra node for the scenemanger as <visual_scene> has that job in Collada.
- Colladwriter no longer makes all Scenenodes children of ambient-light as that can be parallel on the same layer instead.
- Colladareader now creates the ambient-light correct instead of creating a point-light for it.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4267 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2012-08-03 16:13:41 +00:00
parent 80d80fcfe8
commit 7dc53232df
4 changed files with 150 additions and 42 deletions

View File

@ -1,5 +1,15 @@
Changes in 1.8 (??.??.2011)
- Colladawriter now exports materials per node when those are used in Irrlicht
- Colladawriter now writing matrices for node transformations as old solution did not work with CDummyTransformationSceneNode's.
- Colladawriter no longer create an extra node for the scenemanger as <visual_scene> has that job in Collada.
- Colladwriter no longer makes all Scenenodes children of ambient-light as that can be parallel on the same layer instead.
- Colladareader now creates the ambient-light correct instead of creating a point-light for it.
- Add IAnimatedMeshSceneNode::getLoopMode (asked for by JLouisB)
- CSceneNodeAnimatorCameraFPS now resets the key-input when it was disabled (thx @ gerdb for reporting and patch-proposal)

View File

@ -123,6 +123,9 @@ namespace
const char* const inputSemanticNames[] = {"POSITION", "VERTEX", "NORMAL", "TEXCOORD",
"UV", "TANGENT", "IMAGE", "TEXTURE", 0};
// We have to read ambient lights like other light types here, so we need a type for it
const video::E_LIGHT_TYPE ELT_AMBIENT = video::E_LIGHT_TYPE(video::ELT_COUNT+1);
}
//! following class is for holding and creating instances of library
@ -177,6 +180,12 @@ namespace
os::Printer::log("COLLADA: Constructing light instance", Id.c_str(), ELL_DEBUG);
#endif
if ( LightData.Type == ELT_AMBIENT )
{
mgr->setAmbientLight( LightData.DiffuseColor );
return 0;
}
scene::ILightSceneNode* l = mgr->addLightSceneNode(parent);
if (l)
{
@ -287,6 +296,7 @@ namespace
{
s->setName(getId());
s->getRelativeTransformationMatrix() = Transformation;
s->updateAbsolutePosition();
core::stringc t;
for (u32 i=0; i<16; ++i)
{
@ -2392,7 +2402,7 @@ void CColladaFileLoader::readLightPrefab(io::IXMLReaderUTF8* reader)
prefab->LightData.Type=video::ELT_SPOT;
else
if (ambientSectionName == reader->getNodeName())
prefab->LightData.Type=video::ELT_POINT; // TODO: This needs some change
prefab->LightData.Type=ELT_AMBIENT;
else
if (colorNodeName == reader->getNodeName())
prefab->LightData.DiffuseColor=readColorNode(reader);

View File

@ -253,18 +253,36 @@ bool CColladaMeshWriter::writeScene(io::IWriteFile* file, scene::ISceneNode* roo
Writer->writeElement(L"visual_scene", false, L"id", L"default_scene");
Writer->writeLineBreak();
// ambient light
// ambient light (instance_light also needs a node as parent so we have to create one)
Writer->writeElement(L"node", false);
Writer->writeLineBreak();
Writer->writeElement(L"instance_light", true, L"url", L"#ambientlight");
Writer->writeLineBreak();
// scenegraph
writeSceneNode(root);
Writer->writeClosingTag(L"node");
Writer->writeLineBreak();
// Write the scenegraph.
if ( root->getType() != ESNT_SCENE_MANAGER )
{
// TODO: Not certain if we should really write the root or if we should just always only write the children.
// For now writing root to keep backward compatibility for this case, but if anyone needs to _not_ write
// that root-node we can add a parameter for this later on in writeScene.
writeSceneNode(root);
}
else
{
// The visual_scene element is identical to our scenemanager and acts as root,
// so we do not write the root itself if it points to the scenemanager.
const core::list<ISceneNode*>& rootChildren = root->getChildren();
for ( core::list<ISceneNode*>::ConstIterator it = rootChildren.begin();
it != rootChildren.end();
++ it )
{
writeSceneNode(*it);
}
}
Writer->writeClosingTag(L"visual_scene");
Writer->writeLineBreak();
Writer->writeClosingTag(L"library_visual_scenes");
@ -321,11 +339,29 @@ void CColladaMeshWriter::writeNodeMaterials(irr::scene::ISceneNode * node)
IMesh* mesh = getProperties()->getMesh(node);
if ( mesh )
{
MeshNode * n = Meshes.find(mesh);
if ( n && !n->getValue().MaterialWritten )
if ( node->getType() == ESNT_MESH
&& static_cast<IMeshSceneNode*>(node)->isReadOnlyMaterials() )
{
writeMeshMaterials(n->getValue().Name, mesh);
n->getValue().MaterialWritten = true;
// no material overrides - write mesh materials
MeshNode * n = Meshes.find(mesh);
if ( n && !n->getValue().MaterialWritten )
{
writeMeshMaterials(n->getValue().Name, mesh);
n->getValue().MaterialWritten = true;
}
}
else
{
// write node materials
irr::core::stringw nodename(nameForNode(node));
for (u32 i=0; i<node->getMaterialCount(); ++i)
{
core::stringw strMat = "mat";
strMat += nodename;
strMat += i;
writeMaterial(strMat);
}
}
}
@ -336,6 +372,25 @@ void CColladaMeshWriter::writeNodeMaterials(irr::scene::ISceneNode * node)
}
}
void CColladaMeshWriter::writeMaterial(const irr::core::stringw& materialname)
{
Writer->writeElement(L"material", false,
L"id", materialname.c_str(),
L"name", materialname.c_str());
Writer->writeLineBreak();
// We don't make a difference between material and effect on export.
// Every material is just using an instance of an effect.
core::stringw strFx(materialname);
strFx += L"-fx";
Writer->writeElement(L"instance_effect", true,
L"url", (core::stringw(L"#") + strFx).c_str());
Writer->writeLineBreak();
Writer->writeClosingTag(L"material");
Writer->writeLineBreak();
}
void CColladaMeshWriter::writeNodeEffects(irr::scene::ISceneNode * node)
{
if ( !node || !getProperties() || !getProperties()->isExportable(node) )
@ -344,21 +399,33 @@ void CColladaMeshWriter::writeNodeEffects(irr::scene::ISceneNode * node)
IMesh* mesh = getProperties()->getMesh(node);
if ( mesh )
{
MeshNode * n = Meshes.find(mesh);
if ( n && !n->getValue().EffectWritten )
if ( node->getType() == ESNT_MESH
&& static_cast<IMeshSceneNode*>(node)->isReadOnlyMaterials() )
{
irr::core::stringw meshname(n->getValue().Name);
// no material overrides - write mesh materials
MeshNode * n = Meshes.find(mesh);
if ( n && !n->getValue().EffectWritten )
{
irr::core::stringw meshname(n->getValue().Name);
writeMeshEffects(meshname, mesh);
n->getValue().EffectWritten = true;
}
}
else
{
irr::core::stringw nodename(nameForNode(node));
irr::core::stringw meshname(nameForMesh(mesh)); // still need meshname for textures
// write node materials
for (u32 i=0; i<node->getMaterialCount(); ++i)
{
core::stringw strMat = "mat";
strMat += meshname;
strMat += nodename;
strMat += i;
strMat += L"-fx";
video::SMaterial & material = node->getMaterial(i);
writeMaterialEffect(meshname, strMat, material);
}
n->getValue().EffectWritten = true;
}
}
@ -505,12 +572,7 @@ void CColladaMeshWriter::writeSceneNode(irr::scene::ISceneNode * node )
Writer->writeElement(L"node", false, L"id", nameId.c_str());
Writer->writeLineBreak();
irr::core::vector3df rot(node->getRotation());
writeTranslateElement( node->getPosition() );
writeRotateElement( irr::core::vector3df(1.f, 0.f, 0.f), rot.X );
writeRotateElement( irr::core::vector3df(0.f, 1.f, 0.f), rot.Y );
writeRotateElement( irr::core::vector3df(0.f, 0.f, 1.f), rot.Z );
writeScaleElement( node->getScale() );
writeMatrixElement(node->getRelativeTransformation());
// instance geometry
IMesh* mesh = getProperties()->getMesh(node);
@ -518,7 +580,7 @@ void CColladaMeshWriter::writeSceneNode(irr::scene::ISceneNode * node )
{
MeshNode * n = Meshes.find(mesh);
if ( n )
writeMeshInstanceGeometry(n->getValue().Name, mesh);
writeMeshInstanceGeometry(n->getValue().Name, mesh, node);
}
// instance light
@ -648,8 +710,19 @@ bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32
return true;
}
void CColladaMeshWriter::writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh)
void CColladaMeshWriter::writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh, scene::ISceneNode* node)
{
core::stringw materialOwner;
if ( !node || ( node->getType() == ESNT_MESH )
&& static_cast<IMeshSceneNode*>(node)->isReadOnlyMaterials() )
{
materialOwner = meshname;
}
else
{
materialOwner = nameForNode(node);
}
//<instance_geometry url="#mesh">
core::stringw meshId(meshname);
Writer->writeElement(L"instance_geometry", false, L"url", toRef(meshId).c_str());
@ -665,12 +738,13 @@ void CColladaMeshWriter::writeMeshInstanceGeometry(const irr::core::stringw& mes
// <instance_material symbol="leaf" target="#MidsummerLeaf01"/>
for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
{
core::stringw strMat = "mat";
strMat += meshname;
strMat += i;
core::stringw strMatInst(L"#");
strMatInst += strMat;
Writer->writeElement(L"instance_material", false, L"symbol", strMat.c_str(), L"target", strMatInst.c_str());
core::stringw strMatSymbol = "mat";
strMatSymbol += meshname;
strMatSymbol += i;
core::stringw strMatTarget = "#mat";
strMatTarget += materialOwner;
strMatTarget += i;
Writer->writeElement(L"instance_material", false, L"symbol", strMatSymbol.c_str(), L"target", strMatTarget.c_str());
Writer->writeLineBreak();
// <bind_vertex_input semantic="mesh-TexCoord0" input_semantic="TEXCOORD" input_set="0"/>
@ -960,18 +1034,7 @@ void CColladaMeshWriter::writeMeshMaterials(const irr::core::stringw& meshname,
strMat += meshname;
strMat += i;
Writer->writeElement(L"material", false,
L"id", strMat.c_str(),
L"name", strMat.c_str());
Writer->writeLineBreak();
strMat += L"-fx";
Writer->writeElement(L"instance_effect", true,
L"url", (core::stringw(L"#") + strMat).c_str());
Writer->writeLineBreak();
Writer->writeClosingTag(L"material");
Writer->writeLineBreak();
writeMaterial(strMat);
}
}
@ -1922,6 +1985,29 @@ void CColladaMeshWriter::writeTranslateElement(const irr::core::vector3df& trans
Writer->writeLineBreak();
}
void CColladaMeshWriter::writeMatrixElement(const irr::core::matrix4& matrix)
{
Writer->writeElement(L"matrix", false);
Writer->writeLineBreak();
for ( int a=0; a<4; ++a )
{
irr::core::stringw txt;
for ( int b=0; b<4; ++b )
{
if ( b > 0 )
txt += " ";
// row-column switched compared to Irrlicht
txt += irr::core::stringw(matrix[b*4+a]);
}
Writer->writeText(txt.c_str());
Writer->writeLineBreak();
}
Writer->writeClosingTag(L"matrix");
Writer->writeLineBreak();
}
} // end namespace
} // end namespace

View File

@ -111,7 +111,8 @@ protected:
void writeMeshEffects(const irr::core::stringw& meshname, scene::IMesh* mesh);
void writeMaterialEffect(const irr::core::stringw& meshname, const irr::core::stringw& materialname, const video::SMaterial & material);
void writeMeshGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh);
void writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh);
void writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh, scene::ISceneNode* node=0);
void writeMaterial(const irr::core::stringw& materialname);
void writeLightInstance(const irr::core::stringw& lightName);
void writeLibraryImages();
void writeColorFx(const irr::core::stringw& meshname, const video::SMaterial & material, const wchar_t * colorname, E_COLLADA_COLOR_SAMPLER cs, const wchar_t* attr1Name=0, const wchar_t* attr1Value=0);
@ -124,6 +125,7 @@ protected:
void writeRotateElement(const irr::core::vector3df& axis, irr::f32 angle);
void writeScaleElement(const irr::core::vector3df& scale);
void writeTranslateElement(const irr::core::vector3df& translate);
void writeMatrixElement(const irr::core::matrix4& matrix);
struct SComponentGlobalStartPos
{