summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/ColladaLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/ColladaLoader.cpp')
-rw-r--r--src/3rdparty/assimp/code/ColladaLoader.cpp715
1 files changed, 394 insertions, 321 deletions
diff --git a/src/3rdparty/assimp/code/ColladaLoader.cpp b/src/3rdparty/assimp/code/ColladaLoader.cpp
index 50d5116a6..d2141c374 100644
--- a/src/3rdparty/assimp/code/ColladaLoader.cpp
+++ b/src/3rdparty/assimp/code/ColladaLoader.cpp
@@ -3,7 +3,8 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2016, assimp team
+Copyright (c) 2006-2017, assimp team
+
All rights reserved.
@@ -49,8 +50,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
-#include "ColladaParser.h"
+#include <assimp/importerdesc.h>
+#include "ColladaParser.h"
#include "fast_atof.h"
#include "ParsingUtils.h"
#include "SkeletonMeshBuilder.h"
@@ -58,9 +60,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "time.h"
#include "math.h"
+#include <algorithm>
#include <numeric>
-#include "Defines.h"
-
+#include <assimp/Defines.h>
using namespace Assimp;
using namespace Assimp::Formatter;
@@ -82,15 +84,15 @@ static const aiImporterDesc desc = {
// Constructor to be privately used by Importer
ColladaLoader::ColladaLoader()
: mFileName()
- , mMeshIndexByID()
- , mMaterialIndexByName()
- , mMeshes()
- , newMats()
- , mCameras()
- , mLights()
- , mTextures()
- , mAnims()
- , noSkeletonMesh( false )
+ , mMeshIndexByID()
+ , mMaterialIndexByName()
+ , mMeshes()
+ , newMats()
+ , mCameras()
+ , mLights()
+ , mTextures()
+ , mAnims()
+ , noSkeletonMesh( false )
, ignoreUpDirection(false)
, mNodeNameCounter( 0 )
{}
@@ -117,7 +119,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
* might be NULL and it's our duty to return true here.
*/
if (!pIOHandler)return true;
- const char* tokens[] = {"collada"};
+ const char* tokens[] = {"<collada"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
}
return false;
@@ -130,7 +132,6 @@ void ColladaLoader::SetupProperties(const Importer* pImp)
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
}
-
// ------------------------------------------------------------------------------------------------
// Get file extension list
const aiImporterDesc* ColladaLoader::GetInfo () const
@@ -241,7 +242,7 @@ aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Colla
ResolveNodeInstances(pParser,pNode,instances);
// add children. first the *real* ones
- node->mNumChildren = pNode->mChildren.size()+instances.size();
+ node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size()+instances.size());
node->mChildren = new aiNode*[node->mNumChildren];
for( size_t a = 0; a < pNode->mChildren.size(); a++)
@@ -421,13 +422,13 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
out->mHorizontalFOV = srcCamera->mHorFov;
if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
- out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
- tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
+ out->mAspect = std::tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
+ std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
}
}
else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
- out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect *
- tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
+ out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(std::atan(srcCamera->mAspect *
+ std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
}
// Collada uses degrees, we use radians
@@ -507,7 +508,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find( meshMaterial);
unsigned int matIdx;
if( matIt != mMaterialIndexByName.end())
- matIdx = matIt->second;
+ matIdx = static_cast<unsigned int>(matIt->second);
else
matIdx = 0;
@@ -554,11 +555,19 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
}
// now place all mesh references we gathered in the target node
- pTarget->mNumMeshes = newMeshRefs.size();
+ pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
if( newMeshRefs.size())
{
+ struct UIntTypeConverter
+ {
+ unsigned int operator()(const size_t& v) const
+ {
+ return static_cast<unsigned int>(v);
+ }
+ };
+
pTarget->mMeshes = new unsigned int[pTarget->mNumMeshes];
- std::copy( newMeshRefs.begin(), newMeshRefs.end(), pTarget->mMeshes);
+ std::transform( newMeshRefs.begin(), newMeshRefs.end(), pTarget->mMeshes, UIntTypeConverter());
}
}
@@ -586,86 +595,86 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
dstMesh->mName = pSrcMesh->mName;
- // count the vertices addressed by its faces
- const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
- pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, 0);
-
- // copy positions
- dstMesh->mNumVertices = numVertices;
- dstMesh->mVertices = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() +
- pStartVertex + numVertices, dstMesh->mVertices);
-
- // normals, if given. HACK: (thom) Due to the glorious 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( pSrcMesh->mNormals.size() >= pStartVertex + numVertices)
- {
- dstMesh->mNormals = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() +
- pStartVertex + numVertices, dstMesh->mNormals);
- }
-
- // tangents, if given.
- if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices)
- {
- dstMesh->mTangents = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() +
- pStartVertex + numVertices, dstMesh->mTangents);
- }
-
- // bitangents, if given.
- if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices)
- {
- dstMesh->mBitangents = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() +
- pStartVertex + numVertices, dstMesh->mBitangents);
- }
-
- // same for texturecoords, as many as we have
- // empty slots are not allowed, need to pack and adjust UV indexes accordingly
- for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
- {
- if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices)
- {
- dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
- for( size_t b = 0; b < numVertices; ++b)
- dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex+b];
-
- dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
- ++real;
- }
- }
-
- // same for vertex colors, as many as we have. again the same packing to avoid empty slots
- for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
- {
- if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices)
- {
- dstMesh->mColors[real] = new aiColor4D[numVertices];
- std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);
- ++real;
- }
- }
-
- // create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
- size_t vertex = 0;
- dstMesh->mNumFaces = pSubMesh.mNumFaces;
- dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
- for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
- {
- size_t s = pSrcMesh->mFaceSize[ pStartFace + 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++;
- }
+ // count the vertices addressed by its faces
+ const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
+ pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, size_t(0));
+
+ // copy positions
+ dstMesh->mNumVertices = static_cast<unsigned int>(numVertices);
+ dstMesh->mVertices = new aiVector3D[numVertices];
+ std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() +
+ pStartVertex + numVertices, dstMesh->mVertices);
+
+ // normals, if given. HACK: (thom) Due to the glorious 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( pSrcMesh->mNormals.size() >= pStartVertex + numVertices)
+ {
+ dstMesh->mNormals = new aiVector3D[numVertices];
+ std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() +
+ pStartVertex + numVertices, dstMesh->mNormals);
+ }
+
+ // tangents, if given.
+ if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices)
+ {
+ dstMesh->mTangents = new aiVector3D[numVertices];
+ std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() +
+ pStartVertex + numVertices, dstMesh->mTangents);
+ }
+
+ // bitangents, if given.
+ if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices)
+ {
+ dstMesh->mBitangents = new aiVector3D[numVertices];
+ std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() +
+ pStartVertex + numVertices, dstMesh->mBitangents);
+ }
+
+ // same for texturecoords, as many as we have
+ // empty slots are not allowed, need to pack and adjust UV indexes accordingly
+ for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
+ {
+ if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices)
+ {
+ dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
+ for( size_t b = 0; b < numVertices; ++b)
+ dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex+b];
+
+ dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
+ ++real;
+ }
+ }
+
+ // same for vertex colors, as many as we have. again the same packing to avoid empty slots
+ for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
+ {
+ if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices)
+ {
+ dstMesh->mColors[real] = new aiColor4D[numVertices];
+ std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);
+ ++real;
+ }
+ }
+
+ // create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
+ size_t vertex = 0;
+ dstMesh->mNumFaces = static_cast<unsigned int>(pSubMesh.mNumFaces);
+ dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
+ for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
+ {
+ size_t s = pSrcMesh->mFaceSize[ pStartFace + a];
+ aiFace& face = dstMesh->mFaces[a];
+ face.mNumIndices = static_cast<unsigned int>(s);
+ face.mIndices = new unsigned int[s];
+ for( size_t b = 0; b < s; ++b)
+ face.mIndices[b] = static_cast<unsigned int>(vertex++);
+ }
// create morph target meshes if any
std::vector<aiMesh*> targetMeshes;
std::vector<float> targetWeights;
- Collada::MorphMethod method;
+ Collada::MorphMethod method = Collada::Normalized;
for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
it != pParser.mControllerLibrary.end(); it++)
@@ -719,7 +728,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
? aiMorphingMethod_MORPH_RELATIVE
: aiMorphingMethod_MORPH_NORMALIZED;
dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()];
- dstMesh->mNumAnimMeshes = animMeshes.size();
+ dstMesh->mNumAnimMeshes = static_cast<unsigned int>(animMeshes.size());
for (unsigned int i = 0; i < animMeshes.size(); i++)
dstMesh->mAnimMeshes[i] = animMeshes.at(i);
}
@@ -728,8 +737,8 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
if( pSrcController && pSrcController->mType == Collada::Skin)
{
// refuse if the vertex count does not match
-// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
-// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
+// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
+// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
// resolve references - joint names
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
@@ -782,13 +791,13 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
size_t jointIndex = iit->first;
size_t vertexIndex = iit->second;
- float weight = ReadFloat( weightsAcc, weights, vertexIndex, 0);
+ ai_real weight = ReadFloat( weightsAcc, weights, vertexIndex, 0);
// one day I gonna kill that XSI Collada exporter
if( weight > 0.0f)
{
aiVertexWeight w;
- w.mVertexId = a - pStartVertex;
+ w.mVertexId = static_cast<unsigned int>(a - pStartVertex);
w.mWeight = weight;
dstBones[jointIndex].push_back( w);
}
@@ -802,7 +811,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
numRemainingBones++;
// create bone array and copy bone weights one by one
- dstMesh->mNumBones = numRemainingBones;
+ dstMesh->mNumBones = static_cast<unsigned int>(numRemainingBones);
dstMesh->mBones = new aiBone*[numRemainingBones];
size_t boneCount = 0;
for( size_t a = 0; a < numBones; ++a)
@@ -826,7 +835,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
bone->mOffsetMatrix.c2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 9);
bone->mOffsetMatrix.c3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 10);
bone->mOffsetMatrix.c4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 11);
- bone->mNumWeights = dstBones[a].size();
+ bone->mNumWeights = static_cast<unsigned int>(dstBones[a].size());
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
std::copy( dstBones[a].begin(), dstBones[a].end(), bone->mWeights);
@@ -876,7 +885,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
// Stores all meshes in the given scene
void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
{
- pScene->mNumMeshes = mMeshes.size();
+ pScene->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
if( mMeshes.size() > 0)
{
pScene->mMeshes = new aiMesh*[mMeshes.size()];
@@ -889,7 +898,7 @@ void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
// Stores all cameras in the given scene
void ColladaLoader::StoreSceneCameras( aiScene* pScene)
{
- pScene->mNumCameras = mCameras.size();
+ pScene->mNumCameras = static_cast<unsigned int>(mCameras.size());
if( mCameras.size() > 0)
{
pScene->mCameras = new aiCamera*[mCameras.size()];
@@ -902,7 +911,7 @@ void ColladaLoader::StoreSceneCameras( aiScene* pScene)
// Stores all lights in the given scene
void ColladaLoader::StoreSceneLights( aiScene* pScene)
{
- pScene->mNumLights = mLights.size();
+ pScene->mNumLights = static_cast<unsigned int>(mLights.size());
if( mLights.size() > 0)
{
pScene->mLights = new aiLight*[mLights.size()];
@@ -915,7 +924,7 @@ void ColladaLoader::StoreSceneLights( aiScene* pScene)
// Stores all textures in the given scene
void ColladaLoader::StoreSceneTextures( aiScene* pScene)
{
- pScene->mNumTextures = mTextures.size();
+ pScene->mNumTextures = static_cast<unsigned int>(mTextures.size());
if( mTextures.size() > 0)
{
pScene->mTextures = new aiTexture*[mTextures.size()];
@@ -928,7 +937,7 @@ void ColladaLoader::StoreSceneTextures( aiScene* pScene)
// Stores all materials in the given scene
void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
{
- pScene->mNumMaterials = newMats.size();
+ pScene->mNumMaterials = static_cast<unsigned int>(newMats.size());
if (newMats.size() > 0) {
pScene->mMaterials = new aiMaterial*[newMats.size()];
@@ -969,7 +978,7 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
combinedAnim->mName = aiString( std::string( "combinedAnim_") + char( '0' + a));
combinedAnim->mDuration = templateAnim->mDuration;
combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
- combinedAnim->mNumChannels = collectedAnimIndices.size() + 1;
+ combinedAnim->mNumChannels = static_cast<unsigned int>(collectedAnimIndices.size() + 1);
combinedAnim->mChannels = new aiNodeAnim*[combinedAnim->mNumChannels];
// add the template anim as first channel by moving its aiNodeAnim to the combined animation
combinedAnim->mChannels[0] = templateAnim->mChannels[0];
@@ -1001,7 +1010,7 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
// now store all anims in the scene
if( !mAnims.empty())
{
- pScene->mNumAnimations = mAnims.size();
+ pScene->mNumAnimations = static_cast<unsigned int>(mAnims.size());
pScene->mAnimations = new aiAnimation*[mAnims.size()];
std::copy( mAnims.begin(), mAnims.end(), pScene->mAnimations);
}
@@ -1097,32 +1106,33 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
std::vector<aiNodeAnim*> anims;
std::vector<aiMeshMorphAnim*> morphAnims;
- for( std::vector<const aiNode*>::const_iterator nit = nodes.begin(); nit != nodes.end(); ++nit)
- {
- // find all the collada anim channels which refer to the current node
- std::vector<Collada::ChannelEntry> entries;
- std::string nodeName = (*nit)->mName.data;
-
- // find the collada node corresponding to the aiNode
- const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName);
-// ai_assert( srcNode != NULL);
- if( !srcNode)
- continue;
-
- // now check all channels if they affect the current node
- for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
- cit != pSrcAnim->mChannels.end(); ++cit)
- {
- const Collada::AnimationChannel& srcChannel = *cit;
- Collada::ChannelEntry entry;
-
- // we expect the animation target to be of type "nodeName/transformID.subElement". Ignore all others
- // find the slash that separates the node name - there should be only one
- std::string::size_type slashPos = srcChannel.mTarget.find( '/');
- if( slashPos == std::string::npos) {
- std::string::size_type targetPos = srcChannel.mTarget.find(srcNode->mID);
- if (targetPos == std::string::npos)
- continue;
+ for( std::vector<const aiNode*>::const_iterator nit = nodes.begin(); nit != nodes.end(); ++nit)
+ {
+ // find all the collada anim channels which refer to the current node
+ std::vector<Collada::ChannelEntry> entries;
+ std::string nodeName = (*nit)->mName.data;
+
+ // find the collada node corresponding to the aiNode
+ const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName);
+// ai_assert( srcNode != NULL);
+ if( !srcNode)
+ continue;
+
+ // now check all channels if they affect the current node
+ for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
+ cit != pSrcAnim->mChannels.end(); ++cit)
+ {
+ const Collada::AnimationChannel& srcChannel = *cit;
+ Collada::ChannelEntry entry;
+
+ // we expect the animation target to be of type "nodeName/transformID.subElement". Ignore all others
+ // find the slash that separates the node name - there should be only one
+ std::string::size_type slashPos = srcChannel.mTarget.find( '/');
+ if( slashPos == std::string::npos)
+ {
+ std::string::size_type targetPos = srcChannel.mTarget.find(srcNode->mID);
+ if (targetPos == std::string::npos)
+ continue;
// not node transform, but something else. store as unknown animation channel for now
entry.mChannel = &(*cit);
@@ -1139,37 +1149,78 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
if( targetID != srcNode->mID)
continue;
- // find the dot that separates the transformID - there should be only one or zero
- std::string::size_type dotPos = srcChannel.mTarget.find( '.');
- if( dotPos != std::string::npos)
- {
- if( srcChannel.mTarget.find( '.', dotPos+1) != std::string::npos)
- continue;
-
- entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
-
- std::string subElement = srcChannel.mTarget.substr( dotPos+1);
- if( subElement == "ANGLE")
- entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
- else if( subElement == "X")
- entry.mSubElement = 0;
- else if( subElement == "Y")
- entry.mSubElement = 1;
- else if( subElement == "Z")
- entry.mSubElement = 2;
- else
- DefaultLogger::get()->warn( format() << "Unknown anim subelement <" << subElement << ">. Ignoring" );
- } else
- {
- // no subelement following, transformId is remaining string
- entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
- }
-
- // determine which transform step is affected by this channel
- entry.mTransformIndex = SIZE_MAX;
- for( size_t a = 0; a < srcNode->mTransforms.size(); ++a)
- if( srcNode->mTransforms[a].mID == entry.mTransformId)
- entry.mTransformIndex = a;
+ // find the dot that separates the transformID - there should be only one or zero
+ std::string::size_type dotPos = srcChannel.mTarget.find( '.');
+ if( dotPos != std::string::npos)
+ {
+ if( srcChannel.mTarget.find( '.', dotPos+1) != std::string::npos)
+ continue;
+
+ entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
+
+ std::string subElement = srcChannel.mTarget.substr( dotPos+1);
+ if( subElement == "ANGLE")
+ entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
+ else if( subElement == "X")
+ entry.mSubElement = 0;
+ else if( subElement == "Y")
+ entry.mSubElement = 1;
+ else if( subElement == "Z")
+ entry.mSubElement = 2;
+ else
+ DefaultLogger::get()->warn( format() << "Unknown anim subelement <" << subElement << ">. Ignoring" );
+ } else
+ {
+ // no subelement following, transformId is remaining string
+ entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
+ }
+
+ std::string::size_type bracketPos = srcChannel.mTarget.find('(');
+ if (bracketPos != std::string::npos)
+ {
+ entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, bracketPos - slashPos - 1);
+ std::string subElement = srcChannel.mTarget.substr(bracketPos);
+
+ if (subElement == "(0)(0)")
+ entry.mSubElement = 0;
+ else if (subElement == "(1)(0)")
+ entry.mSubElement = 1;
+ else if (subElement == "(2)(0)")
+ entry.mSubElement = 2;
+ else if (subElement == "(3)(0)")
+ entry.mSubElement = 3;
+ else if (subElement == "(0)(1)")
+ entry.mSubElement = 4;
+ else if (subElement == "(1)(1)")
+ entry.mSubElement = 5;
+ else if (subElement == "(2)(1)")
+ entry.mSubElement = 6;
+ else if (subElement == "(3)(1)")
+ entry.mSubElement = 7;
+ else if (subElement == "(0)(2)")
+ entry.mSubElement = 8;
+ else if (subElement == "(1)(2)")
+ entry.mSubElement = 9;
+ else if (subElement == "(2)(2)")
+ entry.mSubElement = 10;
+ else if (subElement == "(3)(2)")
+ entry.mSubElement = 11;
+ else if (subElement == "(0)(3)")
+ entry.mSubElement = 12;
+ else if (subElement == "(1)(3)")
+ entry.mSubElement = 13;
+ else if (subElement == "(2)(3)")
+ entry.mSubElement = 14;
+ else if (subElement == "(3)(3)")
+ entry.mSubElement = 15;
+
+ }
+
+ // determine which transform step is affected by this channel
+ entry.mTransformIndex = SIZE_MAX;
+ for( size_t a = 0; a < srcNode->mTransforms.size(); ++a)
+ if( srcNode->mTransforms[a].mID == entry.mTransformId)
+ entry.mTransformIndex = a;
if( entry.mTransformIndex == SIZE_MAX)
{
@@ -1181,127 +1232,142 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
continue;
}
- entry.mChannel = &(*cit);
- entries.push_back( entry);
- }
-
- // if there's no channel affecting the current node, we skip it
- if( entries.empty())
- continue;
-
- // resolve the data pointers for all anim channels. Find the minimum time while we're at it
- float startTime = 1e20f, endTime = -1e20f;
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
- e.mTimeAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceTimes);
- e.mTimeData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mTimeAccessor->mSource);
- e.mValueAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceValues);
- e.mValueData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mValueAccessor->mSource);
-
- // time count and value count must match
- if( e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
- throw DeadlyImportError( format() << "Time count / value count mismatch in animation channel \"" << e.mChannel->mTarget << "\"." );
-
- if( e.mTimeAccessor->mCount > 0 )
- {
- // find bounding times
- startTime = std::min( startTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, 0, 0));
- endTime = std::max( endTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, e.mTimeAccessor->mCount-1, 0));
- }
+ entry.mChannel = &(*cit);
+ entries.push_back( entry);
}
- std::vector<aiMatrix4x4> resultTrafos;
- if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
+ // if there's no channel affecting the current node, we skip it
+ if( entries.empty())
+ continue;
+
+ // resolve the data pointers for all anim channels. Find the minimum time while we're at it
+ ai_real startTime = ai_real( 1e20 ), endTime = ai_real( -1e20 );
+ for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
{
- // create a local transformation chain of the node's transforms
- std::vector<Collada::Transform> transforms = srcNode->mTransforms;
+ Collada::ChannelEntry& e = *it;
+ e.mTimeAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceTimes);
+ e.mTimeData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mTimeAccessor->mSource);
+ e.mValueAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceValues);
+ e.mValueData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mValueAccessor->mSource);
+
+ // time count and value count must match
+ if( e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
+ throw DeadlyImportError( format() << "Time count / value count mismatch in animation channel \"" << e.mChannel->mTarget << "\"." );
+
+ if( e.mTimeAccessor->mCount > 0 )
+ {
+ // find bounding times
+ startTime = std::min( startTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, 0, 0));
+ endTime = std::max( endTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, e.mTimeAccessor->mCount-1, 0));
+ }
+ }
- // now for every unique point in time, find or interpolate the key values for that time
- // and apply them to the transform chain. Then the node's present transformation can be calculated.
- float time = startTime;
- while( 1)
+ std::vector<aiMatrix4x4> resultTrafos;
+ if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
+ {
+ // create a local transformation chain of the node's transforms
+ std::vector<Collada::Transform> transforms = srcNode->mTransforms;
+
+ // now for every unique point in time, find or interpolate the key values for that time
+ // and apply them to the transform chain. Then the node's present transformation can be calculated.
+ ai_real time = startTime;
+ while( 1)
+ {
+ for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
{
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
+ Collada::ChannelEntry& e = *it;
+
+ // find the keyframe behind the current point in time
+ size_t pos = 0;
+ ai_real postTime = 0.0;
+ while( 1)
{
- Collada::ChannelEntry& e = *it;
+ if( pos >= e.mTimeAccessor->mCount)
+ break;
+ postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
+ if( postTime >= time)
+ break;
+ ++pos;
+ }
- // skip non-transform types
- if (e.mTransformId.empty())
- continue;
+ pos = std::min( pos, e.mTimeAccessor->mCount-1);
- // find the keyframe behind the current point in time
- size_t pos = 0;
- float postTime = 0.f;
- while( 1)
- {
- if( pos >= e.mTimeAccessor->mCount)
- break;
- postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
- if( postTime >= time)
- break;
- ++pos;
- }
+ // read values from there
+ ai_real temp[16];
+ for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
+ temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
- pos = std::min( pos, e.mTimeAccessor->mCount-1);
+ // if not exactly at the key time, interpolate with previous value set
+ if( postTime > time && pos > 0)
+ {
+ ai_real preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
+ ai_real factor = (time - postTime) / (preTime - postTime);
- // read values from there
- float temp[16];
for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
- temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
-
- // if not exactly at the key time, interpolate with previous value set
- if( postTime > time && pos > 0)
{
- float preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
- float factor = (time - postTime) / (preTime - postTime);
-
- for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
- {
- float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
- temp[c] += (v - temp[c]) * factor;
- }
+ ai_real v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
+ temp[c] += (v - temp[c]) * factor;
}
-
- // Apply values to current transformation
- std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement);
}
- // Calculate resulting transformation
- aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms);
+ // Apply values to current transformation
+ std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement);
+ }
- // out of laziness: we store the time in matrix.d4
- mat.d4 = time;
- resultTrafos.push_back( mat);
+ // Calculate resulting transformation
+ aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms);
- // find next point in time to evaluate. That's the closest frame larger than the current in any channel
- float nextTime = 1e20f;
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
+ // out of laziness: we store the time in matrix.d4
+ mat.d4 = time;
+ resultTrafos.push_back( mat);
+
+ // find next point in time to evaluate. That's the closest frame larger than the current in any channel
+ ai_real nextTime = ai_real( 1e20 );
+ for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
+ {
+ Collada::ChannelEntry& channelElement = *it;
- // find the next time value larger than the current
- size_t pos = 0;
- while( pos < e.mTimeAccessor->mCount)
+ // find the next time value larger than the current
+ size_t pos = 0;
+ while( pos < channelElement.mTimeAccessor->mCount)
+ {
+ const ai_real t = ReadFloat( *channelElement.mTimeAccessor, *channelElement.mTimeData, pos, 0);
+ if( t > time)
{
- float t = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
- if( t > time)
- {
- nextTime = std::min( nextTime, t);
- break;
- }
- ++pos;
+ nextTime = std::min( nextTime, t);
+ break;
}
+ ++pos;
}
- // no more keys on any channel after the current time -> we're done
- if( nextTime > 1e19)
- break;
-
- // else construct next keyframe at this following time point
- time = nextTime;
+ // https://github.com/assimp/assimp/issues/458
+ // Sub-sample axis-angle channels if the delta between two consecutive
+ // key-frame angles is >= 180 degrees.
+ if (transforms[channelElement.mTransformIndex].mType == Collada::TF_ROTATE && channelElement.mSubElement == 3 && pos > 0 && pos < channelElement.mTimeAccessor->mCount) {
+ const ai_real cur_key_angle = ReadFloat(*channelElement.mValueAccessor, *channelElement.mValueData, pos, 0);
+ const ai_real last_key_angle = ReadFloat(*channelElement.mValueAccessor, *channelElement.mValueData, pos - 1, 0);
+ const ai_real cur_key_time = ReadFloat(*channelElement.mTimeAccessor, *channelElement.mTimeData, pos, 0);
+ const ai_real last_key_time = ReadFloat(*channelElement.mTimeAccessor, *channelElement.mTimeData, pos - 1, 0);
+ const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
+ const ai_real delta = std::abs(cur_key_angle - last_eval_angle);
+ if (delta >= 180.0) {
+ const int subSampleCount = static_cast<int>(std::floor(delta / 90.0));
+ if (cur_key_time != time) {
+ const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount;
+ nextTime = std::min(nextTime, nextSampleTime);
+ }
+ }
+ }
}
- }
+
+ // no more keys on any channel after the current time -> we're done
+ if( nextTime > 1e19)
+ break;
+
+ // else construct next keyframe at this following time point
+ time = nextTime;
+ }
+ }
// there should be some keyframes, but we aren't that fixated on valid input data
// ai_assert( resultTrafos.size() > 0);
@@ -1311,9 +1377,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
{
aiNodeAnim* dstAnim = new aiNodeAnim;
dstAnim->mNodeName = nodeName;
- dstAnim->mNumPositionKeys = resultTrafos.size();
- dstAnim->mNumRotationKeys= resultTrafos.size();
- dstAnim->mNumScalingKeys = resultTrafos.size();
+ dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
+ dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
+ dstAnim->mNumScalingKeys = static_cast<unsigned int>(resultTrafos.size());
dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
@@ -1379,11 +1445,11 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
++morphAnimChannelIndex;
}
- morphAnim->mNumKeys = morphTimeValues.size();
+ morphAnim->mNumKeys = static_cast<unsigned int>(morphTimeValues.size());
morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys];
for (unsigned int key = 0; key < morphAnim->mNumKeys; key++)
{
- morphAnim->mKeys[key].mNumValuesAndWeights = morphChannels.size();
+ morphAnim->mKeys[key].mNumValuesAndWeights = static_cast<unsigned int>(morphChannels.size());
morphAnim->mKeys[key].mValues = new unsigned int [morphChannels.size()];
morphAnim->mKeys[key].mWeights = new double [morphChannels.size()];
@@ -1400,36 +1466,36 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
}
}
- if( !anims.empty() || !morphAnims.empty())
- {
- aiAnimation* anim = new aiAnimation;
- anim->mName.Set( pName);
- anim->mNumChannels = anims.size();
- if (anim->mNumChannels > 0)
- {
- anim->mChannels = new aiNodeAnim*[anims.size()];
- std::copy( anims.begin(), anims.end(), anim->mChannels);
- }
- anim->mNumMorphMeshChannels = morphAnims.size();
- if (anim->mNumMorphMeshChannels > 0)
- {
- anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
- std::copy( morphAnims.begin(), morphAnims.end(), anim->mMorphMeshChannels);
- }
- anim->mDuration = 0.0f;
- for( size_t a = 0; a < anims.size(); ++a)
- {
- anim->mDuration = std::max( anim->mDuration, anims[a]->mPositionKeys[anims[a]->mNumPositionKeys-1].mTime);
- anim->mDuration = std::max( anim->mDuration, anims[a]->mRotationKeys[anims[a]->mNumRotationKeys-1].mTime);
- anim->mDuration = std::max( anim->mDuration, anims[a]->mScalingKeys[anims[a]->mNumScalingKeys-1].mTime);
- }
- for (size_t a = 0; a < morphAnims.size(); ++a)
- {
- anim->mDuration = std::max(anim->mDuration, morphAnims[a]->mKeys[morphAnims[a]->mNumKeys-1].mTime);
- }
- anim->mTicksPerSecond = 1;
- mAnims.push_back( anim);
- }
+ if( !anims.empty() || !morphAnims.empty())
+ {
+ aiAnimation* anim = new aiAnimation;
+ anim->mName.Set( pName);
+ anim->mNumChannels = static_cast<unsigned int>(anims.size());
+ if (anim->mNumChannels > 0)
+ {
+ anim->mChannels = new aiNodeAnim*[anims.size()];
+ std::copy( anims.begin(), anims.end(), anim->mChannels);
+ }
+ anim->mNumMorphMeshChannels = static_cast<unsigned int>(morphAnims.size());
+ if (anim->mNumMorphMeshChannels > 0)
+ {
+ anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
+ std::copy( morphAnims.begin(), morphAnims.end(), anim->mMorphMeshChannels);
+ }
+ anim->mDuration = 0.0f;
+ for( size_t a = 0; a < anims.size(); ++a)
+ {
+ anim->mDuration = std::max( anim->mDuration, anims[a]->mPositionKeys[anims[a]->mNumPositionKeys-1].mTime);
+ anim->mDuration = std::max( anim->mDuration, anims[a]->mRotationKeys[anims[a]->mNumRotationKeys-1].mTime);
+ anim->mDuration = std::max( anim->mDuration, anims[a]->mScalingKeys[anims[a]->mNumScalingKeys-1].mTime);
+ }
+ for (size_t a = 0; a < morphAnims.size(); ++a)
+ {
+ anim->mDuration = std::max(anim->mDuration, morphAnims[a]->mKeys[morphAnims[a]->mNumKeys-1].mTime);
+ }
+ anim->mTicksPerSecond = 1;
+ mAnims.push_back( anim);
+ }
}
// ------------------------------------------------------------------------------------------------
@@ -1469,7 +1535,7 @@ void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
_AI_MATKEY_TEXBLEND_BASE, type, idx);
// Blend factor
- mat.AddProperty((float*)&sampler.mWeighting , 1,
+ mat.AddProperty((ai_real*)&sampler.mWeighting , 1,
_AI_MATKEY_TEXBLEND_BASE, type, idx);
// UV source index ... if we didn't resolve the mapping, it is actually just
@@ -1553,13 +1619,13 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
// transparency, a very hard one. seemingly not all files are following the
- // specification here (1.0 transparency => completly opaque)...
+ // specification here (1.0 transparency => completely opaque)...
// therefore, we let the opportunity for the user to manually invert
// the transparency if necessary and we add preliminary support for RGB_ZERO mode
if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
// handle RGB transparency completely, cf Collada specs 1.5.0 pages 249 and 304
if(effect.mRGBTransparency) {
- // use luminance as defined by ISO/CIE color standards (see ITU-R Recommendation BT.709-4)
+ // use luminance as defined by ISO/CIE color standards (see ITU-R Recommendation BT.709-4)
effect.mTransparency *= (
0.212671f * effect.mTransparent.r +
0.715160f * effect.mTransparent.g +
@@ -1644,11 +1710,11 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
const 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);
+ aiColor4D colAmbient( 0.2, 0.2, 0.2, 1.0), colDiffuse( 0.8, 0.8, 0.8, 1.0), colSpecular( 0.5, 0.5, 0.5, 0.5);
mat->AddProperty( &colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
mat->AddProperty( &colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty( &colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- const float specExp = 5.0f;
+ const ai_real specExp = 5.0;
mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
}
#endif
@@ -1659,6 +1725,8 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName)
{
+ aiString result;
+
// recurse through the param references until we end up at an image
std::string name = pName;
while( 1)
@@ -1677,11 +1745,17 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
if( imIt == pParser.mImageLibrary.end())
{
- throw DeadlyImportError( format() <<
- "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
- }
+ //missing texture should not stop the conversion
+ //throw DeadlyImportError( format() <<
+ // "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
- aiString result;
+ DefaultLogger::get()->warn("Collada: Unable to resolve effect texture entry \"" + pName + "\", ended up at ID \"" + name + "\".");
+
+ //set default texture file name
+ result.Set(name + ".jpg");
+ ConvertPath(result);
+ return result;
+ }
// if this is an embedded texture image setup an aiTexture for it
if (imIt->second.mFileName.empty())
@@ -1700,13 +1774,13 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
// and copy texture data
tex->mHeight = 0;
- tex->mWidth = imIt->second.mImageData.size();
+ tex->mWidth = static_cast<unsigned int>(imIt->second.mImageData.size());
tex->pcData = (aiTexel*)new char[tex->mWidth];
memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
// setup texture reference string
result.data[0] = '*';
- result.length = 1 + ASSIMP_itoa10(result.data+1,MAXLEN-1,mTextures.size());
+ result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));
// and add this texture to the list
mTextures.push_back(tex);
@@ -1767,7 +1841,7 @@ void ColladaLoader::ConvertPath (aiString& ss)
// ------------------------------------------------------------------------------------------------
// Reads a float value from an accessor and its data array.
-float ColladaLoader::ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const
+ai_real ColladaLoader::ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const
{
// FIXME: (thom) Test for data type here in every access? For the moment, I leave this to the caller
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
@@ -1829,14 +1903,13 @@ const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, c
}
// ------------------------------------------------------------------------------------------------
-// Finds a proper name for a node derived from the collada-node's properties
+// Finds a proper unique name for a node derived from the collada-node's properties.
+// The name must be unique for proper node-bone association.
std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
{
- // now setup the name of the node. We take the name if not empty, otherwise the collada ID
- // FIX: Workaround for XSI calling the instanced visual scene 'untitled' by default.
- if (!pNode->mName.empty() && pNode->mName != "untitled")
- return pNode->mName;
- else if (!pNode->mID.empty())
+ // Now setup the name of the assimp node. The collada name might not be
+ // unique, so we use the collada ID.
+ if (!pNode->mID.empty())
return pNode->mID;
else if (!pNode->mSID.empty())
return pNode->mSID;