Sfoglia il codice sorgente

Kimkulling/fix double precision tests (#5660)

* Make color single precision

* Fix the unittests for double precision

* Fix merge issues

* Fix issues with Vertex + Color4

* Fix vertex operator, some tests are still red.
Kim Kulling 1 anno fa
parent
commit
35e4f1bf64

+ 2 - 3
code/AssetLib/3DS/3DSHelper.h

@@ -365,14 +365,13 @@ struct Texture {
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif // _MSC_VER
-
 // ---------------------------------------------------------------------------
 /** Helper structure representing a 3ds material */
 struct Material {
     //! Default constructor has been deleted
     Material() :
             mName(),
-            mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
+            mDiffuse(0.6f, 0.6f, 0.6f),
             mSpecularExponent(ai_real(0.0)),
             mShininessStrength(ai_real(1.0)),
             mShading(Discreet3DS::Gouraud),
@@ -385,7 +384,7 @@ struct Material {
     //! Constructor with explicit name
     explicit Material(const std::string &name) :
             mName(name),
-            mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
+            mDiffuse(0.6f, 0.6f, 0.6f),
             mSpecularExponent(ai_real(0.0)),
             mShininessStrength(ai_real(1.0)),
             mShading(Discreet3DS::Gouraud),

+ 6 - 6
code/AssetLib/AMF/AMFImporter.cpp

@@ -384,17 +384,17 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
         for (auto &currentNode : node.children()) {
             const std::string &currentName = currentNode.name();
             if (currentName == "deltax") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.x);
+                XmlParser::getValueAsReal(currentNode, als.Delta.x);
             } else if (currentName == "deltay") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.y);
+                XmlParser::getValueAsReal(currentNode, als.Delta.y);
             } else if (currentName == "deltaz") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.z);
+                XmlParser::getValueAsReal(currentNode, als.Delta.z);
             } else if (currentName == "rx") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.x);
+                XmlParser::getValueAsReal(currentNode, als.Delta.x);
             } else if (currentName == "ry") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.y);
+                XmlParser::getValueAsReal(currentNode, als.Delta.y);
             } else if (currentName == "rz") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.z);
+                XmlParser::getValueAsReal(currentNode, als.Delta.z);
             }
         }
         ParseHelper_Node_Exit();

+ 3 - 3
code/AssetLib/AMF/AMFImporter_Geometry.cpp

@@ -167,11 +167,11 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
             AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
             const std::string &currentName = ai_tolower(currentNode.name());
             if (currentName == "x") {
-                XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
+                XmlParser::getValueAsReal(currentNode, als.Coordinate.x);
             } else if (currentName == "y") {
-                XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
+                XmlParser::getValueAsReal(currentNode, als.Coordinate.y);
             } else if (currentName == "z") {
-                XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
+                XmlParser::getValueAsReal(currentNode, als.Coordinate.z);
             }
         }
         ParseHelper_Node_Exit();

+ 6 - 7
code/AssetLib/AMF/AMFImporter_Material.cpp

@@ -263,26 +263,25 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
             const std::string &name = currentNode.name();
             if (name == "utex1") {
 				read_flag[0] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[0].x);
             } else if (name == "utex2") {
 				read_flag[1] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[1].x);
             } else if (name == "utex3") {
 				read_flag[2] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[2].x);
             } else if (name == "vtex1") {
 				read_flag[3] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[0].y);
             } else if (name == "vtex2") {
 				read_flag[4] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[1].y);
             } else if (name == "vtex3") {
 				read_flag[5] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[2].y);
 			}
 		}
         ParseHelper_Node_Exit();
-
 	} else {
 		for (pugi::xml_attribute &attr : node.attributes()) {
             const std::string name = attr.name();

+ 64 - 33
code/AssetLib/ASE/ASEParser.cpp

@@ -422,7 +422,7 @@ void Parser::ParseLV1SoftSkinBlock() {
                                 me.first = static_cast<int>(curMesh->mBones.size());
                                 curMesh->mBones.emplace_back(bone);
                             }
-                            ParseLV4MeshFloat(me.second);
+                            ParseLV4MeshReal(me.second);
 
                             // Add the new bone weight to list
                             vert.mBoneWeights.push_back(me);
@@ -580,14 +580,14 @@ void Parser::ParseLV2MaterialBlock(ASE::Material &mat) {
             }
             // material transparency
             if (TokenMatch(mFilePtr, "MATERIAL_TRANSPARENCY", 21)) {
-                ParseLV4MeshFloat(mat.mTransparency);
+                ParseLV4MeshReal(mat.mTransparency);
                 mat.mTransparency = ai_real(1.0) - mat.mTransparency;
                 continue;
             }
             // material self illumination
             if (TokenMatch(mFilePtr, "MATERIAL_SELFILLUM", 18)) {
                 ai_real f = 0.0;
-                ParseLV4MeshFloat(f);
+                ParseLV4MeshReal(f);
 
                 mat.mEmissive.r = f;
                 mat.mEmissive.g = f;
@@ -596,7 +596,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material &mat) {
             }
             // material shininess
             if (TokenMatch(mFilePtr, "MATERIAL_SHINE", 14)) {
-                ParseLV4MeshFloat(mat.mSpecularExponent);
+                ParseLV4MeshReal(mat.mSpecularExponent);
                 mat.mSpecularExponent *= 15;
                 continue;
             }
@@ -607,7 +607,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material &mat) {
             }
             // material shininess strength
             if (TokenMatch(mFilePtr, "MATERIAL_SHINESTRENGTH", 22)) {
-                ParseLV4MeshFloat(mat.mShininessStrength);
+                ParseLV4MeshReal(mat.mShininessStrength);
                 continue;
             }
             // diffuse color map
@@ -731,32 +731,32 @@ void Parser::ParseLV3MapBlock(Texture &map) {
             }
             // offset on the u axis
             if (TokenMatch(mFilePtr, "UVW_U_OFFSET", 12)) {
-                ParseLV4MeshFloat(map.mOffsetU);
+                ParseLV4MeshReal(map.mOffsetU);
                 continue;
             }
             // offset on the v axis
             if (TokenMatch(mFilePtr, "UVW_V_OFFSET", 12)) {
-                ParseLV4MeshFloat(map.mOffsetV);
+                ParseLV4MeshReal(map.mOffsetV);
                 continue;
             }
             // tiling on the u axis
             if (TokenMatch(mFilePtr, "UVW_U_TILING", 12)) {
-                ParseLV4MeshFloat(map.mScaleU);
+                ParseLV4MeshReal(map.mScaleU);
                 continue;
             }
             // tiling on the v axis
             if (TokenMatch(mFilePtr, "UVW_V_TILING", 12)) {
-                ParseLV4MeshFloat(map.mScaleV);
+                ParseLV4MeshReal(map.mScaleV);
                 continue;
             }
             // rotation around the z-axis
             if (TokenMatch(mFilePtr, "UVW_ANGLE", 9)) {
-                ParseLV4MeshFloat(map.mRotation);
+                ParseLV4MeshReal(map.mRotation);
                 continue;
             }
             // map blending factor
             if (TokenMatch(mFilePtr, "MAP_AMOUNT", 10)) {
-                ParseLV4MeshFloat(map.mTextureBlend);
+                ParseLV4MeshReal(map.mTextureBlend);
                 continue;
             }
         }
@@ -895,15 +895,15 @@ void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) {
         if ('*' == *mFilePtr) {
             ++mFilePtr;
             if (TokenMatch(mFilePtr, "CAMERA_NEAR", 11)) {
-                ParseLV4MeshFloat(camera.mNear);
+                ParseLV4MeshReal(camera.mNear);
                 continue;
             }
             if (TokenMatch(mFilePtr, "CAMERA_FAR", 10)) {
-                ParseLV4MeshFloat(camera.mFar);
+                ParseLV4MeshReal(camera.mFar);
                 continue;
             }
             if (TokenMatch(mFilePtr, "CAMERA_FOV", 10)) {
-                ParseLV4MeshFloat(camera.mFOV);
+                ParseLV4MeshReal(camera.mFOV);
                 continue;
             }
         }
@@ -922,15 +922,15 @@ void Parser::ParseLV2LightSettingsBlock(ASE::Light &light) {
                 continue;
             }
             if (TokenMatch(mFilePtr, "LIGHT_INTENS", 12)) {
-                ParseLV4MeshFloat(light.mIntensity);
+                ParseLV4MeshReal(light.mIntensity);
                 continue;
             }
             if (TokenMatch(mFilePtr, "LIGHT_HOTSPOT", 13)) {
-                ParseLV4MeshFloat(light.mAngle);
+                ParseLV4MeshReal(light.mAngle);
                 continue;
             }
             if (TokenMatch(mFilePtr, "LIGHT_FALLOFF", 13)) {
-                ParseLV4MeshFloat(light.mFalloff);
+                ParseLV4MeshReal(light.mFalloff);
                 continue;
             }
         }
@@ -1038,7 +1038,7 @@ void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation &anim) {
             if (b) {
                 anim.akeyScaling.emplace_back();
                 aiVectorKey &key = anim.akeyScaling.back();
-                ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
+                ParseLV4MeshRealTriple(&key.mValue.x, iIndex);
                 key.mTime = (double)iIndex;
             }
         }
@@ -1077,7 +1077,7 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Animation &anim) {
             if (b) {
                 anim.akeyPositions.emplace_back();
                 aiVectorKey &key = anim.akeyPositions.back();
-                ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
+                ParseLV4MeshRealTriple(&key.mValue.x, iIndex);
                 key.mTime = (double)iIndex;
             }
         }
@@ -1118,8 +1118,8 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation &anim) {
                 aiQuatKey &key = anim.akeyRotations.back();
                 aiVector3D v;
                 ai_real f;
-                ParseLV4MeshFloatTriple(&v.x, iIndex);
-                ParseLV4MeshFloat(f);
+                ParseLV4MeshRealTriple(&v.x, iIndex);
+                ParseLV4MeshReal(f);
                 key.mTime = (double)iIndex;
                 key.mValue = aiQuaternion(v, f);
             }
@@ -1163,23 +1163,23 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
                 // fourth row of the transformation matrix - and also the
                 // only information here that is interesting for targets
                 if (TokenMatch(mFilePtr, "TM_ROW3", 7)) {
-                    ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
+                    ParseLV4MeshRealTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
                     continue;
                 }
                 if (mode == 1) {
                     // first row of the transformation matrix
                     if (TokenMatch(mFilePtr, "TM_ROW0", 7)) {
-                        ParseLV4MeshFloatTriple(mesh.mTransform[0]);
+                        ParseLV4MeshRealTriple(mesh.mTransform[0]);
                         continue;
                     }
                     // second row of the transformation matrix
                     if (TokenMatch(mFilePtr, "TM_ROW1", 7)) {
-                        ParseLV4MeshFloatTriple(mesh.mTransform[1]);
+                        ParseLV4MeshRealTriple(mesh.mTransform[1]);
                         continue;
                     }
                     // third row of the transformation matrix
                     if (TokenMatch(mFilePtr, "TM_ROW2", 7)) {
-                        ParseLV4MeshFloatTriple(mesh.mTransform[2]);
+                        ParseLV4MeshRealTriple(mesh.mTransform[2]);
                         continue;
                     }
                     // inherited position axes
@@ -1414,7 +1414,7 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
 
                 // --- ignored
                 ai_real afVert[3];
-                ParseLV4MeshFloatTriple(afVert);
+                ParseLV4MeshRealTriple(afVert);
 
                 std::pair<int, float> pairOut;
                 while (true) {
@@ -1453,7 +1453,7 @@ void Parser::ParseLV3MeshVertexListBlock(
 
                 aiVector3D vTemp;
                 unsigned int iIndex;
-                ParseLV4MeshFloatTriple(&vTemp.x, iIndex);
+                ParseLV4MeshRealTriple(&vTemp.x, iIndex);
 
                 if (iIndex >= iNumVertices) {
                     LogWarning("Invalid vertex index. It will be ignored");
@@ -1506,7 +1506,7 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
             if (TokenMatch(mFilePtr, "MESH_TVERT", 10)) {
                 aiVector3D vTemp;
                 unsigned int iIndex;
-                ParseLV4MeshFloatTriple(&vTemp.x, iIndex);
+                ParseLV4MeshRealTriple(&vTemp.x, iIndex);
 
                 if (iIndex >= iNumVertices) {
                     LogWarning("Tvertex has an invalid index. It will be ignored");
@@ -1657,7 +1657,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
             ++mFilePtr;
             if (faceIdx != UINT_MAX && TokenMatch(mFilePtr, "MESH_VERTEXNORMAL", 17)) {
                 aiVector3D vNormal;
-                ParseLV4MeshFloatTriple(&vNormal.x, index);
+                ParseLV4MeshRealTriple(&vNormal.x, index);
                 if (faceIdx >= sMesh.mFaces.size())
                     continue;
 
@@ -1679,7 +1679,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
             }
             if (TokenMatch(mFilePtr, "MESH_FACENORMAL", 15)) {
                 aiVector3D vNormal;
-                ParseLV4MeshFloatTriple(&vNormal.x, faceIdx);
+                ParseLV4MeshRealTriple(&vNormal.x, faceIdx);
 
                 if (faceIdx >= sMesh.mFaces.size()) {
                     ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_FACENORMAL section");
@@ -1844,7 +1844,17 @@ void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut
     ParseLV4MeshLongTriple(apOut);
 }
 // ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
+void Parser::ParseLV4MeshRealTriple(ai_real *apOut, unsigned int &rIndexOut) {
+    ai_assert(nullptr != apOut);
+
+    // parse the index
+    ParseLV4MeshLong(rIndexOut);
+
+    // parse the three others
+    ParseLV4MeshRealTriple(apOut);
+}
+// ------------------------------------------------------------------------------------------------
+void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut) {
     ai_assert(nullptr != apOut);
 
     // parse the index
@@ -1854,7 +1864,15 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
     ParseLV4MeshFloatTriple(apOut);
 }
 // ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
+void Parser::ParseLV4MeshRealTriple(ai_real *apOut) {
+    ai_assert(nullptr != apOut);
+
+    for (unsigned int i = 0; i < 3; ++i) {
+        ParseLV4MeshReal(apOut[i]);
+    }
+}
+// ------------------------------------------------------------------------------------------------
+void Parser::ParseLV4MeshFloatTriple(float* apOut) {
     ai_assert(nullptr != apOut);
 
     for (unsigned int i = 0; i < 3; ++i) {
@@ -1862,7 +1880,7 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
     }
 }
 // ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloat(ai_real &fOut) {
+void Parser::ParseLV4MeshReal(ai_real &fOut) {
     // skip spaces and tabs
     if (!SkipSpaces(&mFilePtr, mEnd)) {
         // LOG
@@ -1875,6 +1893,19 @@ void Parser::ParseLV4MeshFloat(ai_real &fOut) {
     mFilePtr = fast_atoreal_move<ai_real>(mFilePtr, fOut);
 }
 // ------------------------------------------------------------------------------------------------
+void Parser::ParseLV4MeshFloat(float &fOut) {
+    // skip spaces and tabs
+    if (!SkipSpaces(&mFilePtr, mEnd)) {
+        // LOG
+        LogWarning("Unable to parse float: unexpected EOL [#1]");
+        fOut = 0.0;
+        ++iLineNumber;
+        return;
+    }
+    // parse the first float
+    mFilePtr = fast_atoreal_move<float>(mFilePtr, fOut);
+}
+// ------------------------------------------------------------------------------------------------
 void Parser::ParseLV4MeshLong(unsigned int &iOut) {
     // Skip spaces and tabs
     if (!SkipSpaces(&mFilePtr, mEnd)) {

+ 6 - 3
code/AssetLib/ASE/ASEParser.h

@@ -553,13 +553,15 @@ private:
     //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
     //! \param apOut Output buffer (3 floats)
     //! \param rIndexOut Output index
-    void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut);
+    void ParseLV4MeshRealTriple(ai_real *apOut, unsigned int &rIndexOut);
+    void ParseLV4MeshFloatTriple(float *apOut, unsigned int &rIndexOut);
 
     // -------------------------------------------------------------------
     //! Parse a *MESH_VERT block in a file
     //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
     //! \param apOut Output buffer (3 floats)
-    void ParseLV4MeshFloatTriple(ai_real *apOut);
+    void ParseLV4MeshRealTriple(ai_real *apOut);
+    void ParseLV4MeshFloatTriple(float *apOut);
 
     // -------------------------------------------------------------------
     //! Parse a *MESH_TFACE block in a file
@@ -577,7 +579,8 @@ private:
     // -------------------------------------------------------------------
     //! Parse a single float element
     //! \param fOut Output float
-    void ParseLV4MeshFloat(ai_real &fOut);
+    void ParseLV4MeshReal(ai_real &fOut);
+    void ParseLV4MeshFloat(float &fOut);
 
     // -------------------------------------------------------------------
     //! Parse a single int element

+ 27 - 27
code/AssetLib/Collada/ColladaParser.cpp

@@ -968,34 +968,34 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
             SkipSpacesAndLineEnd(&content, end);
         } else if (currentName == "constant_attenuation") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
+            XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
         } else if (currentName == "linear_attenuation") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mAttLinear);
+            XmlParser::getValueAsReal(currentNode, pLight.mAttLinear);
         } else if (currentName == "quadratic_attenuation") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mAttQuadratic);
+            XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic);
         } else if (currentName == "falloff_angle") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
         } else if (currentName == "falloff_exponent") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mFalloffExponent);
+            XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent);
         }
         // FCOLLADA extensions
         // -------------------------------------------------------
         else if (currentName == "outer_cone") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
         } else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
-            XmlParser::getValueAsFloat(currentNode, pLight.mPenumbraAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle);
         } else if (currentName == "intensity") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mIntensity);
+            XmlParser::getValueAsReal(currentNode, pLight.mIntensity);
         }
         else if (currentName == "falloff") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
         } else if (currentName == "hotspot_beam") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
         }
         // OpenCOLLADA extensions
         // -------------------------------------------------------
         else if (currentName == "decay_falloff") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
         }
     }
 }
@@ -1010,15 +1010,15 @@ void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
         if (currentName == "orthographic") {
             camera.mOrtho = true;
         } else if (currentName == "xfov" || currentName == "xmag") {
-            XmlParser::getValueAsFloat(currentNode, camera.mHorFov);
+            XmlParser::getValueAsReal(currentNode, camera.mHorFov);
         } else if (currentName == "yfov" || currentName == "ymag") {
-            XmlParser::getValueAsFloat(currentNode, camera.mVerFov);
+            XmlParser::getValueAsReal(currentNode, camera.mVerFov);
         } else if (currentName == "aspect_ratio") {
-            XmlParser::getValueAsFloat(currentNode, camera.mAspect);
+            XmlParser::getValueAsReal(currentNode, camera.mAspect);
         } else if (currentName == "znear") {
-            XmlParser::getValueAsFloat(currentNode, camera.mZNear);
+            XmlParser::getValueAsReal(currentNode, camera.mZNear);
         } else if (currentName == "zfar") {
-            XmlParser::getValueAsFloat(currentNode, camera.mZFar);
+            XmlParser::getValueAsReal(currentNode, camera.mZFar);
         }
     }
 }
@@ -1170,15 +1170,15 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
         } else if (currentName == "mirrorV") {
             XmlParser::getValueAsBool(currentNode, out.mMirrorV);
         } else if (currentName == "repeatU") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.x);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.x);
         } else if (currentName == "repeatV") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.y);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.y);
         } else if (currentName == "offsetU") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.x);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.x);
         } else if (currentName == "offsetV") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.y);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.y);
         } else if (currentName == "rotateUV") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mRotation);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mRotation);
         } else if (currentName == "blend_mode") {
             std::string v;
             XmlParser::getValueAsString(currentNode, v);
@@ -1198,14 +1198,14 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
         // OKINO extensions
         // -------------------------------------------------------
         else if (currentName == "weighting") {
-            XmlParser::getValueAsFloat(currentNode, out.mWeighting);
+            XmlParser::getValueAsReal(currentNode, out.mWeighting);
         } else if (currentName == "mix_with_previous_layer") {
-            XmlParser::getValueAsFloat(currentNode, out.mMixWithPrevious);
+            XmlParser::getValueAsReal(currentNode, out.mMixWithPrevious);
         }
         // MAX3D extensions
         // -------------------------------------------------------
         else if (currentName == "amount") {
-            XmlParser::getValueAsFloat(currentNode, out.mWeighting);
+            XmlParser::getValueAsReal(currentNode, out.mWeighting);
         }
     }
 }
@@ -1265,13 +1265,13 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
 
 // ------------------------------------------------------------------------------------------------
 // Reads an effect entry containing a float
-void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
-    pFloat = 0.f;
+void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pReal) {
+    pReal = 0.f;
     XmlNode floatNode = node.child("float");
     if (floatNode.empty()) {
         return;
     }
-    XmlParser::getValueAsFloat(floatNode, pFloat);
+    XmlParser::getValueAsReal(floatNode, pReal);
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/AssetLib/MDL/MDLMaterialLoader.cpp

@@ -610,7 +610,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         if (is_not_qnan(clrTexture.r)) {
             clrTemp.r *= clrTexture.a;
         }
-        pcMatOut->AddProperty<ai_real>(&clrTemp.r, 1, AI_MATKEY_OPACITY);
+        pcMatOut->AddProperty<float>(&clrTemp.r, 1, AI_MATKEY_OPACITY);
 
         // read phong power
         int iShadingMode = (int)aiShadingMode_Gouraud;

+ 1 - 1
code/AssetLib/OFF/OFFLoader.cpp

@@ -316,7 +316,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
     aiMaterial *pcMat = new aiMaterial();
 
-    aiColor4D clr(ai_real(0.6), ai_real(0.6), ai_real(0.6), ai_real(1.0));
+    aiColor4D clr(0.6f, 0.6f, 0.6f, 1.0f);
     pcMat->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
     pScene->mMaterials[0] = pcMat;
 

+ 2 - 2
code/AssetLib/Obj/ObjFileData.h

@@ -199,12 +199,12 @@ struct Material {
 
     //! Constructor
     Material() :
-            diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
+            diffuse(0.6f, 0.6f, 0.6f),
             alpha(ai_real(1.0)),
             shineness(ai_real(0.0)),
             illumination_model(1),
             ior(ai_real(1.0)),
-            transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
+            transparent(1.0f, 1.0, 1.0),
             roughness(),
             metallic(),
             sheen(),

+ 2 - 2
code/AssetLib/STL/STLLoader.cpp

@@ -181,7 +181,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     mBuffer = &buffer2[0];
 
     // the default vertex color is light gray.
-    mClrColorDefault.r = mClrColorDefault.g = mClrColorDefault.b = mClrColorDefault.a = (ai_real)0.6;
+    mClrColorDefault.r = mClrColorDefault.g = mClrColorDefault.b = mClrColorDefault.a = 0.6f;
 
     // allocate a single node
     mScene->mRootNode = new aiNode();
@@ -209,7 +209,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     }
     pcMat->AddProperty(&clrDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
     pcMat->AddProperty(&clrDiffuse, 1, AI_MATKEY_COLOR_SPECULAR);
-    clrDiffuse = aiColor4D(ai_real(0.05), ai_real(0.05), ai_real(0.05), ai_real(1.0));
+    clrDiffuse = aiColor4D(0.05f, 0.05f, 0.05f, 1.0f);
     pcMat->AddProperty(&clrDiffuse, 1, AI_MATKEY_COLOR_AMBIENT);
 
     mScene->mNumMaterials = 1;

+ 8 - 8
code/Common/Assimp.cpp

@@ -743,14 +743,14 @@ ASSIMP_API void aiVector2DivideByVector(
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiVector2Length(
+ASSIMP_API ai_real aiVector2Length(
         const C_STRUCT aiVector2D *v) {
     ai_assert(nullptr != v);
     return v->Length();
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiVector2SquareLength(
+ASSIMP_API ai_real aiVector2SquareLength(
         const C_STRUCT aiVector2D *v) {
     ai_assert(nullptr != v);
     return v->SquareLength();
@@ -764,7 +764,7 @@ ASSIMP_API void aiVector2Negate(
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiVector2DotProduct(
+ASSIMP_API ai_real aiVector2DotProduct(
         const C_STRUCT aiVector2D *a,
         const C_STRUCT aiVector2D *b) {
     ai_assert(nullptr != a);
@@ -859,14 +859,14 @@ ASSIMP_API void aiVector3DivideByVector(
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiVector3Length(
+ASSIMP_API ai_real aiVector3Length(
         const C_STRUCT aiVector3D *v) {
     ai_assert(nullptr != v);
     return v->Length();
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiVector3SquareLength(
+ASSIMP_API ai_real aiVector3SquareLength(
         const C_STRUCT aiVector3D *v) {
     ai_assert(nullptr != v);
     return v->SquareLength();
@@ -880,7 +880,7 @@ ASSIMP_API void aiVector3Negate(
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiVector3DotProduct(
+ASSIMP_API ai_real aiVector3DotProduct(
         const C_STRUCT aiVector3D *a,
         const C_STRUCT aiVector3D *b) {
     ai_assert(nullptr != a);
@@ -966,7 +966,7 @@ ASSIMP_API void aiMatrix3Inverse(C_STRUCT aiMatrix3x3 *mat) {
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiMatrix3Determinant(const C_STRUCT aiMatrix3x3 *mat) {
+ASSIMP_API ai_real aiMatrix3Determinant(const C_STRUCT aiMatrix3x3 *mat) {
     ai_assert(nullptr != mat);
     return mat->Determinant();
 }
@@ -1066,7 +1066,7 @@ ASSIMP_API void aiMatrix4Inverse(C_STRUCT aiMatrix4x4 *mat) {
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API float aiMatrix4Determinant(const C_STRUCT aiMatrix4x4 *mat) {
+ASSIMP_API ai_real aiMatrix4Determinant(const C_STRUCT aiMatrix4x4 *mat) {
     ai_assert(nullptr != mat);
     return mat->Determinant();
 }

+ 89 - 0
code/Material/MaterialSystem.cpp

@@ -174,6 +174,95 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial *pMat,
     return AI_SUCCESS;
 }
 
+// ------------------------------------------------------------------------------------------------
+// Get an array of floating-point values from the material.
+aiReturn aiGetMaterialDoubleArray(const aiMaterial *pMat,
+        const char *pKey,
+        unsigned int type,
+        unsigned int index,
+        double *pOut,
+        unsigned int *pMax) {
+    ai_assert(pOut != nullptr);
+    ai_assert(pMat != nullptr);
+
+    const aiMaterialProperty *prop;
+    aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop);
+    if (nullptr == prop) {
+        return AI_FAILURE;
+    }
+
+    // data is given in floats, convert to ai_real
+    unsigned int iWrite = 0;
+    if (aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
+        iWrite = prop->mDataLength / sizeof(float);
+        if (pMax) {
+            iWrite = std::min(*pMax, iWrite);
+            ;
+        }
+
+        for (unsigned int a = 0; a < iWrite; ++a) {
+            pOut[a] = static_cast<ai_real>(reinterpret_cast<float *>(prop->mData)[a]);
+        }
+
+        if (pMax) {
+            *pMax = iWrite;
+        }
+    }
+    // data is given in doubles, convert to float
+    else if (aiPTI_Double == prop->mType) {
+        iWrite = prop->mDataLength / sizeof(double);
+        if (pMax) {
+            iWrite = std::min(*pMax, iWrite);
+            ;
+        }
+        for (unsigned int a = 0; a < iWrite; ++a) {
+            pOut[a] = static_cast<ai_real>(reinterpret_cast<double *>(prop->mData)[a]);
+        }
+        if (pMax) {
+            *pMax = iWrite;
+        }
+    }
+    // data is given in ints, convert to float
+    else if (aiPTI_Integer == prop->mType) {
+        iWrite = prop->mDataLength / sizeof(int32_t);
+        if (pMax) {
+            iWrite = std::min(*pMax, iWrite);
+        }
+        for (unsigned int a = 0; a < iWrite; ++a) {
+            pOut[a] = static_cast<ai_real>(reinterpret_cast<int32_t *>(prop->mData)[a]);
+        }
+        if (pMax) {
+            *pMax = iWrite;
+        }
+    }
+    // a string ... read floats separated by spaces
+    else {
+        if (pMax) {
+            iWrite = *pMax;
+        }
+        // strings are zero-terminated with a 32 bit length prefix, so this is safe
+        const char *cur = prop->mData + 4;
+        ai_assert(prop->mDataLength >= 5);
+        ai_assert(!prop->mData[prop->mDataLength - 1]);
+        for (unsigned int a = 0;; ++a) {
+            cur = fast_atoreal_move<double>(cur, pOut[a]);
+            if (a == iWrite - 1) {
+                break;
+            }
+            if (!IsSpace(*cur)) {
+                ASSIMP_LOG_ERROR("Material property", pKey,
+                        " is a string; failed to parse a float array out of it.");
+                return AI_FAILURE;
+            }
+        }
+
+        if (pMax) {
+            *pMax = iWrite;
+        }
+    }
+    return AI_SUCCESS;
+}
+
 // ------------------------------------------------------------------------------------------------
 // Get an array if integers from the material
 aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat,

+ 7 - 6
include/assimp/Vertex.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2024, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -61,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <functional>
 
-namespace Assimp    {
+namespace Assimp {
 
     ///////////////////////////////////////////////////////////////////////////
     // std::plus-family operates on operands with identical types - we need to
@@ -231,7 +230,8 @@ private:
 
     // ----------------------------------------------------------------------------
     /// This time binary arithmetic of v0 with a floating-point number
-    template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) {
+    template <template <typename, typename, typename> class op>
+    static Vertex BinaryOp(const Vertex& v0, ai_real f) {
         // this is a heavy task for the compiler to optimize ... *pray*
 
         Vertex res;
@@ -244,14 +244,15 @@ private:
             res.texcoords[i] = op<aiVector3D,ai_real,aiVector3D>()(v0.texcoords[i],f);
         }
         for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
-            res.colors[i] = op<aiColor4D,ai_real,aiColor4D>()(v0.colors[i],f);
+            res.colors[i] = op<aiColor4D,float, aiColor4D>()(v0.colors[i],f);
         }
         return res;
     }
 
     // ----------------------------------------------------------------------------
     /** This time binary arithmetic of v0 with a floating-point number */
-    template <template <typename, typename, typename> class op> static Vertex BinaryOp(ai_real f, const Vertex& v0) {
+    template <template <typename, typename, typename> class op>
+    static Vertex BinaryOp(ai_real f, const Vertex& v0) {
         // this is a heavy task for the compiler to optimize ... *pray*
 
         Vertex res;
@@ -264,7 +265,7 @@ private:
             res.texcoords[i] = op<ai_real,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
         }
         for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
-            res.colors[i] = op<ai_real,aiColor4D,aiColor4D>()(f,v0.colors[i]);
+            res.colors[i] = op<float, aiColor4D,aiColor4D>()(f,v0.colors[i]);
         }
         return res;
     }

+ 25 - 7
include/assimp/XmlParser.h

@@ -211,21 +211,27 @@ public:
     /// @return true, if the value can be read out.
     static inline bool getValueAsString(XmlNode &node, std::string &text);
 
+    /// @brief Will try to get the value of the node as a real.
+    /// @param[in]  node   The node to search in.
+    /// @param[out] v      The value as a ai_real.
+    /// @return true, if the value can be read out.
+    static inline bool getValueAsReal(XmlNode &node, ai_real &v);
+
     /// @brief Will try to get the value of the node as a float.
     /// @param[in] node     The node to search in.
-    /// @param[out] text    The value as a float.
+    /// @param[out]v        The value as a float.
     /// @return true, if the value can be read out.
-    static inline bool getValueAsFloat(XmlNode &node, ai_real &v);
+    static inline bool getValueAsFloat(XmlNode &node, float &v);
 
     /// @brief Will try to get the value of the node as an integer.
-    /// @param[in] node     The node to search in.
-    /// @param[out] text    The value as a int.
+    /// @param[in]  node    The node to search in.
+    /// @param[out] i       The value as a int.
     /// @return true, if the value can be read out.
     static inline bool getValueAsInt(XmlNode &node, int &v);
 
     /// @brief Will try to get the value of the node as an bool.
-    /// @param[in] node     The node to search in.
-    /// @param[out] text    The value as a bool.
+    /// @param[in]  node    The node to search in.
+    /// @param[out] v       The value as a bool.
     /// @return true, if the value can be read out.
     static inline bool getValueAsBool(XmlNode &node, bool &v);
 
@@ -454,7 +460,19 @@ inline bool TXmlParser<TNodeType>::getValueAsString(XmlNode &node, std::string &
 }
 
 template <class TNodeType>
-inline bool TXmlParser<TNodeType>::getValueAsFloat(XmlNode &node, ai_real &v) {
+inline bool TXmlParser<TNodeType>::getValueAsReal(XmlNode& node, ai_real& v) {
+    if (node.empty()) {
+        return false;
+    }
+
+    v = node.text().as_float();
+
+    return true;
+}
+
+
+template <class TNodeType>
+inline bool TXmlParser<TNodeType>::getValueAsFloat(XmlNode &node, float &v) {
     if (node.empty()) {
         return false;
     }

+ 8 - 8
include/assimp/cimport.h

@@ -644,14 +644,14 @@ ASSIMP_API void aiVector2DivideByVector(
 /** Get the length of a 2D vector.
  *  @return v Vector to evaluate
  */
-ASSIMP_API float aiVector2Length(
+ASSIMP_API ai_real aiVector2Length(
         const C_STRUCT aiVector2D *v);
 
 // --------------------------------------------------------------------------------
 /** Get the squared length of a 2D vector.
  *  @return v Vector to evaluate
  */
-ASSIMP_API float aiVector2SquareLength(
+ASSIMP_API ai_real aiVector2SquareLength(
         const C_STRUCT aiVector2D *v);
 
 // --------------------------------------------------------------------------------
@@ -667,7 +667,7 @@ ASSIMP_API void aiVector2Negate(
  *  @param b Second vector
  *  @return The dot product of vectors
  */
-ASSIMP_API float aiVector2DotProduct(
+ASSIMP_API ai_real aiVector2DotProduct(
         const C_STRUCT aiVector2D *a,
         const C_STRUCT aiVector2D *b);
 
@@ -774,14 +774,14 @@ ASSIMP_API void aiVector3DivideByVector(
 /** Get the length of a 3D vector.
  *  @return v Vector to evaluate
  */
-ASSIMP_API float aiVector3Length(
+ASSIMP_API ai_real aiVector3Length(
         const C_STRUCT aiVector3D *v);
 
 // --------------------------------------------------------------------------------
 /** Get the squared length of a 3D vector.
  *  @return v Vector to evaluate
  */
-ASSIMP_API float aiVector3SquareLength(
+ASSIMP_API ai_real aiVector3SquareLength(
         const C_STRUCT aiVector3D *v);
 
 // --------------------------------------------------------------------------------
@@ -797,7 +797,7 @@ ASSIMP_API void aiVector3Negate(
  *  @param b Second vector
  *  @return The dot product of vectors
  */
-ASSIMP_API float aiVector3DotProduct(
+ASSIMP_API ai_real aiVector3DotProduct(
         const C_STRUCT aiVector3D *a,
         const C_STRUCT aiVector3D *b);
 
@@ -889,7 +889,7 @@ ASSIMP_API void aiMatrix3Inverse(
 /** Get the determinant of a 3x3 matrix.
  *  @param mat Matrix to get the determinant from
  */
-ASSIMP_API float aiMatrix3Determinant(
+ASSIMP_API ai_real aiMatrix3Determinant(
         const C_STRUCT aiMatrix3x3 *mat);
 
 // --------------------------------------------------------------------------------
@@ -999,7 +999,7 @@ ASSIMP_API void aiMatrix4Inverse(
  *  @param mat Matrix to get the determinant from
  *  @return The determinant of the matrix
  */
-ASSIMP_API float aiMatrix4Determinant(
+ASSIMP_API ai_real aiMatrix4Determinant(
         const C_STRUCT aiMatrix4x4 *mat);
 
 // --------------------------------------------------------------------------------

+ 2 - 2
include/assimp/color4.h

@@ -88,12 +88,12 @@ public:
     TReal r, g, b, a;
 };  // !struct aiColor4D
 
-typedef aiColor4t<ai_real> aiColor4D;
+typedef aiColor4t<float> aiColor4D;
 
 #else
 
 struct aiColor4D {
-    ai_real r, g, b, a;
+    float r, g, b, a;
 };
 
 #endif // __cplusplus

+ 5 - 6
include/assimp/defs.h

@@ -196,15 +196,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifdef __cplusplus
 /* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
- * in doxydocs.
- */
+ * in doxydocs. */
 #define C_STRUCT
 #define C_ENUM
 #else
 //////////////////////////////////////////////////////////////////////////
 /* To build the documentation, make sure ASSIMP_DOXYGEN_BUILD
-     * is defined by Doxygen's preprocessor. The corresponding
-     * entries in the DOXYFILE are: */
+ * is defined by Doxygen's preprocessor. The corresponding
+ * entries in the DOXYFILE are: */
 //////////////////////////////////////////////////////////////////////////
 #if 0
     ENABLE_PREPROCESSING   = YES
@@ -251,7 +250,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 //////////////////////////////////////////////////////////////////////////
 /* Define ASSIMP_DOUBLE_PRECISION to compile assimp
-     * with double precision support (64-bit). */
+ * with double precision support (64-bit). */
 //////////////////////////////////////////////////////////////////////////
 
 #ifdef ASSIMP_DOUBLE_PRECISION
@@ -343,4 +342,4 @@ constexpr ai_real ai_epsilon = (ai_real) 1e-6;
 
 #define AI_COUNT_OF(X) (sizeof(X) / sizeof((X)[0]))
 
-#endif // !! AI_DEFINES_H_INC
+#endif // !! AI_DEFINES_H_INC

+ 6 - 6
include/assimp/types.h

@@ -165,9 +165,9 @@ struct aiRay {
 struct aiColor3D {
 #ifdef __cplusplus
     aiColor3D() AI_NO_EXCEPT : r(0.0f), g(0.0f), b(0.0f) {}
-    aiColor3D(ai_real _r, ai_real _g, ai_real _b) :
+    aiColor3D(float _r, float _g, float _b) :
             r(_r), g(_g), b(_b) {}
-    explicit aiColor3D(ai_real _r) :
+    explicit aiColor3D(float _r) :
             r(_r), g(_r), b(_r) {}
     aiColor3D(const aiColor3D &o) :
             r(o.r), g(o.g), b(o.b) {}
@@ -214,12 +214,12 @@ struct aiColor3D {
     }
 
     /** Access a specific color component */
-    ai_real operator[](unsigned int i) const {
+    float operator[](unsigned int i) const {
         return *(&r + i);
     }
 
     /** Access a specific color component */
-    ai_real &operator[](unsigned int i) {
+    float &operator[](unsigned int i) {
         if (0 == i) {
             return r;
         } else if (1 == i) {
@@ -232,14 +232,14 @@ struct aiColor3D {
 
     /** Check whether a color is black */
     bool IsBlack() const {
-        static const ai_real epsilon = ai_real(10e-3);
+        static const float epsilon = float(10e-3);
         return std::fabs(r) < epsilon && std::fabs(g) < epsilon && std::fabs(b) < epsilon;
     }
 
 #endif // !__cplusplus
 
     //! Red, green and blue color values
-    ai_real r, g, b;
+    float r, g, b;
 }; // !struct aiColor3D
 
 // ----------------------------------------------------------------------------------

+ 12 - 3
test/unit/AssimpAPITest_aiMatrix3x3.cpp

@@ -47,7 +47,7 @@ using namespace Assimp;
 
 class AssimpAPITest_aiMatrix3x3 : public AssimpMathTest {
 protected:
-    virtual void SetUp() {
+    void SetUp() override {
         result_c = result_cpp = aiMatrix3x3();
     }
 
@@ -114,10 +114,19 @@ TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3InverseTest) {
     EXPECT_EQ(result_cpp, result_c);
 }
 
+inline void AI_EXPECT_REAL_EQ(ai_real val1, ai_real val2) {
+#ifdef ASSIMP_DOUBLE_PRECISION
+    EXPECT_DOUBLE_EQ((val1), (val2));
+#else
+    EXPECT_FLOAT_EQ((val1), (val2));
+#endif
+}
+
 TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3DeterminantTest) {
     result_c = result_cpp = random_mat3();
-    EXPECT_EQ(result_cpp.Determinant(),
-        aiMatrix3Determinant(&result_c));
+    const ai_real det_1 = result_cpp.Determinant();
+    const ai_real det_2 = aiMatrix3Determinant(&result_c);
+    AI_EXPECT_REAL_EQ(det_1, det_2);
 }
 
 TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3RotationZTest) {

+ 4 - 2
test/unit/AssimpAPITest_aiMatrix4x4.cpp

@@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 #include "UnitTestPCH.h"
 #include "MathTest.h"
+#include <assimp/MathFunctions.h>
 
 using namespace Assimp;
 
@@ -63,8 +64,9 @@ protected:
 };
 
 TEST_F(AssimpAPITest_aiMatrix4x4, isIdendityTest) {
-    aiMatrix4x4 m = aiMatrix4x4(1.001f, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
-    EXPECT_TRUE(m.IsIdentity(1e-3f));
+    aiMatrix4x4 m = aiMatrix4x4(1 + Math::getEpsilon<ai_real>(), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    const bool result = m.IsIdentity(Math::getEpsilon<ai_real>());
+    EXPECT_TRUE(result);
 }
 
 TEST_F(AssimpAPITest_aiMatrix4x4, aiIdentityMatrix4Test) {

+ 5 - 9
test/unit/utIssues.cpp

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2024, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -51,21 +49,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-class utIssues : public ::testing::Test {
-    // empty
-};
+class utIssues : public ::testing::Test {};
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
 TEST_F( utIssues, OpacityBugWhenExporting_727 ) {
     float opacity;
-    aiScene *scene( TestModelFacttory::createDefaultTestModel( opacity ) );
+    aiScene *scene = TestModelFacttory::createDefaultTestModel(opacity);
     Assimp::Importer importer;
     Assimp::Exporter exporter;
 
-    std::string path = "dae";
     const aiExportFormatDesc *desc = exporter.GetExportFormatDescription( 0 );
-    EXPECT_NE( desc, nullptr );
+    ASSERT_NE( desc, nullptr );
+
+    std::string path = "dae";
     path.append(".");
     path.append( desc->fileExtension );
     EXPECT_EQ( AI_SUCCESS, exporter.Export( scene, desc->id, path ) );
@@ -73,7 +70,6 @@ TEST_F( utIssues, OpacityBugWhenExporting_727 ) {
     ASSERT_NE( nullptr, newScene );
     float newOpacity;
     if ( newScene->mNumMaterials > 0 ) {
-        std::cout << "Desc = " << desc->description << "\n";
         EXPECT_EQ( AI_SUCCESS, newScene->mMaterials[ 0 ]->Get( AI_MATKEY_OPACITY, newOpacity ) );
         EXPECT_FLOAT_EQ( opacity, newOpacity );
     }