[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]; //!< 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 );
}
};

//! 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]

Math library for developers 2
Метки:                

Одно мнение о “Math library for developers 2

  • Понедельник Август 3, 2009 на 08:24
    Постоянная ссылка

    Neil, свяжись со мной. Другого варианта написать тебе я не нашёл.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *