ColladaLoader: format.

pull/502/head
Alexander Gessler 2015-02-15 22:25:04 +01:00 committed by Alexander Gessler
parent ce1302cd71
commit 51b790c482
1 changed files with 195 additions and 195 deletions

View File

@ -73,7 +73,7 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
ColladaLoader::ColladaLoader() ColladaLoader::ColladaLoader()
: noSkeletonMesh(), ignoreUpDirection(false), mNodeNameCounter() : noSkeletonMesh(), ignoreUpDirection(false), mNodeNameCounter()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -94,9 +94,9 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
// XML - too generic, we need to open the file and search for typical keywords // XML - too generic, we need to open the file and search for typical keywords
if( extension == "xml" || !extension.length() || checkSig) { if( extension == "xml" || !extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we /* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler * support a specific file extension in general pIOHandler
* might be NULL and it's our duty to return true here. * might be NULL and it's our duty to return true here.
*/ */
if (!pIOHandler)return true; if (!pIOHandler)return true;
const char* tokens[] = {"collada"}; const char* tokens[] = {"collada"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
@ -157,26 +157,26 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
// ... then fill the materials with the now adjusted settings // ... then fill the materials with the now adjusted settings
FillMaterials(parser, pScene); FillMaterials(parser, pScene);
// Apply unitsize scale calculation // Apply unitsize scale calculation
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0, pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
0, parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0, 0,
0, 0, parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0,
0, 0, 0, 1); 0, 0, 0, 1);
if( !ignoreUpDirection ) { if( !ignoreUpDirection ) {
// Convert to Y_UP, if different orientation // Convert to Y_UP, if different orientation
if( parser.mUpDirection == ColladaParser::UP_X) if( parser.mUpDirection == ColladaParser::UP_X)
pScene->mRootNode->mTransformation *= aiMatrix4x4( pScene->mRootNode->mTransformation *= aiMatrix4x4(
0, -1, 0, 0, 0, -1, 0, 0,
1, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1); 0, 0, 0, 1);
else if( parser.mUpDirection == ColladaParser::UP_Z) else if( parser.mUpDirection == ColladaParser::UP_Z)
pScene->mRootNode->mTransformation *= aiMatrix4x4( pScene->mRootNode->mTransformation *= aiMatrix4x4(
1, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, -1, 0, 0, 0, -1, 0, 0,
0, 0, 0, 1); 0, 0, 0, 1);
} }
// store all meshes // store all meshes
StoreSceneMeshes( pScene); StoreSceneMeshes( pScene);
@ -251,14 +251,14 @@ aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Colla
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Resolve node instances // Resolve node instances
void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode, void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
std::vector<const Collada::Node*>& resolved) std::vector<const Collada::Node*>& resolved)
{ {
// reserve enough storage // reserve enough storage
resolved.reserve(pNode->mNodeInstances.size()); resolved.reserve(pNode->mNodeInstances.size());
// ... and iterate through all nodes to be instanced as children of pNode // ... and iterate through all nodes to be instanced as children of pNode
for (std::vector<Collada::NodeInstance>::const_iterator it = pNode->mNodeInstances.begin(), for (std::vector<Collada::NodeInstance>::const_iterator it = pNode->mNodeInstances.begin(),
end = pNode->mNodeInstances.end(); it != end; ++it) end = pNode->mNodeInstances.end(); it != end; ++it)
{ {
// find the corresponding node in the library // find the corresponding node in the library
const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find((*it).mNode); const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find((*it).mNode);
@ -283,7 +283,7 @@ void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Co
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Resolve UV channels // Resolve UV channels
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler, void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
const Collada::SemanticMappingTable& table) const Collada::SemanticMappingTable& table)
{ {
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel); std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
if (it != table.mMap.end()) { if (it != table.mMap.end()) {
@ -387,7 +387,7 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
// ... but for the rest some values are optional // ... but for the rest some values are optional
// and we need to compute the others in any combination. // and we need to compute the others in any combination.
if (srcCamera->mAspect != 10e10f) if (srcCamera->mAspect != 10e10f)
out->mAspect = srcCamera->mAspect; out->mAspect = srcCamera->mAspect;
if (srcCamera->mHorFov != 10e10f) { if (srcCamera->mHorFov != 10e10f) {
@ -395,12 +395,12 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) { if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) / out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
tan(AI_DEG_TO_RAD(srcCamera->mVerFov)); tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
} }
} }
else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) { else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect * out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect *
tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f))); tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
} }
// Collada uses degrees, we use radians // Collada uses degrees, we use radians
@ -518,11 +518,11 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
// assign the material index // assign the material index
dstMesh->mMaterialIndex = matIdx; dstMesh->mMaterialIndex = matIdx;
if(dstMesh->mName.length == 0) if(dstMesh->mName.length == 0)
{ {
dstMesh->mName = mid.mMeshOrController; dstMesh->mName = mid.mMeshOrController;
} }
} }
} }
} }
@ -538,11 +538,11 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh // Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace) const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
{ {
aiMesh* dstMesh = new aiMesh; aiMesh* dstMesh = new aiMesh;
dstMesh->mName = pSrcMesh->mName; dstMesh->mName = pSrcMesh->mName;
// count the vertices addressed by its faces // count the vertices addressed by its faces
const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace, const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace,
@ -624,8 +624,8 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
if( pSrcController) if( pSrcController)
{ {
// refuse if the vertex count does not match // refuse if the vertex count does not match
// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices) // if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count"); // throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
// resolve references - joint names // resolve references - joint names
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource); const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
@ -937,7 +937,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
// find the collada node corresponding to the aiNode // find the collada node corresponding to the aiNode
const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName); const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName);
// ai_assert( srcNode != NULL); // ai_assert( srcNode != NULL);
if( !srcNode) if( !srcNode)
continue; continue;
@ -1058,134 +1058,134 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
if( e.mTimeAccessor->mCount != e.mValueAccessor->mCount) if( e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
throw DeadlyImportError( boost::str( boost::format( "Time count / value count mismatch in animation channel \"%s\".") % e.mChannel->mTarget)); throw DeadlyImportError( boost::str( boost::format( "Time count / value count mismatch in animation channel \"%s\".") % e.mChannel->mTarget));
if( e.mTimeAccessor->mCount > 0 ) if( e.mTimeAccessor->mCount > 0 )
{ {
// find bounding times // find bounding times
startTime = std::min( startTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, 0, 0)); 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)); endTime = std::max( endTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, e.mTimeAccessor->mCount-1, 0));
} }
} }
std::vector<aiMatrix4x4> resultTrafos; std::vector<aiMatrix4x4> resultTrafos;
if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 ) if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
{ {
// create a local transformation chain of the node's transforms // create a local transformation chain of the node's transforms
std::vector<Collada::Transform> transforms = srcNode->mTransforms; std::vector<Collada::Transform> transforms = srcNode->mTransforms;
// now for every unique point in time, find or interpolate the key values for that time // 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. // and apply them to the transform chain. Then the node's present transformation can be calculated.
float time = startTime; float time = startTime;
while( 1) 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; Collada::ChannelEntry& e = *it;
// find the keyframe behind the current point in time // find the keyframe behind the current point in time
size_t pos = 0; size_t pos = 0;
float postTime = 0.f; float postTime = 0.f;
while( 1) while( 1)
{ {
if( pos >= e.mTimeAccessor->mCount) if( pos >= e.mTimeAccessor->mCount)
break; break;
postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0); postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
if( postTime >= time) if( postTime >= time)
break; break;
++pos; ++pos;
} }
pos = std::min( pos, e.mTimeAccessor->mCount-1); pos = std::min( pos, e.mTimeAccessor->mCount-1);
// read values from there // read values from there
float temp[16]; float temp[16];
for( size_t c = 0; c < e.mValueAccessor->mSize; ++c) for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c); temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
// if not exactly at the key time, interpolate with previous value set // if not exactly at the key time, interpolate with previous value set
if( postTime > time && pos > 0) if( postTime > time && pos > 0)
{ {
float preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0); float preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
float factor = (time - postTime) / (preTime - postTime); float factor = (time - postTime) / (preTime - postTime);
for( size_t c = 0; c < e.mValueAccessor->mSize; ++c) for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
{ {
float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c); float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
temp[c] += (v - temp[c]) * factor; temp[c] += (v - temp[c]) * factor;
} }
} }
// Apply values to current transformation // Apply values to current transformation
std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement); std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement);
} }
// Calculate resulting transformation // Calculate resulting transformation
aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms); aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms);
// out of lazyness: we store the time in matrix.d4 // out of lazyness: we store the time in matrix.d4
mat.d4 = time; mat.d4 = time;
resultTrafos.push_back( mat); resultTrafos.push_back( mat);
// find next point in time to evaluate. That's the closest frame larger than the current in any channel // find next point in time to evaluate. That's the closest frame larger than the current in any channel
float nextTime = 1e20f; float nextTime = 1e20f;
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; Collada::ChannelEntry& e = *it;
// find the next time value larger than the current // find the next time value larger than the current
size_t pos = 0; size_t pos = 0;
while( pos < e.mTimeAccessor->mCount) while( pos < e.mTimeAccessor->mCount)
{ {
float t = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0); float t = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
if( t > time) if( t > time)
{ {
nextTime = std::min( nextTime, t); nextTime = std::min( nextTime, t);
break; break;
} }
++pos; ++pos;
} }
} }
// no more keys on any channel after the current time -> we're done // no more keys on any channel after the current time -> we're done
if( nextTime > 1e19) if( nextTime > 1e19)
break; break;
// else construct next keyframe at this following time point // else construct next keyframe at this following time point
time = nextTime; time = nextTime;
} }
} }
// there should be some keyframes, but we aren't that fixated on valid input data // there should be some keyframes, but we aren't that fixated on valid input data
// ai_assert( resultTrafos.size() > 0); // ai_assert( resultTrafos.size() > 0);
// build an animation channel for the given node out of these trafo keys // build an animation channel for the given node out of these trafo keys
if( !resultTrafos.empty() ) if( !resultTrafos.empty() )
{ {
aiNodeAnim* dstAnim = new aiNodeAnim; aiNodeAnim* dstAnim = new aiNodeAnim;
dstAnim->mNodeName = nodeName; dstAnim->mNodeName = nodeName;
dstAnim->mNumPositionKeys = resultTrafos.size(); dstAnim->mNumPositionKeys = resultTrafos.size();
dstAnim->mNumRotationKeys= resultTrafos.size(); dstAnim->mNumRotationKeys= resultTrafos.size();
dstAnim->mNumScalingKeys = resultTrafos.size(); dstAnim->mNumScalingKeys = resultTrafos.size();
dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()]; dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()]; dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()]; dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
for( size_t a = 0; a < resultTrafos.size(); ++a) for( size_t a = 0; a < resultTrafos.size(); ++a)
{ {
aiMatrix4x4 mat = resultTrafos[a]; aiMatrix4x4 mat = resultTrafos[a];
double time = double( mat.d4); // remember? time is stored in mat.d4 double time = double( mat.d4); // remember? time is stored in mat.d4
mat.d4 = 1.0f; mat.d4 = 1.0f;
dstAnim->mPositionKeys[a].mTime = time; dstAnim->mPositionKeys[a].mTime = time;
dstAnim->mRotationKeys[a].mTime = time; dstAnim->mRotationKeys[a].mTime = time;
dstAnim->mScalingKeys[a].mTime = time; dstAnim->mScalingKeys[a].mTime = time;
mat.Decompose( dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue); mat.Decompose( dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue);
} }
anims.push_back( dstAnim); anims.push_back( dstAnim);
} else } else
{ {
DefaultLogger::get()->warn( "Collada loader: found empty animation channel, ignored. Please check your exporter."); DefaultLogger::get()->warn( "Collada loader: found empty animation channel, ignored. Please check your exporter.");
} }
} }
if( !anims.empty()) if( !anims.empty())
@ -1210,9 +1210,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Add a texture to a material structure // Add a texture to a material structure
void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser, void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
const Collada::Effect& effect, const Collada::Effect& effect,
const Collada::Sampler& sampler, const Collada::Sampler& sampler,
aiTextureType type, unsigned int idx) aiTextureType type, unsigned int idx)
{ {
// first of all, basic file name // first of all, basic file name
const aiString name = FindFilenameForEffectTexture( pParser, effect, sampler.mName ); const aiString name = FindFilenameForEffectTexture( pParser, effect, sampler.mName );
@ -1339,8 +1339,8 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
// add textures, if given // add textures, if given
if( !effect.mTexAmbient.mName.empty()) if( !effect.mTexAmbient.mName.empty())
/* It is merely a lightmap */ /* It is merely a lightmap */
AddTexture( mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP); AddTexture( mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
if( !effect.mTexEmissive.mName.empty()) if( !effect.mTexEmissive.mName.empty())
AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE); AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE);
@ -1411,7 +1411,7 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Resolves the texture name for the given effect texture entry // Resolves the texture name for the given effect texture entry
aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser, aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName) const Collada::Effect& pEffect, const std::string& pName)
{ {
// recurse through the param references until we end up at an image // recurse through the param references until we end up at an image
std::string name = pName; std::string name = pName;
@ -1488,35 +1488,35 @@ void ColladaLoader::ConvertPath (aiString& ss)
ss.data[ss.length] = '\0'; ss.data[ss.length] = '\0';
} }
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes... // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
// I need to filter it without destroying linux paths starting with "/somewhere" // I need to filter it without destroying linux paths starting with "/somewhere"
if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' ) if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
{ {
ss.length--; ss.length--;
memmove( ss.data, ss.data+1, ss.length); memmove( ss.data, ss.data+1, ss.length);
ss.data[ss.length] = 0; ss.data[ss.length] = 0;
} }
// find and convert all %xy special chars // find and convert all %xy special chars
char* out = ss.data; char* out = ss.data;
for( const char* it = ss.data; it != ss.data + ss.length; /**/ ) for( const char* it = ss.data; it != ss.data + ss.length; /**/ )
{ {
if( *it == '%' && (it + 3) < ss.data + ss.length ) if( *it == '%' && (it + 3) < ss.data + ss.length )
{ {
// separate the number to avoid dragging in chars from behind into the parsing // separate the number to avoid dragging in chars from behind into the parsing
char mychar[3] = { it[1], it[2], 0 }; char mychar[3] = { it[1], it[2], 0 };
size_t nbr = strtoul16( mychar); size_t nbr = strtoul16( mychar);
it += 3; it += 3;
*out++ = (char)(nbr & 0xFF); *out++ = (char)(nbr & 0xFF);
} else } else
{ {
*out++ = *it++; *out++ = *it++;
} }
} }
// adjust length and terminator of the shortened string // adjust length and terminator of the shortened string
*out = 0; *out = 0;
ss.length = (ptrdiff_t) (out - ss.data); ss.length = (ptrdiff_t) (out - ss.data);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1569,17 +1569,17 @@ const Collada::Node* ColladaLoader::FindNode( const Collada::Node* pNode, const
// Finds a node in the collada scene by the given SID // Finds a node in the collada scene by the given SID
const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const
{ {
if( pNode->mSID == pSID) if( pNode->mSID == pSID)
return pNode; return pNode;
for( size_t a = 0; a < pNode->mChildren.size(); ++a) for( size_t a = 0; a < pNode->mChildren.size(); ++a)
{ {
const Collada::Node* node = FindNodeBySID( pNode->mChildren[a], pSID); const Collada::Node* node = FindNodeBySID( pNode->mChildren[a], pSID);
if( node) if( node)
return node; return node;
} }
return NULL; return NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1593,12 +1593,12 @@ std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
else if (!pNode->mID.empty()) else if (!pNode->mID.empty())
return pNode->mID; return pNode->mID;
else if (!pNode->mSID.empty()) else if (!pNode->mSID.empty())
return pNode->mSID; return pNode->mSID;
else else
{ {
// No need to worry. Unnamed nodes are no problem at all, except // No need to worry. Unnamed nodes are no problem at all, except
// if cameras or lights need to be assigned to them. // if cameras or lights need to be assigned to them.
return boost::str( boost::format( "$ColladaAutoName$_%d") % mNodeNameCounter++); return boost::str( boost::format( "$ColladaAutoName$_%d") % mNodeNameCounter++);
} }
} }