- templatize math library. All standard math classes (i.e. aiMatrix4x4) have been replaced by templates which are usually named like the old type with a 't' postfix. For compatibility, typedefs to replace the old types exist. For the C interface, these still map to raw structures.

While principally backwards-compatible, this is still a breaking change since I also changed some method signatures (i.e. aiVector3t<TReal>(TReal) is now explicit). Normal users should not be affected, though.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1129 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/5/head
aramis_acg 2012-02-02 02:06:08 +00:00
parent 418c1bfbe0
commit ea3f655c57
20 changed files with 1189 additions and 733 deletions

View File

@ -36,10 +36,12 @@ SET( PUBLIC_HEADERS
${HEADER_PATH}/aiMesh.h
${HEADER_PATH}/aiPostProcess.h
${HEADER_PATH}/aiQuaternion.h
${HEADER_PATH}/aiQuaternion.inl
${HEADER_PATH}/aiScene.h
${HEADER_PATH}/aiTexture.h
${HEADER_PATH}/aiTypes.h
${HEADER_PATH}/aiVector2D.h
${HEADER_PATH}/aiVector2D.inl
${HEADER_PATH}/aiVector3D.h
${HEADER_PATH}/aiVector3D.inl
${HEADER_PATH}/aiVersion.h

View File

@ -160,8 +160,8 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{
register unsigned int idx = face.mIndices[i];
vertexDone [idx] = true;
meshTang [idx] = qnan;
meshBitang [idx] = qnan;
meshTang [idx] = aiVector3D(qnan);
meshBitang [idx] = aiVector3D(qnan);
}
continue;

View File

@ -337,7 +337,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt];
out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv);
out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.f);
}
}
else if (axis * base_axis_y >= angle_epsilon) {
@ -347,7 +347,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt];
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv);
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
}
}
else if (axis * base_axis_z >= angle_epsilon) {
@ -357,7 +357,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt];
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv);
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.f);
}
}
// slower code path in case the mapping axis is not one of the coordinate system axes
@ -372,7 +372,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
// again the same, except we're applying a transformation now
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv);
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
}
}

View File

@ -120,7 +120,7 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
if (face.mNumIndices < 3) {
// either a point or a line -> no well-defined normal vector
for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = qnan;
pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
}
continue;
}
@ -128,7 +128,7 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = vNor;

View File

@ -132,19 +132,22 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
if (face.mNumIndices < 3)
{
// either a point or a line -> no normal vector
for (unsigned int i = 0;i < face.mNumIndices;++i)
pMesh->mNormals[face.mIndices[i]] = qnan;
for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
}
continue;
}
aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize();
for (unsigned int i = 0;i < face.mNumIndices;++i)
for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = vNor;
}
}
// Set up a SpatialSort to quickly find all vertices close to a given position
// check whether we can reuse the SpatialSort of a previous step.
@ -175,7 +178,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
// to optimize the whole algorithm a little bit ...
std::vector<bool> abHad(pMesh->mNumVertices,false);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
if (abHad[i])continue;
if (abHad[i]) {
continue;
}
// Get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);

View File

@ -44,51 +44,60 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLOR4D_H_INC
#define AI_COLOR4D_H_INC
#ifdef __cplusplus
extern "C" {
#endif
#include "./Compiler/pushpack1.h"
#ifdef __cplusplus
// ----------------------------------------------------------------------------------
/** Represents a color in Red-Green-Blue space including an
* alpha component. Color values range from 0 to 1. */
// ----------------------------------------------------------------------------------
struct aiColor4D
template <typename TReal>
class aiColor4t
{
#ifdef __cplusplus
aiColor4D () : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}
aiColor4D (float _r, float _g, float _b, float _a)
public:
aiColor4t () : r(), g(), b(), a() {}
aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a)
: r(_r), g(_g), b(_b), a(_a) {}
aiColor4D (float _r) : r(_r), g(_r), b(_r), a(_r) {}
aiColor4D (const aiColor4D& o)
aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
aiColor4t (const aiColor4t& o)
: r(o.r), g(o.g), b(o.b), a(o.a) {}
public:
// combined operators
const aiColor4D& operator += (const aiColor4D& o);
const aiColor4D& operator -= (const aiColor4D& o);
const aiColor4D& operator *= (float f);
const aiColor4D& operator /= (float f);
const aiColor4t& operator += (const aiColor4t& o);
const aiColor4t& operator -= (const aiColor4t& o);
const aiColor4t& operator *= (TReal f);
const aiColor4t& operator /= (TReal f);
public:
// comparison
bool operator == (const aiColor4D& other) const;
bool operator != (const aiColor4D& other) const;
bool operator == (const aiColor4t& other) const;
bool operator != (const aiColor4t& other) const;
// color tuple access, rgba order
inline float operator[](unsigned int i) const;
inline float& operator[](unsigned int i);
inline TReal operator[](unsigned int i) const;
inline TReal& operator[](unsigned int i);
/** check whether a color is (close to) black */
inline bool IsBlack() const;
#endif // !__cplusplus
public:
// Red, green, blue and alpha color values
float r, g, b, a;
TReal r, g, b, a;
} PACK_STRUCT; // !struct aiColor4D
#include "./Compiler/poppack1.h"
#ifdef __cplusplus
} // end extern "C"
typedef aiColor4t<float> aiColor4D;
#else
struct aiColor4D {
float r, g, b, a;
} PACK_STRUCT;
#endif // __cplusplus
#include "./Compiler/poppack1.h"
#endif // AI_VECTOR3D_H_INC

View File

@ -40,99 +40,124 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file aiColor4D.inl
* @brief Inline implementation of aiColor4D operators
* @brief Inline implementation of aiColor4t<TReal> operators
*/
#ifndef AI_COLOR4D_INL_INC
#define AI_COLOR4D_INL_INC
#include "aiColor4D.h"
#ifdef __cplusplus
#include "aiColor4D.h"
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiColor4D& aiColor4D::operator += (const aiColor4D& o) {
r += o.r; g += o.g; b += o.b; a += o.a; return *this;
template <typename TReal>
AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
r += o.r; g += o.g; b += o.b; a += o.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiColor4D& aiColor4D::operator -= (const aiColor4D& o) {
r -= o.r; g -= o.g; b -= o.b; a -= o.a; return *this;
template <typename TReal>
AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
r -= o.r; g -= o.g; b -= o.b; a -= o.a;
return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiColor4D& aiColor4D::operator *= (float f) {
r *= f; g *= f; b *= f; a *= f; return *this;
template <typename TReal>
AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
r *= f; g *= f; b *= f; a *= f;
return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiColor4D& aiColor4D::operator /= (float f) {
r /= f; g /= f; b /= f; a /= f; return *this;
template <typename TReal>
AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
r /= f; g /= f; b /= f; a /= f;
return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE float aiColor4D::operator[](unsigned int i) const {
template <typename TReal>
AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
return *(&r + i);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE float& aiColor4D::operator[](unsigned int i) {
template <typename TReal>
AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
return *(&r + i);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool aiColor4D::operator== (const aiColor4D& other) const {
template <typename TReal>
AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
return r == other.r && g == other.g && b == other.b && a == other.a;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool aiColor4D::operator!= (const aiColor4D& other) const {
template <typename TReal>
AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
return r != other.r || g != other.g || b != other.b || a != other.a;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator + (const aiColor4D& v1, const aiColor4D& v2) {
return aiColor4D( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator - (const aiColor4D& v1, const aiColor4D& v2) {
return aiColor4D( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator * (const aiColor4D& v1, const aiColor4D& v2) {
return aiColor4D( v1.r * v2.r, v1.g * v2.g, v1.b * v2.b, v1.a * v2.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r * v2.r, v1.g * v2.g, v1.b * v2.b, v1.a * v2.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator / (const aiColor4D& v1, const aiColor4D& v2) {
return aiColor4D( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator * ( float f, const aiColor4D& v) {
return aiColor4D( f*v.r, f*v.g, f*v.b, f*v.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator * ( const aiColor4D& v, float f) {
return aiColor4D( f*v.r, f*v.g, f*v.b, f*v.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator / ( const aiColor4D& v, float f) {
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) {
return v * (1/f);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator / ( float f,const aiColor4D& v) {
return aiColor4D(f,f,f,f)/v;
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) {
return aiColor4t<TReal>(f,f,f,f)/v;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator + ( const aiColor4D& v, float f) {
return aiColor4D( f+v.r, f+v.g, f+v.b, f+v.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator - ( const aiColor4D& v, float f) {
return aiColor4D( v.r-f, v.g-f, v.b-f, v.a-f);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator + ( float f, const aiColor4D& v) {
return aiColor4D( f+v.r, f+v.g, f+v.b, f+v.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiColor4D operator - ( float f, const aiColor4D& v) {
return aiColor4D( f-v.r, f-v.g, f-v.b, f-v.a);
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a);
}
// ------------------------------------------------------------------------------------------------
inline bool aiColor4D :: IsBlack() const {
template <typename TReal>
inline bool aiColor4t<TReal> :: IsBlack() const {
// The alpha component doesn't care here. black is black.
static const float epsilon = 10e-3f;
static const TReal epsilon = 10e-3f;
return fabs( r ) < epsilon && fabs( g ) < epsilon && fabs( b ) < epsilon;
}

View File

@ -45,32 +45,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX3x3_H_INC
#define AI_MATRIX3x3_H_INC
#ifdef __cplusplus
extern "C" {
#endif
#include "./Compiler/pushpack1.h"
struct aiMatrix4x4;
struct aiVector2D;
#ifdef __cplusplus
template <typename T> class aiMatrix4x4t;
template <typename T> class aiVector2t;
// ---------------------------------------------------------------------------
/** @brief Represents a row-major 3x3 matrix
*
* There's much confusion about matrix layouts (colum vs. row order).
* This is *always* a row-major matrix. Even with the
* aiProcess_ConvertToLeftHanded flag.
* There's much confusion about matrix layouts (column vs. row order).
* This is *always* a row-major matrix. Not even with the
* #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
* matrix order - it just affects the handedness of the coordinate system
* defined thereby.
*/
struct aiMatrix3x3
template <typename TReal>
class aiMatrix3x3t
{
#ifdef __cplusplus
public:
aiMatrix3x3 () :
a1(1.0f), a2(0.0f), a3(0.0f),
b1(0.0f), b2(1.0f), b3(0.0f),
c1(0.0f), c2(0.0f), c3(1.0f) {}
aiMatrix3x3t () :
a1(static_cast<TReal>(1.0f)), a2(), a3(),
b1(), b2(static_cast<TReal>(1.0f)), b3(),
c1(), c2(), c3(static_cast<TReal>(1.0f)) {}
aiMatrix3x3 ( float _a1, float _a2, float _a3,
float _b1, float _b2, float _b3,
float _c1, float _c2, float _c3) :
aiMatrix3x3t ( TReal _a1, TReal _a2, TReal _a3,
TReal _b1, TReal _b2, TReal _b3,
TReal _c1, TReal _c2, TReal _c3) :
a1(_a1), a2(_a2), a3(_a3),
b1(_b1), b2(_b2), b3(_b3),
c1(_c1), c2(_c2), c3(_c3)
@ -78,17 +81,20 @@ struct aiMatrix3x3
public:
// matrix multiplication. beware, not commutative
aiMatrix3x3& operator *= (const aiMatrix3x3& m);
aiMatrix3x3 operator * (const aiMatrix3x3& m) const;
// matrix multiplication.
aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
aiMatrix3x3t operator * (const aiMatrix3x3t& m) const;
// array access operators
float* operator[] (unsigned int p_iIndex);
const float* operator[] (unsigned int p_iIndex) const;
TReal* operator[] (unsigned int p_iIndex);
const TReal* operator[] (unsigned int p_iIndex) const;
// comparison operators
bool operator== (const aiMatrix4x4 m) const;
bool operator!= (const aiMatrix4x4 m) const;
bool operator== (const aiMatrix4x4t<TReal> m) const;
bool operator!= (const aiMatrix4x4t<TReal> m) const;
template <typename TOther>
operator aiMatrix3x3t<TOther> () const;
public:
@ -96,20 +102,20 @@ public:
/** @brief Construction from a 4x4 matrix. The remaining parts
* of the matrix are ignored.
*/
explicit aiMatrix3x3( const aiMatrix4x4& pMatrix);
explicit aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix);
// -------------------------------------------------------------------
/** @brief Transpose the matrix
*/
aiMatrix3x3& Transpose();
aiMatrix3x3t& Transpose();
// -------------------------------------------------------------------
/** @brief Invert the matrix.
* If the matrix is not invertible all elements are set to qnan.
* Beware, use (f != f) to check whether a float f is qnan.
* Beware, use (f != f) to check whether a TReal f is qnan.
*/
aiMatrix3x3& Inverse();
float Determinant() const;
aiMatrix3x3t& Inverse();
TReal Determinant() const;
public:
// -------------------------------------------------------------------
@ -118,7 +124,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix3x3& RotationZ(float a, aiMatrix3x3& out);
static aiMatrix3x3t& RotationZ(TReal a, aiMatrix3x3t& out);
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around
@ -128,8 +134,8 @@ public:
* @param axis Axis to rotate around
* @param out To be filled
*/
static aiMatrix3x3& Rotation( float a,
const aiVector3D& axis, aiMatrix3x3& out);
static aiMatrix3x3t& Rotation( TReal a,
const aiVector3t<TReal>& axis, aiMatrix3x3t& out);
// -------------------------------------------------------------------
/** @brief Returns a translation matrix
@ -137,7 +143,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix3x3& Translation( const aiVector2D& v, aiMatrix3x3& out);
static aiMatrix3x3t& Translation( const aiVector2t<TReal>& v, aiMatrix3x3t& out);
// -------------------------------------------------------------------
/** @brief A function for creating a rotation matrix that rotates a
@ -148,19 +154,30 @@ public:
* "Efficiently Building a Matrix to Rotate One Vector to Another"
* Journal of Graphics Tools, 4(4):1-4, 1999
*/
static aiMatrix3x3& FromToMatrix(const aiVector3D& from,
const aiVector3D& to, aiMatrix3x3& out);
static aiMatrix3x3t& FromToMatrix(const aiVector3t<TReal>& from,
const aiVector3t<TReal>& to, aiMatrix3x3t& out);
#endif // __cplusplus
public:
TReal a1, a2, a3;
TReal b1, b2, b3;
TReal c1, c2, c3;
} PACK_STRUCT;
typedef aiMatrix3x3t<float> aiMatrix3x3;
#else
struct aiMatrix3x3 {
float a1, a2, a3;
float b1, b2, b3;
float c1, c2, c3;
};
} PACK_STRUCT;
#ifdef __cplusplus
} // end of extern C
#endif
#include "./Compiler/poppack1.h"
#endif // AI_MATRIX3x3_H_INC

View File

@ -1,19 +1,61 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2010, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file aiMatrix3x3.inl
* @brief Inline implementation of the 3x3 matrix operators
*/
#ifndef AI_MATRIX3x3_INL_INC
#define AI_MATRIX3x3_INL_INC
#ifdef __cplusplus
#include "aiMatrix3x3.h"
#ifdef __cplusplus
#include "aiMatrix4x4.h"
#include <algorithm>
#include <limits>
// ------------------------------------------------------------------------------------------------
// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
inline aiMatrix3x3::aiMatrix3x3( const aiMatrix4x4& pMatrix)
template <typename TReal>
inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
{
a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
@ -21,9 +63,10 @@ inline aiMatrix3x3::aiMatrix3x3( const aiMatrix4x4& pMatrix)
}
// ------------------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::operator *= (const aiMatrix3x3& m)
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
{
*this = aiMatrix3x3(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
*this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
m.a1 * b1 + m.b1 * b2 + m.c1 * b3,
@ -36,27 +79,41 @@ inline aiMatrix3x3& aiMatrix3x3::operator *= (const aiMatrix3x3& m)
}
// ------------------------------------------------------------------------------------------------
inline aiMatrix3x3 aiMatrix3x3::operator* (const aiMatrix3x3& m) const
template <typename TReal>
template <typename TOther>
aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
{
aiMatrix3x3 temp( *this);
return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
{
aiMatrix3x3t<TReal> temp( *this);
temp *= m;
return temp;
}
// ------------------------------------------------------------------------------------------------
inline float* aiMatrix3x3::operator[] (unsigned int p_iIndex)
template <typename TReal>
inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex)
{
return &this->a1 + p_iIndex * 3;
}
// ------------------------------------------------------------------------------------------------
inline const float* aiMatrix3x3::operator[] (unsigned int p_iIndex) const
template <typename TReal>
inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const
{
return &this->a1 + p_iIndex * 3;
}
// ------------------------------------------------------------------------------------------------
inline bool aiMatrix3x3::operator== (const aiMatrix4x4 m) const
template <typename TReal>
inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
{
return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
@ -64,46 +121,51 @@ inline bool aiMatrix3x3::operator== (const aiMatrix4x4 m) const
}
// ------------------------------------------------------------------------------------------------
inline bool aiMatrix3x3::operator!= (const aiMatrix4x4 m) const
template <typename TReal>
inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
{
return !(*this == m);
}
// ------------------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::Transpose()
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
{
// (float&) don't remove, GCC complains cause of packed fields
std::swap( (float&)a2, (float&)b1);
std::swap( (float&)a3, (float&)c1);
std::swap( (float&)b3, (float&)c2);
// (TReal&) don't remove, GCC complains cause of packed fields
std::swap( (TReal&)a2, (TReal&)b1);
std::swap( (TReal&)a3, (TReal&)c1);
std::swap( (TReal&)b3, (TReal&)c2);
return *this;
}
// ----------------------------------------------------------------------------------------
inline float aiMatrix3x3::Determinant() const
template <typename TReal>
inline TReal aiMatrix3x3t<TReal>::Determinant() const
{
return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
}
// ----------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::Inverse()
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
{
// Compute the reciprocal determinant
float det = Determinant();
if(det == 0.0f)
TReal det = Determinant();
if(det == static_cast<TReal>(0.0))
{
// Matrix not invertible. Setting all elements to nan is not really
// correct in a mathematical sense but it is easy to debug for the
// programmer.
const float nan = std::numeric_limits<float>::quiet_NaN();
*this = aiMatrix3x3( nan,nan,nan,nan,nan,nan,nan,nan,nan);
// correct in a mathematical sense; but at least qnans are easy to
// spot. XXX we might throw an exception instead, which would
// be even much better to spot :/.
const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
*this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan);
return *this;
}
float invdet = 1.0f / det;
TReal invdet = static_cast<TReal>(1.0) / det;
aiMatrix3x3 res;
aiMatrix3x3t<TReal> res;
res.a1 = invdet * (b2 * c3 - b3 * c2);
res.a2 = -invdet * (a2 * c3 - a3 * c2);
res.a3 = invdet * (a2 * b3 - a3 * b2);
@ -119,7 +181,8 @@ inline aiMatrix3x3& aiMatrix3x3::Inverse()
}
// ------------------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::RotationZ(float a, aiMatrix3x3& out)
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
{
out.a1 = out.b2 = ::cos(a);
out.b1 = ::sin(a);
@ -133,10 +196,11 @@ inline aiMatrix3x3& aiMatrix3x3::RotationZ(float a, aiMatrix3x3& out)
// ------------------------------------------------------------------------------------------------
// Returns a rotation matrix for a rotation around an arbitrary axis.
inline aiMatrix3x3& aiMatrix3x3::Rotation( float a, const aiVector3D& axis, aiMatrix3x3& out)
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
{
float c = cos( a), s = sin( a), t = 1 - c;
float x = axis.x, y = axis.y, z = axis.z;
TReal c = cos( a), s = sin( a), t = 1 - c;
TReal x = axis.x, y = axis.y, z = axis.z;
// Many thanks to MathWorld and Wikipedia
out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
@ -147,9 +211,10 @@ inline aiMatrix3x3& aiMatrix3x3::Rotation( float a, const aiVector3D& axis, aiMa
}
// ------------------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::Translation( const aiVector2D& v, aiMatrix3x3& out)
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
{
out = aiMatrix3x3();
out = aiMatrix3x3t<TReal>();
out.a3 = v.x;
out.b3 = v.y;
return out;
@ -165,13 +230,14 @@ inline aiMatrix3x3& aiMatrix3x3::Translation( const aiVector2D& v, aiMatrix3x3&
* Journal of Graphics Tools, 4(4):1-4, 1999
*/
// ----------------------------------------------------------------------------------------
inline aiMatrix3x3& aiMatrix3x3::FromToMatrix(const aiVector3D& from,
const aiVector3D& to, aiMatrix3x3& mtx)
template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
{
const float e = from * to;
const float f = (e < 0)? -e:e;
const TReal e = from * to;
const TReal f = (e < 0)? -e:e;
if (f > 1.0 - 0.00001f) /* "from" and "to"-vector almost parallel */
if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001)) /* "from" and "to"-vector almost parallel */
{
aiVector3D u,v; /* temporary storage vectors */
aiVector3D x; /* vector most nearly orthogonal to "from" */
@ -184,31 +250,31 @@ inline aiMatrix3x3& aiMatrix3x3::FromToMatrix(const aiVector3D& from,
{
if (x.x < x.z)
{
x.x = 1.0; x.y = x.z = 0.0;
x.x = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
}
else
{
x.z = 1.0; x.y = x.z = 0.0;
x.z = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
}
}
else
{
if (x.y < x.z)
{
x.y = 1.0; x.x = x.z = 0.0;
x.y = static_cast<TReal>(1.0); x.x = x.z = static_cast<TReal>(0.0);
}
else
{
x.z = 1.0; x.x = x.y = 0.0;
x.z = static_cast<TReal>(1.0); x.x = x.y = static_cast<TReal>(0.0);
}
}
u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z;
v.x = x.x - to.x; v.y = x.y - to.y; v.z = x.z - to.z;
const float c1 = 2.0f / (u * u);
const float c2 = 2.0f / (v * v);
const float c3 = c1 * c2 * (u * v);
const TReal c1 = static_cast<TReal>(2.0) / (u * u);
const TReal c2 = static_cast<TReal>(2.0) / (v * v);
const TReal c3 = c1 * c2 * (u * v);
for (unsigned int i = 0; i < 3; i++)
{
@ -217,19 +283,19 @@ inline aiMatrix3x3& aiMatrix3x3::FromToMatrix(const aiVector3D& from,
mtx[i][j] = - c1 * u[i] * u[j] - c2 * v[i] * v[j]
+ c3 * v[i] * u[j];
}
mtx[i][i] += 1.0;
mtx[i][i] += static_cast<TReal>(1.0);
}
}
else /* the most common case, unless "from"="to", or "from"=-"to" */
{
const aiVector3D v = from ^ to;
/* ... use this hand optimized version (9 mults less) */
const float h = 1.0f/(1.0f + e); /* optimization by Gottfried Chen */
const float hvx = h * v.x;
const float hvz = h * v.z;
const float hvxy = hvx * v.y;
const float hvxz = hvx * v.z;
const float hvyz = hvz * v.y;
const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e); /* optimization by Gottfried Chen */
const TReal hvx = h * v.x;
const TReal hvz = h * v.z;
const TReal hvxy = hvx * v.y;
const TReal hvxz = hvx * v.z;
const TReal hvyz = hvz * v.y;
mtx[0][0] = e + hvx * v.x;
mtx[0][1] = hvxy - v.z;
mtx[0][2] = hvxz + v.y;

View File

@ -44,81 +44,71 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX4X4_H_INC
#define AI_MATRIX4X4_H_INC
#ifdef __cplusplus
extern "C" {
#endif
struct aiMatrix3x3;
struct aiQuaternion;
#include "./Compiler/pushpack1.h"
#ifdef __cplusplus
template<typename TReal> class aiMatrix3x3t;
template<typename TReal> class aiQuaterniont;
// ---------------------------------------------------------------------------
/** @brief Represents a row-major 4x4 matrix, use this for homogeneous
* coordinates.
*
* There's much confusion about matrix layouts (colum vs. row order).
* This is *always* a row-major matrix. Even with the
* aiProcess_ConvertToLeftHanded flag.
* There's much confusion about matrix layouts (column vs. row order).
* This is *always* a row-major matrix. Not even with the
* #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
* matrix order - it just affects the handedness of the coordinate system
* defined thereby.
*/
struct aiMatrix4x4
template<typename TReal>
class aiMatrix4x4t
{
#ifdef __cplusplus
public:
// default c'tor, init to zero
aiMatrix4x4 () :
a1(1.0f), a2(0.0f), a3(0.0f), a4(0.0f),
b1(0.0f), b2(1.0f), b3(0.0f), b4(0.0f),
c1(0.0f), c2(0.0f), c3(1.0f), c4(0.0f),
d1(0.0f), d2(0.0f), d3(0.0f), d4(1.0f)
{}
/** set to identity */
aiMatrix4x4t ();
// from single values
aiMatrix4x4 ( float _a1, float _a2, float _a3, float _a4,
float _b1, float _b2, float _b3, float _b4,
float _c1, float _c2, float _c3, float _c4,
float _d1, float _d2, float _d3, float _d4) :
a1(_a1), a2(_a2), a3(_a3), a4(_a4),
b1(_b1), b2(_b2), b3(_b3), b4(_b4),
c1(_c1), c2(_c2), c3(_c3), c4(_c4),
d1(_d1), d2(_d2), d3(_d3), d4(_d4)
{}
/** construction from single values */
aiMatrix4x4t ( TReal _a1, TReal _a2, TReal _a3, TReal _a4,
TReal _b1, TReal _b2, TReal _b3, TReal _b4,
TReal _c1, TReal _c2, TReal _c3, TReal _c4,
TReal _d1, TReal _d2, TReal _d3, TReal _d4);
// -------------------------------------------------------------------
/** @brief Constructor from 3x3 matrix.
* The remaining elements are set to identity.
*/
explicit aiMatrix4x4( const aiMatrix3x3& m);
/** construction from 3x3 matrix, remaining elements are set to identity */
explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m);
public:
// array access operators
float* operator[] (unsigned int p_iIndex);
const float* operator[] (unsigned int p_iIndex) const;
TReal* operator[] (unsigned int p_iIndex);
const TReal* operator[] (unsigned int p_iIndex) const;
// comparison operators
bool operator== (const aiMatrix4x4 m) const;
bool operator!= (const aiMatrix4x4 m) const;
bool operator== (const aiMatrix4x4t m) const;
bool operator!= (const aiMatrix4x4t m) const;
// Matrix multiplication. Not commutative.
aiMatrix4x4& operator *= (const aiMatrix4x4& m);
aiMatrix4x4 operator * (const aiMatrix4x4& m) const;
// matrix multiplication.
aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);
aiMatrix4x4t operator * (const aiMatrix4x4t& m) const;
template <typename TOther>
operator aiMatrix4x4t<TOther> () const;
public:
// -------------------------------------------------------------------
/** @brief Transpose the matrix
*/
aiMatrix4x4& Transpose();
/** @brief Transpose the matrix */
aiMatrix4x4t& Transpose();
// -------------------------------------------------------------------
/** @brief Invert the matrix.
* If the matrix is not invertible all elements are set to qnan.
* Beware, use (f != f) to check whether a float f is qnan.
* Beware, use (f != f) to check whether a TReal f is qnan.
*/
aiMatrix4x4& Inverse();
float Determinant() const;
aiMatrix4x4t& Inverse();
TReal Determinant() const;
// -------------------------------------------------------------------
@ -134,8 +124,8 @@ public:
* quaternion
* @param position Receives the output position for the x,y,z axes
*/
void Decompose (aiVector3D& scaling, aiQuaternion& rotation,
aiVector3D& position) const;
void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position) const;
// -------------------------------------------------------------------
/** @brief Decompose a trafo matrix with no scaling into its
@ -144,8 +134,8 @@ public:
* quaternion
* @param position Receives the output position for the x,y,z axes
*/
void DecomposeNoScaling (aiQuaternion& rotation,
aiVector3D& position) const;
void DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position) const;
// -------------------------------------------------------------------
@ -154,8 +144,8 @@ public:
* @param y Rotation angle for the y-axis, in radians
* @param z Rotation angle for the z-axis, in radians
*/
aiMatrix4x4& FromEulerAnglesXYZ(float x, float y, float z);
aiMatrix4x4& FromEulerAnglesXYZ(const aiVector3D& blubb);
aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z);
aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb);
public:
// -------------------------------------------------------------------
@ -164,7 +154,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix4x4& RotationX(float a, aiMatrix4x4& out);
static aiMatrix4x4t& RotationX(TReal a, aiMatrix4x4t& out);
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around the y axis
@ -172,7 +162,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix4x4& RotationY(float a, aiMatrix4x4& out);
static aiMatrix4x4t& RotationY(TReal a, aiMatrix4x4t& out);
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around the z axis
@ -180,7 +170,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix4x4& RotationZ(float a, aiMatrix4x4& out);
static aiMatrix4x4t& RotationZ(TReal a, aiMatrix4x4t& out);
// -------------------------------------------------------------------
/** Returns a rotation matrix for a rotation around an arbitrary axis.
@ -189,8 +179,8 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix4x4& Rotation(float a, const aiVector3D& axis,
aiMatrix4x4& out);
static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis,
aiMatrix4x4t& out);
// -------------------------------------------------------------------
/** @brief Returns a translation matrix
@ -198,7 +188,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix4x4& Translation( const aiVector3D& v, aiMatrix4x4& out);
static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
// -------------------------------------------------------------------
/** @brief Returns a scaling matrix
@ -206,7 +196,7 @@ public:
* @param out Receives the output matrix
* @return Reference to the output matrix
*/
static aiMatrix4x4& Scaling( const aiVector3D& v, aiMatrix4x4& out);
static aiMatrix4x4t& Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
// -------------------------------------------------------------------
/** @brief A function for creating a rotation matrix that rotates a
@ -217,24 +207,32 @@ public:
* "Efficiently Building a Matrix to Rotate One Vector to Another"
* Journal of Graphics Tools, 4(4):1-4, 1999
*/
static aiMatrix4x4& FromToMatrix(const aiVector3D& from,
const aiVector3D& to, aiMatrix4x4& out);
static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
#endif // __cplusplus
public:
TReal a1, a2, a3, a4;
TReal b1, b2, b3, b4;
TReal c1, c2, c3, c4;
TReal d1, d2, d3, d4;
} PACK_STRUCT;
typedef aiMatrix4x4t<float> aiMatrix4x4;
#else
struct aiMatrix4x4 {
float a1, a2, a3, a4;
float b1, b2, b3, b4;
float c1, c2, c3, c4;
float d1, d2, d3, d4;
} PACK_STRUCT; // !class aiMatrix4x4
#include "./Compiler/poppack1.h"
#ifdef __cplusplus
} // end extern "C"
};
#endif // __cplusplus
#include "./Compiler/poppack1.h"
#endif // AI_MATRIX4X4_H_INC

View File

@ -39,37 +39,74 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file aiMatrix4x4.inl
/** @file aiMatrix4x4t<TReal>.inl
* @brief Inline implementation of the 4x4 matrix operators
*/
#ifndef AI_MATRIX4x4_INL_INC
#define AI_MATRIX4x4_INL_INC
#include "aiMatrix4x4.h"
#ifdef __cplusplus
#include "aiMatrix4x4.h"
#include "aiMatrix3x3.h"
#include "aiQuaternion.h"
#include <algorithm>
#include <limits>
#include <math.h>
#include "aiAssert.h"
#include "aiQuaternion.h"
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4::aiMatrix4x4( const aiMatrix3x3& m)
template <typename TReal>
aiMatrix4x4t<TReal> ::aiMatrix4x4t () :
a1(1.0f), a2(), a3(), a4(),
b1(), b2(1.0f), b3(), b4(),
c1(), c2(), c3(1.0f), c4(),
d1(), d2(), d3(), d4(1.0f)
{
a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = 0.0f;
b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = 0.0f;
c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = 0.0f;
d1 = 0.0f; d2 = 0.0f; d3 = 0.0f; d4 = 1.0f;
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::operator *= (const aiMatrix4x4& m)
template <typename TReal>
aiMatrix4x4t<TReal> ::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
TReal _b1, TReal _b2, TReal _b3, TReal _b4,
TReal _c1, TReal _c2, TReal _c3, TReal _c4,
TReal _d1, TReal _d2, TReal _d3, TReal _d4) :
a1(_a1), a2(_a2), a3(_a3), a4(_a4),
b1(_b1), b2(_b2), b3(_b3), b4(_b4),
c1(_c1), c2(_c2), c3(_c3), c4(_c4),
d1(_d1), d2(_d2), d3(_d3), d4(_d4)
{
*this = aiMatrix4x4(
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
template <typename TOther>
aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
{
return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
{
a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0);
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
{
*this = aiMatrix4x4t<TReal>(
m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
@ -90,30 +127,33 @@ inline aiMatrix4x4& aiMatrix4x4::operator *= (const aiMatrix4x4& m)
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4 aiMatrix4x4::operator* (const aiMatrix4x4& m) const
template <typename TReal>
inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
{
aiMatrix4x4 temp( *this);
aiMatrix4x4t<TReal> temp( *this);
temp *= m;
return temp;
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::Transpose()
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
{
// (float&) don't remove, GCC complains cause of packed fields
std::swap( (float&)b1, (float&)a2);
std::swap( (float&)c1, (float&)a3);
std::swap( (float&)c2, (float&)b3);
std::swap( (float&)d1, (float&)a4);
std::swap( (float&)d2, (float&)b4);
std::swap( (float&)d3, (float&)c4);
// (TReal&) don't remove, GCC complains cause of packed fields
std::swap( (TReal&)b1, (TReal&)a2);
std::swap( (TReal&)c1, (TReal&)a3);
std::swap( (TReal&)c2, (TReal&)b3);
std::swap( (TReal&)d1, (TReal&)a4);
std::swap( (TReal&)d2, (TReal&)b4);
std::swap( (TReal&)d3, (TReal&)c4);
return *this;
}
// ----------------------------------------------------------------------------------------
inline float aiMatrix4x4::Determinant() const
template <typename TReal>
inline TReal aiMatrix4x4t<TReal>::Determinant() const
{
return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4
+ a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4
@ -124,17 +164,18 @@ inline float aiMatrix4x4::Determinant() const
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::Inverse()
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
{
// Compute the reciprocal determinant
float det = Determinant();
if(det == 0.0f)
const TReal det = Determinant();
if(det == static_cast<TReal>(0.0))
{
// Matrix not invertible. Setting all elements to nan is not really
// correct in a mathematical sense but it is easy to debug for the
// programmer.
const float nan = std::numeric_limits<float>::quiet_NaN();
*this = aiMatrix4x4(
const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
*this = aiMatrix4x4t<TReal>(
nan,nan,nan,nan,
nan,nan,nan,nan,
nan,nan,nan,nan,
@ -143,9 +184,9 @@ inline aiMatrix4x4& aiMatrix4x4::Inverse()
return *this;
}
float invdet = 1.0f / det;
const TReal invdet = static_cast<TReal>(1.0) / det;
aiMatrix4x4 res;
aiMatrix4x4t<TReal> res;
res.a1 = invdet * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
res.a3 = invdet * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
@ -168,19 +209,24 @@ inline aiMatrix4x4& aiMatrix4x4::Inverse()
}
// ----------------------------------------------------------------------------------------
inline float* aiMatrix4x4::operator[](unsigned int p_iIndex)
template <typename TReal>
inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex)
{
// XXX this is UB. Has been for years. The fact that it works now does not make it better.
return &this->a1 + p_iIndex * 4;
}
// ----------------------------------------------------------------------------------------
inline const float* aiMatrix4x4::operator[](unsigned int p_iIndex) const
template <typename TReal>
inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
{
// XXX same
return &this->a1 + p_iIndex * 4;
}
// ----------------------------------------------------------------------------------------
inline bool aiMatrix4x4::operator== (const aiMatrix4x4 m) const
template <typename TReal>
inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
{
return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
@ -189,16 +235,18 @@ inline bool aiMatrix4x4::operator== (const aiMatrix4x4 m) const
}
// ----------------------------------------------------------------------------------------
inline bool aiMatrix4x4::operator!= (const aiMatrix4x4 m) const
template <typename TReal>
inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const
{
return !(*this == m);
}
// ----------------------------------------------------------------------------------------
inline void aiMatrix4x4::Decompose (aiVector3D& scaling, aiQuaternion& rotation,
aiVector3D& position) const
template <typename TReal>
inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position) const
{
const aiMatrix4x4& _this = *this;
const aiMatrix4x4t<TReal>& _this = *this;
// extract translation
position.x = _this[0][3];
@ -206,10 +254,10 @@ inline void aiMatrix4x4::Decompose (aiVector3D& scaling, aiQuaternion& rotation,
position.z = _this[2][3];
// extract the rows of the matrix
aiVector3D vRows[3] = {
aiVector3D(_this[0][0],_this[1][0],_this[2][0]),
aiVector3D(_this[0][1],_this[1][1],_this[2][1]),
aiVector3D(_this[0][2],_this[1][2],_this[2][2])
aiVector3t<TReal> vRows[3] = {
aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]),
aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]),
aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2])
};
// extract the scaling factors
@ -239,19 +287,20 @@ inline void aiMatrix4x4::Decompose (aiVector3D& scaling, aiQuaternion& rotation,
}
// build a 3x3 rotation matrix
aiMatrix3x3 m(vRows[0].x,vRows[1].x,vRows[2].x,
aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x,
vRows[0].y,vRows[1].y,vRows[2].y,
vRows[0].z,vRows[1].z,vRows[2].z);
// and generate the rotation quaternion from it
rotation = aiQuaternion(m);
rotation = aiQuaterniont<TReal>(m);
}
// ----------------------------------------------------------------------------------------
inline void aiMatrix4x4::DecomposeNoScaling (aiQuaternion& rotation,
aiVector3D& position) const
template <typename TReal>
inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position) const
{
const aiMatrix4x4& _this = *this;
const aiMatrix4x4t<TReal>& _this = *this;
// extract translation
position.x = _this[0][3];
@ -259,33 +308,35 @@ inline void aiMatrix4x4::DecomposeNoScaling (aiQuaternion& rotation,
position.z = _this[2][3];
// extract rotation
rotation = aiQuaternion((aiMatrix3x3)_this);
rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::FromEulerAnglesXYZ(const aiVector3D& blubb)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
{
return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::FromEulerAnglesXYZ(float x, float y, float z)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
{
aiMatrix4x4& _this = *this;
aiMatrix4x4t<TReal>& _this = *this;
float cr = cos( x );
float sr = sin( x );
float cp = cos( y );
float sp = sin( y );
float cy = cos( z );
float sy = sin( z );
TReal cr = cos( x );
TReal sr = sin( x );
TReal cp = cos( y );
TReal sp = sin( y );
TReal cy = cos( z );
TReal sy = sin( z );
_this.a1 = cp*cy ;
_this.a2 = cp*sy;
_this.a3 = -sp ;
float srsp = sr*sp;
float crsp = cr*sp;
TReal srsp = sr*sp;
TReal crsp = cr*sp;
_this.b1 = srsp*cy-cr*sy ;
_this.b2 = srsp*sy+cr*cy ;
@ -299,10 +350,11 @@ inline aiMatrix4x4& aiMatrix4x4::FromEulerAnglesXYZ(float x, float y, float z)
}
// ----------------------------------------------------------------------------------------
inline bool aiMatrix4x4::IsIdentity() const
template <typename TReal>
inline bool aiMatrix4x4t<TReal>::IsIdentity() const
{
// Use a small epsilon to solve floating-point inaccuracies
const static float epsilon = 10e-3f;
const static TReal epsilon = 10e-3f;
return (a2 <= epsilon && a2 >= -epsilon &&
a3 <= epsilon && a3 >= -epsilon &&
@ -323,21 +375,23 @@ inline bool aiMatrix4x4::IsIdentity() const
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::RotationX(float a, aiMatrix4x4& out)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
{
/*
| 1 0 0 0 |
M = | 0 cos(A) -sin(A) 0 |
| 0 sin(A) cos(A) 0 |
| 0 0 0 1 | */
out = aiMatrix4x4();
out = aiMatrix4x4t<TReal>();
out.b2 = out.c3 = cos(a);
out.b3 = -(out.c2 = sin(a));
return out;
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::RotationY(float a, aiMatrix4x4& out)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
{
/*
| cos(A) 0 sin(A) 0 |
@ -345,21 +399,22 @@ inline aiMatrix4x4& aiMatrix4x4::RotationY(float a, aiMatrix4x4& out)
| -sin(A) 0 cos(A) 0 |
| 0 0 0 1 |
*/
out = aiMatrix4x4();
out = aiMatrix4x4t<TReal>();
out.a1 = out.c3 = cos(a);
out.c1 = -(out.a3 = sin(a));
return out;
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::RotationZ(float a, aiMatrix4x4& out)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
{
/*
| cos(A) -sin(A) 0 0 |
M = | sin(A) cos(A) 0 0 |
| 0 0 1 0 |
| 0 0 0 1 | */
out = aiMatrix4x4();
out = aiMatrix4x4t<TReal>();
out.a1 = out.b2 = cos(a);
out.a2 = -(out.b1 = sin(a));
return out;
@ -367,26 +422,28 @@ inline aiMatrix4x4& aiMatrix4x4::RotationZ(float a, aiMatrix4x4& out)
// ----------------------------------------------------------------------------------------
// Returns a rotation matrix for a rotation around an arbitrary axis.
inline aiMatrix4x4& aiMatrix4x4::Rotation( float a, const aiVector3D& axis, aiMatrix4x4& out)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
{
float c = cos( a), s = sin( a), t = 1 - c;
float x = axis.x, y = axis.y, z = axis.z;
TReal c = cos( a), s = sin( a), t = 1 - c;
TReal x = axis.x, y = axis.y, z = axis.z;
// Many thanks to MathWorld and Wikipedia
out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
out.a4 = out.b4 = out.c4 = 0.0f;
out.d1 = out.d2 = out.d3 = 0.0f;
out.d4 = 1.0f;
out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
out.d4 = static_cast<TReal>(1.0);
return out;
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::Translation( const aiVector3D& v, aiMatrix4x4& out)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
{
out = aiMatrix4x4();
out = aiMatrix4x4t<TReal>();
out.a4 = v.x;
out.b4 = v.y;
out.c4 = v.z;
@ -394,9 +451,10 @@ inline aiMatrix4x4& aiMatrix4x4::Translation( const aiVector3D& v, aiMatrix4x4&
}
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::Scaling( const aiVector3D& v, aiMatrix4x4& out)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
{
out = aiMatrix4x4();
out = aiMatrix4x4t<TReal>();
out.a1 = v.x;
out.b2 = v.y;
out.c3 = v.z;
@ -413,12 +471,13 @@ inline aiMatrix4x4& aiMatrix4x4::Scaling( const aiVector3D& v, aiMatrix4x4& out)
* Journal of Graphics Tools, 4(4):1-4, 1999
*/
// ----------------------------------------------------------------------------------------
inline aiMatrix4x4& aiMatrix4x4::FromToMatrix(const aiVector3D& from,
const aiVector3D& to, aiMatrix4x4& mtx)
template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
{
aiMatrix3x3 m3;
aiMatrix3x3::FromToMatrix(from,to,m3);
mtx = aiMatrix4x4(m3);
aiMatrix3x3t<TReal> m3;
aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
mtx = aiMatrix4x4t<TReal>(m3);
return mtx;
}

View File

@ -44,54 +44,56 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_QUATERNION_H_INC
#define AI_QUATERNION_H_INC
#include <math.h>
#include "aiTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
template <typename TReal> class aiVector3t;
template <typename TReal> class aiMatrix3x3t;
// ---------------------------------------------------------------------------
/** Represents a quaternion in a 4D vector. */
struct aiQuaternion
template <typename TReal>
class aiQuaterniont
{
#ifdef __cplusplus
aiQuaternion() : w(0.0f), x(0.0f), y(0.0f), z(0.0f) {}
aiQuaternion(float _w, float _x, float _y, float _z) : w(_w), x(_x), y(_y), z(_z) {}
public:
aiQuaterniont() : w(), x(), y(), z() {}
aiQuaterniont(TReal w, TReal x, TReal y, TReal z)
: w(w), x(x), y(y), z(z) {}
/** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */
aiQuaternion( const aiMatrix3x3& pRotMatrix);
aiQuaterniont( const aiMatrix3x3t<TReal>& pRotMatrix);
/** Construct from euler angles */
aiQuaternion( float rotx, float roty, float rotz);
aiQuaterniont( TReal rotx, TReal roty, TReal rotz);
/** Construct from an axis-angle pair */
aiQuaternion( aiVector3D axis, float angle);
aiQuaterniont( aiVector3t<TReal> axis, TReal angle);
/** Construct from a normalized quaternion stored in a vec3 */
aiQuaternion( aiVector3D normalized);
aiQuaterniont( aiVector3t<TReal> normalized);
/** Returns a matrix representation of the quaternion */
aiMatrix3x3 GetMatrix() const;
aiMatrix3x3t<TReal> GetMatrix() const;
public:
bool operator== (const aiQuaternion& o) const
{return x == o.x && y == o.y && z == o.z && w == o.w;}
bool operator== (const aiQuaterniont& o) const;
bool operator!= (const aiQuaterniont& o) const;
bool operator!= (const aiQuaternion& o) const
{return !(*this == o);}
public:
/** Normalize the quaternion */
aiQuaternion& Normalize();
aiQuaterniont& Normalize();
/** Compute quaternion conjugate */
aiQuaternion& Conjugate ();
aiQuaterniont& Conjugate ();
/** Rotate a point by this quaternion */
aiVector3D Rotate (const aiVector3D& in);
aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in);
/** Multiply two quaternions */
aiQuaternion operator* (const aiQuaternion& two) const;
aiQuaterniont operator* (const aiQuaterniont& two) const;
public:
/** Performs a spherical interpolation between two quaternions and writes the result into the third.
* @param pOut Target object to received the interpolated rotation.
@ -99,214 +101,24 @@ struct aiQuaternion
* @param pEnd End rotation, factor == 1.
* @param pFactor Interpolation factor between 0 and 1. Values outside of this range yield undefined results.
*/
static void Interpolate( aiQuaternion& pOut, const aiQuaternion& pStart, const aiQuaternion& pEnd, float pFactor);
static void Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart,
const aiQuaterniont& pEnd, TReal pFactor);
#endif // __cplusplus
public:
//! w,x,y,z components of the quaternion
TReal w, x, y, z;
} ;
typedef aiQuaterniont<float> aiQuaternion;
#else
struct aiQuaternion {
float w, x, y, z;
};
#endif
#ifdef __cplusplus
// ---------------------------------------------------------------------------
// Constructs a quaternion from a rotation matrix
inline aiQuaternion::aiQuaternion( const aiMatrix3x3 &pRotMatrix)
{
float t = 1 + pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3;
// large enough
if( t > 0.001f)
{
float s = sqrt( t) * 2.0f;
x = (pRotMatrix.c2 - pRotMatrix.b3) / s;
y = (pRotMatrix.a3 - pRotMatrix.c1) / s;
z = (pRotMatrix.b1 - pRotMatrix.a2) / s;
w = 0.25f * s;
} // else we have to check several cases
else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 )
{
// Column 0:
float s = sqrt( 1.0f + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * 2.0f;
x = 0.25f * s;
y = (pRotMatrix.b1 + pRotMatrix.a2) / s;
z = (pRotMatrix.a3 + pRotMatrix.c1) / s;
w = (pRotMatrix.c2 - pRotMatrix.b3) / s;
}
else if( pRotMatrix.b2 > pRotMatrix.c3)
{
// Column 1:
float s = sqrt( 1.0f + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * 2.0f;
x = (pRotMatrix.b1 + pRotMatrix.a2) / s;
y = 0.25f * s;
z = (pRotMatrix.c2 + pRotMatrix.b3) / s;
w = (pRotMatrix.a3 - pRotMatrix.c1) / s;
} else
{
// Column 2:
float s = sqrt( 1.0f + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * 2.0f;
x = (pRotMatrix.a3 + pRotMatrix.c1) / s;
y = (pRotMatrix.c2 + pRotMatrix.b3) / s;
z = 0.25f * s;
w = (pRotMatrix.b1 - pRotMatrix.a2) / s;
}
}
// ---------------------------------------------------------------------------
// Construction from euler angles
inline aiQuaternion::aiQuaternion( float fPitch, float fYaw, float fRoll )
{
const float fSinPitch(sin(fPitch*0.5F));
const float fCosPitch(cos(fPitch*0.5F));
const float fSinYaw(sin(fYaw*0.5F));
const float fCosYaw(cos(fYaw*0.5F));
const float fSinRoll(sin(fRoll*0.5F));
const float fCosRoll(cos(fRoll*0.5F));
const float fCosPitchCosYaw(fCosPitch*fCosYaw);
const float fSinPitchSinYaw(fSinPitch*fSinYaw);
x = fSinRoll * fCosPitchCosYaw - fCosRoll * fSinPitchSinYaw;
y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
w = fCosRoll * fCosPitchCosYaw + fSinRoll * fSinPitchSinYaw;
}
// ---------------------------------------------------------------------------
// Returns a matrix representation of the quaternion
inline aiMatrix3x3 aiQuaternion::GetMatrix() const
{
aiMatrix3x3 resMatrix;
resMatrix.a1 = 1.0f - 2.0f * (y * y + z * z);
resMatrix.a2 = 2.0f * (x * y - z * w);
resMatrix.a3 = 2.0f * (x * z + y * w);
resMatrix.b1 = 2.0f * (x * y + z * w);
resMatrix.b2 = 1.0f - 2.0f * (x * x + z * z);
resMatrix.b3 = 2.0f * (y * z - x * w);
resMatrix.c1 = 2.0f * (x * z - y * w);
resMatrix.c2 = 2.0f * (y * z + x * w);
resMatrix.c3 = 1.0f - 2.0f * (x * x + y * y);
return resMatrix;
}
// ---------------------------------------------------------------------------
// Construction from an axis-angle pair
inline aiQuaternion::aiQuaternion( aiVector3D axis, float angle)
{
axis.Normalize();
const float sin_a = sin( angle / 2 );
const float cos_a = cos( angle / 2 );
x = axis.x * sin_a;
y = axis.y * sin_a;
z = axis.z * sin_a;
w = cos_a;
}
// ---------------------------------------------------------------------------
// Construction from am existing, normalized quaternion
inline aiQuaternion::aiQuaternion( aiVector3D normalized)
{
x = normalized.x;
y = normalized.y;
z = normalized.z;
const float t = 1.0f - (x*x) - (y*y) - (z*z);
if (t < 0.0f)
w = 0.0f;
else w = sqrt (t);
}
// ---------------------------------------------------------------------------
// Performs a spherical interpolation between two quaternions
// Implementation adopted from the gmtl project. All others I found on the net fail in some cases.
// Congrats, gmtl!
inline void aiQuaternion::Interpolate( aiQuaternion& pOut, const aiQuaternion& pStart, const aiQuaternion& pEnd, float pFactor)
{
// calc cosine theta
float cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w;
// adjust signs (if necessary)
aiQuaternion end = pEnd;
if( cosom < 0.0f)
{
cosom = -cosom;
end.x = -end.x; // Reverse all signs
end.y = -end.y;
end.z = -end.z;
end.w = -end.w;
}
// Calculate coefficients
float sclp, sclq;
if( (1.0f - cosom) > 0.0001f) // 0.0001 -> some epsillon
{
// Standard case (slerp)
float omega, sinom;
omega = acos( cosom); // extract theta from dot product's cos theta
sinom = sin( omega);
sclp = sin( (1.0f - pFactor) * omega) / sinom;
sclq = sin( pFactor * omega) / sinom;
} else
{
// Very close, do linear interp (because it's faster)
sclp = 1.0f - pFactor;
sclq = pFactor;
}
pOut.x = sclp * pStart.x + sclq * end.x;
pOut.y = sclp * pStart.y + sclq * end.y;
pOut.z = sclp * pStart.z + sclq * end.z;
pOut.w = sclp * pStart.w + sclq * end.w;
}
// ---------------------------------------------------------------------------
inline aiQuaternion& aiQuaternion::Normalize()
{
// compute the magnitude and divide through it
const float mag = sqrt(x*x + y*y + z*z + w*w);
if (mag)
{
const float invMag = 1.0f/mag;
x *= invMag;
y *= invMag;
z *= invMag;
w *= invMag;
}
return *this;
}
// ---------------------------------------------------------------------------
inline aiQuaternion aiQuaternion::operator* (const aiQuaternion& t) const
{
return aiQuaternion(w*t.w - x*t.x - y*t.y - z*t.z,
w*t.x + x*t.w + y*t.z - z*t.y,
w*t.y + y*t.w + z*t.x - x*t.z,
w*t.z + z*t.w + x*t.y - y*t.x);
}
// ---------------------------------------------------------------------------
inline aiQuaternion& aiQuaternion::Conjugate ()
{
x = -x;
y = -y;
z = -z;
return *this;
}
// ---------------------------------------------------------------------------
inline aiVector3D aiQuaternion::Rotate (const aiVector3D& v)
{
aiQuaternion q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
q.Conjugate();
q = q*q2*qinv;
return aiVector3D(q.x,q.y,q.z);
}
} // end extern "C"
#endif // __cplusplus
#endif // AI_QUATERNION_H_INC

View File

@ -0,0 +1,274 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2010, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file aiQuaterniont.inl
* @brief Inline implementation of aiQuaterniont<TReal> operators
*/
#ifndef AI_QUATERNION_INL_INC
#define AI_QUATERNION_INL_INC
#ifdef __cplusplus
#include "aiQuaternion.h"
// ---------------------------------------------------------------------------
template<typename TReal>
bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const
{
return x == o.x && y == o.y && z == o.z && w == o.w;
}
// ---------------------------------------------------------------------------
template<typename TReal>
bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const
{
return !(*this == o);
}
// ---------------------------------------------------------------------------
// Constructs a quaternion from a rotation matrix
template<typename TReal>
inline aiQuaterniont<TReal>::aiQuaterniont( const aiMatrix3x3t<TReal> &pRotMatrix)
{
TReal t = 1 + pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3;
// large enough
if( t > static_cast<TReal>(0.001))
{
TReal s = sqrt( t) * static_cast<TReal>(2.0);
x = (pRotMatrix.c2 - pRotMatrix.b3) / s;
y = (pRotMatrix.a3 - pRotMatrix.c1) / s;
z = (pRotMatrix.b1 - pRotMatrix.a2) / s;
w = static_cast<TReal>(0.25) * s;
} // else we have to check several cases
else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 )
{
// Column 0:
TReal s = sqrt( static_cast<TReal>(1.0) + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * static_cast<TReal>(2.0);
x = static_cast<TReal>(0.25) * s;
y = (pRotMatrix.b1 + pRotMatrix.a2) / s;
z = (pRotMatrix.a3 + pRotMatrix.c1) / s;
w = (pRotMatrix.c2 - pRotMatrix.b3) / s;
}
else if( pRotMatrix.b2 > pRotMatrix.c3)
{
// Column 1:
TReal s = sqrt( static_cast<TReal>(1.0) + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * static_cast<TReal>(2.0);
x = (pRotMatrix.b1 + pRotMatrix.a2) / s;
y = static_cast<TReal>(0.25) * s;
z = (pRotMatrix.c2 + pRotMatrix.b3) / s;
w = (pRotMatrix.a3 - pRotMatrix.c1) / s;
} else
{
// Column 2:
TReal s = sqrt( static_cast<TReal>(1.0) + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * static_cast<TReal>(2.0);
x = (pRotMatrix.a3 + pRotMatrix.c1) / s;
y = (pRotMatrix.c2 + pRotMatrix.b3) / s;
z = static_cast<TReal>(0.25) * s;
w = (pRotMatrix.b1 - pRotMatrix.a2) / s;
}
}
// ---------------------------------------------------------------------------
// Construction from euler angles
template<typename TReal>
inline aiQuaterniont<TReal>::aiQuaterniont( TReal fPitch, TReal fYaw, TReal fRoll )
{
const TReal fSinPitch(sin(fPitch*static_cast<TReal>(0.5)));
const TReal fCosPitch(cos(fPitch*static_cast<TReal>(0.5)));
const TReal fSinYaw(sin(fYaw*static_cast<TReal>(0.5)));
const TReal fCosYaw(cos(fYaw*static_cast<TReal>(0.5)));
const TReal fSinRoll(sin(fRoll*static_cast<TReal>(0.5)));
const TReal fCosRoll(cos(fRoll*static_cast<TReal>(0.5)));
const TReal fCosPitchCosYaw(fCosPitch*fCosYaw);
const TReal fSinPitchSinYaw(fSinPitch*fSinYaw);
x = fSinRoll * fCosPitchCosYaw - fCosRoll * fSinPitchSinYaw;
y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
w = fCosRoll * fCosPitchCosYaw + fSinRoll * fSinPitchSinYaw;
}
// ---------------------------------------------------------------------------
// Returns a matrix representation of the quaternion
template<typename TReal>
inline aiMatrix3x3t<TReal> aiQuaterniont<TReal>::GetMatrix() const
{
aiMatrix3x3t<TReal> resMatrix;
resMatrix.a1 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (y * y + z * z);
resMatrix.a2 = static_cast<TReal>(2.0) * (x * y - z * w);
resMatrix.a3 = static_cast<TReal>(2.0) * (x * z + y * w);
resMatrix.b1 = static_cast<TReal>(2.0) * (x * y + z * w);
resMatrix.b2 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + z * z);
resMatrix.b3 = static_cast<TReal>(2.0) * (y * z - x * w);
resMatrix.c1 = static_cast<TReal>(2.0) * (x * z - y * w);
resMatrix.c2 = static_cast<TReal>(2.0) * (y * z + x * w);
resMatrix.c3 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + y * y);
return resMatrix;
}
// ---------------------------------------------------------------------------
// Construction from an axis-angle pair
template<typename TReal>
inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> axis, TReal angle)
{
axis.Normalize();
const TReal sin_a = sin( angle / 2 );
const TReal cos_a = cos( angle / 2 );
x = axis.x * sin_a;
y = axis.y * sin_a;
z = axis.z * sin_a;
w = cos_a;
}
// ---------------------------------------------------------------------------
// Construction from am existing, normalized quaternion
template<typename TReal>
inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> normalized)
{
x = normalized.x;
y = normalized.y;
z = normalized.z;
const TReal t = static_cast<TReal>(1.0) - (x*x) - (y*y) - (z*z);
if (t < static_cast<TReal>(0.0)) {
w = static_cast<TReal>(0.0);
}
else w = sqrt (t);
}
// ---------------------------------------------------------------------------
// Performs a spherical interpolation between two quaternions
// Implementation adopted from the gmtl project. All others I found on the net fail in some cases.
// Congrats, gmtl!
template<typename TReal>
inline void aiQuaterniont<TReal>::Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, const aiQuaterniont& pEnd, TReal pFactor)
{
// calc cosine theta
TReal cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w;
// adjust signs (if necessary)
aiQuaterniont end = pEnd;
if( cosom < static_cast<TReal>(0.0))
{
cosom = -cosom;
end.x = -end.x; // Reverse all signs
end.y = -end.y;
end.z = -end.z;
end.w = -end.w;
}
// Calculate coefficients
TReal sclp, sclq;
if( (static_cast<TReal>(1.0) - cosom) > static_cast<TReal>(0.0001)) // 0.0001 -> some epsillon
{
// Standard case (slerp)
TReal omega, sinom;
omega = acos( cosom); // extract theta from dot product's cos theta
sinom = sin( omega);
sclp = sin( (static_cast<TReal>(1.0) - pFactor) * omega) / sinom;
sclq = sin( pFactor * omega) / sinom;
} else
{
// Very close, do linear interp (because it's faster)
sclp = static_cast<TReal>(1.0) - pFactor;
sclq = pFactor;
}
pOut.x = sclp * pStart.x + sclq * end.x;
pOut.y = sclp * pStart.y + sclq * end.y;
pOut.z = sclp * pStart.z + sclq * end.z;
pOut.w = sclp * pStart.w + sclq * end.w;
}
// ---------------------------------------------------------------------------
template<typename TReal>
inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Normalize()
{
// compute the magnitude and divide through it
const TReal mag = sqrt(x*x + y*y + z*z + w*w);
if (mag)
{
const TReal invMag = static_cast<TReal>(1.0)/mag;
x *= invMag;
y *= invMag;
z *= invMag;
w *= invMag;
}
return *this;
}
// ---------------------------------------------------------------------------
template<typename TReal>
inline aiQuaterniont<TReal> aiQuaterniont<TReal>::operator* (const aiQuaterniont& t) const
{
return aiQuaterniont(w*t.w - x*t.x - y*t.y - z*t.z,
w*t.x + x*t.w + y*t.z - z*t.y,
w*t.y + y*t.w + z*t.x - x*t.z,
w*t.z + z*t.w + x*t.y - y*t.x);
}
// ---------------------------------------------------------------------------
template<typename TReal>
inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Conjugate ()
{
x = -x;
y = -y;
z = -z;
return *this;
}
// ---------------------------------------------------------------------------
template<typename TReal>
inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v)
{
aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
q.Conjugate();
q = q*q2*qinv;
return aiVector3t<TReal>(q.x,q.y,q.z);
}
#endif
#endif

View File

@ -168,7 +168,6 @@ struct aiTexture
//! @return true if the given string matches the format hint
bool CheckFormat(const char* s) const
{
ai_assert(s && !mHeight);
return (0 == ::strncmp(achFormatHint,s,3));
}

View File

@ -489,9 +489,11 @@ struct aiMemoryInfo
}
#endif //! __cplusplus
// Include implementations
// Include implementation files
#include "aiVector2D.inl"
#include "aiVector3D.inl"
#include "aiColor4D.inl"
#include "aiQuaternion.inl"
#include "aiMatrix3x3.inl"
#include "aiMatrix4x4.inl"
#endif

View File

@ -38,7 +38,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file aiVector2D.h
/** @file aiVector2t.h
* @brief 2D vector structure, including operators when compiling in C++
*/
#ifndef AI_VECTOR2D_H_INC
@ -46,142 +46,62 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "./Compiler/pushpack1.h"
// ----------------------------------------------------------------------------------
/** Represents a two-dimensional vector.
*/
struct aiVector2D
{
#ifdef __cplusplus
aiVector2D () : x(0.0f), y(0.0f) {}
aiVector2D (float _x, float _y) : x(_x), y(_y) {}
aiVector2D (float _xyz) : x(_xyz), y(_xyz) {}
aiVector2D (const aiVector2D& o) : x(o.x), y(o.y) {}
template <typename TReal>
class aiVector2t
{
public:
void Set( float pX, float pY) {
x = pX; y = pY;
}
aiVector2t () : x(), y() {}
aiVector2t (TReal _x, TReal _y) : x(_x), y(_y) {}
explicit aiVector2t (TReal _xyz) : x(_xyz), y(_xyz) {}
aiVector2t (const aiVector2t& o) : x(o.x), y(o.y) {}
float SquareLength() const {
return x*x + y*y;
}
public:
float Length() const {
return ::sqrt( SquareLength());
}
void Set( TReal pX, TReal pY);
TReal SquareLength() const ;
TReal Length() const ;
aiVector2t& Normalize();
aiVector2D& Normalize() {
*this /= Length(); return *this;
}
public:
const aiVector2D& operator += (const aiVector2D& o) {
x += o.x; y += o.y; return *this;
}
const aiVector2D& operator -= (const aiVector2D& o) {
x -= o.x; y -= o.y; return *this;
}
const aiVector2D& operator *= (float f) {
x *= f; y *= f; return *this;
}
const aiVector2D& operator /= (float f) {
x /= f; y /= f; return *this;
}
const aiVector2t& operator += (const aiVector2t& o);
const aiVector2t& operator -= (const aiVector2t& o);
const aiVector2t& operator *= (TReal f);
const aiVector2t& operator /= (TReal f);
float operator[](unsigned int i) const {
return *(&x + i);
}
TReal operator[](unsigned int i) const;
TReal& operator[](unsigned int i);
float& operator[](unsigned int i) {
return *(&x + i);
}
bool operator== (const aiVector2t& other) const;
bool operator!= (const aiVector2t& other) const;
bool operator== (const aiVector2D& other) const {
return x == other.x && y == other.y;
}
aiVector2t& operator= (TReal f);
const aiVector2t SymMul(const aiVector2t& o);
bool operator!= (const aiVector2D& other) const {
return x != other.x || y != other.y;
}
template <typename TOther>
operator aiVector2t<TOther> () const;
aiVector2D& operator= (float f) {
x = y = f;return *this;
}
TReal x, y;
} PACK_STRUCT;
const aiVector2D SymMul(const aiVector2D& o) {
return aiVector2D(x*o.x,y*o.y);
}
typedef aiVector2t<float> aiVector2D;
#else
struct aiVector2t {
TReal x,y;
};
#endif // __cplusplus
float x, y;
} PACK_STRUCT;
#include "./Compiler/poppack1.h"
#ifdef __cplusplus
} // end extern "C"
// ----------------------------------------------------------------------------------
// symmetric addition
inline aiVector2D operator + (const aiVector2D& v1, const aiVector2D& v2)
{
return aiVector2D( v1.x + v2.x, v1.y + v2.y);
}
// ----------------------------------------------------------------------------------
// symmetric subtraction
inline aiVector2D operator - (const aiVector2D& v1, const aiVector2D& v2)
{
return aiVector2D( v1.x - v2.x, v1.y - v2.y);
}
// ----------------------------------------------------------------------------------
// scalar product
inline float operator * (const aiVector2D& v1, const aiVector2D& v2)
{
return v1.x*v2.x + v1.y*v2.y;
}
// ----------------------------------------------------------------------------------
// scalar multiplication
inline aiVector2D operator * ( float f, const aiVector2D& v)
{
return aiVector2D( f*v.x, f*v.y);
}
// ----------------------------------------------------------------------------------
// and the other way around
inline aiVector2D operator * ( const aiVector2D& v, float f)
{
return aiVector2D( f*v.x, f*v.y);
}
// ----------------------------------------------------------------------------------
// scalar division
inline aiVector2D operator / ( const aiVector2D& v, float f)
{
return v * (1/f);
}
// ----------------------------------------------------------------------------------
// vector division
inline aiVector2D operator / ( const aiVector2D& v, const aiVector2D& v2)
{
return aiVector2D(v.x / v2.x,v.y / v2.y);
}
// ----------------------------------------------------------------------------------
// vector inversion
inline aiVector2D operator - ( const aiVector2D& v)
{
return aiVector2D( -v.x, -v.y);
}
#endif // __cplusplus
#endif // AI_VECTOR2D_H_INC

View File

@ -0,0 +1,214 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2010, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file aiVector2D.inl
* @brief Inline implementation of aiVector2t<TReal> operators
*/
#ifndef AI_VECTOR2D_INL_INC
#define AI_VECTOR2D_INL_INC
#ifdef __cplusplus
#include "aiVector2D.h"
// ------------------------------------------------------------------------------------------------
template <typename TReal>
template <typename TOther>
aiVector2t<TReal>::operator aiVector2t<TOther> () const {
return aiVector2t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y));
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
void aiVector2t<TReal>::Set( TReal pX, TReal pY) {
x = pX; y = pY;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
TReal aiVector2t<TReal>::SquareLength() const {
return x*x + y*y;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
TReal aiVector2t<TReal>::Length() const {
return ::sqrt( SquareLength());
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
aiVector2t<TReal>& aiVector2t<TReal>::Normalize() {
*this /= Length();
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
const aiVector2t<TReal>& aiVector2t<TReal>::operator += (const aiVector2t& o) {
x += o.x; y += o.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
const aiVector2t<TReal>& aiVector2t<TReal>::operator -= (const aiVector2t& o) {
x -= o.x; y -= o.y;
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
const aiVector2t<TReal>& aiVector2t<TReal>::operator *= (TReal f) {
x *= f; y *= f;
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
const aiVector2t<TReal>& aiVector2t<TReal>::operator /= (TReal f) {
x /= f; y /= f;
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
TReal aiVector2t<TReal>::operator[](unsigned int i) const {
return *(&x + i);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
TReal& aiVector2t<TReal>::operator[](unsigned int i) {
return *(&x + i);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
bool aiVector2t<TReal>::operator== (const aiVector2t& other) const {
return x == other.x && y == other.y;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const {
return x != other.x || y != other.y;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f) {
x = y = f;
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
const aiVector2t<TReal> aiVector2t<TReal>::SymMul(const aiVector2t& o) {
return aiVector2t(x*o.x,y*o.y);
}
// ------------------------------------------------------------------------------------------------
// symmetric addition
template <typename TReal>
inline aiVector2t<TReal> operator + (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
{
return aiVector2t<TReal>( v1.x + v2.x, v1.y + v2.y);
}
// ------------------------------------------------------------------------------------------------
// symmetric subtraction
template <typename TReal>
inline aiVector2t<TReal> operator - (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
{
return aiVector2t<TReal>( v1.x - v2.x, v1.y - v2.y);
}
// ------------------------------------------------------------------------------------------------
// scalar product
template <typename TReal>
inline TReal operator * (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
{
return v1.x*v2.x + v1.y*v2.y;
}
// ------------------------------------------------------------------------------------------------
// scalar multiplication
template <typename TReal>
inline aiVector2t<TReal> operator * ( TReal f, const aiVector2t<TReal>& v)
{
return aiVector2t<TReal>( f*v.x, f*v.y);
}
// ------------------------------------------------------------------------------------------------
// and the other way around
template <typename TReal>
inline aiVector2t<TReal> operator * ( const aiVector2t<TReal>& v, TReal f)
{
return aiVector2t<TReal>( f*v.x, f*v.y);
}
// ------------------------------------------------------------------------------------------------
// scalar division
template <typename TReal>
inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, TReal f)
{
return v * (1/f);
}
// ------------------------------------------------------------------------------------------------
// vector division
template <typename TReal>
inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, const aiVector2t<TReal>& v2)
{
return aiVector2t<TReal>(v.x / v2.x,v.y / v2.y);
}
// ------------------------------------------------------------------------------------------------
// vector negation
template <typename TReal>
inline aiVector2t<TReal> operator - ( const aiVector2t<TReal>& v)
{
return aiVector2t<TReal>( -v.x, -v.y);
}
#endif
#endif

View File

@ -46,44 +46,48 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "./Compiler/pushpack1.h"
struct aiMatrix3x3;
struct aiMatrix4x4;
#ifdef __cplusplus
template<typename TReal> class aiMatrix3x3t;
template<typename TReal> class aiMatrix4x4t;
// ---------------------------------------------------------------------------
/** Represents a three-dimensional vector. */
struct aiVector3D
template <typename TReal>
class aiVector3t
{
#ifdef __cplusplus
aiVector3D () : x(0.0f), y(0.0f), z(0.0f) {}
aiVector3D (float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
aiVector3D (float _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3D (const aiVector3D& o) : x(o.x), y(o.y), z(o.z) {}
public:
aiVector3t () : x(), y(), z() {}
aiVector3t (TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
explicit aiVector3t (TReal _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3t (const aiVector3t& o) : x(o.x), y(o.y), z(o.z) {}
public:
// combined operators
const aiVector3D& operator += (const aiVector3D& o);
const aiVector3D& operator -= (const aiVector3D& o);
const aiVector3D& operator *= (float f);
const aiVector3D& operator /= (float f);
const aiVector3t& operator += (const aiVector3t& o);
const aiVector3t& operator -= (const aiVector3t& o);
const aiVector3t& operator *= (TReal f);
const aiVector3t& operator /= (TReal f);
// transform vector by matrix
aiVector3D& operator *= (const aiMatrix3x3& mat);
aiVector3D& operator *= (const aiMatrix4x4& mat);
aiVector3t& operator *= (const aiMatrix3x3t<TReal>& mat);
aiVector3t& operator *= (const aiMatrix4x4t<TReal>& mat);
// access a single element
float operator[](unsigned int i) const;
float& operator[](unsigned int i);
TReal operator[](unsigned int i) const;
TReal& operator[](unsigned int i);
// comparison
bool operator== (const aiVector3D& other) const;
bool operator!= (const aiVector3D& other) const;
bool operator== (const aiVector3t& other) const;
bool operator!= (const aiVector3t& other) const;
template <typename TOther>
operator aiVector3t<TOther> () const;
public:
@ -91,37 +95,47 @@ public:
* @param pX X component
* @param pY Y component
* @param pZ Z component */
void Set( float pX, float pY, float pZ = 0.f);
void Set( TReal pX, TReal pY, TReal pZ);
/** @brief Get the squared length of the vector
* @return Square length */
float SquareLength() const;
TReal SquareLength() const;
/** @brief Get the length of the vector
* @return length */
float Length() const;
TReal Length() const;
/** @brief Normalize the vector */
aiVector3D& Normalize();
aiVector3t& Normalize();
/** @brief Componentwise multiplication of two vectors
*
* Note that vec*vec yields the dot product.
* @param o Second factor */
const aiVector3D SymMul(const aiVector3D& o);
const aiVector3t SymMul(const aiVector3t& o);
TReal x, y, z;
} PACK_STRUCT;
typedef aiVector3t<float> aiVector3D;
#else
struct aiVector3D {
float x,y,y;
} PACK_STRUCT;
#endif // __cplusplus
float x, y, z;
} PACK_STRUCT;
#include "./Compiler/poppack1.h"
#ifdef __cplusplus
} // end extern "C"
#endif // __cplusplus

View File

@ -40,19 +40,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file aiVector3D.inl
* @brief Inline implementation of aiVector3D operators
* @brief Inline implementation of aiVector3t<TReal> operators
*/
#ifndef AI_VECTOR3D_INL_INC
#define AI_VECTOR3D_INL_INC
#include "aiVector3D.h"
#ifdef __cplusplus
#include "aiVector3D.h"
// ------------------------------------------------------------------------------------------------
/** Transformation of a vector by a 3x3 matrix */
inline aiVector3D operator * (const aiMatrix3x3& pMatrix, const aiVector3D& pVector)
template <typename TReal>
inline aiVector3t<TReal> operator * (const aiMatrix3x3t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
{
aiVector3D res;
aiVector3t<TReal> res;
res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z;
res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z;
res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z;
@ -61,118 +62,149 @@ inline aiVector3D operator * (const aiMatrix3x3& pMatrix, const aiVector3D& pVec
// ------------------------------------------------------------------------------------------------
/** Transformation of a vector by a 4x4 matrix */
inline aiVector3D operator * (const aiMatrix4x4& pMatrix, const aiVector3D& pVector)
template <typename TReal>
inline aiVector3t<TReal> operator * (const aiMatrix4x4t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
{
aiVector3D res;
aiVector3t<TReal> res;
res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z + pMatrix.a4;
res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z + pMatrix.b4;
res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z + pMatrix.c4;
return res;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE void aiVector3D::Set( float pX, float pY, float pZ) {
template <typename TReal>
template <typename TOther>
aiVector3t<TReal>::operator aiVector3t<TOther> () const {
return aiVector3t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y),static_cast<TOther>(z));
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
AI_FORCE_INLINE void aiVector3t<TReal>::Set( TReal pX, TReal pY, TReal pZ) {
x = pX; y = pY; z = pZ;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE float aiVector3D::SquareLength() const {
template <typename TReal>
AI_FORCE_INLINE TReal aiVector3t<TReal>::SquareLength() const {
return x*x + y*y + z*z;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE float aiVector3D::Length() const {
template <typename TReal>
AI_FORCE_INLINE TReal aiVector3t<TReal>::Length() const {
return sqrt( SquareLength());
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiVector3D& aiVector3D::Normalize() {
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::Normalize() {
*this /= Length(); return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiVector3D& aiVector3D::operator += (const aiVector3D& o) {
template <typename TReal>
AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator += (const aiVector3t<TReal>& o) {
x += o.x; y += o.y; z += o.z; return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiVector3D& aiVector3D::operator -= (const aiVector3D& o) {
template <typename TReal>
AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator -= (const aiVector3t<TReal>& o) {
x -= o.x; y -= o.y; z -= o.z; return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiVector3D& aiVector3D::operator *= (float f) {
template <typename TReal>
AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator *= (TReal f) {
x *= f; y *= f; z *= f; return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiVector3D& aiVector3D::operator /= (float f) {
template <typename TReal>
AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator /= (TReal f) {
x /= f; y /= f; z /= f; return *this;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiVector3D& aiVector3D::operator *= (const aiMatrix3x3& mat){
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& mat){
return(*this = mat * (*this));
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE aiVector3D& aiVector3D::operator *= (const aiMatrix4x4& mat){
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix4x4t<TReal>& mat){
return(*this = mat * (*this));
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE float aiVector3D::operator[](unsigned int i) const {
template <typename TReal>
AI_FORCE_INLINE TReal aiVector3t<TReal>::operator[](unsigned int i) const {
return *(&x + i);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE float& aiVector3D::operator[](unsigned int i) {
template <typename TReal>
AI_FORCE_INLINE TReal& aiVector3t<TReal>::operator[](unsigned int i) {
return *(&x + i);
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool aiVector3D::operator== (const aiVector3D& other) const {
template <typename TReal>
AI_FORCE_INLINE bool aiVector3t<TReal>::operator== (const aiVector3t<TReal>& other) const {
return x == other.x && y == other.y && z == other.z;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool aiVector3D::operator!= (const aiVector3D& other) const {
template <typename TReal>
AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const {
return x != other.x || y != other.y || z != other.z;
}
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE const aiVector3D aiVector3D::SymMul(const aiVector3D& o) {
return aiVector3D(x*o.x,y*o.y,z*o.z);
template <typename TReal>
AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {
return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z);
}
// ------------------------------------------------------------------------------------------------
// symmetric addition
AI_FORCE_INLINE aiVector3D operator + (const aiVector3D& v1, const aiVector3D& v2) {
return aiVector3D( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator + (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
return aiVector3t<TReal>( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
// ------------------------------------------------------------------------------------------------
// symmetric subtraction
AI_FORCE_INLINE aiVector3D operator - (const aiVector3D& v1, const aiVector3D& v2) {
return aiVector3D( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator - (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
return aiVector3t<TReal>( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
// ------------------------------------------------------------------------------------------------
// scalar product
AI_FORCE_INLINE float operator * (const aiVector3D& v1, const aiVector3D& v2) {
template <typename TReal>
AI_FORCE_INLINE TReal operator * (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
// ------------------------------------------------------------------------------------------------
// scalar multiplication
AI_FORCE_INLINE aiVector3D operator * ( float f, const aiVector3D& v) {
return aiVector3D( f*v.x, f*v.y, f*v.z);
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator * ( TReal f, const aiVector3t<TReal>& v) {
return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
}
// ------------------------------------------------------------------------------------------------
// and the other way around
AI_FORCE_INLINE aiVector3D operator * ( const aiVector3D& v, float f) {
return aiVector3D( f*v.x, f*v.y, f*v.z);
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator * ( const aiVector3t<TReal>& v, TReal f) {
return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
}
// ------------------------------------------------------------------------------------------------
// scalar division
AI_FORCE_INLINE aiVector3D operator / ( const aiVector3D& v, float f) {
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, TReal f) {
return v * (1/f);
}
// ------------------------------------------------------------------------------------------------
// vector division
AI_FORCE_INLINE aiVector3D operator / ( const aiVector3D& v, const aiVector3D& v2) {
return aiVector3D(v.x / v2.x,v.y / v2.y,v.z / v2.z);
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, const aiVector3t<TReal>& v2) {
return aiVector3t<TReal>(v.x / v2.x,v.y / v2.y,v.z / v2.z);
}
// ------------------------------------------------------------------------------------------------
// cross product
AI_FORCE_INLINE aiVector3D operator ^ ( const aiVector3D& v1, const aiVector3D& v2) {
return aiVector3D( v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator ^ ( const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
return aiVector3t<TReal>( v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
}
// ------------------------------------------------------------------------------------------------
// vector inversion
AI_FORCE_INLINE aiVector3D operator - ( const aiVector3D& v) {
return aiVector3D( -v.x, -v.y, -v.z);
// vector negation
template <typename TReal>
AI_FORCE_INLINE aiVector3t<TReal> operator - ( const aiVector3t<TReal>& v) {
return aiVector3t<TReal>( -v.x, -v.y, -v.z);
}

View File

@ -1248,6 +1248,10 @@
RelativePath="..\..\include\aiQuaternion.h"
>
</File>
<File
RelativePath="..\..\include\aiQuaternion.inl"
>
</File>
<File
RelativePath="..\..\include\aiScene.h"
>
@ -1264,6 +1268,10 @@
RelativePath="..\..\include\aiVector2D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector2D.inl"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.h"
>