// ********************************************************************************** // * "a3i_intb.c" * // * Written by : Sébastien Rubens * // * Tabulations : 4 char * // ********************************************************************************** #define A3I_INTB_C // ********************************************************************************** // Included files #include #include #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