- corrected example code in the documentation. Thanks to Ingrater to point it out.
- Further work on the Collada loader. Halve way through the material import, I have to leave it here and continue at home. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@253 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
9fc698bb2f
commit
5639220859
|
@ -66,6 +66,13 @@ struct Transform
|
|||
float f[16]; ///< Interpretation of data depends on the type of the transformation
|
||||
};
|
||||
|
||||
/** A reference to a mesh inside a node, including materials assigned to the various subgroups */
|
||||
struct MeshInstance
|
||||
{
|
||||
std::string mMesh; ///< ID of the mesh
|
||||
std::map<std::string, std::string> mMaterials; ///< Map of materials by the subgroup ID they're applied to
|
||||
};
|
||||
|
||||
/** A node in a scene hierarchy */
|
||||
struct Node
|
||||
{
|
||||
|
@ -77,7 +84,7 @@ struct Node
|
|||
/** Operations in order to calculate the resulting transformation to parent. */
|
||||
std::vector<Transform> mTransforms;
|
||||
|
||||
std::vector<std::string> mMeshes; ///< Meshes at this node
|
||||
std::vector<MeshInstance> mMeshes; ///< Meshes at this node
|
||||
|
||||
Node() { mParent = NULL; }
|
||||
~Node() { for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) delete *it; }
|
||||
|
@ -166,6 +173,48 @@ enum PrimitiveType
|
|||
Prim_Polygon
|
||||
};
|
||||
|
||||
/** A collada material. Pretty much the only member is a reference to an effect. */
|
||||
struct Material
|
||||
{
|
||||
std::string mEffect;
|
||||
};
|
||||
|
||||
/** Shading type supported by the standard effect spec of Collada */
|
||||
enum ShadeType
|
||||
{
|
||||
Shade_Invalid,
|
||||
Shade_Constant,
|
||||
Shade_Lambert,
|
||||
Shade_Phong,
|
||||
Shade_Blinn
|
||||
};
|
||||
|
||||
|
||||
/** A collada effect. Can contain about anything according to the Collada spec, but we limit our version to a reasonable subset. */
|
||||
struct Effect
|
||||
{
|
||||
ShadeType mShadeType;
|
||||
aiColor4D mEmmisive, mAmbient, mDiffuse, mSpecular;
|
||||
aiColor4D mReflectivity, mRefractivity;
|
||||
std::string mTexEmmisive, mTexAmbient, mTexDiffuse, mTexSpecular;
|
||||
float mShininess, mRefractIndex;
|
||||
|
||||
Effect() : mEmmisive( 0, 0, 0, 1), mAmbient( 0.1f, 0.1f, 0.1f, 1),
|
||||
mDiffuse( 0.6f, 0.6f, 0.6f, 1), mSpecular( 0.4f, 0.4f, 0.4f, 1),
|
||||
mReflectivity( 0, 0, 0, 0), mRefractivity( 0, 0, 0, 0)
|
||||
{
|
||||
mShadeType = Shade_Phong;
|
||||
mShininess = 10;
|
||||
mRefractIndex = 1;
|
||||
}
|
||||
};
|
||||
|
||||
/** An image, meaning texture */
|
||||
struct Image
|
||||
{
|
||||
std::string mFileName;
|
||||
};
|
||||
|
||||
} // end of namespace Collada
|
||||
} // end of namespace Assimp
|
||||
|
||||
|
|
|
@ -159,18 +159,18 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
|||
std::vector<size_t> newMeshRefs;
|
||||
|
||||
// for the moment we simply ignore all material tags and transfer the meshes one by one
|
||||
BOOST_FOREACH( const std::string& mid, pNode->mMeshes)
|
||||
BOOST_FOREACH( const Collada::MeshInstance& mid, pNode->mMeshes)
|
||||
{
|
||||
// find the referred mesh
|
||||
ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find( mid);
|
||||
ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find( mid.mMesh);
|
||||
if( srcMeshIt == pParser.mMeshLibrary.end())
|
||||
{
|
||||
DefaultLogger::get()->warn( boost::str( boost::format( "Unable to find geometry for ID \"%s\". Skipping.") % mid));
|
||||
DefaultLogger::get()->warn( boost::str( boost::format( "Unable to find geometry for ID \"%s\". Skipping.") % mid.mMesh));
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we already have the mesh at the library, just add its index to the node's array
|
||||
std::map<std::string, size_t>::const_iterator dstMeshIt = mMeshIndexbyID.find( mid);
|
||||
std::map<std::string, size_t>::const_iterator dstMeshIt = mMeshIndexbyID.find( mid.mMesh);
|
||||
if( dstMeshIt != mMeshIndexbyID.end())
|
||||
{
|
||||
newMeshRefs.push_back( dstMeshIt->second);
|
||||
|
|
|
@ -174,6 +174,152 @@ void ColladaParser::ReadAssetInfo()
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the image library contents
|
||||
void ColladaParser::ReadImageLibrary()
|
||||
{
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "image"))
|
||||
{
|
||||
// read ID. Another entry which is "optional" by design but obligatory in reality
|
||||
int attrID = GetAttribute( "id");
|
||||
std::string id = mReader->getAttributeValue( attrID);
|
||||
|
||||
// create an entry and store it in the library under its ID
|
||||
mImageLibrary[id] = Image();
|
||||
|
||||
// read on from there
|
||||
ReadImage( mImageLibrary[id]);
|
||||
} else
|
||||
{
|
||||
// ignore the rest
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "library_images") != 0)
|
||||
ThrowException( "Expected end of \"library_images\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads an image entry into the given image
|
||||
void ColladaParser::ReadImage( Collada::Image& pImage)
|
||||
{
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "init_from"))
|
||||
{
|
||||
// element content is filename - hopefully
|
||||
const char* content = GetTextContent();
|
||||
pImage.mFileName = content;
|
||||
TestClosing( "init_from");
|
||||
} else
|
||||
{
|
||||
// ignore the rest
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "image") != 0)
|
||||
ThrowException( "Expected end of \"image\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the material library
|
||||
void ColladaParser::ReadMaterialLibrary()
|
||||
{
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "material"))
|
||||
{
|
||||
// read ID. By now you propably know my opinion about this "specification"
|
||||
int attrID = GetAttribute( "id");
|
||||
std::string id = mReader->getAttributeValue( attrID);
|
||||
|
||||
// create an entry and store it in the library under its ID
|
||||
mMaterialLibrary[id] = Material();
|
||||
// read on from there
|
||||
ReadMaterial( mMaterialLibrary[id]);
|
||||
} else
|
||||
{
|
||||
// ignore the rest
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "library_materials") != 0)
|
||||
ThrowException( "Expected end of \"library_materials\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a material entry into the given material
|
||||
void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
|
||||
{
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "instance_effect"))
|
||||
{
|
||||
// referred effect by URL
|
||||
int attrUrl = GetAttribute( "url");
|
||||
const char* url = mReader->getAttributeValue( attrUrl);
|
||||
if( url[0] != '#')
|
||||
ThrowException( "Unknown reference format");
|
||||
|
||||
pMaterial.mEffect = url;
|
||||
|
||||
SkipElement();
|
||||
} else
|
||||
{
|
||||
// ignore the rest
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "material") != 0)
|
||||
ThrowException( "Expected end of \"image\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the effect library
|
||||
void ColladaParser::ReadEffectLibrary()
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads an effect entry into the given effect
|
||||
void ColladaParser::ReadEffect( Collada::Effect* pEffect)
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads the geometry library contents
|
||||
void ColladaParser::ReadGeometryLibrary()
|
||||
|
@ -200,7 +346,7 @@ void ColladaParser::ReadGeometryLibrary()
|
|||
// read on from there
|
||||
ReadMesh( mesh);
|
||||
|
||||
// check for the closing tag of the outer <geometry" element, the inner closing of <mesh> has been consumed by ReadMesh()
|
||||
// check for the closing tag of the outer <geometry> element, the inner closing of <mesh> has been consumed by ReadMesh()
|
||||
TestClosing( "geometry");
|
||||
} else
|
||||
{
|
||||
|
@ -871,11 +1017,41 @@ void ColladaParser::ReadNodeGeometry( Node* pNode)
|
|||
if( url[0] != '#')
|
||||
ThrowException( "Unknown reference format");
|
||||
|
||||
// store the mesh ID
|
||||
pNode->mMeshes.push_back( std::string( url+1));
|
||||
Collada::MeshInstance instance;
|
||||
instance.mMesh = url+1; // skipping the leading #
|
||||
|
||||
// for the moment, skip the rest
|
||||
// read material associations. Ignore additional elements inbetween
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "instance_material"))
|
||||
{
|
||||
// read ID of the geometry subgroup and the target material
|
||||
int attrGroup = GetAttribute( "symbol");
|
||||
std::string group = mReader->getAttributeValue( attrGroup);
|
||||
int attrMaterial = GetAttribute( "target");
|
||||
const char* urlMat = mReader->getAttributeValue( attrMaterial);
|
||||
if( urlMat[0] != '#')
|
||||
ThrowException( "Unknown reference format");
|
||||
std::string mat = mReader->getAttributeValue( attrMaterial+1);
|
||||
|
||||
// store the association
|
||||
instance.mMaterials[group] = mat;
|
||||
} else
|
||||
{
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "instance_geometry") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// store it
|
||||
pNode->mMeshes.push_back( instance);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -72,6 +72,24 @@ protected:
|
|||
/** Reads asset informations such as coordinate system informations and legal blah */
|
||||
void ReadAssetInfo();
|
||||
|
||||
/** Reads the image library contents */
|
||||
void ReadImageLibrary();
|
||||
|
||||
/** Reads an image entry into the given image */
|
||||
void ReadImage( Collada::Image& pImage);
|
||||
|
||||
/** Reads the material library */
|
||||
void ReadMaterialLibrary();
|
||||
|
||||
/** Reads a material entry into the given material */
|
||||
void ReadMaterial( Collada::Material& pMaterial);
|
||||
|
||||
/** Reads the effect library */
|
||||
void ReadEffectLibrary();
|
||||
|
||||
/** Reads an effect entry into the given effect*/
|
||||
void ReadEffect( Collada::Effect* pEffect);
|
||||
|
||||
/** Reads the geometry library contents */
|
||||
void ReadGeometryLibrary();
|
||||
|
||||
|
@ -174,6 +192,18 @@ protected:
|
|||
typedef std::map<std::string, Collada::Node*> NodeLibrary;
|
||||
NodeLibrary mNodeLibrary;
|
||||
|
||||
/** Image library: stores texture properties by ID */
|
||||
typedef std::map<std::string, Collada::Image> ImageLibrary;
|
||||
ImageLibrary mImageLibrary;
|
||||
|
||||
/** Effect library: surface attributes by ID */
|
||||
typedef std::map<std::string, Collada::Effect> EffectLibrary;
|
||||
EffectLibrary mEffectLibrary;
|
||||
|
||||
/** Material library: surface material by ID */
|
||||
typedef std::map<std::string, Collada::Material> MaterialLibrary;
|
||||
MaterialLibrary mMaterialLibrary;
|
||||
|
||||
/** Pointer to the root node. Don't delete, it just points to one of the nodes in the node library. */
|
||||
Collada::Node* mRootNode;
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ C++ example:
|
|||
@code
|
||||
#include <assimp.hpp> // C++ importer interface
|
||||
#include <aiScene.h> // root structure of the imported data
|
||||
#include <aiPostProcess.h> // Post processing flags
|
||||
#include <aiMesh.h> // example: mesh data structures. you'll propably need other includes, too
|
||||
|
||||
bool DoTheImportThing( const std::string& pFile)
|
||||
|
@ -148,7 +149,7 @@ bool DoTheImportThing( const std::string& pFile)
|
|||
// if the import failed, report it
|
||||
if( !scene)
|
||||
{
|
||||
DoTheErrorLogging( importer.GetErrorText());
|
||||
DoTheErrorLogging( importer.GetErrorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -177,6 +178,7 @@ C example:
|
|||
@code
|
||||
#include <assimp.h> // Plain C importer interface
|
||||
#include <aiScene.h> // Root structure of the imported data
|
||||
#include <aiPostProcess.h> // Post processing flags
|
||||
#include <aiMesh.h> // Example: mesh data structures. you'll propably need other includes, too
|
||||
|
||||
bool DoTheImportThing( const char* pFile)
|
||||
|
|
Loading…
Reference in New Issue