/* 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