212 lines
7.9 KiB
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
|