reman3/Rayman_X/cpa/Appli/CvrtA3DtoA3i/Src/a3x_intb.cpp

166 lines
5.7 KiB
C++

// **********************************************************************************
// * "a3i_intb.c" *
// * Written by : Sébastien Rubens *
// * Tabulations : 4 char *
// **********************************************************************************
#define A3I_INTB_C
// **********************************************************************************
// Included files
#include <stdio.h>
#include <math.h>
#include "specif\\a3x_pref.h"
#include "a3x_glob.h"
#include "a3x_int.h"
#include "a3x_intb.h"
// temp
extern SEB_xReal xEps;
extern SEB_xReal xOneSubEps;
// **********************************************************************************
// Interpolations computations
// Interpolation of the whole matrixial definition of an object
// By : Sébastien Rubens (thursday 97/10/16)
// Input :
// _stKey1 = first key
// _stKey2 = second key
// _a3a3_xMtxOri <- interpolated orientation matrix
// _a3a3_xMtxSca <- interpolated scale matrix
// _a3a3_xVecTra <- interpolated translation vector
// _xT = interpolation parameter
// Output :
// void
// Modif 28/08/98 : Treat Interpolation - type 1 (Non Linear)
void fn_v_BinInterpolBetweenKeys( tdstBinFrame *_p_stKey1,
tdstBinFrame *_p_stKey2,
tdxMatrix33 _a3a3_xMtxOri,
tdxMatrix33 _a3a3_xMtxSca,
tdxVector3 _a3_xPosition,
register SEB_xReal _xT,
tdxVector3 _a3_xPivotPosition,
tdxQuater4 _a4_xQuatOri,
tdxQuater4 _a4_xQuatSca,
tdxVector3 _a3_xVecSca )
{ static tdxQuater4 a4_xQuatI;
static tdxVector3 a3_xTmpVec;
register SEB_xReal xSinOmega;
register SEB_xReal xCoef1, xCoef2;
register SEB_xReal xOmega, xCosOmega, xTbyOmega;
// -- Non linear T parameter -------
if ( (fabs(_p_stKey1->xInterpolationParameter) > xEps) && (_xT != xZero) )
{ register SEB_xReal xTmp;
xTmp= _p_stKey1->xInterpolationParameter * ((SEB_xReal) (1.0f / 8192.0f));
_xT= _xT * (_xT * xTmp + xOne - xTmp);
}
// -- Interpolation of scale -------
// Interpolation of scale direction
fn_v_InterpolQuat( _a4_xQuatSca, _p_stKey1->a4_xQuatSca, _p_stKey2->a4_xQuatSca, _xT );
//fn_v_InterpolQuatWithOmega( a4_xQuatI, _p_stKey1->a4_xQuatSca, _p_stKey2->a4_xQuatSca,
// _xT, _p_stKey1->uwOmegaSca );
fn_v_QuatToMatrix( _a3a3_xMtxOri, _a4_xQuatSca);
// Linear interpolation of scale values
fn_v_InterpolVect( _a3_xVecSca, _p_stKey1->a3_xScaleValues, _p_stKey2->a3_xScaleValues, _xT );
// Create final scale matrix
// Final matrix= [scale dir. matrix]^-1*[values scale matrix]*[scale dir. matrix]
fn_v_InvRotDiaRot( _a3a3_xMtxSca, _a3a3_xMtxOri, _a3_xVecSca );
//printf("%3.8f %3.8f %3.8f %3.8f\n", a4_xQuatI[0], a4_xQuatI[1], a4_xQuatI[2], a4_xQuatI[3] );
// -- Interpolation of orientation -------
fn_v_InterpolQuat( _a4_xQuatOri, _p_stKey1->a4_xQuatOri, _p_stKey2->a4_xQuatOri, _xT );
//fn_v_InterpolQuatWithOmega( a4_xQuatI, _p_stKey1->a4_xQuatOri, _p_stKey2->a4_xQuatOri,
// _xT, _p_stKey1->uwOmegaOri );
fn_v_QuatToMatrix( _a3a3_xMtxOri, _a4_xQuatOri );
// -- Les deux matrices multipliées -------
// Multiplie dans l'espace des quaternions (16 mul), et transformation en matrice (9 mul)
// puis multiplie par matrice diagonale (9 mul)
// -- Interpolation of position -------
if ( (_p_stKey1->uwTypeOfObject & SEB_xTypeHierarchized) == 0 )
{
// Interpolation with the pivot
// Rotate pivot (local to object)
fn_v_MatrixByVector( _a3_xPosition, _a3a3_xMtxSca, _a3_xPivotPosition );
fn_v_MatrixByVector( a3_xTmpVec, _a3a3_xMtxOri, _a3_xPosition );
// Pivot (linear) interpolation in world axes
fn_v_InterpolVect( _a3_xPosition, _p_stKey1->a3_xWorldPivotPosition,
_p_stKey2->a3_xWorldPivotPosition, _xT );
// Computes the interpolated position
_a3_xPosition[0]-= a3_xTmpVec[0];
_a3_xPosition[1]-= a3_xTmpVec[1];
_a3_xPosition[2]-= a3_xTmpVec[2];
}
else
{
// Interpolation with Hierarchy
if ( (_p_stKey1->xDistMaster > xEps) || (_p_stKey2->xDistMaster > xEps) )
{
// Computes values for "Geodesic" interpolation
if ( (_p_stKey1->xDistMaster > xEps) && (_p_stKey2->xDistMaster > xEps) )
{
xCosOmega= (_p_stKey1->a3_xPosition[0] * _p_stKey2->a3_xPosition[0] +
_p_stKey1->a3_xPosition[1] * _p_stKey2->a3_xPosition[1] +
_p_stKey1->a3_xPosition[2] * _p_stKey2->a3_xPosition[2]) /
(_p_stKey1->xDistMaster * _p_stKey2->xDistMaster);
xOmega= (SEB_xReal) acos( xCosOmega );
if ( xOneSubEps > xCosOmega )
{ xSinOmega= xOne / (SEB_xReal) sin( xOmega );
xTbyOmega= (_xT * xOmega); // Toujours < _lOmega et toujours positif
xCoef1= (SEB_xReal) sin( xOmega - xTbyOmega ) * xSinOmega;
xCoef2= (SEB_xReal) sin( xTbyOmega ) * xSinOmega;
}
else
{ xCoef1= xOne - _xT;
xCoef2= _xT;
}
// Linear interpolation of vector length
xSinOmega= ( _p_stKey2->xDistMaster - _p_stKey1->xDistMaster ) * _xT
+ _p_stKey1->xDistMaster;
xCoef1*= xSinOmega / _p_stKey1->xDistMaster;
xCoef2*= xSinOmega / _p_stKey2->xDistMaster;
// Computes the interpolated position
_a3_xPosition[0]= xCoef1 * _p_stKey1->a3_xPosition[0] + xCoef2 * _p_stKey2->a3_xPosition[0];
_a3_xPosition[1]= xCoef1 * _p_stKey1->a3_xPosition[1] + xCoef2 * _p_stKey2->a3_xPosition[1];
_a3_xPosition[2]= xCoef1 * _p_stKey1->a3_xPosition[2] + xCoef2 * _p_stKey2->a3_xPosition[2];
}
else
{ fn_v_InterpolVect( _a3_xPosition, _p_stKey1->a3_xPosition, _p_stKey2->a3_xPosition, _xT );
}
}
else
{
_a3_xPosition[0]= xZero;
_a3_xPosition[1]= xZero;
_a3_xPosition[2]= xZero;
}
}
}
// **********************************************************************************
#undef A3I_INTB_C