Kaynağa Gözat

Bugfix/ensure collada parsing works issue 1488 (#6087)

* Add text to ensure that float parsing in colladata works right
Kim Kulling 3 ay önce
ebeveyn
işleme
2f3e72413f

+ 47 - 47
code/AssetLib/Collada/ColladaLoader.cpp

@@ -89,6 +89,14 @@ inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value
     node->mMetaData->Add(key, value);
     node->mMetaData->Add(key, value);
 }
 }
 
 
+// ------------------------------------------------------------------------------------------------
+// Reads a float value from an accessor and its data array.
+static ai_real ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) {
+    size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
+    ai_assert(pos < pData.mValues.size());
+    return pData.mValues[pos];
+}
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 // Constructor to be privately used by Importer
 ColladaLoader::ColladaLoader() :
 ColladaLoader::ColladaLoader() :
@@ -152,7 +160,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
         throw DeadlyImportError("Collada: File came out empty. Something is wrong here.");
         throw DeadlyImportError("Collada: File came out empty. Something is wrong here.");
     }
     }
 
 
-    // reserve some storage to avoid unnecessary reallocs
+    // reserve some storage to avoid unnecessary reallocates
     newMats.reserve(parser.mMaterialLibrary.size() * 2u);
     newMats.reserve(parser.mMaterialLibrary.size() * 2u);
     mMeshes.reserve(parser.mMeshLibrary.size() * 2u);
     mMeshes.reserve(parser.mMeshLibrary.size() * 2u);
 
 
@@ -224,7 +232,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
 // Recursively constructs a scene node for the given parser node and returns it.
 // Recursively constructs a scene node for the given parser node and returns it.
 aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode) {
 aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode) {
     // create a node for it
     // create a node for it
-    aiNode *node = new aiNode();
+    auto *node = new aiNode();
 
 
     // find a name for the new node. It's more complicated than you might think
     // find a name for the new node. It's more complicated than you might think
     node->mName.Set(FindNameForNode(pNode));
     node->mName.Set(FindNameForNode(pNode));
@@ -272,24 +280,24 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Resolve node instances
 // Resolve node instances
 void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Node *pNode,
 void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Node *pNode,
-        std::vector<const Node*> &resolved) {
+        std::vector<const Node*> &resolved) const {
     // 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 (const auto &nodeInst : pNode->mNodeInstances) {
+    for (const auto &[mNode] : pNode->mNodeInstances) {
         // find the corresponding node in the library
         // find the corresponding node in the library
-        const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
+        const auto itt = pParser.mNodeLibrary.find(mNode);
         const Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
         const Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
 
 
         // FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
         // FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
         // need to check for both name and ID to catch all. To avoid breaking valid files,
         // need to check for both name and ID to catch all. To avoid breaking valid files,
         // the workaround is only enabled when the first attempt to resolve the node has failed.
         // the workaround is only enabled when the first attempt to resolve the node has failed.
         if (nullptr == nd) {
         if (nullptr == nd) {
-            nd = FindNode(pParser.mRootNode, nodeInst.mNode);
+            nd = FindNode(pParser.mRootNode, mNode);
         }
         }
         if (nullptr == nd) {
         if (nullptr == nd) {
-            ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
+            ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", mNode);
         } else {
         } else {
             //  attach this node to the list of children
             //  attach this node to the list of children
             resolved.push_back(nd);
             resolved.push_back(nd);
@@ -299,8 +307,8 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Nod
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Resolve UV channels
 // Resolve UV channels
-void ColladaLoader::ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
-    SemanticMappingTable::InputSemanticMap::const_iterator it = table.mMap.find(sampler.mUVChannel);
+static void ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
+    const auto it = table.mMap.find(sampler.mUVChannel);
     if (it == table.mMap.end()) {
     if (it == table.mMap.end()) {
         return;
         return;
     }
     }
@@ -317,7 +325,7 @@ void ColladaLoader::ApplyVertexToEffectSemanticMapping(Sampler &sampler, const S
 void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
 void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
     for (const LightInstance &lid : pNode->mLights) {
     for (const LightInstance &lid : pNode->mLights) {
         // find the referred light
         // find the referred light
-        ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight);
+        auto srcLightIt = pParser.mLightLibrary.find(lid.mLight);
         if (srcLightIt == pParser.mLightLibrary.end()) {
         if (srcLightIt == pParser.mLightLibrary.end()) {
             ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping.");
             ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping.");
             continue;
             continue;
@@ -325,7 +333,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
         const Collada::Light *srcLight = &srcLightIt->second;
         const Collada::Light *srcLight = &srcLightIt->second;
 
 
         // now fill our ai data structure
         // now fill our ai data structure
-        aiLight *out = new aiLight();
+        auto out = new aiLight();
         out->mName = pTarget->mName;
         out->mName = pTarget->mName;
         out->mType = (aiLightSourceType)srcLight->mType;
         out->mType = (aiLightSourceType)srcLight->mType;
 
 
@@ -382,7 +390,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
 void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
 void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
     for (const CameraInstance &cid : pNode->mCameras) {
     for (const CameraInstance &cid : pNode->mCameras) {
         // find the referred light
         // find the referred light
-        ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
+        auto srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
         if (srcCameraIt == pParser.mCameraLibrary.end()) {
         if (srcCameraIt == pParser.mCameraLibrary.end()) {
             ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping.");
             ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping.");
             continue;
             continue;
@@ -395,7 +403,7 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node
         }
         }
 
 
         // now fill our ai data structure
         // now fill our ai data structure
-        aiCamera *out = new aiCamera();
+        auto *out = new aiCamera();
         out->mName = pTarget->mName;
         out->mName = pTarget->mName;
 
 
         // collada cameras point in -Z by default, rest is specified in node transform
         // collada cameras point in -Z by default, rest is specified in node transform
@@ -445,10 +453,10 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
         const Controller *srcController = nullptr;
         const Controller *srcController = nullptr;
 
 
         // find the referred mesh
         // find the referred mesh
-        ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
+        auto srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
         if (srcMeshIt == pParser.mMeshLibrary.end()) {
         if (srcMeshIt == pParser.mMeshLibrary.end()) {
             // if not found in the mesh-library, it might also be a controller referring to a mesh
             // if not found in the mesh-library, it might also be a controller referring to a mesh
-            ColladaParser::ControllerLibrary::const_iterator srcContrIt = pParser.mControllerLibrary.find(mid.mMeshOrController);
+            auto srcContrIt = pParser.mControllerLibrary.find(mid.mMeshOrController);
             if (srcContrIt != pParser.mControllerLibrary.end()) {
             if (srcContrIt != pParser.mControllerLibrary.end()) {
                 srcController = &srcContrIt->second;
                 srcController = &srcContrIt->second;
                 srcMeshIt = pParser.mMeshLibrary.find(srcController->mMeshId);
                 srcMeshIt = pParser.mMeshLibrary.find(srcController->mMeshId);
@@ -462,7 +470,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
                 continue;
                 continue;
             }
             }
         } else {
         } else {
-            // ID found in the mesh library -> direct reference to an unskinned mesh
+            // ID found in the mesh library -> direct reference to a not skinned mesh
             srcMesh = srcMeshIt->second;
             srcMesh = srcMeshIt->second;
         }
         }
 
 
@@ -476,7 +484,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
 
 
             // find material assigned to this submesh
             // find material assigned to this submesh
             std::string meshMaterial;
             std::string meshMaterial;
-            std::map<std::string, SemanticMappingTable>::const_iterator meshMatIt = mid.mMaterials.find(submesh.mMaterial);
+            auto meshMatIt = mid.mMaterials.find(submesh.mMaterial);
 
 
             const Collada::SemanticMappingTable *table = nullptr;
             const Collada::SemanticMappingTable *table = nullptr;
             if (meshMatIt != mid.mMaterials.end()) {
             if (meshMatIt != mid.mMaterials.end()) {
@@ -492,7 +500,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
 
 
             // OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
             // OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
             // given. The only mapping stuff which we do actually support is the UV channel.
             // given. The only mapping stuff which we do actually support is the UV channel.
-            std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find(meshMaterial);
+            auto matIt = mMaterialIndexByName.find(meshMaterial);
             unsigned int matIdx = 0;
             unsigned int matIdx = 0;
             if (matIt != mMaterialIndexByName.end()) {
             if (matIt != mMaterialIndexByName.end()) {
                 matIdx = static_cast<unsigned int>(matIt->second);
                 matIdx = static_cast<unsigned int>(matIt->second);
@@ -515,7 +523,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
             ColladaMeshIndex index(mid.mMeshOrController, sm, meshMaterial);
             ColladaMeshIndex index(mid.mMeshOrController, sm, meshMaterial);
 
 
             // if we already have the mesh at the library, just add its index to the node's array
             // if we already have the mesh at the library, just add its index to the node's array
-            std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find(index);
+            auto dstMeshIt = mMeshIndexByID.find(index);
             if (dstMeshIt != mMeshIndexByID.end()) {
             if (dstMeshIt != mMeshIndexByID.end()) {
                 newMeshRefs.push_back(dstMeshIt->second);
                 newMeshRefs.push_back(dstMeshIt->second);
             } else {
             } else {
@@ -530,7 +538,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
                 faceStart += submesh.mNumFaces;
                 faceStart += submesh.mNumFaces;
 
 
                 // assign the material index
                 // assign the material index
-                std::map<std::string, size_t>::const_iterator subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
+                auto subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
                 if (subMatIt != mMaterialIndexByName.end()) {
                 if (subMatIt != mMaterialIndexByName.end()) {
                     dstMesh->mMaterialIndex = static_cast<unsigned int>(subMatIt->second);
                     dstMesh->mMaterialIndex = static_cast<unsigned int>(subMatIt->second);
                 } else {
                 } else {
@@ -618,7 +626,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
         std::copy(pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + pStartVertex + numVertices, dstMesh->mTangents);
         std::copy(pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + pStartVertex + numVertices, dstMesh->mTangents);
     }
     }
 
 
-    // bitangents, if given.
+    // bi-tangents, if given.
     if (pSrcMesh->mBitangents.size() >= pStartVertex + numVertices) {
     if (pSrcMesh->mBitangents.size() >= pStartVertex + numVertices) {
         dstMesh->mBitangents = new aiVector3D[numVertices];
         dstMesh->mBitangents = new aiVector3D[numVertices];
         std::copy(pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + pStartVertex + numVertices, dstMesh->mBitangents);
         std::copy(pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + pStartVertex + numVertices, dstMesh->mBitangents);
@@ -664,7 +672,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
     std::vector<float> targetWeights;
     std::vector<float> targetWeights;
     Collada::MorphMethod method = Normalized;
     Collada::MorphMethod method = Normalized;
 
 
-    for (std::map<std::string, Controller>::const_iterator it = pParser.mControllerLibrary.begin();
+    for (auto it = pParser.mControllerLibrary.begin();
             it != pParser.mControllerLibrary.end(); ++it) {
             it != pParser.mControllerLibrary.end(); ++it) {
         const Controller &c = it->second;
         const Controller &c = it->second;
         const Collada::Mesh *baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
         const Collada::Mesh *baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
@@ -754,7 +762,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
         std::vector<IndexPairVector::const_iterator> weightStartPerVertex;
         std::vector<IndexPairVector::const_iterator> weightStartPerVertex;
         weightStartPerVertex.resize(pSrcController->mWeightCounts.size(), pSrcController->mWeights.end());
         weightStartPerVertex.resize(pSrcController->mWeightCounts.size(), pSrcController->mWeights.end());
 
 
-        IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
+        auto pit = pSrcController->mWeights.begin();
         for (size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a) {
         for (size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a) {
             weightStartPerVertex[a] = pit;
             weightStartPerVertex[a] = pit;
             pit += pSrcController->mWeightCounts[a];
             pit += pSrcController->mWeightCounts[a];
@@ -766,7 +774,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
             // the controller assigns the vertex weights
             // the controller assigns the vertex weights
             size_t orgIndex = pSrcMesh->mFacePosIndices[a];
             size_t orgIndex = pSrcMesh->mFacePosIndices[a];
             // find the vertex weights for this vertex
             // find the vertex weights for this vertex
-            IndexPairVector::const_iterator iit = weightStartPerVertex[orgIndex];
+            auto iit = weightStartPerVertex[orgIndex];
             size_t pairCount = pSrcController->mWeightCounts[orgIndex];
             size_t pairCount = pSrcController->mWeightCounts[orgIndex];
 
 
             for (size_t b = 0; b < pairCount; ++b, ++iit) {
             for (size_t b = 0; b < pairCount; ++b, ++iit) {
@@ -807,7 +815,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
             }
             }
 
 
             // create bone with its weights
             // create bone with its weights
-            aiBone *bone = new aiBone;
+            auto bone = new aiBone;
             bone->mName = ReadString(jointNamesAcc, jointNames, a);
             bone->mName = ReadString(jointNamesAcc, jointNames, a);
             bone->mOffsetMatrix.a1 = ReadFloat(jointMatrixAcc, jointMatrices, a, 0);
             bone->mOffsetMatrix.a1 = ReadFloat(jointMatrixAcc, jointMatrices, a, 0);
             bone->mOffsetMatrix.a2 = ReadFloat(jointMatrixAcc, jointMatrices, a, 1);
             bone->mOffsetMatrix.a2 = ReadFloat(jointMatrixAcc, jointMatrices, a, 1);
@@ -973,7 +981,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
 
 
             // if there are other animations which fit the template anim, combine all channels into a single anim
             // if there are other animations which fit the template anim, combine all channels into a single anim
             if (!collectedAnimIndices.empty()) {
             if (!collectedAnimIndices.empty()) {
-                aiAnimation *combinedAnim = new aiAnimation();
+                auto *combinedAnim = new aiAnimation();
                 combinedAnim->mName = aiString(std::string("combinedAnim_") + char('0' + a));
                 combinedAnim->mName = aiString(std::string("combinedAnim_") + char('0' + a));
                 combinedAnim->mDuration = templateAnim->mDuration;
                 combinedAnim->mDuration = templateAnim->mDuration;
                 combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
                 combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
@@ -1040,7 +1048,7 @@ struct MorphTimeValues {
 };
 };
 
 
 void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, float weight, unsigned int value) {
 void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, float weight, unsigned int value) {
-    MorphTimeValues::key k;
+    MorphTimeValues::key k{};
     k.mValue = value;
     k.mValue = value;
     k.mWeight = weight;
     k.mWeight = weight;
     if (values.empty() || time < values[0].mTime) {
     if (values.empty() || time < values[0].mTime) {
@@ -1106,7 +1114,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
 
 
         // now check all channels if they affect the current node
         // now check all channels if they affect the current node
         std::string targetID, subElement;
         std::string targetID, subElement;
-        for (std::vector<AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
+        for (auto cit = pSrcAnim->mChannels.begin();
                 cit != pSrcAnim->mChannels.end(); ++cit) {
                 cit != pSrcAnim->mChannels.end(); ++cit) {
             const AnimationChannel &srcChannel = *cit;
             const AnimationChannel &srcChannel = *cit;
             ChannelEntry entry;
             ChannelEntry entry;
@@ -1349,7 +1357,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
 
 
         // 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;
+            auto *dstAnim = new aiNodeAnim;
             dstAnim->mNodeName = nodeName;
             dstAnim->mNodeName = nodeName;
             dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
             dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
             dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
             dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
@@ -1391,7 +1399,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
                 // or     2) one channel with morph target count arrays
                 // or     2) one channel with morph target count arrays
                 // assume first
                 // assume first
 
 
-                aiMeshMorphAnim *morphAnim = new aiMeshMorphAnim;
+                auto *morphAnim = new aiMeshMorphAnim;
                 morphAnim->mName.Set(nodeName);
                 morphAnim->mName.Set(nodeName);
 
 
                 std::vector<MorphTimeValues> morphTimeValues;
                 std::vector<MorphTimeValues> morphTimeValues;
@@ -1434,7 +1442,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
     }
     }
 
 
     if (!anims.empty() || !morphAnims.empty()) {
     if (!anims.empty() || !morphAnims.empty()) {
-        aiAnimation *anim = new aiAnimation;
+        auto anim = new aiAnimation;
         anim->mName.Set(pName);
         anim->mName.Set(pName);
         anim->mNumChannels = static_cast<unsigned int>(anims.size());
         anim->mNumChannels = static_cast<unsigned int>(anims.size());
         if (anim->mNumChannels > 0) {
         if (anim->mNumChannels > 0) {
@@ -1514,7 +1522,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
         map = sampler.mUVId;
         map = sampler.mUVId;
     } else {
     } else {
         map = -1;
         map = -1;
-        for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
+        for (auto it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
             if (IsNumeric(*it)) {
             if (IsNumeric(*it)) {
                 map = strtoul10(&(*it));
                 map = strtoul10(&(*it));
                 break;
                 break;
@@ -1532,7 +1540,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
 // Fills materials from the collada material definitions
 // Fills materials from the collada material definitions
 void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pScene*/) {
 void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pScene*/) {
     for (auto &elem : newMats) {
     for (auto &elem : newMats) {
-        aiMaterial &mat = (aiMaterial &)*elem.second;
+        auto &mat = (aiMaterial &)*elem.second;
         Collada::Effect &effect = *elem.first;
         Collada::Effect &effect = *elem.first;
 
 
         // resolve shading mode
         // resolve shading mode
@@ -1642,17 +1650,17 @@ void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pSce
 void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/) {
 void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/) {
     newMats.reserve(pParser.mMaterialLibrary.size());
     newMats.reserve(pParser.mMaterialLibrary.size());
 
 
-    for (ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin();
+    for (auto matIt = pParser.mMaterialLibrary.begin();
             matIt != pParser.mMaterialLibrary.end(); ++matIt) {
             matIt != pParser.mMaterialLibrary.end(); ++matIt) {
         const Material &material = matIt->second;
         const Material &material = matIt->second;
         // a material is only a reference to an effect
         // a material is only a reference to an effect
-        ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
+        auto effIt = pParser.mEffectLibrary.find(material.mEffect);
         if (effIt == pParser.mEffectLibrary.end())
         if (effIt == pParser.mEffectLibrary.end())
             continue;
             continue;
         Effect &effect = effIt->second;
         Effect &effect = effIt->second;
 
 
         // create material
         // create material
-        aiMaterial *mat = new aiMaterial;
+        auto *mat = new aiMaterial;
         aiString name(material.mName.empty() ? matIt->first : material.mName);
         aiString name(material.mName.empty() ? matIt->first : material.mName);
         mat->AddProperty(&name, AI_MATKEY_NAME);
         mat->AddProperty(&name, AI_MATKEY_NAME);
 
 
@@ -1675,7 +1683,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
     std::string name = pName;
     std::string name = pName;
     while (true) {
     while (true) {
         // the given string is a param entry. Find it
         // the given string is a param entry. Find it
-        Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
+        auto 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 not found, we're at the end of the recursion. The resulting string should be the image ID
         if (it == pEffect.mParams.end())
         if (it == pEffect.mParams.end())
             break;
             break;
@@ -1685,7 +1693,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
     }
     }
 
 
     // find the image referred by this name in the image library of the scene
     // find the image referred by this name in the image library of the scene
-    ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find(name);
+    auto imIt = pParser.mImageLibrary.find(name);
     if (imIt == pParser.mImageLibrary.end()) {
     if (imIt == pParser.mImageLibrary.end()) {
         ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
         ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
 
 
@@ -1697,7 +1705,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
 
 
     // if this is an embedded texture image setup an aiTexture for it
     // if this is an embedded texture image setup an aiTexture for it
     if (!imIt->second.mImageData.empty()) {
     if (!imIt->second.mImageData.empty()) {
-        aiTexture *tex = new aiTexture();
+        auto *tex = new aiTexture();
 
 
         // Store embedded texture name reference
         // Store embedded texture name reference
         tex->mFilename.Set(imIt->second.mFileName.c_str());
         tex->mFilename.Set(imIt->second.mFileName.c_str());
@@ -1729,14 +1737,6 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
     return result;
     return result;
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-// Reads a float value from an accessor and its data array.
-ai_real ColladaLoader::ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) const {
-    size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
-    ai_assert(pos < pData.mValues.size());
-    return pData.mValues[pos];
-}
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Reads a string value from an accessor and its data array.
 // Reads a string value from an accessor and its data array.
 const std::string &ColladaLoader::ReadString(const Accessor &pAccessor, const Data &pData, size_t pIndex) const {
 const std::string &ColladaLoader::ReadString(const Accessor &pAccessor, const Data &pData, size_t pIndex) const {

+ 3 - 16
code/AssetLib/Collada/ColladaLoader.h

@@ -109,7 +109,7 @@ protected:
 
 
     /// Resolve node instances
     /// Resolve node instances
     void ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
     void ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
-            std::vector<const Collada::Node *> &resolved);
+            std::vector<const Collada::Node *> &resolved) const;
 
 
     /// Builds meshes for the given node and references them
     /// Builds meshes for the given node and references them
     void BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode,
     void BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode,
@@ -166,10 +166,6 @@ protected:
     /** Fill materials from the collada material definitions */
     /** Fill materials from the collada material definitions */
     void FillMaterials(const ColladaParser &pParser, aiScene *pScene);
     void FillMaterials(const ColladaParser &pParser, aiScene *pScene);
 
 
-    /** Resolve UV channel mappings*/
-    void ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler,
-            const Collada::SemanticMappingTable &table);
-
     /** Add a texture and all of its sampling properties to a material*/
     /** Add a texture and all of its sampling properties to a material*/
     void AddTexture(aiMaterial &mat, const ColladaParser &pParser,
     void AddTexture(aiMaterial &mat, const ColladaParser &pParser,
             const Collada::Effect &effect,
             const Collada::Effect &effect,
@@ -180,22 +176,13 @@ protected:
     aiString FindFilenameForEffectTexture(const ColladaParser &pParser,
     aiString FindFilenameForEffectTexture(const ColladaParser &pParser,
             const Collada::Effect &pEffect, const std::string &pName);
             const Collada::Effect &pEffect, const std::string &pName);
 
 
-    /** Reads a float value from an accessor and its data array.
-     * @param pAccessor The accessor to use for reading
-     * @param pData The data array to read from
-     * @param pIndex The index of the element to retrieve
-     * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
-     * @return the specified value
-     */
-    ai_real ReadFloat(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex, size_t pOffset) const;
-
     /** Reads a string value from an accessor and its data array.
     /** Reads a string value from an accessor and its data array.
      * @param pAccessor The accessor to use for reading
      * @param pAccessor The accessor to use for reading
      * @param pData The data array to read from
      * @param pData The data array to read from
      * @param pIndex The index of the element to retrieve
      * @param pIndex The index of the element to retrieve
      * @return the specified value
      * @return the specified value
      */
      */
-    const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
+    [[nodiscard]] const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
 
 
     /** Recursively collects all nodes into the given array */
     /** Recursively collects all nodes into the given array */
     void CollectNodes(const aiNode *pNode, std::vector<const aiNode *> &poNodes) const;
     void CollectNodes(const aiNode *pNode, std::vector<const aiNode *> &poNodes) const;
@@ -208,7 +195,7 @@ protected:
     /** Finds a proper name for a node derived from the collada-node's properties */
     /** Finds a proper name for a node derived from the collada-node's properties */
     std::string FindNameForNode(const Collada::Node *pNode);
     std::string FindNameForNode(const Collada::Node *pNode);
 
 
-protected:
+private:
     /** Filename, for a verbose error message */
     /** Filename, for a verbose error message */
     std::string mFileName;
     std::string mFileName;
 
 

Dosya farkı çok büyük olduğundan ihmal edildi
+ 354 - 357
code/AssetLib/Collada/ColladaParser.cpp


+ 82 - 111
code/AssetLib/Collada/ColladaParser.h

@@ -48,7 +48,6 @@
 #define AI_COLLADAPARSER_H_INC
 #define AI_COLLADAPARSER_H_INC
 
 
 #include "ColladaHelper.h"
 #include "ColladaHelper.h"
-#include <assimp/TinyFormatter.h>
 #include <assimp/ai_assert.h>
 #include <assimp/ai_assert.h>
 #include <assimp/XmlParser.h>
 #include <assimp/XmlParser.h>
 
 
@@ -67,268 +66,240 @@ class ZipArchiveIOSystem;
 class ColladaParser {
 class ColladaParser {
     friend class ColladaLoader;
     friend class ColladaLoader;
 
 
-    /** Converts a path read from a collada file to the usual representation */
-    static void UriDecodePath(aiString &ss);
-
-protected:
-    /** Map for generic metadata as aiString */
-    typedef std::map<std::string, aiString> StringMetaData;
+public:
+    /// Map for generic metadata as aiString.
+    using StringMetaData = std::map<std::string, aiString>;
 
 
-    /** Constructor from XML file */
+    /// Constructor from XML file.
     ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
     ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
 
 
-    /** Destructor */
+    /// Destructor
     ~ColladaParser();
     ~ColladaParser();
 
 
-    /** Attempts to read the ZAE manifest and returns the DAE to open */
+    /// Attempts to read the ZAE manifest and returns the DAE to open
     static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
     static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
 
 
-    /** Reads the contents of the file */
+    /// Reads the contents of the file
     void ReadContents(XmlNode &node);
     void ReadContents(XmlNode &node);
 
 
-    /** Reads the structure of the file */
+    /// Reads the structure of the file
     void ReadStructure(XmlNode &node);
     void ReadStructure(XmlNode &node);
 
 
-    /** Reads asset information such as coordinate system information and legal blah */
+    /// Reads asset information such as coordinate system information and legal blah
     void ReadAssetInfo(XmlNode &node);
     void ReadAssetInfo(XmlNode &node);
 
 
-    /** Reads contributor information such as author and legal blah */
+    /// Reads contributor information such as author and legal blah
     void ReadContributorInfo(XmlNode &node);
     void ReadContributorInfo(XmlNode &node);
 
 
-    /** Reads generic metadata into provided map and renames keys for Assimp */
-    void ReadMetaDataItem(XmlNode &node, StringMetaData &metadata);
-
-    /** Reads the animation library */
+    /// Reads the animation library
     void ReadAnimationLibrary(XmlNode &node);
     void ReadAnimationLibrary(XmlNode &node);
 
 
-    /** Reads the animation clip library */
+    /// Reads the animation clip library
     void ReadAnimationClipLibrary(XmlNode &node);
     void ReadAnimationClipLibrary(XmlNode &node);
 
 
-    /** Unwrap controllers dependency hierarchy */
+    /// Unwrap controllers dependency hierarchy
     void PostProcessControllers();
     void PostProcessControllers();
 
 
-    /** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
+    /// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
     void PostProcessRootAnimations();
     void PostProcessRootAnimations();
 
 
-    /** Reads an animation into the given parent structure */
+    /// Reads an animation into the given parent structure
     void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
     void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
 
 
-    /** Reads an animation sampler into the given anim channel */
-    void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel);
-
-    /** Reads the skeleton controller library */
+    /// Reads the skeleton controller library
     void ReadControllerLibrary(XmlNode &node);
     void ReadControllerLibrary(XmlNode &node);
 
 
-    /** Reads a controller into the given mesh structure */
+    /// Reads a controller into the given mesh structure
     void ReadController(XmlNode &node, Collada::Controller &pController);
     void ReadController(XmlNode &node, Collada::Controller &pController);
 
 
-    /** Reads the joint definitions for the given controller */
-    void ReadControllerJoints(XmlNode &node, Collada::Controller &pController);
-
-    /** Reads the joint weights for the given controller */
-    void ReadControllerWeights(XmlNode &node, Collada::Controller &pController);
+    /// Reads the image library contents
+    void ReadImageLibrary(const XmlNode &node);
 
 
-    /** Reads the image library contents */
-    void ReadImageLibrary(XmlNode &node);
+    /// Reads an image entry into the given image
+    void ReadImage(const XmlNode &node, Collada::Image &pImage) const;
 
 
-    /** Reads an image entry into the given image */
-    void ReadImage(XmlNode &node, Collada::Image &pImage);
-
-    /** Reads the material library */
+    /// Reads the material library
     void ReadMaterialLibrary(XmlNode &node);
     void ReadMaterialLibrary(XmlNode &node);
 
 
-    /** Reads a material entry into the given material */
-    void ReadMaterial(XmlNode &node, Collada::Material &pMaterial);
-
-    /** Reads the camera library */
+    /// Reads the camera library
     void ReadCameraLibrary(XmlNode &node);
     void ReadCameraLibrary(XmlNode &node);
 
 
-    /** Reads a camera entry into the given camera */
-    void ReadCamera(XmlNode &node, Collada::Camera &pCamera);
-
-    /** Reads the light library */
+    /// Reads the light library
     void ReadLightLibrary(XmlNode &node);
     void ReadLightLibrary(XmlNode &node);
 
 
-    /** Reads a light entry into the given light */
-    void ReadLight(XmlNode &node, Collada::Light &pLight);
-
-    /** Reads the effect library */
+    /// Reads the effect library
     void ReadEffectLibrary(XmlNode &node);
     void ReadEffectLibrary(XmlNode &node);
 
 
-    /** Reads an effect entry into the given effect*/
+    /// Reads an effect entry into the given effect
     void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
     void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
 
 
-    /** Reads an COMMON effect profile */
+    /// Reads an COMMON effect profile
     void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
     void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
 
 
-    /** Read sampler properties */
+    /// Read sampler properties
     void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
     void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
 
 
-    /** Reads an effect entry containing a color or a texture defining that color */
+    /// Reads an effect entry containing a color or a texture defining that color
     void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
     void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
 
 
-    /** Reads an effect entry containing a float */
+    /// Reads an effect entry containing a float
     void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
     void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
 
 
-    /** Reads an effect parameter specification of any kind */
+    /// Reads an effect parameter specification of any kind
     void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
     void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
 
 
-    /** Reads the geometry library contents */
+    /// Reads the geometry library contents
     void ReadGeometryLibrary(XmlNode &node);
     void ReadGeometryLibrary(XmlNode &node);
 
 
-    /** Reads a geometry from the geometry library. */
+    /// Reads a geometry from the geometry library.
     void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
     void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
 
 
-    /** Reads a mesh from the geometry library */
+    /// Reads a mesh from the geometry library
     void ReadMesh(XmlNode &node, Collada::Mesh &pMesh);
     void ReadMesh(XmlNode &node, Collada::Mesh &pMesh);
 
 
-    /** Reads a source element - a combination of raw data and an accessor defining
-         * things that should not be redefinable. Yes, that's another rant.
-         */
+    /// Reads a source element - a combination of raw data and an accessor defining
+    ///things that should not be definable. Yes, that's another rant.
     void ReadSource(XmlNode &node);
     void ReadSource(XmlNode &node);
 
 
-    /** Reads a data array holding a number of elements, and stores it in the global library.
-         * Currently supported are array of floats and arrays of strings.
-         */
+    /// Reads a data array holding a number of elements, and stores it in the global library.
+    /// Currently supported are array of floats and arrays of strings.
     void ReadDataArray(XmlNode &node);
     void ReadDataArray(XmlNode &node);
 
 
-    /** Reads an accessor and stores it in the global library under the given ID -
-         * accessors use the ID of the parent <source> element
-         */
+    /// Reads an accessor and stores it in the global library under the given ID -
+    /// accessors use the ID of the parent <source> element
     void ReadAccessor(XmlNode &node, const std::string &pID);
     void ReadAccessor(XmlNode &node, const std::string &pID);
 
 
-    /** Reads input declarations of per-vertex mesh data into the given mesh */
+    /// Reads input declarations of per-vertex mesh data into the given mesh
     void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
     void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
 
 
-    /** Reads input declarations of per-index mesh data into the given mesh */
+    /// Reads input declarations of per-index mesh data into the given mesh
     void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh);
     void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh);
 
 
-    /** Reads a single input channel element and stores it in the given array, if valid */
+    /// Reads a single input channel element and stores it in the given array, if valid
     void ReadInputChannel(XmlNode &node, std::vector<Collada::InputChannel> &poChannels);
     void ReadInputChannel(XmlNode &node, std::vector<Collada::InputChannel> &poChannels);
 
 
-    /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
+    /// Reads a <p> primitive index list and assembles the mesh data into the given mesh
     size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
     size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
             size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
             size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
 
 
-    /** Copies the data for a single primitive into the mesh, based on the InputChannels */
+    /// Copies the data for a single primitive into the mesh, based on the InputChannels
     void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
     void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
             Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
             Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
             size_t currentPrimitive, const std::vector<size_t> &indices);
             size_t currentPrimitive, const std::vector<size_t> &indices);
 
 
-    /** Reads one triangle of a tristrip into the mesh */
+    /// Reads one triangle of a tristrip into the mesh
     void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
     void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
             std::vector<Collada::InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices);
             std::vector<Collada::InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices);
 
 
-    /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
+    /// Extracts a single object from an input channel and stores it in the appropriate mesh data array
     void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
     void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
 
 
-    /** Reads the library of node hierarchies and scene parts */
+    /// Reads the library of node hierarchies and scene parts
     void ReadSceneLibrary(XmlNode &node);
     void ReadSceneLibrary(XmlNode &node);
 
 
-    /** Reads a scene node's contents including children and stores it in the given node */
+    /// Reads a scene node's contents including children and stores it in the given node
     void ReadSceneNode(XmlNode &node, Collada::Node *pNode);
     void ReadSceneNode(XmlNode &node, Collada::Node *pNode);
-
-    /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
-    void ReadNodeTransformation(XmlNode &node, Collada::Node *pNode, Collada::TransformType pType);
-
-    /** Reads a mesh reference in a node and adds it to the node's mesh list */
+    
+    /// Reads a mesh reference in a node and adds it to the node's mesh list
     void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
     void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
 
 
-    /** Reads the collada scene */
+    /// Reads the collada scene
     void ReadScene(XmlNode &node);
     void ReadScene(XmlNode &node);
 
 
-    // Processes bind_vertex_input and bind elements
+    /// Processes bind_vertex_input and bind elements
     void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
     void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
 
 
-    /** Reads embedded textures from a ZAE archive*/
+    /// Reads embedded textures from a ZAE archive
     void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
     void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
 
 
 protected:
 protected:
-    /** Calculates the resulting transformation from all the given transform steps */
+    /// Converts a path read from a collada file to the usual representation
+    static void UriDecodePath(aiString &ss);
+
+    /// Calculates the resulting transformation from all the given transform steps
     aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
     aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
 
 
-    /** Determines the input data type for the given semantic string */
+    /// Determines the input data type for the given semantic string
     Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
     Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
 
 
-    /** Finds the item in the given library by its reference, throws if not found */
+    /// Finds the item in the given library by its reference, throws if not found
     template <typename Type>
     template <typename Type>
     const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
     const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
 
 
-protected:
-    // Filename, for a verbose error message
+private:
+    /// Filename, for a verbose error message
     std::string mFileName;
     std::string mFileName;
 
 
-    // XML reader, member for everyday use
+    /// XML reader, member for everyday use
     XmlParser mXmlParser;
     XmlParser mXmlParser;
 
 
-    /** All data arrays found in the file by ID. Might be referred to by actually
-         everyone. Collada, you are a steaming pile of indirection. */
+    /// All data arrays found in the file by ID. Might be referred to by actually
+    ///     everyone. Collada, you are a steaming pile of indirection.
     using DataLibrary = std::map<std::string, Collada::Data> ;
     using DataLibrary = std::map<std::string, Collada::Data> ;
     DataLibrary mDataLibrary;
     DataLibrary mDataLibrary;
 
 
-    /** Same for accessors which define how the data in a data array is accessed. */
+    /// Same for accessors which define how the data in a data array is accessed.
     using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
     using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
     AccessorLibrary mAccessorLibrary;
     AccessorLibrary mAccessorLibrary;
 
 
-    /** Mesh library: mesh by ID */
+    /// Mesh library: mesh by ID
     using MeshLibrary = std::map<std::string, Collada::Mesh *>;
     using MeshLibrary = std::map<std::string, Collada::Mesh *>;
     MeshLibrary mMeshLibrary;
     MeshLibrary mMeshLibrary;
 
 
-    /** node library: root node of the hierarchy part by ID */
+    /// node library: root node of the hierarchy part by ID
     using NodeLibrary = std::map<std::string, Collada::Node *>;
     using NodeLibrary = std::map<std::string, Collada::Node *>;
     NodeLibrary mNodeLibrary;
     NodeLibrary mNodeLibrary;
 
 
-    /** Image library: stores texture properties by ID */
+    /// Image library: stores texture properties by ID
     using ImageLibrary = std::map<std::string, Collada::Image> ;
     using ImageLibrary = std::map<std::string, Collada::Image> ;
     ImageLibrary mImageLibrary;
     ImageLibrary mImageLibrary;
 
 
-    /** Effect library: surface attributes by ID */
+    /// Effect library: surface attributes by ID
     using EffectLibrary = std::map<std::string, Collada::Effect> ;
     using EffectLibrary = std::map<std::string, Collada::Effect> ;
     EffectLibrary mEffectLibrary;
     EffectLibrary mEffectLibrary;
 
 
-    /** Material library: surface material by ID */
+    /// Material library: surface material by ID
     using MaterialLibrary = std::map<std::string, Collada::Material> ;
     using MaterialLibrary = std::map<std::string, Collada::Material> ;
     MaterialLibrary mMaterialLibrary;
     MaterialLibrary mMaterialLibrary;
 
 
-    /** Light library: surface light by ID */
+    /// Light library: surface light by ID
     using LightLibrary = std::map<std::string, Collada::Light> ;
     using LightLibrary = std::map<std::string, Collada::Light> ;
     LightLibrary mLightLibrary;
     LightLibrary mLightLibrary;
 
 
-    /** Camera library: surface material by ID */
+    /// Camera library: surface material by ID
     using CameraLibrary = std::map<std::string, Collada::Camera> ;
     using CameraLibrary = std::map<std::string, Collada::Camera> ;
     CameraLibrary mCameraLibrary;
     CameraLibrary mCameraLibrary;
 
 
-    /** Controller library: joint controllers by ID */
+    /// Controller library: joint controllers by ID
     using ControllerLibrary = std::map<std::string, Collada::Controller> ;
     using ControllerLibrary = std::map<std::string, Collada::Controller> ;
     ControllerLibrary mControllerLibrary;
     ControllerLibrary mControllerLibrary;
 
 
-    /** Animation library: animation references by ID */
+    /// Animation library: animation references by ID
     using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
     using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
     AnimationLibrary mAnimationLibrary;
     AnimationLibrary mAnimationLibrary;
 
 
-    /** Animation clip library: clip animation references by ID */
+    /// Animation clip library: clip animation references by ID
     using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
     using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
     AnimationClipLibrary mAnimationClipLibrary;
     AnimationClipLibrary mAnimationClipLibrary;
 
 
-    /** Pointer to the root node. Don't delete, it just points to one of
-         the nodes in the node library. */
+    /// Pointer to the root node. Don't delete, it just points to one of the nodes in the node library.
     Collada::Node *mRootNode;
     Collada::Node *mRootNode;
 
 
-    /** Root animation container */
+    /// Root animation container
     Collada::Animation mAnims;
     Collada::Animation mAnims;
 
 
-    /** Size unit: how large compared to a meter */
+    /// Size unit: how large compared to a meter
     ai_real mUnitSize;
     ai_real mUnitSize;
 
 
-    /** Which is the up vector */
+    /// Which is the up vector
     enum { UP_X,
     enum { UP_X,
         UP_Y,
         UP_Y,
         UP_Z } mUpDirection;
         UP_Z } mUpDirection;
 
 
-    /** Asset metadata (global for scene) */
+    /// Asset metadata (global for scene)
     StringMetaData mAssetMetaData;
     StringMetaData mAssetMetaData;
 
 
-    /** Collada file format version */
+    /// Collada file format version
     Collada::FormatVersion mFormat;
     Collada::FormatVersion mFormat;
 };
 };
 
 

+ 1 - 0
test/CMakeLists.txt

@@ -86,6 +86,7 @@ SET( COMMON
   unit/TestModelFactory.h
   unit/TestModelFactory.h
   unit/utTypes.cpp
   unit/utTypes.cpp
   unit/utVersion.cpp
   unit/utVersion.cpp
+  unit/Common/utParsingUtils.cpp
   unit/utProfiler.cpp
   unit/utProfiler.cpp
   unit/utSharedPPData.cpp
   unit/utSharedPPData.cpp
   unit/utStringUtils.cpp
   unit/utStringUtils.cpp

+ 66 - 0
test/unit/Common/utParsingUtils.cpp

@@ -0,0 +1,66 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2025, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "UnitTestPCH.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
+#include <array>
+
+using namespace Assimp;
+
+class utParsingUtils : public ::testing::Test {};
+
+TEST_F(utParsingUtils, parseFloatsStringTest) {
+    const std::array<float, 16> floatArray = {
+        1.0f, 0.0f,         0.0f,        0.0f,
+        0.0f, 7.54979e-8f, -1.0f,        0.0f,
+        0.0f, 1.0f,         7.54979e-8f, 0.0f,
+        0.0f, 0.0f,         0.0f,        1.0f};
+    const std::string floatArrayAsStr = "1 0 0 0 0 7.54979e-8 -1 0 0 1 7.54979e-8 0 0 0 0 1";
+    const char *content = floatArrayAsStr.c_str();
+    const char *end = content + floatArrayAsStr.size();
+    for (float i : floatArray) {
+        float value = 0.0f;
+        SkipSpacesAndLineEnd(&content, end);
+        content = fast_atoreal_move<ai_real>(content, value);
+        EXPECT_FLOAT_EQ(value, i);
+    }
+}

+ 1 - 2
test/unit/utFastAtof.cpp

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 
 Copyright (c) 2006-2025, assimp team
 Copyright (c) 2006-2025, assimp team
 
 
-
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -122,6 +120,7 @@ protected:
         TEST_CASE(0e-19);
         TEST_CASE(0e-19);
         TEST_CASE(400012);
         TEST_CASE(400012);
         TEST_CASE(5.9e-76);
         TEST_CASE(5.9e-76);
+        TEST_CASE(7.54979e-8);
         TEST_CASE_INF(inf);
         TEST_CASE_INF(inf);
         TEST_CASE_INF(inf);
         TEST_CASE_INF(inf);
         TEST_CASE_INF(infinity);
         TEST_CASE_INF(infinity);

+ 0 - 3
test/unit/utTypes.cpp

@@ -1,12 +1,9 @@
 /*
 /*
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
----------------------------------------------------------------------------
 
 
 Copyright (c) 2006-2025, assimp team
 Copyright (c) 2006-2025, assimp team
 
 
-
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor