reman3/Rayman_X/cpa/tempgrp/GliGlou/MultiDRV/Src/Linear.c

412 lines
18 KiB
C

/*
=======================================================================================
Name : Linear.c
Description : compute serial operation on verticex
=======================================================================================
*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define MTH_LOW
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include"gli_st.h"
#include "GLI_Defn.h"
#include "vertex.h"
#include "light_st.h"
#include "PvObj_st.h"
#include "camera.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef __cplusplus
extern "C"
{
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
=======================================================================================
Globals & Externals & Protos
=======================================================================================
*/
extern void GLI_vSinusEffetOn3DVertex( MTH3D_tdstVector * p_stVertex3D );
/*
=======================================================================================
Macros
=======================================================================================
*/
#define GLI_M_SWAP(a,b)\
{\
fSwapValue = (a);\
(a) = (b);\
(b) = fSwapValue ;\
}\
/*
=======================================================================================
Functions
=======================================================================================
*/
/*
----------------------------------------------------------------------------------------
Description : serial dot product : do a dot product for a list of source point
source point are MTH3D_tdstVector (ie 3 float)
----------------------------------------------------------------------------------------
*/
void GLI_xSerialDotProduct(long lNbOfVertex, MTH3D_tdstVector *p_stSource, float *p_stDest, MTH3D_tdstVector *p_stMultiplicator, long lIncrement)
{
float *p_stLastResult;
p_stLastResult = p_stDest + lNbOfVertex;
for ( ; p_stDest < p_stLastResult; p_stSource++ )
*p_stDest++ = MTH_M_xRealToFloat( MTH3D_M_xDotProductVector( p_stSource,p_stMultiplicator) ) ;
}
/*
----------------------------------------------------------------------------------------
Description : serial dot product : do a dot product for a list of point
source point are Aligned3DVector (ie 4 float)
----------------------------------------------------------------------------------------
*/
void GLI_xSerialDotProductAligned ( long lNbOfVertex, GLI_tdstAligned3DVector *p_stSource, float *p_stDest, MTH3D_tdstVector *p_stMultiplicator, long lIncrement)
{
float *p_stLastResult;
p_stLastResult = p_stDest + lNbOfVertex;
for ( ; p_stDest < p_stLastResult; p_stSource++ )
*p_stDest++ = MTH_M_xRealToFloat ( MTH3D_M_xDotProductVector( (MTH3D_tdstVector *)p_stSource, p_stMultiplicator) ) ;
}
/*
----------------------------------------------------------------------------------------
Description : multiply a list of vertex with a matrix
source vertices are MTH3D_tdstVector (ie 3 float)
target vertices are Aligned3DVector (ie 4 float)
----------------------------------------------------------------------------------------
*/
void GLI_xSerialLinearOp( long lNbOfVertex, MTH3D_tdstVector *p_stSource, GLI_tdstAligned3DVector *p_stDest, POS_tdstCompletePosition *p_stMatrix)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
MTH3D_tdstVector stX,stY,stZ,stTrans;
GLI_tdstAligned3DVector *p_stLastDest ;
float fSwapValue;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
POS_fn_vGetTransformMatrix ( p_stMatrix,&stX,&stY,&stZ);
GLI_M_SWAP (stX.xY,stY.xX);
GLI_M_SWAP (stX.xZ,stZ.xX);
GLI_M_SWAP (stY.xZ,stZ.xY);
POS_fn_vGetTranslationVector( p_stMatrix,&stTrans);
p_stLastDest = p_stDest + lNbOfVertex;
for ( ; p_stDest < p_stLastDest; p_stDest++, p_stSource++)
{
p_stDest->xX = MTH3D_M_xDotProductVector ( &stX , p_stSource ) + stTrans.xX;
p_stDest->xY = MTH3D_M_xDotProductVector ( &stY , p_stSource ) + stTrans.xY;
p_stDest->xZ = MTH3D_M_xDotProductVector ( &stZ , p_stSource ) + stTrans.xZ;
}
}
/*
----------------------------------------------------------------------------------------
Description : new version of above function, parameters are in big structure
----------------------------------------------------------------------------------------
*/
void GLI_xNewSerialLinearOp ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_tdstAligned3DVector *p_stDest;
GLI_tdstAligned3DVector *p_stLastDest;
MTH3D_tdstVector *p_stSource ;
float fSwapValue;
MTH3D_tdstVector stX,stY,stZ,stTrans;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
POS_fn_vGetTransformMatrix ( &GLI_BG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, &stX, &stY, &stZ);
GLI_M_SWAP (stX.xY,stY.xX);
GLI_M_SWAP (stX.xZ,stZ.xX);
GLI_M_SWAP (stY.xZ,stZ.xY);
POS_fn_vGetTranslationVector( &GLI_BG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stTrans);
p_stDest = GLI_BG->GLI_TurnedScaledDisplecedPoint;
p_stSource = GLI_BG->p_stObj->d_stListOfPoints ;
p_stLastDest = p_stDest + GLI_BG->p_stObj->xNbPoints;
for ( ; p_stDest < p_stLastDest ; p_stDest++ , p_stSource++ )
{
p_stDest->xX = MTH3D_M_xDotProductVector( &stX, p_stSource ) + stTrans.xX;
p_stDest->xY = MTH3D_M_xDotProductVector( &stY, p_stSource ) + stTrans.xY;
p_stDest->xZ = MTH3D_M_xDotProductVector( &stZ, p_stSource ) + stTrans.xZ;
}
}
/*
----------------------------------------------------------------------------------------
Description : projection of 3D point that are in camera system axis
----------------------------------------------------------------------------------------
*/
void GLI_xNewSerialProjOp ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_tdstAligned3DVector *p_stDest;
GLI_tdstAligned3DVector *p_stLastDest;
GLI_tdstAligned2DVector *p_st2DDest;
float fScaleX,fScaleY;
long lNewX;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
*(float * )&lNewX = 8000.0f;
fScaleX = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xX ;
fScaleY = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xY ;
p_stDest = GLI_BG->GLI_TurnedScaledDisplecedPoint;
p_st2DDest = GLI_BG->GLI_ScreenPoint;
p_stLastDest = p_stDest + GLI_BG->p_stObj->xNbPoints;
if (GLI_BG -> lClippingModeMask & GLI_C_ClipMaskZ)
{
for ( ; p_stDest < p_stLastDest ; p_stDest ++ , p_st2DDest++ )
{
if ( *(long *)&p_stDest->xZ < *(long *)&GLI_BG->p_stCurrentCamera->xNear)
{
*(long *)&p_st2DDest -> xOoZ |= 0x80000000;
*((unsigned long *)&p_st2DDest->xX) = lNewX | ((*((unsigned long *)&p_stDest->xX) & 0x80000000) ^ 0x80000000);
*((unsigned long *)&p_st2DDest->xY) = lNewX | ((*((unsigned long *)&p_stDest->xY) & 0x80000000) ^ 0x80000000);
continue ;
}
p_st2DDest->xOoZ = MTH_M_xInvLow(p_stDest->xZ ) ;
p_st2DDest->xX = GLI_BG->p_stCurrentCamera->stTrans.xX + p_stDest->xX * fScaleX * p_st2DDest->xOoZ ;
p_st2DDest->xY = GLI_BG->p_stCurrentCamera->stTrans.xY + p_stDest->xY * fScaleY * p_st2DDest->xOoZ ;
p_st2DDest->xOoZ *= GLI_C_xZClippingNear;
}
}
else
{
for ( ; p_stDest < p_stLastDest ; p_stDest ++ , p_st2DDest++ )
{
p_st2DDest->xOoZ = MTH_M_xInvLow(p_stDest->xZ ) ;
p_st2DDest->xX = GLI_BG->p_stCurrentCamera->stTrans.xX + p_stDest->xX * fScaleX * p_st2DDest->xOoZ ;
p_st2DDest->xY = GLI_BG->p_stCurrentCamera->stTrans.xY + p_stDest->xY * fScaleY * p_st2DDest->xOoZ ;
p_st2DDest->xOoZ *= GLI_C_xZClippingNear;
}
}
}
/*
----------------------------------------------------------------------------------------
Description : turned and project object vertex to get 2D coords
----------------------------------------------------------------------------------------
*/
void GLI_xNewSerialLinearProjOpZClip ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_tdstAligned3DVector *p_stDest;
GLI_tdstAligned3DVector *p_stLastDest;
GLI_tdstAligned2DVector *p_st2DDest;
MTH3D_tdstVector *p_stSource ;
MTH3D_tdstVector stX, stY, stZ, stTrans;
float fSwapValue, fScaleX, fScaleY, fTmpZ;
long lNewX;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
*(float * )&lNewX = 8000.0f;
fScaleX = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xX;
fScaleY = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xY;
POS_fn_vGetTransformMatrix ( &GLI_BG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, &stX, &stY, &stZ);
GLI_M_SWAP (stX.xY,stY.xX);
GLI_M_SWAP (stX.xZ,stZ.xX);
GLI_M_SWAP (stY.xZ,stZ.xY);
POS_fn_vGetTranslationVector( &GLI_BG -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stTrans);
p_stDest = GLI_BG->GLI_TurnedScaledDisplecedPoint;
p_st2DDest = GLI_BG->GLI_ScreenPoint;
p_stSource = GLI_BG->p_stObj->d_stListOfPoints ;
p_stLastDest = p_stDest + GLI_BG->p_stObj->xNbPoints;
for ( ; p_stDest < p_stLastDest ; p_stDest ++ , p_stSource++ , p_st2DDest++ )
{
p_stDest->xX = MTH3D_M_xDotProductVector( &stX , p_stSource ) + stTrans.xX;
p_stDest->xY = MTH3D_M_xDotProductVector( &stY , p_stSource ) + stTrans.xY;
p_stDest->xZ = MTH3D_M_xDotProductVector( &stZ , p_stSource ) + stTrans.xZ;
if ( *(long *)&p_stDest->xZ < *(long *)&GLI_BG -> p_stCurrentCamera -> xNear)
{
/* point is before the near plane, so */
/* turn OoZ into negative value */
*(long *)&p_st2DDest -> xOoZ |= 0x80000000;
/* and put X and Y to +/- 8000.0f according to the sign of the 3dPoint coordinates*/
*((unsigned long *)&p_st2DDest ->xX) = lNewX | ((*((unsigned long *)&p_stDest->xX) & 0x80000000) ^ 0x80000000);
*((unsigned long *)&p_st2DDest ->xY) = lNewX | ((*((unsigned long *)&p_stDest->xY) & 0x80000000) ^ 0x80000000);
continue ;
}
fTmpZ = MTH_M_xInvLow(p_stDest->xZ);
p_st2DDest->xX = GLI_BG->p_stCurrentCamera->stTrans.xX + p_stDest->xX * fScaleX * fTmpZ;
p_st2DDest->xY = GLI_BG->p_stCurrentCamera->stTrans.xY + p_stDest->xY * fScaleY * fTmpZ;
p_st2DDest->xOoZ = fTmpZ * GLI_C_xZClippingNear;
}
}
/*
----------------------------------------------------------------------------------------
Description : turned and project object vertex to get 2D coords
apply sinus effect on 3D transformed vertices
----------------------------------------------------------------------------------------
*/
void GLI_xSerialLinearProjOpZClipWithEffect ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_tdstAligned3DVector *p_stDest;
GLI_tdstAligned3DVector *p_stLastDest;
GLI_tdstAligned2DVector *p_st2DDest;
MTH3D_tdstVector *p_stSource ;
MTH3D_tdstVector stX,stY,stZ,stTrans;
float fSwapValue,fScaleX,fScaleY, fTmpZ;
long lNewX;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
*(float * )&lNewX = 8000.0f;
fScaleX = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xX;
fScaleY = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xY;
POS_fn_vGetTransformMatrix ( &GLI_BG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, &stX, &stY, &stZ);
GLI_M_SWAP (stX.xY,stY.xX);
GLI_M_SWAP (stX.xZ,stZ.xX);
GLI_M_SWAP (stY.xZ,stZ.xY);
POS_fn_vGetTranslationVector( &GLI_BG -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stTrans);
p_stDest = GLI_BG->GLI_TurnedScaledDisplecedPoint;
p_st2DDest = GLI_BG->GLI_ScreenPoint;
p_stSource = GLI_BG->p_stObj->d_stListOfPoints ;
p_stLastDest = p_stDest + GLI_BG->p_stObj->xNbPoints;
for ( ; p_stDest < p_stLastDest ; p_stDest ++ , p_stSource++ , p_st2DDest++ )
{
p_stDest->xX = MTH3D_M_xDotProductVector( &stX , p_stSource ) + stTrans.xX;
p_stDest->xY = MTH3D_M_xDotProductVector( &stY , p_stSource ) + stTrans.xY;
p_stDest->xZ = MTH3D_M_xDotProductVector( &stZ , p_stSource ) + stTrans.xZ;
GLI_vSinusEffetOn3DVertex((MTH3D_tdstVector *)p_stDest) ;
if ( *(long *)&p_stDest->xZ < *(long *)&GLI_BG -> p_stCurrentCamera -> xNear)
{
*(long *)&p_st2DDest -> xOoZ |= 0x80000000;
*((unsigned long *)&p_st2DDest ->xX) = lNewX | ((*((unsigned long *)&p_stDest->xX) & 0x80000000) ^ 0x80000000);
*((unsigned long *)&p_st2DDest ->xY) = lNewX | ((*((unsigned long *)&p_stDest->xY) & 0x80000000) ^ 0x80000000);
continue ;
}
fTmpZ = MTH_M_xInvLow(p_stDest->xZ);
p_st2DDest->xX = GLI_BG->p_stCurrentCamera->stTrans.xX + p_stDest->xX * fScaleX * fTmpZ;
p_st2DDest->xY = GLI_BG->p_stCurrentCamera->stTrans.xY + p_stDest->xY * fScaleY * fTmpZ;
p_st2DDest->xOoZ = fTmpZ * GLI_C_xZClippingNear;
}
}
/*
----------------------------------------------------------------------------------------
Description : turned and project object vertex to get 2D coords
object is not Z clipped so do no test on Z
----------------------------------------------------------------------------------------
*/
void GLI_xNewSerialLinearProjOpNoZClip ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_tdstAligned3DVector *p_stDest;
GLI_tdstAligned3DVector *p_stLastDest;
GLI_tdstAligned2DVector *p_st2DDest;
MTH3D_tdstVector *p_stSource ;
MTH3D_tdstVector stX, stY, stZ, stTrans;
float fSwapValue, fScaleX, fScaleY, fTmpZ;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
fScaleX = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xX ;
fScaleY = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xY ;
POS_fn_vGetTransformMatrix ( &GLI_BG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stX , &stY , &stZ);
GLI_M_SWAP (stX.xY,stY.xX);
GLI_M_SWAP (stX.xZ,stZ.xX);
GLI_M_SWAP (stY.xZ,stZ.xY);
/* here, stX contains the first line of the matrix */
/* stY the second, and stz the third */
POS_fn_vGetTranslationVector( &GLI_BG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stTrans);
p_stDest = GLI_BG->GLI_TurnedScaledDisplecedPoint;
p_st2DDest = GLI_BG->GLI_ScreenPoint;
p_stSource = GLI_BG->p_stObj->d_stListOfPoints ;
p_stLastDest = p_stDest + GLI_BG->p_stObj->xNbPoints;
for ( ; p_stDest < p_stLastDest ; p_stDest ++ , p_stSource++ , p_st2DDest++ )
{
/* compute object's points in camera coordinates */
/* this is a faster version of the mullmatrixvertex*/
/* note that it uses the specially-computed stX, stY and stZ */
p_stDest->xZ = MTH3D_M_xDotProductVector( &stZ , p_stSource ) + stTrans.xZ;
p_stDest->xX = MTH3D_M_xDotProductVector( &stX , p_stSource ) + stTrans.xX;
p_stDest->xY = MTH3D_M_xDotProductVector( &stY , p_stSource ) + stTrans.xY;
/* and scale the coordinates to let them fit in the viewport, with perspective correction */
fTmpZ = MTH_M_xInvLow(p_stDest->xZ);
p_st2DDest->xX = GLI_BG->p_stCurrentCamera->stTrans.xX + p_stDest->xX * fScaleX * fTmpZ;
p_st2DDest->xY = GLI_BG->p_stCurrentCamera->stTrans.xY + p_stDest->xY * fScaleY * fTmpZ;
p_st2DDest->xOoZ = fTmpZ * GLI_C_xZClippingNear;
}
}
/*
----------------------------------------------------------------------------------------
Description : turned and project object vertex to get 2D coords
object is not Z clipped so do no test on Z
apply sinus effect on transformed vertices
----------------------------------------------------------------------------------------
*/
void GLI_xSerialLinearProjOpNoZClipWithEffect ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_tdstAligned3DVector *p_stDest;
GLI_tdstAligned3DVector *p_stLastDest;
GLI_tdstAligned2DVector *p_st2DDest;
MTH3D_tdstVector *p_stSource ;
MTH3D_tdstVector stX,stY,stZ,stTrans;
float fSwapValue,fScaleX,fScaleY, fTmpZ;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
fScaleX = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xX ;
fScaleY = GLI_BG->p_stCurrentCamera->xScreen * GLI_BG->p_stCurrentCamera->stScale.xY ;
POS_fn_vGetTransformMatrix ( &GLI_BG -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stX , &stY , &stZ);
GLI_M_SWAP (stX.xY,stY.xX);
GLI_M_SWAP (stX.xZ,stZ.xX);
GLI_M_SWAP (stY.xZ,stZ.xY);
POS_fn_vGetTranslationVector( &GLI_BG -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stTrans);
p_stDest = GLI_BG->GLI_TurnedScaledDisplecedPoint;
p_st2DDest = GLI_BG->GLI_ScreenPoint;
p_stSource = GLI_BG->p_stObj->d_stListOfPoints ;
p_stLastDest = p_stDest + GLI_BG -> p_stObj -> xNbPoints;
for ( ; p_stDest < p_stLastDest ; p_stDest ++ , p_stSource++ , p_st2DDest++ )
{
p_stDest->xZ = MTH3D_M_xDotProductVector ( &stZ , p_stSource ) + stTrans . xZ;
p_stDest->xX = MTH3D_M_xDotProductVector ( &stX , p_stSource ) + stTrans . xX;
p_stDest->xY = MTH3D_M_xDotProductVector ( &stY , p_stSource ) + stTrans . xY;
GLI_vSinusEffetOn3DVertex((MTH3D_tdstVector *)p_stDest) ;
fTmpZ = MTH_M_xInvLow(p_stDest->xZ);
p_st2DDest -> xX = GLI_BG->p_stCurrentCamera->stTrans.xX + p_stDest -> xX * fScaleX * fTmpZ;
p_st2DDest -> xY = GLI_BG->p_stCurrentCamera->stTrans.xY + p_stDest -> xY * fScaleY * fTmpZ;
p_st2DDest -> xOoZ = fTmpZ * GLI_BG->p_stCurrentCamera->xNear ;
}
}
#ifdef __cplusplus
} /*extern "C"*/
#endif