Make color single precision

pull/5660/head
Kim Kulling 2024-07-04 15:23:12 +02:00
parent 0b19b7d73b
commit e70a7db009
12 changed files with 209 additions and 79 deletions

View File

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

View File

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

View File

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

View File

@ -610,7 +610,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
if (is_not_qnan(clrTexture.r)) { if (is_not_qnan(clrTexture.r)) {
clrTemp.r *= clrTexture.a; 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 // read phong power
int iShadingMode = (int)aiShadingMode_Gouraud; int iShadingMode = (int)aiShadingMode_Gouraud;

View File

@ -199,12 +199,12 @@ struct Material {
//! Constructor //! Constructor
Material() : 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)), alpha(ai_real(1.0)),
shineness(ai_real(0.0)), shineness(ai_real(0.0)),
illumination_model(1), illumination_model(1),
ior(ai_real(1.0)), 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(), roughness(),
metallic(), metallic(),
sheen(), sheen(),

View File

@ -743,14 +743,14 @@ ASSIMP_API void aiVector2DivideByVector(
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API float aiVector2Length( ASSIMP_API ai_real aiVector2Length(
const C_STRUCT aiVector2D *v) { const C_STRUCT aiVector2D *v) {
ai_assert(nullptr != v); ai_assert(nullptr != v);
return v->Length(); return v->Length();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API float aiVector2SquareLength( ASSIMP_API ai_real aiVector2SquareLength(
const C_STRUCT aiVector2D *v) { const C_STRUCT aiVector2D *v) {
ai_assert(nullptr != v); ai_assert(nullptr != v);
return v->SquareLength(); 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 *a,
const C_STRUCT aiVector2D *b) { const C_STRUCT aiVector2D *b) {
ai_assert(nullptr != a); 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) { const C_STRUCT aiVector3D *v) {
ai_assert(nullptr != v); ai_assert(nullptr != v);
return v->Length(); return v->Length();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API float aiVector3SquareLength( ASSIMP_API ai_real aiVector3SquareLength(
const C_STRUCT aiVector3D *v) { const C_STRUCT aiVector3D *v) {
ai_assert(nullptr != v); ai_assert(nullptr != v);
return v->SquareLength(); 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 *a,
const C_STRUCT aiVector3D *b) { const C_STRUCT aiVector3D *b) {
ai_assert(nullptr != a); 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); ai_assert(nullptr != mat);
return mat->Determinant(); 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); ai_assert(nullptr != mat);
return mat->Determinant(); return mat->Determinant();
} }

View File

@ -174,6 +174,96 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial *pMat,
return AI_SUCCESS; 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<ai_real>(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 // Get an array if integers from the material
aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat, aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat,

View File

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

View File

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

View File

@ -47,7 +47,7 @@ using namespace Assimp;
class AssimpAPITest_aiMatrix3x3 : public AssimpMathTest { class AssimpAPITest_aiMatrix3x3 : public AssimpMathTest {
protected: protected:
virtual void SetUp() { void SetUp() override {
result_c = result_cpp = aiMatrix3x3(); result_c = result_cpp = aiMatrix3x3();
} }
@ -114,10 +114,19 @@ TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3InverseTest) {
EXPECT_EQ(result_cpp, result_c); 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) { TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3DeterminantTest) {
result_c = result_cpp = random_mat3(); result_c = result_cpp = random_mat3();
EXPECT_EQ(result_cpp.Determinant(), const ai_real det_1 = result_cpp.Determinant();
aiMatrix3Determinant(&result_c)); const ai_real det_2 = aiMatrix3Determinant(&result_c);
AI_EXPECT_REAL_EQ(det_1, det_2);
} }
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3RotationZTest) { TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3RotationZTest) {

View File

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

View File

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