-
Math library for developers 2
Дата: Июль 29th, 2009 Neill 1 комментарий[lang_ru]В предыдущем одноименном посте я опубликовал библиотеку в виде фукнций для классов вектора, матрицы и кватерниона. На этот раз я решил пойти дальше и переписать непосредственно сами классы в файле fbtypes.h[/lang_ru]
[lang_en]In a previous «math library for developers» post, I published a library of classes for vectors, matrices and quaternions. At this time I decided to go ahead and rewrite the classes directly in the file fbtypes.h[/lang_en]
[lang_ru]В MotionBuilder базовые типы имеет весьма ограниченный функционал, побороть его можно только путем избавления от зависимости от библиотеки fbsdk.
Для этого перед типом вектора и матрицы я вырезал индентификатор импортирования FBSDK_DLL и дополнил классы соответствующим недостающим кодом…
Теперь класс для вектора выглядит следующим образом:[/lang_ru]
[lang_en]In MotionBuilder basic types have very limited functionality, it can be overcome only by getting rid of dependence on the library fbsdk.
For this type of vector, I cut out import FBSDK_DLL and added the missing class methods as in the code below …Now the class for a vector is as follows:[/lang_en]
//! Three dimensional vector (template).template <class tType> class FBVector3{private:public:tType mValue[3]; //!< Valuespublic://! Constructor.FBVector3(){mValue[0]=mValue[1]=mValue[2] = (tType)0.0;}//! Copy ConstructorFBVector3( const FBVector3& pVector ){memcpy( &mValue[0], pVector, sizeof(tType)*3 );}/** Constructor from array.* \param pValue Array to take values from.*/FBVector3( tType *pValue ){memcpy( &mValue[0], pValue, sizeof(tType)*3 );}/** Constructor.* \param p1 First element* \param p2 Second element.* \param p3 Third element(default=0).*/FBVector3( tType p1,tType p2, tType p3=0 ){mValue[0] = p1;mValue[1] = p2;mValue[2] = p3;}/** Initialization function.* Clear vector.*/void Init(){mValue[0] = mValue[1] = mValue[2] = (tType)0.0;}/** Overloaded [] operator.* \param pIndex Element to access.* \return Element at \e pIndex.*/tType &operator[](int pIndex){return mValue[pIndex];}/** Set vector from an array.* \param pValue Array to copy value from.*/void Set( tType *pValue ){memcpy( &mValue[0], pValue, sizeof(tType)*3 );}/** Overloaded cast to array.* \return Array of items of \e tType.*/operator tType *() const{return (tType*)&mValue[0];}/** Overloaded equal operator.* \param pVector Vector to copy.* \return this vector as a const.*/const FBVector3& operator = ( const FBVector3& pVector ){memcpy( &mValue[0], pVector, sizeof(tType) * 3 );}};//! Three dimensional vector (template).
template <class tType> class FBVector3
{
private:
public:
tType mValue[3]; //!< Values
public:
//! Constructor.
FBVector3()
{
mValue[0]=mValue[1]=mValue[2] = (tType)0.0;
}
//! Copy Constructor
FBVector3( const FBVector3& pVector )
{
memcpy( &mValue[0], pVector, sizeof(tType)*3 );
}
/** Constructor from array.
* \param pValue Array to take values from.
*/
FBVector3( tType *pValue )
{
memcpy( &mValue[0], pValue, sizeof(tType)*3 );
}
/** Constructor.
* \param p1 First element
* \param p2 Second element.
* \param p3 Third element(default=0).
*/
FBVector3( tType p1,tType p2, tType p3=0 )
{
mValue[0] = p1;
mValue[1] = p2;
mValue[2] = p3;
}
/** Initialization function.
* Clear vector.
*/
void Init()
{
mValue[0] = mValue[1] = mValue[2] = (tType)0.0;
}
/** Overloaded [] operator.
* \param pIndex Element to access.
* \return Element at \e pIndex.
*/
tType &operator[](int pIndex)
{
return mValue[pIndex];
}
/** Set vector from an array.
* \param pValue Array to copy value from.
*/
void Set( tType *pValue )
{
memcpy( &mValue[0], pValue, sizeof(tType)*3 );
}
/** Overloaded cast to array.
* \return Array of items of \e tType.
*/
operator tType *() const
{
return (tType*)&mValue[0];
}
/** Overloaded equal operator.
* \param pVector Vector to copy.
* \return this vector as a const.
*/
const FBVector3& operator = ( const FBVector3& pVector )
{
memcpy( &mValue[0], pVector, sizeof(tType) * 3 );
}
};
[lang_ru]Класс для матрицы с добавленным методом инвертирования:[/lang_ru]
[lang_en]The class of the matrix with the inversion method:[/lang_en]
#define MATRIX_INVERSE_EPSILON 1e-14
static float Fabs( float f ) {
int tmp = *reinterpret_cast<int *>( &f );
tmp &= 0x7FFFFFFF;
return *reinterpret_cast<float *>( &tmp );
}
//! Four x Four (double) Matrix
class FBMatrix
{
private:
double mValue[4][4]; //!< Matrix
public:
/** Constructor
* Initializes matrix to identity.
*/
FBMatrix()
{
Identity();
}
/** Constructor.
* \param pValue Array to intialize matrix from.
*/
FBMatrix( double *pValue )
{
memcpy( &mValue[0][0], &pValue[0], sizeof(double)*16 );
}
/** Copy Constructor.
* \param pMatrix Matrix to copy.
*/
FBMatrix( const FBMatrix& pMatrix )
{
memcpy( &mValue[0][0], &pMatrix[0], sizeof(double)*16 );
}
//! Load identity matrix.
void Identity()
{
memset( &mValue[0][0], 0, sizeof(double)*16 );
mValue[0][0] = mValue[1][1] = mValue[2][2] = mValue[3][3] = 1.0;
}
/** Set matrix from an array.
* \param pValue Array to intialize matrix from.
*/
void Set( double *pValue )
{
memcpy( &mValue[0][0], &pValue[0], sizeof(double)*16 );
}
/** Overloaded double* cast
* \return Matrix as an array.
*/
operator double *() const
{
return (double*)&mValue[0][0];
}
/** return internal Data
* \return return an array[4][4].
*/
double ** GetData() const
{
return (double**) &mValue[0][0];
}
/** Overloaded operator (,)
* \return element at position i,j
*/
double& operator () ( int i, int j )
{
return mValue[i][j];
}
const double& operator () (int i, int j) const
{
return mValue[i][j];
}
/** Overloaded equal operator.
* \param pMatrix Matrix to copy.
* \return this matrix as a const.
*/
const FBMatrix& operator = ( const FBMatrix& pMatrix )
{
memcpy(&mValue[0][0], &pMatrix[0], sizeof(double)*16);
return *this;
}
// inverse matrix
bool Inverse( void ) {
// 84+4+16 = 104 multiplications
// 1 division
double det, invDet;
// 2×2 sub-determinants required to calculate 4×4 determinant
float det2_01_01 = mValue[0][0] * mValue[1][1] – mValue[0][1] * mValue[1][0];
float det2_01_02 = mValue[0][0] * mValue[1][2] – mValue[0][2] * mValue[1][0];
float det2_01_03 = mValue[0][0] * mValue[1][3] – mValue[0][3] * mValue[1][0];
float det2_01_12 = mValue[0][1] * mValue[1][2] – mValue[0][2] * mValue[1][1];
float det2_01_13 = mValue[0][1] * mValue[1][3] – mValue[0][3] * mValue[1][1];
float det2_01_23 = mValue[0][2] * mValue[1][3] – mValue[0][3] * mValue[1][2];
// 3×3 sub-determinants required to calculate 4×4 determinant
float det3_201_012 = mValue[2][0] * det2_01_12 – mValue[2][1] * det2_01_02 + mValue[2][2] * det2_01_01;
float det3_201_013 = mValue[2][0] * det2_01_13 – mValue[2][1] * det2_01_03 + mValue[2][3] * det2_01_01;
float det3_201_023 = mValue[2][0] * det2_01_23 – mValue[2][2] * det2_01_03 + mValue[2][3] * det2_01_02;
float det3_201_123 = mValue[2][1] * det2_01_23 – mValue[2][2] * det2_01_13 + mValue[2][3] * det2_01_12;
det = ( – det3_201_123 * mValue[3][0] + det3_201_023 * mValue[3][1] – det3_201_013 * mValue[3][2] + det3_201_012 * mValue[3][3] );
if ( Fabs( (float)det ) < MATRIX_INVERSE_EPSILON ) {
return false;
}
invDet = 1.0 / det;
// remaining 2×2 sub-determinants
float det2_03_01 = mValue[0][0] * mValue[3][1] – mValue[0][1] * mValue[3][0];
float det2_03_02 = mValue[0][0] * mValue[3][2] – mValue[0][2] * mValue[3][0];
float det2_03_03 = mValue[0][0] * mValue[3][3] – mValue[0][3] * mValue[3][0];
float det2_03_12 = mValue[0][1] * mValue[3][2] – mValue[0][2] * mValue[3][1];
float det2_03_13 = mValue[0][1] * mValue[3][3] – mValue[0][3] * mValue[3][1];
float det2_03_23 = mValue[0][2] * mValue[3][3] – mValue[0][3] * mValue[3][2];
float det2_13_01 = mValue[1][0] * mValue[3][1] – mValue[1][1] * mValue[3][0];
float det2_13_02 = mValue[1][0] * mValue[3][2] – mValue[1][2] * mValue[3][0];
float det2_13_03 = mValue[1][0] * mValue[3][3] – mValue[1][3] * mValue[3][0];
float det2_13_12 = mValue[1][1] * mValue[3][2] – mValue[1][2] * mValue[3][1];
float det2_13_13 = mValue[1][1] * mValue[3][3] – mValue[1][3] * mValue[3][1];
float det2_13_23 = mValue[1][2] * mValue[3][3] – mValue[1][3] * mValue[3][2];
// remaining 3×3 sub-determinants
float det3_203_012 = mValue[2][0] * det2_03_12 – mValue[2][1] * det2_03_02 + mValue[2][2] * det2_03_01;
float det3_203_013 = mValue[2][0] * det2_03_13 – mValue[2][1] * det2_03_03 + mValue[2][3] * det2_03_01;
float det3_203_023 = mValue[2][0] * det2_03_23 – mValue[2][2] * det2_03_03 + mValue[2][3] * det2_03_02;
float det3_203_123 = mValue[2][1] * det2_03_23 – mValue[2][2] * det2_03_13 + mValue[2][3] * det2_03_12;
float det3_213_012 = mValue[2][0] * det2_13_12 – mValue[2][1] * det2_13_02 + mValue[2][2] * det2_13_01;
float det3_213_013 = mValue[2][0] * det2_13_13 – mValue[2][1] * det2_13_03 + mValue[2][3] * det2_13_01;
float det3_213_023 = mValue[2][0] * det2_13_23 – mValue[2][2] * det2_13_03 + mValue[2][3] * det2_13_02;
float det3_213_123 = mValue[2][1] * det2_13_23 – mValue[2][2] * det2_13_13 + mValue[2][3] * det2_13_12;
float det3_301_012 = mValue[3][0] * det2_01_12 – mValue[3][1] * det2_01_02 + mValue[3][2] * det2_01_01;
float det3_301_013 = mValue[3][0] * det2_01_13 – mValue[3][1] * det2_01_03 + mValue[3][3] * det2_01_01;
float det3_301_023 = mValue[3][0] * det2_01_23 – mValue[3][2] * det2_01_03 + mValue[3][3] * det2_01_02;
float det3_301_123 = mValue[3][1] * det2_01_23 – mValue[3][2] * det2_01_13 + mValue[3][3] * det2_01_12;
mValue[0][0] = - det3_213_123 * invDet;
mValue[1][0] = + det3_213_023 * invDet;
mValue[2][0] = – det3_213_013 * invDet;
mValue[3][0] = + det3_213_012 * invDet;
mValue[0][1] = + det3_203_123 * invDet;
mValue[1][1] = – det3_203_023 * invDet;
mValue[2][1] = + det3_203_013 * invDet;
mValue[3][1] = – det3_203_012 * invDet;
mValue[0][2] = + det3_301_123 * invDet;
mValue[1][2] = – det3_301_023 * invDet;
mValue[2][2] = + det3_301_013 * invDet;
mValue[3][2] = – det3_301_012 * invDet;
mValue[0][3] = – det3_201_123 * invDet;
mValue[1][3] = + det3_201_023 * invDet;
mValue[2][3] = – det3_201_013 * invDet;
mValue[3][3] = + det3_201_012 * invDet;
return true;
}
};
[lang_ru]Это конечно все показательный вариант, более добротный вариант будет когда я закончу его форматирование.[/lang_ru]
[lang_en]This, of course, all the illustrative version, a good option would be when I finish its formatting[/lang_en]
MotionBuilder, Программирование Math, Matrix, SDK, Source, VectorOne Response to “Math library for developers 2”
-
prografix Август 3rd, 2009 at 08:24
Neil, свяжись со мной. Другого варианта написать тебе я не нашёл.
Добавить комментарий
-



Свежие комментарии