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

212 lines
7.9 KiB
C

/*
Tested with LINT
*/
#include"gli_st.h"
#include "GLI_Defn.h"
#include "light_st.h"
#include "PvObj_st.h"
#include "proj.h"
#include "camera.h"
tdstGlobalsProjection stProjGlobs;
#ifdef __cplusplus
extern "C"
{
#endif
/**********************************************************************************************/
/* Name: GLI_xSerialProjectionNoTrans 1.1 */
/* Goal: Perspective Project a list of 3d vertex with no translation - for sprites*/
/* Code: Elie Khoury / 1.0*/
/* Philippe Vimont / 1.1 -> ASSEMBLY CODE*/
/* Steve McCalla / 1.2 -> No Trans, no isometric cameras*/
/* OPTIMMIZED : */
/**********************************************************************************************/
void
GLI_xSerialProjectionNoTrans ( GLI_tdstCamera *p_stCam ,
long lNbOfVertex ,
GLI_tdstAligned3DVector *p_stSource ,
GLI_tdstAligned2DVector *p_stDest )
{
GLI_tdxValue xInterm ;
long lNewX;
GLI_tdstAligned2DVector *p_stDestLast;
p_stDestLast = p_stDest + lNbOfVertex;
*(float * )&lNewX = 8000.0f;
assert(p_stCam -> lCameraMode == GLI_C_lPersCamWithoutDistorsion
|| p_stCam -> lCameraMode == GLI_C_lPersCamWithDistorsion);
for ( ; p_stDest < p_stDestLast ; p_stSource++ ,p_stDest++)
{
if ( *(long *)&p_stSource->xZ < *(long *)&p_stCam -> xNear )
{
*(long *)&p_stDest -> xOoZ |= 0x80000000;
*((unsigned long *)&p_stDest->xX) = lNewX | ((*((unsigned long *)&p_stSource->xX) & 0x80000000) ^ 0x80000000);
*((unsigned long *)&p_stDest->xY) = lNewX | ((*((unsigned long *)&p_stSource->xY) & 0x80000000) ^ 0x80000000);
continue ;
}
p_stDest -> xOoZ = MTH_M_xInvLow((float)p_stSource -> xZ ) ;
xInterm = p_stCam -> xScreen * p_stDest -> xOoZ ;
p_stDest -> xOoZ *= GLI_C_xZClippingNear /*(float)p_stCam -> xNear*/ ;
p_stDest -> xX = p_stSource -> xX * p_stCam -> stScale . xX * xInterm ;
p_stDest -> xY = p_stSource -> xY * p_stCam -> stScale . xY * xInterm ;
}
return;
}
/**********************************************************************************************/
/* Name: GLI_xSerialProjection 1.1 */
/* Goal: Project a list of 3d vertex*/
/* Code: Elie Khoury / 1.0*/
/* Philippe Vimont / 1.1 -> ASSEMBLY CODE*/
/* OPTIMMIZED : */
/**********************************************************************************************/
void
GLI_xSerialProjection ( GLI_tdstCamera *p_stCam ,
long lNbOfVertex ,
GLI_tdstAligned3DVector *p_stSource ,
GLI_tdstAligned2DVector *p_stDest )
{
GLI_tdxValue xInterm ;
long lVertexIndex , lNewX;
GLI_tdstAligned2DVector *p_stDestLast;
p_stDestLast = p_stDest + lNbOfVertex;
*(float * )&lNewX = 8000.0f;
switch ( p_stCam -> lCameraMode )
{
case GLI_C_lPersCamWithDistorsion :
case GLI_C_lPersCamWithoutDistorsion :
for ( ; p_stDest < p_stDestLast ; p_stSource++ ,p_stDest++)
{
if ( *(long *)&p_stSource->xZ < *(long *)&p_stCam->xNear )
{
*(long *)&p_stDest -> xOoZ |= 0x80000000;
*((unsigned long *)&p_stDest->xX) = lNewX | ((*((unsigned long *)&p_stSource->xX) & 0x80000000) ^ 0x80000000);
*((unsigned long *)&p_stDest->xY) = lNewX | ((*((unsigned long *)&p_stSource->xY) & 0x80000000) ^ 0x80000000);
continue ;
}
p_stDest -> xOoZ = MTH_M_xInvLow((float)p_stSource -> xZ ) ;
xInterm = p_stCam -> xScreen * p_stDest -> xOoZ ;
p_stDest -> xOoZ *= GLI_C_xZClippingNear /*(float)p_stCam -> xNear*/ ;
p_stDest -> xX = p_stCam -> stTrans . xX + p_stSource -> xX * p_stCam -> stScale . xX * xInterm ;
p_stDest -> xY = p_stCam -> stTrans . xY + p_stSource -> xY * p_stCam -> stScale . xY * xInterm ;
} /* */
break ;
case GLI_C_lIsoCamWithDistorsion :
case GLI_C_lIsoCamWithoutDistorsion :
for ( lVertexIndex = 0 ; lVertexIndex < lNbOfVertex ; lVertexIndex ++ )
{
/**** NO PROJECTION IF THE POINT IS BEFORE NEAR PLAN ****/
if ( p_stSource[lVertexIndex].xZ < p_stCam -> xNear )
continue ;
p_stDest[lVertexIndex].xOoZ =1.0f;
p_stDest[lVertexIndex].xX =
MTH_M_xRealToFloat(
GLI_M_Add ( p_stCam -> stTrans . xX ,
GLI_M_Mul ( p_stSource[lVertexIndex] . xX ,
p_stCam -> stScale . xX ) ) ) ;
p_stDest[lVertexIndex].xY =
MTH_M_xRealToFloat(
GLI_M_Add ( p_stCam -> stTrans . xY ,
GLI_M_Mul ( p_stSource[lVertexIndex] . xY ,
p_stCam -> stScale . xY ) ) ) ;
}
break ;
}
return ;
}
/**********************************************************************************************/
/* Name: GLI_xProjection 1.0*/
/* Goal: Project a 3d vertex*/
/* Code: Elie Khoury / 1.0*/
/* OPTIMMIZED : unused*/
/**********************************************************************************************/
void
GLI_xProjection ( GLI_tdstCamera *p_stCam ,
MTH3D_tdstVector *p_stSource ,
GLI_tdst2DVertex *p_stDest )
{
float xInterm ;
switch ( p_stCam -> lCameraMode )
{
case GLI_C_lPersCamWithDistorsion :
case GLI_C_lPersCamWithoutDistorsion :
/**** NO PROJECTION IF THE POINT IS BEFORE NEAR PLAN ****/
if ( p_stSource -> xZ < p_stCam -> xNear )
return ;
p_stDest -> xOoZ = MTH_M_xInvLow((float) p_stSource -> xZ ) ;
xInterm = p_stCam -> xScreen * p_stDest -> xOoZ ;
p_stDest -> xOoZ *= GLI_C_xZClippingNear /*(float)p_stCam -> xNear*/ ;
p_stDest -> xX = p_stCam -> stTrans . xX + p_stSource -> xX * p_stCam -> stScale . xX * xInterm ;
p_stDest -> xY = p_stCam -> stTrans . xY + p_stSource -> xY * p_stCam -> stScale . xY * xInterm ;
break ;
case GLI_C_lIsoCamWithDistorsion :
case GLI_C_lIsoCamWithoutDistorsion :
/**** NO PROJECTION IF THE POINT IS BEFORE NEAR PLAN ****/
if ( p_stSource -> xZ < p_stCam -> xNear )
return ;
p_stDest -> xOoZ = 1.0f;
p_stDest -> xX
=
MTH_M_xRealToFloat(
GLI_M_Add ( p_stCam -> stTrans . xX ,
GLI_M_Mul ( p_stSource -> xX ,
p_stCam -> stScale . xX ) ) ) ;
p_stDest -> xY
=
MTH_M_xRealToFloat(
GLI_M_Add ( p_stCam -> stTrans . xY ,
GLI_M_Mul ( p_stSource -> xY ,
p_stCam -> stScale . xY ) ) ) ;
break ;
}
return ;
}
/**********************************************************************************************/
/* Name: GLI_vInit_Projections*/
/* Goal: Init a table for f(x) = 1/x;*/
/* Code: Philippe Vimont / 1.0*/
/* OPTIMMIZED : No*/
/**********************************************************************************************/
void
GLI_vInit_Projections()
{
ACP_tdxIndex xZcounter;
long *p_lZAdjust;
for (xZcounter = 0 ; xZcounter < 1024 ; xZcounter ++)
{
stProjGlobs.xOoXTable[xZcounter] =(1.0f) / ((float)( xZcounter +1024 ) * 1024.0f );
}
p_lZAdjust = (long *) stProjGlobs.xOoXTable;
for (xZcounter = 0 ; xZcounter < 1024 ; xZcounter++, p_lZAdjust++ )
{
*(p_lZAdjust) = *(p_lZAdjust) + 0x49800000;
}
}
#ifdef __cplusplus
}/* extern "C" */
#endif