- further Collada work: materials are now loaded from profile_COMMON, meshes are properly split up at material borders
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@260 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
d320a4bc64
commit
917db45b3c
|
@ -44,38 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#define ASSIMP_INTERNAL_BUILD
|
#define ASSIMP_INTERNAL_BUILD
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_DLL_EXPORT
|
|
||||||
# if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Building Windows DLL" )
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// *******************************************************************
|
|
||||||
// Print detailled memory allocation statistics? In this case we'll
|
|
||||||
// need to overload all C++ memory management functions. It is assumed
|
|
||||||
// that old C routines, such as malloc(), are NOT used in Assimp.
|
|
||||||
// *******************************************************************
|
|
||||||
#ifdef ASSIMP_BUILD_MEMORY_STATISTICS
|
|
||||||
|
|
||||||
void *operator new (size_t);
|
|
||||||
void operator delete (void *);
|
|
||||||
void *operator new[] (size_t);
|
|
||||||
void operator delete[] (void *);
|
|
||||||
|
|
||||||
# if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Memory tracking enabled" )
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# ifdef _DEBUG
|
|
||||||
# pragma message( "AssimpBuild: Debug build" )
|
|
||||||
# else
|
|
||||||
# pragma message( "AssimpBuild: Release build" )
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// *******************************************************************
|
// *******************************************************************
|
||||||
// If we have at least VC8 some C string manipulation functions
|
// If we have at least VC8 some C string manipulation functions
|
||||||
// are mapped to their safe _s counterparts (e.g. _itoa_s).
|
// are mapped to their safe _s counterparts (e.g. _itoa_s).
|
||||||
|
@ -98,7 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
// *******************************************************************
|
// *******************************************************************
|
||||||
// public ASSIMP headers
|
// public ASSIMP headers
|
||||||
|
@ -124,10 +92,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// *******************************************************************
|
// *******************************************************************
|
||||||
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
|
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Using -noBoost workaround" )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "../include/BoostWorkaround/boost/scoped_ptr.hpp"
|
# include "../include/BoostWorkaround/boost/scoped_ptr.hpp"
|
||||||
# include "../include/BoostWorkaround/boost/scoped_array.hpp"
|
# include "../include/BoostWorkaround/boost/scoped_array.hpp"
|
||||||
# include "../include/BoostWorkaround/boost/format.hpp"
|
# include "../include/BoostWorkaround/boost/format.hpp"
|
||||||
|
@ -135,10 +99,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Using standard boost headers" )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include <boost/scoped_ptr.hpp>
|
# include <boost/scoped_ptr.hpp>
|
||||||
# include <boost/scoped_array.hpp>
|
# include <boost/scoped_array.hpp>
|
||||||
# include <boost/format.hpp>
|
# include <boost/format.hpp>
|
||||||
|
|
|
@ -144,6 +144,13 @@ struct InputChannel
|
||||||
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
|
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Subset of a mesh with a certain material */
|
||||||
|
struct SubMesh
|
||||||
|
{
|
||||||
|
std::string mMaterial; ///< subgroup identifier
|
||||||
|
size_t mNumFaces; ///< number of faces in this submesh
|
||||||
|
};
|
||||||
|
|
||||||
/** Contains data for a single mesh */
|
/** Contains data for a single mesh */
|
||||||
struct Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
|
@ -158,6 +165,9 @@ struct Mesh
|
||||||
|
|
||||||
// Faces. Stored are only the number of vertices for each face. 1 == point, 2 == line, 3 == triangle, 4+ == poly
|
// Faces. Stored are only the number of vertices for each face. 1 == point, 2 == line, 3 == triangle, 4+ == poly
|
||||||
std::vector<size_t> mFaceSize;
|
std::vector<size_t> mFaceSize;
|
||||||
|
|
||||||
|
// Submeshes in this mesh, each with a given material
|
||||||
|
std::vector<SubMesh> mSubMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Which type of primitives the ReadPrimitives() function is going to read */
|
/** Which type of primitives the ReadPrimitives() function is going to read */
|
||||||
|
@ -179,6 +189,20 @@ struct Material
|
||||||
std::string mEffect;
|
std::string mEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Type of the effect param */
|
||||||
|
enum ParamType
|
||||||
|
{
|
||||||
|
Param_Sampler,
|
||||||
|
Param_Surface
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
|
||||||
|
struct EffectParam
|
||||||
|
{
|
||||||
|
ParamType mType;
|
||||||
|
std::string mReference; // to which other thing the param is referring to.
|
||||||
|
};
|
||||||
|
|
||||||
/** Shading type supported by the standard effect spec of Collada */
|
/** Shading type supported by the standard effect spec of Collada */
|
||||||
enum ShadeType
|
enum ShadeType
|
||||||
{
|
{
|
||||||
|
@ -194,18 +218,25 @@ enum ShadeType
|
||||||
struct Effect
|
struct Effect
|
||||||
{
|
{
|
||||||
ShadeType mShadeType;
|
ShadeType mShadeType;
|
||||||
aiColor4D mEmmisive, mAmbient, mDiffuse, mSpecular;
|
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular;
|
||||||
aiColor4D mReflectivity, mRefractivity;
|
aiColor4D mReflective, mRefractive;
|
||||||
std::string mTexEmmisive, mTexAmbient, mTexDiffuse, mTexSpecular;
|
std::string mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular;
|
||||||
float mShininess, mRefractIndex;
|
float mShininess, mRefractIndex;
|
||||||
|
float mReflectivity, mRefractivity;
|
||||||
|
|
||||||
Effect() : mEmmisive( 0, 0, 0, 1), mAmbient( 0.1f, 0.1f, 0.1f, 1),
|
// local params referring to each other by their SID
|
||||||
|
typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
|
||||||
|
ParamLibrary mParams;
|
||||||
|
|
||||||
|
Effect() : mEmissive( 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),
|
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)
|
mReflective( 0, 0, 0, 0), mRefractive( 0, 0, 0, 0)
|
||||||
{
|
{
|
||||||
mShadeType = Shade_Phong;
|
mShadeType = Shade_Phong;
|
||||||
mShininess = 10;
|
mShininess = 10.0f;
|
||||||
mRefractIndex = 1;
|
mRefractIndex = 1.0f;
|
||||||
|
mReflectivity = 0.0f;
|
||||||
|
mRefractivity = 0.0f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,12 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
// parse the input file
|
// parse the input file
|
||||||
ColladaParser parser( pFile);
|
ColladaParser parser( pFile);
|
||||||
|
|
||||||
|
if( !parser.mRootNode)
|
||||||
|
throw new ImportErrorException( "File came out empty. Somethings wrong here.");
|
||||||
|
|
||||||
|
// create the materials first, for the meshes to find
|
||||||
|
BuildMaterials( parser, pScene);
|
||||||
|
|
||||||
// build the node hierarchy from it
|
// build the node hierarchy from it
|
||||||
pScene->mRootNode = BuildHierarchy( parser, parser.mRootNode);
|
pScene->mRootNode = BuildHierarchy( parser, parser.mRootNode);
|
||||||
|
|
||||||
|
@ -107,23 +113,6 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
|
|
||||||
// store all meshes
|
// store all meshes
|
||||||
StoreSceneMeshes( pScene);
|
StoreSceneMeshes( pScene);
|
||||||
|
|
||||||
// create dummy material
|
|
||||||
Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
|
|
||||||
aiString name( std::string( "dummy"));
|
|
||||||
mat->AddProperty( &name, AI_MATKEY_NAME);
|
|
||||||
|
|
||||||
int shadeMode = aiShadingMode_Phong;
|
|
||||||
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
|
|
||||||
aiColor4D colAmbient( 0.2f, 0.2f, 0.2f, 1.0f), colDiffuse( 0.8f, 0.8f, 0.8f, 1.0f), colSpecular( 0.5f, 0.5f, 0.5f, 0.5f);
|
|
||||||
mat->AddProperty( &colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
|
|
||||||
mat->AddProperty( &colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
|
||||||
mat->AddProperty( &colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
|
||||||
float specExp = 5.0f;
|
|
||||||
mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
|
|
||||||
pScene->mNumMaterials = 1;
|
|
||||||
pScene->mMaterials = new aiMaterial*[1];
|
|
||||||
pScene->mMaterials[0] = mat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -168,70 +157,100 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
||||||
DefaultLogger::get()->warn( boost::str( boost::format( "Unable to find geometry for ID \"%s\". Skipping.") % mid.mMesh));
|
DefaultLogger::get()->warn( boost::str( boost::format( "Unable to find geometry for ID \"%s\". Skipping.") % mid.mMesh));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const Collada::Mesh* srcMesh = srcMeshIt->second;
|
||||||
|
|
||||||
// if we already have the mesh at the library, just add its index to the node's array
|
// build a mesh for each of its subgroups
|
||||||
std::map<std::string, size_t>::const_iterator dstMeshIt = mMeshIndexbyID.find( mid.mMesh);
|
size_t vertexStart = 0, faceStart = 0;
|
||||||
if( dstMeshIt != mMeshIndexbyID.end())
|
for( size_t sm = 0; sm < srcMesh->mSubMeshes.size(); ++sm)
|
||||||
{
|
{
|
||||||
newMeshRefs.push_back( dstMeshIt->second);
|
const Collada::SubMesh& submesh = srcMesh->mSubMeshes[sm];
|
||||||
} else
|
// find material assigned to this submesh
|
||||||
{
|
std::map<std::string, std::string>::const_iterator meshMatIt = mid.mMaterials.find( submesh.mMaterial);
|
||||||
// else we have to add the mesh to the collection and store its newly assigned index at the node
|
std::string meshMaterial;
|
||||||
aiMesh* dstMesh = new aiMesh;
|
if( meshMatIt != mid.mMaterials.end())
|
||||||
const Collada::Mesh* srcMesh = srcMeshIt->second;
|
meshMaterial = meshMatIt->second;
|
||||||
|
else
|
||||||
|
DefaultLogger::get()->warn( boost::str( boost::format( "No material specified for subgroup \"%s\" in geometry \"%s\".") % submesh.mMaterial % mid.mMesh));
|
||||||
|
|
||||||
// copy positions
|
// built lookup index of the Mesh-Submesh-Material combination
|
||||||
dstMesh->mNumVertices = srcMesh->mPositions.size();
|
ColladaMeshIndex index( mid.mMesh, sm, meshMaterial);
|
||||||
dstMesh->mVertices = new aiVector3D[dstMesh->mNumVertices];
|
|
||||||
std::copy( srcMesh->mPositions.begin(), srcMesh->mPositions.end(), dstMesh->mVertices);
|
|
||||||
|
|
||||||
// normals, if given. HACK: (thom) Due to the fucking Collada spec we never know if we have the same
|
// if we already have the mesh at the library, just add its index to the node's array
|
||||||
// number of normals as there are positions. So we also ignore any vertex attribute if it has a different count
|
std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find( index);
|
||||||
if( srcMesh->mNormals.size() == dstMesh->mNumVertices)
|
if( dstMeshIt != mMeshIndexByID.end())
|
||||||
{
|
{
|
||||||
dstMesh->mNormals = new aiVector3D[dstMesh->mNumVertices];
|
newMeshRefs.push_back( dstMeshIt->second);
|
||||||
std::copy( srcMesh->mNormals.begin(), srcMesh->mNormals.end(), dstMesh->mNormals);
|
} else
|
||||||
}
|
|
||||||
|
|
||||||
// same for texturecoords, as many as we have
|
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
|
||||||
{
|
{
|
||||||
if( srcMesh->mTexCoords[a].size() == dstMesh->mNumVertices)
|
// else we have to add the mesh to the collection and store its newly assigned index at the node
|
||||||
|
aiMesh* dstMesh = new aiMesh;
|
||||||
|
|
||||||
|
// count the vertices addressed by its faces
|
||||||
|
size_t numVertices =
|
||||||
|
std::accumulate( srcMesh->mFaceSize.begin() + faceStart, srcMesh->mFaceSize.begin() + faceStart + submesh.mNumFaces, 0);
|
||||||
|
|
||||||
|
// copy positions
|
||||||
|
dstMesh->mNumVertices = numVertices;
|
||||||
|
dstMesh->mVertices = new aiVector3D[numVertices];
|
||||||
|
std::copy( srcMesh->mPositions.begin() + vertexStart, srcMesh->mPositions.begin() + vertexStart + numVertices, dstMesh->mVertices);
|
||||||
|
|
||||||
|
// normals, if given. HACK: (thom) Due to the fucking Collada spec we never know if we have the same
|
||||||
|
// number of normals as there are positions. So we also ignore any vertex attribute if it has a different count
|
||||||
|
if( srcMesh->mNormals.size() == srcMesh->mPositions.size())
|
||||||
{
|
{
|
||||||
dstMesh->mTextureCoords[a] = new aiVector3D[dstMesh->mNumVertices];
|
dstMesh->mNormals = new aiVector3D[numVertices];
|
||||||
for( size_t b = 0; b < dstMesh->mNumVertices; ++b)
|
std::copy( srcMesh->mNormals.begin() + vertexStart, srcMesh->mNormals.begin() + vertexStart + numVertices, dstMesh->mNormals);
|
||||||
dstMesh->mTextureCoords[a][b].Set( srcMesh->mTexCoords[a][b].x, srcMesh->mTexCoords[a][b].y, 0.0f);
|
|
||||||
dstMesh->mNumUVComponents[a] = 2;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// same for vertex colors, as many as we have
|
// same for texturecoords, as many as we have
|
||||||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
||||||
{
|
|
||||||
if( srcMesh->mColors[a].size() == dstMesh->mNumVertices)
|
|
||||||
{
|
{
|
||||||
dstMesh->mColors[a] = new aiColor4D[dstMesh->mNumVertices];
|
if( srcMesh->mTexCoords[a].size() == srcMesh->mPositions.size())
|
||||||
std::copy( srcMesh->mColors[a].begin(), srcMesh->mColors[a].end(), dstMesh->mColors[a]);
|
{
|
||||||
|
dstMesh->mTextureCoords[a] = new aiVector3D[numVertices];
|
||||||
|
for( size_t b = vertexStart; b < vertexStart + numVertices; ++b)
|
||||||
|
dstMesh->mTextureCoords[a][b].Set( srcMesh->mTexCoords[a][b].x, srcMesh->mTexCoords[a][b].y, 0.0f);
|
||||||
|
dstMesh->mNumUVComponents[a] = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
|
// same for vertex colors, as many as we have
|
||||||
size_t vertex = 0;
|
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
|
||||||
dstMesh->mNumFaces = srcMesh->mFaceSize.size();
|
{
|
||||||
dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
|
if( srcMesh->mColors[a].size() == srcMesh->mPositions.size())
|
||||||
for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
|
{
|
||||||
{
|
dstMesh->mColors[a] = new aiColor4D[numVertices];
|
||||||
size_t s = srcMesh->mFaceSize[a];
|
std::copy( srcMesh->mColors[a].begin() + vertexStart, srcMesh->mColors[a].begin() + vertexStart + numVertices, dstMesh->mColors[a]);
|
||||||
aiFace& face = dstMesh->mFaces[a];
|
}
|
||||||
face.mNumIndices = s;
|
}
|
||||||
face.mIndices = new unsigned int[s];
|
|
||||||
for( size_t b = 0; b < s; ++b)
|
|
||||||
face.mIndices[b] = vertex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the mesh, and store its new index in the node
|
// create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
|
||||||
newMeshRefs.push_back( mMeshes.size());
|
size_t vertex = 0;
|
||||||
mMeshes.push_back( dstMesh);
|
dstMesh->mNumFaces = submesh.mNumFaces;
|
||||||
|
dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
|
||||||
|
for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
|
||||||
|
{
|
||||||
|
size_t s = srcMesh->mFaceSize[ faceStart + a];
|
||||||
|
aiFace& face = dstMesh->mFaces[a];
|
||||||
|
face.mNumIndices = s;
|
||||||
|
face.mIndices = new unsigned int[s];
|
||||||
|
for( size_t b = 0; b < s; ++b)
|
||||||
|
face.mIndices[b] = vertex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the mesh, and store its new index in the node
|
||||||
|
newMeshRefs.push_back( mMeshes.size());
|
||||||
|
mMeshIndexByID[index] = mMeshes.size();
|
||||||
|
mMeshes.push_back( dstMesh);
|
||||||
|
vertexStart += numVertices; faceStart += submesh.mNumFaces;
|
||||||
|
|
||||||
|
// assign the material index
|
||||||
|
std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find( meshMaterial);
|
||||||
|
if( matIt != mMaterialIndexByName.end())
|
||||||
|
dstMesh->mMaterialIndex = matIt->second;
|
||||||
|
else
|
||||||
|
dstMesh->mMaterialIndex = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,3 +274,106 @@ void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
|
||||||
std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
|
std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Constructs materials from the collada material definitions
|
||||||
|
void ColladaLoader::BuildMaterials( const ColladaParser& pParser, aiScene* pScene)
|
||||||
|
{
|
||||||
|
std::vector<aiMaterial*> newMats;
|
||||||
|
|
||||||
|
for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); matIt != pParser.mMaterialLibrary.end(); ++matIt)
|
||||||
|
{
|
||||||
|
const Collada::Material& material = matIt->second;
|
||||||
|
// a material is only a reference to an effect
|
||||||
|
ColladaParser::EffectLibrary::const_iterator effIt = pParser.mEffectLibrary.find( material.mEffect);
|
||||||
|
if( effIt == pParser.mEffectLibrary.end())
|
||||||
|
continue;
|
||||||
|
const Collada::Effect& effect = effIt->second;
|
||||||
|
|
||||||
|
// create material
|
||||||
|
Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
|
||||||
|
aiString name( matIt->first);
|
||||||
|
mat->AddProperty( &name, AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
int shadeMode;
|
||||||
|
switch( effect.mShadeType)
|
||||||
|
{
|
||||||
|
case Collada::Shade_Constant: shadeMode = aiShadingMode_NoShading; break;
|
||||||
|
case Collada::Shade_Lambert: shadeMode = aiShadingMode_Gouraud; break;
|
||||||
|
case Collada::Shade_Blinn: shadeMode = aiShadingMode_Blinn; break;
|
||||||
|
default: shadeMode = aiShadingMode_Phong; break;
|
||||||
|
}
|
||||||
|
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
|
||||||
|
mat->AddProperty( &effect.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
mat->AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
mat->AddProperty( &effect.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
mat->AddProperty( &effect.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||||
|
mat->AddProperty( &effect.mShininess, 1, AI_MATKEY_SHININESS);
|
||||||
|
mat->AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
|
||||||
|
|
||||||
|
// add textures, if given
|
||||||
|
if( !effect.mTexAmbient.empty())
|
||||||
|
mat->AddProperty( &FindFilenameForEffectTexture( pParser, effect, effect.mTexAmbient), AI_MATKEY_TEXTURE_AMBIENT( 0));
|
||||||
|
if( !effect.mTexDiffuse.empty())
|
||||||
|
mat->AddProperty( &FindFilenameForEffectTexture( pParser, effect, effect.mTexDiffuse), AI_MATKEY_TEXTURE_DIFFUSE( 0));
|
||||||
|
if( !effect.mTexEmissive.empty())
|
||||||
|
mat->AddProperty( &FindFilenameForEffectTexture( pParser, effect, effect.mTexEmissive), AI_MATKEY_TEXTURE_EMISSIVE( 0));
|
||||||
|
if( !effect.mTexSpecular.empty())
|
||||||
|
mat->AddProperty( &FindFilenameForEffectTexture( pParser, effect, effect.mTexSpecular), AI_MATKEY_TEXTURE_SPECULAR( 0));
|
||||||
|
|
||||||
|
// store the material
|
||||||
|
mMaterialIndexByName[matIt->first] = newMats.size();
|
||||||
|
newMats.push_back( mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// store a dummy material if none were given
|
||||||
|
if( newMats.size() == 0)
|
||||||
|
{
|
||||||
|
Assimp::MaterialHelper* mat = new Assimp::MaterialHelper;
|
||||||
|
aiString name( std::string( "dummy"));
|
||||||
|
mat->AddProperty( &name, AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
int shadeMode = aiShadingMode_Phong;
|
||||||
|
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||||
|
aiColor4D colAmbient( 0.2f, 0.2f, 0.2f, 1.0f), colDiffuse( 0.8f, 0.8f, 0.8f, 1.0f), colSpecular( 0.5f, 0.5f, 0.5f, 0.5f);
|
||||||
|
mat->AddProperty( &colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
mat->AddProperty( &colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
mat->AddProperty( &colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
float specExp = 5.0f;
|
||||||
|
mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the materials in the scene
|
||||||
|
pScene->mNumMaterials = newMats.size();
|
||||||
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||||
|
std::copy( newMats.begin(), newMats.end(), pScene->mMaterials);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Resolves the texture name for the given effect texture entry
|
||||||
|
const aiString& ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser, const Collada::Effect& pEffect, const std::string& pName)
|
||||||
|
{
|
||||||
|
// recurse through the param references until we end up at an image
|
||||||
|
std::string name = pName;
|
||||||
|
while( 1)
|
||||||
|
{
|
||||||
|
// the given string is a param entry. Find it
|
||||||
|
Collada::Effect::ParamLibrary::const_iterator it = pEffect.mParams.find( name);
|
||||||
|
// if not found, we're at the end of the recursion. The resulting string should be the image ID
|
||||||
|
if( it == pEffect.mParams.end())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// else recurse on
|
||||||
|
name = it->second.mReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the image referred by this name in the image library of the scene
|
||||||
|
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
|
||||||
|
if( imIt == pParser.mImageLibrary.end())
|
||||||
|
throw new ImportErrorException( boost::str( boost::format( "Unable to resolve effect texture entry \"%s\", ended up at ID \"%s\".") % pName % name));
|
||||||
|
|
||||||
|
static aiString result;
|
||||||
|
result.Set( imIt->second.mFileName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct ColladaMeshIndex
|
||||||
|
{
|
||||||
|
std::string mMeshID;
|
||||||
|
size_t mSubMesh;
|
||||||
|
std::string mMaterial;
|
||||||
|
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
|
||||||
|
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool operator < (const ColladaMeshIndex& p) const
|
||||||
|
{
|
||||||
|
if( mMeshID == p.mMeshID)
|
||||||
|
{
|
||||||
|
if( mSubMesh == p.mSubMesh)
|
||||||
|
return mMaterial < p.mMaterial;
|
||||||
|
else
|
||||||
|
return mSubMesh < p.mSubMesh;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return mMeshID < p.mMeshID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
|
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
|
||||||
* more useless stuff, so I limited the data to what I think is useful for games.
|
* more useless stuff, so I limited the data to what I think is useful for games.
|
||||||
*/
|
*/
|
||||||
|
@ -91,12 +115,21 @@ protected:
|
||||||
/** Stores all meshes in the given scene */
|
/** Stores all meshes in the given scene */
|
||||||
void StoreSceneMeshes( aiScene* pScene);
|
void StoreSceneMeshes( aiScene* pScene);
|
||||||
|
|
||||||
|
/** Constructs materials from the collada material definitions */
|
||||||
|
void BuildMaterials( const ColladaParser& pParser, aiScene* pScene);
|
||||||
|
|
||||||
|
/** Resolves the texture name for the given effect texture entry */
|
||||||
|
const aiString& FindFilenameForEffectTexture( const ColladaParser& pParser, const Collada::Effect& pEffect, const std::string& pName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Filename, for a verbose error message */
|
/** Filename, for a verbose error message */
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** Which mesh-material compound was stored under which mesh ID */
|
/** Which mesh-material compound was stored under which mesh ID */
|
||||||
std::map<std::string, size_t> mMeshIndexbyID;
|
std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
|
||||||
|
|
||||||
|
/** Which material was stored under which index in the scene */
|
||||||
|
std::map<std::string, size_t> mMaterialIndexByName;
|
||||||
|
|
||||||
/** Accumulated meshes for the target scene */
|
/** Accumulated meshes for the target scene */
|
||||||
std::vector<aiMesh*> mMeshes;
|
std::vector<aiMesh*> mMeshes;
|
||||||
|
|
|
@ -112,6 +112,12 @@ void ColladaParser::ReadStructure()
|
||||||
{
|
{
|
||||||
if( IsElement( "asset"))
|
if( IsElement( "asset"))
|
||||||
ReadAssetInfo();
|
ReadAssetInfo();
|
||||||
|
else if( IsElement( "library_images"))
|
||||||
|
ReadImageLibrary();
|
||||||
|
else if( IsElement( "library_materials"))
|
||||||
|
ReadMaterialLibrary();
|
||||||
|
else if( IsElement( "library_effects"))
|
||||||
|
ReadEffectLibrary();
|
||||||
else if( IsElement( "library_geometries"))
|
else if( IsElement( "library_geometries"))
|
||||||
ReadGeometryLibrary();
|
ReadGeometryLibrary();
|
||||||
else if( IsElement( "library_visual_scenes"))
|
else if( IsElement( "library_visual_scenes"))
|
||||||
|
@ -289,7 +295,7 @@ void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
|
||||||
if( url[0] != '#')
|
if( url[0] != '#')
|
||||||
ThrowException( "Unknown reference format");
|
ThrowException( "Unknown reference format");
|
||||||
|
|
||||||
pMaterial.mEffect = url;
|
pMaterial.mEffect = url+1;
|
||||||
|
|
||||||
SkipElement();
|
SkipElement();
|
||||||
} else
|
} else
|
||||||
|
@ -312,12 +318,214 @@ void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
|
||||||
// Reads the effect library
|
// Reads the effect library
|
||||||
void ColladaParser::ReadEffectLibrary()
|
void ColladaParser::ReadEffectLibrary()
|
||||||
{
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "effect"))
|
||||||
|
{
|
||||||
|
// read ID. Do I have to repeat my ranting about "optional" attributes?
|
||||||
|
int attrID = GetAttribute( "id");
|
||||||
|
std::string id = mReader->getAttributeValue( attrID);
|
||||||
|
|
||||||
|
// create an entry and store it in the library under its ID
|
||||||
|
mEffectLibrary[id] = Effect();
|
||||||
|
// read on from there
|
||||||
|
ReadEffect( mEffectLibrary[id]);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// ignore the rest
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
if( strcmp( mReader->getNodeName(), "library_effects") != 0)
|
||||||
|
ThrowException( "Expected end of \"library_effects\" element.");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an effect entry into the given effect
|
// Reads an effect entry into the given effect
|
||||||
void ColladaParser::ReadEffect( Collada::Effect* pEffect)
|
void ColladaParser::ReadEffect( Collada::Effect& pEffect)
|
||||||
{
|
{
|
||||||
|
// for the moment we don't support any other type of effect.
|
||||||
|
// TODO: (thom) Rewrite this so that it ignores the whole effect instead of bailing out
|
||||||
|
TestOpening( "profile_COMMON");
|
||||||
|
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "newparam"))
|
||||||
|
{
|
||||||
|
// save ID
|
||||||
|
int attrSID = GetAttribute( "sid");
|
||||||
|
std::string sid = mReader->getAttributeValue( attrSID);
|
||||||
|
pEffect.mParams[sid] = EffectParam();
|
||||||
|
ReadEffectParam( pEffect.mParams[sid]);
|
||||||
|
}
|
||||||
|
else if( IsElement( "technique"))
|
||||||
|
{
|
||||||
|
// just syntactic sugar
|
||||||
|
}
|
||||||
|
else if( IsElement( "phong"))
|
||||||
|
pEffect.mShadeType = Shade_Phong;
|
||||||
|
else if( IsElement( "constant"))
|
||||||
|
pEffect.mShadeType = Shade_Constant;
|
||||||
|
else if( IsElement( "lambert"))
|
||||||
|
pEffect.mShadeType = Shade_Lambert;
|
||||||
|
else if( IsElement( "blinn"))
|
||||||
|
pEffect.mShadeType = Shade_Blinn;
|
||||||
|
else if( IsElement( "emission"))
|
||||||
|
ReadEffectColor( pEffect.mEmissive, pEffect.mTexEmissive);
|
||||||
|
else if( IsElement( "ambient"))
|
||||||
|
ReadEffectColor( pEffect.mAmbient, pEffect.mTexAmbient);
|
||||||
|
else if( IsElement( "diffuse"))
|
||||||
|
ReadEffectColor( pEffect.mDiffuse, pEffect.mTexDiffuse);
|
||||||
|
else if( IsElement( "specular"))
|
||||||
|
ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular);
|
||||||
|
else if( IsElement( "reflective"))
|
||||||
|
ReadEffectColor( pEffect.mReflective, std::string());
|
||||||
|
else if( IsElement( "transparent"))
|
||||||
|
ReadEffectColor( pEffect.mRefractive, std::string());
|
||||||
|
else if( IsElement( "shininess"))
|
||||||
|
ReadEffectFloat( pEffect.mShininess);
|
||||||
|
else if( IsElement( "reflectivity"))
|
||||||
|
ReadEffectFloat( pEffect.mReflectivity);
|
||||||
|
else if( IsElement( "transparency"))
|
||||||
|
ReadEffectFloat( pEffect.mRefractivity);
|
||||||
|
else if( IsElement( "index_of_refraction"))
|
||||||
|
ReadEffectFloat( pEffect.mRefractIndex);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ignore the rest
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
if( strcmp( mReader->getNodeName(), "effect") == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads an effect entry containing a color or a texture defining that color
|
||||||
|
void ColladaParser::ReadEffectColor( aiColor4D& pColor, std::string& pSampler)
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "color"))
|
||||||
|
{
|
||||||
|
// text content contains 4 floats
|
||||||
|
const char* content = GetTextContent();
|
||||||
|
content = fast_atof_move( content, pColor.r);
|
||||||
|
SkipSpacesAndLineEnd( &content);
|
||||||
|
content = fast_atof_move( content, pColor.g);
|
||||||
|
SkipSpacesAndLineEnd( &content);
|
||||||
|
content = fast_atof_move( content, pColor.b);
|
||||||
|
SkipSpacesAndLineEnd( &content);
|
||||||
|
content = fast_atof_move( content, pColor.a);
|
||||||
|
SkipSpacesAndLineEnd( &content);
|
||||||
|
|
||||||
|
TestClosing( "color");
|
||||||
|
}
|
||||||
|
else if( IsElement( "texture"))
|
||||||
|
{
|
||||||
|
int attrTex = GetAttribute( "texture");
|
||||||
|
pSampler = mReader->getAttributeValue( attrTex);
|
||||||
|
SkipElement();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// ignore the rest
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads an effect entry containing a float
|
||||||
|
void ColladaParser::ReadEffectFloat( float& pFloat)
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "float"))
|
||||||
|
{
|
||||||
|
// text content contains a single floats
|
||||||
|
const char* content = GetTextContent();
|
||||||
|
content = fast_atof_move( content, pFloat);
|
||||||
|
SkipSpacesAndLineEnd( &content);
|
||||||
|
|
||||||
|
TestClosing( "float");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// ignore the rest
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads an effect parameter specification of any kind
|
||||||
|
void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "surface"))
|
||||||
|
{
|
||||||
|
// image ID given inside <init_from> tags
|
||||||
|
TestOpening( "init_from");
|
||||||
|
const char* content = GetTextContent();
|
||||||
|
pParam.mType = Param_Surface;
|
||||||
|
pParam.mReference = content;
|
||||||
|
TestClosing( "init_from");
|
||||||
|
|
||||||
|
// don't care for remaining stuff
|
||||||
|
SkipElement( "surface");
|
||||||
|
}
|
||||||
|
else if( IsElement( "sampler2D"))
|
||||||
|
{
|
||||||
|
// surface ID is given inside <source> tags
|
||||||
|
TestOpening( "source");
|
||||||
|
const char* content = GetTextContent();
|
||||||
|
pParam.mType = Param_Sampler;
|
||||||
|
pParam.mReference = content;
|
||||||
|
TestClosing( "source");
|
||||||
|
|
||||||
|
// don't care for remaining stuff
|
||||||
|
SkipElement( "sampler2D");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// ignore unknown element
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -584,6 +792,14 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||||
int attrCount = GetAttribute( "count");
|
int attrCount = GetAttribute( "count");
|
||||||
size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
|
size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
|
||||||
|
|
||||||
|
// material subgroup
|
||||||
|
int attrMaterial = TestAttribute( "material");
|
||||||
|
SubMesh subgroup;
|
||||||
|
if( attrMaterial > -1)
|
||||||
|
subgroup.mMaterial = mReader->getAttributeValue( attrMaterial);
|
||||||
|
subgroup.mNumFaces = numPrimitives;
|
||||||
|
pMesh->mSubMeshes.push_back( subgroup);
|
||||||
|
|
||||||
// distinguish between polys and triangles
|
// distinguish between polys and triangles
|
||||||
std::string elementName = mReader->getNodeName();
|
std::string elementName = mReader->getNodeName();
|
||||||
PrimitiveType primType = Prim_Invalid;
|
PrimitiveType primType = Prim_Invalid;
|
||||||
|
@ -1020,33 +1236,33 @@ void ColladaParser::ReadNodeGeometry( Node* pNode)
|
||||||
Collada::MeshInstance instance;
|
Collada::MeshInstance instance;
|
||||||
instance.mMesh = url+1; // skipping the leading #
|
instance.mMesh = url+1; // skipping the leading #
|
||||||
|
|
||||||
// read material associations. Ignore additional elements inbetween
|
if( !mReader->isEmptyElement())
|
||||||
while( mReader->read())
|
|
||||||
{
|
{
|
||||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
// read material associations. Ignore additional elements inbetween
|
||||||
|
while( mReader->read())
|
||||||
{
|
{
|
||||||
if( IsElement( "instance_material"))
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
{
|
{
|
||||||
// read ID of the geometry subgroup and the target material
|
if( IsElement( "instance_material"))
|
||||||
int attrGroup = GetAttribute( "symbol");
|
{
|
||||||
std::string group = mReader->getAttributeValue( attrGroup);
|
// read ID of the geometry subgroup and the target material
|
||||||
int attrMaterial = GetAttribute( "target");
|
int attrGroup = GetAttribute( "symbol");
|
||||||
const char* urlMat = mReader->getAttributeValue( attrMaterial);
|
std::string group = mReader->getAttributeValue( attrGroup);
|
||||||
if( urlMat[0] != '#')
|
int attrMaterial = GetAttribute( "target");
|
||||||
ThrowException( "Unknown reference format");
|
const char* urlMat = mReader->getAttributeValue( attrMaterial);
|
||||||
std::string mat = mReader->getAttributeValue( attrMaterial+1);
|
if( urlMat[0] != '#')
|
||||||
|
ThrowException( "Unknown reference format");
|
||||||
|
std::string mat = urlMat+1;
|
||||||
|
|
||||||
// store the association
|
// store the association
|
||||||
instance.mMaterials[group] = mat;
|
instance.mMaterials[group] = mat;
|
||||||
} else
|
}
|
||||||
{
|
}
|
||||||
SkipElement();
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
if( strcmp( mReader->getNodeName(), "instance_geometry") == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
|
||||||
{
|
|
||||||
if( strcmp( mReader->getNodeName(), "instance_geometry") == 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,9 +1322,17 @@ void ColladaParser::SkipElement()
|
||||||
if( mReader->isEmptyElement())
|
if( mReader->isEmptyElement())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// reroute
|
||||||
|
SkipElement( mReader->getNodeName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Skips all data until the end node of the given element
|
||||||
|
void ColladaParser::SkipElement( const char* pElement)
|
||||||
|
{
|
||||||
// copy the current node's name because it'a pointer to the reader's internal buffer,
|
// copy the current node's name because it'a pointer to the reader's internal buffer,
|
||||||
// which is going to change with the upcoming parsing
|
// which is going to change with the upcoming parsing
|
||||||
std::string element = mReader->getNodeName();
|
std::string element = pElement;
|
||||||
while( mReader->read())
|
while( mReader->read())
|
||||||
{
|
{
|
||||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
|
|
@ -88,7 +88,15 @@ protected:
|
||||||
void ReadEffectLibrary();
|
void ReadEffectLibrary();
|
||||||
|
|
||||||
/** Reads an effect entry into the given effect*/
|
/** Reads an effect entry into the given effect*/
|
||||||
void ReadEffect( Collada::Effect* pEffect);
|
void ReadEffect( Collada::Effect& pEffect);
|
||||||
|
|
||||||
|
/** Reads an effect entry containing a color or a texture defining that color */
|
||||||
|
void ReadEffectColor( aiColor4D& pColor, std::string& pSampler);
|
||||||
|
/** Reads an effect entry containing a float */
|
||||||
|
void ReadEffectFloat( float& pFloat);
|
||||||
|
|
||||||
|
/** Reads an effect parameter specification of any kind */
|
||||||
|
void ReadEffectParam( Collada::EffectParam& pParam);
|
||||||
|
|
||||||
/** Reads the geometry library contents */
|
/** Reads the geometry library contents */
|
||||||
void ReadGeometryLibrary();
|
void ReadGeometryLibrary();
|
||||||
|
@ -142,6 +150,9 @@ protected:
|
||||||
/** Skips all data until the end node of the current element */
|
/** Skips all data until the end node of the current element */
|
||||||
void SkipElement();
|
void SkipElement();
|
||||||
|
|
||||||
|
/** Skips all data until the end node of the given element */
|
||||||
|
void SkipElement( const char* pElement);
|
||||||
|
|
||||||
/** Compares the current xml element name to the given string and returns true if equal */
|
/** Compares the current xml element name to the given string and returns true if equal */
|
||||||
bool IsElement( const char* pName) const { assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); return strcmp( mReader->getNodeName(), pName) == 0; }
|
bool IsElement( const char* pName) const { assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); return strcmp( mReader->getNodeName(), pName) == 0; }
|
||||||
|
|
||||||
|
|
|
@ -541,10 +541,8 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
|
||||||
// put a large try block around everything to catch all std::exception's
|
// put a large try block around everything to catch all std::exception's
|
||||||
// that might be thrown by STL containers or by new().
|
// that might be thrown by STL containers or by new().
|
||||||
// ImportErrorException's are throw by ourselves and caught elsewhere.
|
// ImportErrorException's are throw by ourselves and caught elsewhere.
|
||||||
#ifndef _DEBUG
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
// check whether this Importer instance has already loaded
|
// check whether this Importer instance has already loaded
|
||||||
// a scene. In this case we need to delete the old one
|
// a scene. In this case we need to delete the old one
|
||||||
if (this->mScene)
|
if (this->mScene)
|
||||||
|
@ -644,7 +642,6 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
|
||||||
|
|
||||||
// clear any data allocated by post-process steps
|
// clear any data allocated by post-process steps
|
||||||
mPPShared->Clean();
|
mPPShared->Clean();
|
||||||
#ifndef _DEBUG
|
|
||||||
}
|
}
|
||||||
catch (std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
|
@ -659,7 +656,6 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
|
||||||
DefaultLogger::get()->error(mErrorString);
|
DefaultLogger::get()->error(mErrorString);
|
||||||
delete mScene;mScene = NULL;
|
delete mScene;mScene = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// either successful or failure - the pointer expresses it anyways
|
// either successful or failure - the pointer expresses it anyways
|
||||||
return mScene;
|
return mScene;
|
||||||
|
|
|
@ -59,20 +59,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
|
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Using -noBoost workaround for boost::random" )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "../include/BoostWorkaround/boost/random/uniform_int.hpp"
|
# include "../include/BoostWorkaround/boost/random/uniform_int.hpp"
|
||||||
# include "../include/BoostWorkaround/boost/random/variate_generator.hpp"
|
# include "../include/BoostWorkaround/boost/random/variate_generator.hpp"
|
||||||
# include "../include/BoostWorkaround/boost/random/mersenne_twister.hpp"
|
# include "../include/BoostWorkaround/boost/random/mersenne_twister.hpp"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Using standard boost headers for boost::random" )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include <boost/random/uniform_int.hpp>
|
# include <boost/random/uniform_int.hpp>
|
||||||
# include <boost/random/variate_generator.hpp>
|
# include <boost/random/variate_generator.hpp>
|
||||||
# include <boost/random/mersenne_twister.hpp>
|
# include <boost/random/mersenne_twister.hpp>
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
#ifndef BOOST_MT_INCLUDED
|
#ifndef BOOST_MT_INCLUDED
|
||||||
#define BOOST_MT_INCLUDED
|
#define BOOST_MT_INCLUDED
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# pragma message( "AssimpBuild: Using CRT's rand() as replacement for mt19937" )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue