Basic changes to introduce optional double precision
This commit is contained in:
@@ -75,7 +75,7 @@ public:
|
||||
// typedefs for our four configuration maps.
|
||||
// We don't need more, so there is no need for a generic solution
|
||||
typedef std::map<KeyType, int> IntPropertyMap;
|
||||
typedef std::map<KeyType, float> FloatPropertyMap;
|
||||
typedef std::map<KeyType, ai_real> FloatPropertyMap;
|
||||
typedef std::map<KeyType, std::string> StringPropertyMap;
|
||||
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
|
||||
|
||||
|
||||
@@ -1132,7 +1132,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src )
|
||||
{
|
||||
ai_assert( NULL != _dest );
|
||||
ai_assert( NULL != src );
|
||||
|
||||
|
||||
aiAnimation* dest = *_dest = new aiAnimation();
|
||||
|
||||
// get a flat copy
|
||||
@@ -1246,6 +1246,9 @@ void SceneCombiner::Copy (aiMetadata** _dest, const aiMetadata* src)
|
||||
case AI_FLOAT:
|
||||
out.mData = new float(*static_cast<float*>(in.mData));
|
||||
break;
|
||||
case AI_DOUBLE:
|
||||
out.mData = new double(*static_cast<double*>(in.mData));
|
||||
break;
|
||||
case AI_AISTRING:
|
||||
out.mData = new aiString(*static_cast<aiString*>(in.mData));
|
||||
break;
|
||||
|
||||
@@ -107,7 +107,7 @@ void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositio
|
||||
const aiVector3D* vec = reinterpret_cast<const aiVector3D*> (tempPointer + a * pElementOffset);
|
||||
|
||||
// store position by index and distance
|
||||
float distance = *vec * mPlaneNormal;
|
||||
ai_real distance = *vec * mPlaneNormal;
|
||||
mPositions.push_back( Entry( a+initial, *vec, distance));
|
||||
}
|
||||
|
||||
@@ -120,10 +120,10 @@ void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositio
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns an iterator for all positions close to the given position.
|
||||
void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
||||
float pRadius, std::vector<unsigned int>& poResults) const
|
||||
ai_real pRadius, std::vector<unsigned int>& poResults) const
|
||||
{
|
||||
const float dist = pPosition * mPlaneNormal;
|
||||
const float minDist = dist - pRadius, maxDist = dist + pRadius;
|
||||
const ai_real dist = pPosition * mPlaneNormal;
|
||||
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
|
||||
|
||||
// clear the array in this strange fashion because a simple clear() would also deallocate
|
||||
// the array which we want to avoid
|
||||
@@ -160,7 +160,7 @@ void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
||||
// Mow start iterating from there until the first position lays outside of the distance range.
|
||||
// Add all positions inside the distance range within the given radius to the result aray
|
||||
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
||||
const float pSquared = pRadius*pRadius;
|
||||
const ai_real pSquared = pRadius*pRadius;
|
||||
while( it->mDistance < maxDist)
|
||||
{
|
||||
if( (it->mPosition - pPosition).SquareLength() < pSquared)
|
||||
@@ -186,19 +186,19 @@ namespace {
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Converts the bit pattern of a floating-point number to its signed integer representation.
|
||||
BinFloat ToBinary( const float & pValue) {
|
||||
BinFloat ToBinary( const ai_real & pValue) {
|
||||
|
||||
// If this assertion fails, signed int is not big enough to store a float on your platform.
|
||||
// Please correct the declaration of BinFloat a few lines above - but do it in a portable,
|
||||
// #ifdef'd manner!
|
||||
static_assert( sizeof(BinFloat) >= sizeof(float), "sizeof(BinFloat) >= sizeof(float)");
|
||||
static_assert( sizeof(BinFloat) >= sizeof(ai_real), "sizeof(BinFloat) >= sizeof(ai_real)");
|
||||
|
||||
#if defined( _MSC_VER)
|
||||
// If this assertion fails, Visual C++ has finally moved to ILP64. This means that this
|
||||
// code has just become legacy code! Find out the current value of _MSC_VER and modify
|
||||
// the #if above so it evaluates false on the current and all upcoming VC versions (or
|
||||
// on the current platform, if LP64 or LLP64 are still used on other platforms).
|
||||
static_assert( sizeof(BinFloat) == sizeof(float), "sizeof(BinFloat) == sizeof(float)");
|
||||
static_assert( sizeof(BinFloat) == sizeof(ai_real), "sizeof(BinFloat) == sizeof(ai_real)");
|
||||
|
||||
// This works best on Visual C++, but other compilers have their problems with it.
|
||||
const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue);
|
||||
@@ -206,7 +206,7 @@ namespace {
|
||||
// On many compilers, reinterpreting a float address as an integer causes aliasing
|
||||
// problems. This is an ugly but more or less safe way of doing it.
|
||||
union {
|
||||
float asFloat;
|
||||
ai_real asFloat;
|
||||
BinFloat asBin;
|
||||
} conversion;
|
||||
conversion.asBin = 0; // zero empty space in case sizeof(BinFloat) > sizeof(float)
|
||||
@@ -311,10 +311,10 @@ void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
|
||||
unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,float pRadius) const
|
||||
{
|
||||
fill.resize(mPositions.size(),UINT_MAX);
|
||||
float dist, maxDist;
|
||||
ai_real dist, maxDist;
|
||||
|
||||
unsigned int t=0;
|
||||
const float pSquared = pRadius*pRadius;
|
||||
const ai_real pSquared = pRadius*pRadius;
|
||||
for (size_t i = 0; i < mPositions.size();) {
|
||||
dist = mPositions[i].mPosition * mPlaneNormal;
|
||||
maxDist = dist + pRadius;
|
||||
@@ -339,4 +339,3 @@ unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,f
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
* @param poResults The container to store the indices of the found positions.
|
||||
* Will be emptied by the call so it may contain anything.
|
||||
* @return An iterator to iterate over all vertices in the given area.*/
|
||||
void FindPositions( const aiVector3D& pPosition, float pRadius,
|
||||
void FindPositions( const aiVector3D& pPosition, ai_real pRadius,
|
||||
std::vector<unsigned int>& poResults) const;
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
* be counted in.
|
||||
* @return Number of unique vertices (n). */
|
||||
unsigned int GenerateMappingTable(std::vector<unsigned int>& fill,
|
||||
float pRadius) const;
|
||||
ai_real pRadius) const;
|
||||
|
||||
protected:
|
||||
/** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
|
||||
@@ -151,10 +151,10 @@ protected:
|
||||
{
|
||||
unsigned int mIndex; ///< The vertex referred by this entry
|
||||
aiVector3D mPosition; ///< Position
|
||||
float mDistance; ///< Distance of this vertex to the sorting plane
|
||||
ai_real mDistance; ///< Distance of this vertex to the sorting plane
|
||||
|
||||
Entry() { /** intentionally not initialized.*/ }
|
||||
Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance)
|
||||
Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance)
|
||||
: mIndex( pIndex), mPosition( pPosition), mDistance( pDistance)
|
||||
{ }
|
||||
|
||||
|
||||
@@ -94,15 +94,15 @@ class Vertex
|
||||
friend Vertex operator + (const Vertex&,const Vertex&);
|
||||
friend Vertex operator - (const Vertex&,const Vertex&);
|
||||
|
||||
// friend Vertex operator + (const Vertex&,float);
|
||||
// friend Vertex operator - (const Vertex&,float);
|
||||
friend Vertex operator * (const Vertex&,float);
|
||||
friend Vertex operator / (const Vertex&,float);
|
||||
// friend Vertex operator + (const Vertex&,ai_real);
|
||||
// friend Vertex operator - (const Vertex&,ai_real);
|
||||
friend Vertex operator * (const Vertex&,ai_real);
|
||||
friend Vertex operator / (const Vertex&,ai_real);
|
||||
|
||||
// friend Vertex operator + (float, const Vertex&);
|
||||
// friend Vertex operator - (float, const Vertex&);
|
||||
friend Vertex operator * (float, const Vertex&);
|
||||
// friend Vertex operator / (float, const Vertex&);
|
||||
// friend Vertex operator + (ai_real, const Vertex&);
|
||||
// friend Vertex operator - (ai_real, const Vertex&);
|
||||
friend Vertex operator * (ai_real, const Vertex&);
|
||||
// friend Vertex operator / (ai_real, const Vertex&);
|
||||
|
||||
public:
|
||||
|
||||
@@ -146,22 +146,22 @@ public:
|
||||
|
||||
|
||||
/*
|
||||
Vertex& operator += (float v) {
|
||||
Vertex& operator += (ai_real v) {
|
||||
*this = *this+v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vertex& operator -= (float v) {
|
||||
Vertex& operator -= (ai_real v) {
|
||||
*this = *this-v;
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
Vertex& operator *= (float v) {
|
||||
Vertex& operator *= (ai_real v) {
|
||||
*this = *this*v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vertex& operator /= (float v) {
|
||||
Vertex& operator /= (ai_real v) {
|
||||
*this = *this/v;
|
||||
return *this;
|
||||
}
|
||||
@@ -217,40 +217,40 @@ private:
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** This time binary arithmetics of v0 with a floating-point number */
|
||||
template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, float 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;
|
||||
res.position = op<aiVector3D,float,aiVector3D>()(v0.position,f);
|
||||
res.normal = op<aiVector3D,float,aiVector3D>()(v0.normal,f);
|
||||
res.tangent = op<aiVector3D,float,aiVector3D>()(v0.tangent,f);
|
||||
res.bitangent = op<aiVector3D,float,aiVector3D>()(v0.bitangent,f);
|
||||
res.position = op<aiVector3D,ai_real,aiVector3D>()(v0.position,f);
|
||||
res.normal = op<aiVector3D,ai_real,aiVector3D>()(v0.normal,f);
|
||||
res.tangent = op<aiVector3D,ai_real,aiVector3D>()(v0.tangent,f);
|
||||
res.bitangent = op<aiVector3D,ai_real,aiVector3D>()(v0.bitangent,f);
|
||||
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
res.texcoords[i] = op<aiVector3D,float,aiVector3D>()(v0.texcoords[i],f);
|
||||
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,float,aiColor4D>()(v0.colors[i],f);
|
||||
res.colors[i] = op<aiColor4D,ai_real,aiColor4D>()(v0.colors[i],f);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** This time binary arithmetics of v0 with a floating-point number */
|
||||
template <template <typename, typename, typename> class op> static Vertex BinaryOp(float 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;
|
||||
res.position = op<float,aiVector3D,aiVector3D>()(f,v0.position);
|
||||
res.normal = op<float,aiVector3D,aiVector3D>()(f,v0.normal);
|
||||
res.tangent = op<float,aiVector3D,aiVector3D>()(f,v0.tangent);
|
||||
res.bitangent = op<float,aiVector3D,aiVector3D>()(f,v0.bitangent);
|
||||
res.position = op<ai_real,aiVector3D,aiVector3D>()(f,v0.position);
|
||||
res.normal = op<ai_real,aiVector3D,aiVector3D>()(f,v0.normal);
|
||||
res.tangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.tangent);
|
||||
res.bitangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.bitangent);
|
||||
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
res.texcoords[i] = op<float,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
|
||||
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<float,aiColor4D,aiColor4D>()(f,v0.colors[i]);
|
||||
res.colors[i] = op<ai_real,aiColor4D,aiColor4D>()(f,v0.colors[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -279,41 +279,41 @@ AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
AI_FORCE_INLINE Vertex operator + (const Vertex& v0,float f) {
|
||||
AI_FORCE_INLINE Vertex operator + (const Vertex& v0,ai_real f) {
|
||||
return Vertex::BinaryOp<Intern::plus>(v0,f);
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE Vertex operator - (const Vertex& v0,float f) {
|
||||
AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) {
|
||||
return Vertex::BinaryOp<Intern::minus>(v0,f);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
AI_FORCE_INLINE Vertex operator * (const Vertex& v0,float f) {
|
||||
AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) {
|
||||
return Vertex::BinaryOp<Intern::multiplies>(v0,f);
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE Vertex operator / (const Vertex& v0,float f) {
|
||||
AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) {
|
||||
return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
AI_FORCE_INLINE Vertex operator + (float f,const Vertex& v0) {
|
||||
AI_FORCE_INLINE Vertex operator + (ai_real f,const Vertex& v0) {
|
||||
return Vertex::BinaryOp<Intern::plus>(f,v0);
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE Vertex operator - (float f,const Vertex& v0) {
|
||||
AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) {
|
||||
return Vertex::BinaryOp<Intern::minus>(f,v0);
|
||||
}
|
||||
*/
|
||||
|
||||
AI_FORCE_INLINE Vertex operator * (float f,const Vertex& v0) {
|
||||
AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) {
|
||||
return Vertex::BinaryOp<Intern::multiplies>(f,v0);
|
||||
}
|
||||
|
||||
/*
|
||||
AI_FORCE_INLINE Vertex operator / (float f,const Vertex& v0) {
|
||||
AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) {
|
||||
return Vertex::BinaryOp<Intern::divides>(f,v0);
|
||||
}
|
||||
*/
|
||||
|
||||
55
code/qnan.h
55
code/qnan.h
@@ -68,7 +68,21 @@ union _IEEESingle
|
||||
uint32_t Exp : 8;
|
||||
uint32_t Sign : 1;
|
||||
} IEEE;
|
||||
} ;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Data structure to represent the bit pattern of a 64 Bit
|
||||
* IEEE 754 floating-point number. */
|
||||
union _IEEEDouble
|
||||
{
|
||||
double Double;
|
||||
struct
|
||||
{
|
||||
uint64_t Frac : 52;
|
||||
uint64_t Exp : 11;
|
||||
uint64_t Sign : 1;
|
||||
} IEEE;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Check whether a given float is qNaN.
|
||||
@@ -87,11 +101,19 @@ AI_FORCE_INLINE bool is_qnan(float in)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Check whether a float is NOT qNaN.
|
||||
/** Check whether a given double is qNaN.
|
||||
* @param in Input value */
|
||||
AI_FORCE_INLINE bool is_not_qnan(float in)
|
||||
AI_FORCE_INLINE bool is_qnan(double in)
|
||||
{
|
||||
return !is_qnan(in);
|
||||
// the straightforward solution does not work:
|
||||
// return (in != in);
|
||||
// compiler generates code like this
|
||||
// load <in> to <register-with-different-width>
|
||||
// compare <register-with-different-width> against <in>
|
||||
|
||||
// FIXME: Use <float> stuff instead? I think fpclassify needs C99
|
||||
return (reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Exp == (1u << 11)-1 &&
|
||||
reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Frac);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -105,10 +127,29 @@ AI_FORCE_INLINE bool is_special_float(float in)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Get a fresh qnan. */
|
||||
AI_FORCE_INLINE float get_qnan()
|
||||
/** @brief check whether a double is either NaN or (+/-) INF.
|
||||
*
|
||||
* Denorms return false, they're treated like normal values.
|
||||
* @param in Input value */
|
||||
AI_FORCE_INLINE bool is_special_float(double in)
|
||||
{
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
return (reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Exp == (1u << 11)-1);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Check whether a float is NOT qNaN.
|
||||
* @param in Input value */
|
||||
template<class TReal>
|
||||
AI_FORCE_INLINE bool is_not_qnan(TReal in)
|
||||
{
|
||||
return !is_qnan(in);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief Get a fresh qnan. */
|
||||
AI_FORCE_INLINE ai_real get_qnan()
|
||||
{
|
||||
return std::numeric_limits<ai_real>::quiet_NaN();
|
||||
}
|
||||
|
||||
#endif // !! AI_QNAN_H_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user