/* ======================================================================================= Name : Object.c Author : Philippe Vimont Description : main function to draw object ======================================================================================= */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include #include #include "gli_st.h" #include "GLI_Defn.h" #include "polygon.h" #include "mater_st.h" #include "light_st.h" #include "PvObj_st.h" #include "material.h" #include "init_gli.h" #include "vpt3D.h" #include "matstack.h" #include "sprite.h" #include "watrplan.h" #include "proj.h" #include "linear.h" #include "light.h" #include "camera.h" #include "Object.h" #include "COL.h" #include "gmt.h" #include "texture.h" #include "PrCovert.h" #include "Pic.h" #include "PRF.h" #include "DLLInter.h" #include "GliBench.h" #include "GLI_Menu.h" /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #define GLI_GLOBAL_MATERIAL /* * Bench Data */ #ifdef GLI_BENCH tdstGliBench GLI_g_stBench; #endif /* * data for 3D computing */ GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BIG_GLOBALS; extern GLI_tdstLight *gs_aDEF_p_CurrentListOfLight[C_lMaxLightInViewport] ; extern long gs_CurrentNumberOfLightInViewport; #ifdef _DEBUG static GEO_tdstGeometricObject *p_stObjectSphereReference; static GEO_tdstGeometricObject *p_stObjectBoxReference; static GEO_tdstGeometricObject *p_stObjectConeReference; #endif static ISI_tdstColor *p_stRLIForNextObjectToDraw; /* * water plane */ extern long bWaterPlaneState; extern MTH3D_tdstVector stWaterPlaneNormale; extern MTH_tdxReal fWaterPlaneDistance; extern MTH_tdxReal GLI_gsfWaterPlaneFogStart ; extern GLI_tdstColor GLI_gsfWaterPlaneFogColor ; extern float GLI_g_xBrightness; ACP_tdxHandleOfMaterial gs_hDefaultMaterial; /*extern float GLI_v3DWaterPlaneEffectForOnePoint(MTH3D_tdstVector *p_Vertex3D , MTH3D_tdstVector *p_Vertex3DDst , POS_tdstCompletePosition *p_stCameraMatrix);*/ void GLI_xNewSerialProjOp ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG ); void GLI_xNewSerialLinearProjOpZClip ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG ); void GLI_xNewSerialLinearProjOpNoZClip ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG ); void GLI_xNewSerialLinearOp ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BIG ); extern POS_tdstCompletePosition *g_p_stCurrentInCamCoordsMatrix; void GLI_xSerialLinearProjOpZClipWithEffect ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG ); void GLI_xSerialLinearProjOpNoZClipWithEffect ( GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG ); void GLI_DoSinusEffetOnRLI ( GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters, long xStart, long lNumber); void GLI_vSerialComputeVertexColor2NoAlpha(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGP, ACP_tdxIndex xNumber) ; void GLI_vSerialComputeVertexColor2Alpha(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGP, ACP_tdxIndex xNumber) ; /*___________________________________________________________________________*/ #ifdef _DEBUG #define GLI_C_lCircleArcs 35 #define GLI_C_lCircleArcsAlpha ( 2.0*3.1415927 / ( (float)GLI_C_lCircleArcs - 1) ) #define GLI_C_lNbTrianglesInSphere (( GLI_C_lNbLongitudes * 2) + (GLI_C_lNbLongitudes) * 2 * (GLI_C_lNbLatitudes - 3)) #define GLI_C_lNbPointsInSphere ( GLI_C_lNbLongitudes * ( GLI_C_lNbLatitudes - 2) + 2 ) #define GLI_C_lNbLatitudes 8 #define GLI_C_lNbLongitudes 8 #define GLI_C_lNbConeEdges 6 #define GLI_M_SendElementSphere( _p_stGP_ , _xElement_ ) GLI_vSendElementSphere( _p_stGP_, _xElement_ ) #define GLI_M_SendElementAlignedBox( _p_stGP_ , _xElement_ ) GLI_vSendElementAlignedBox( _p_stGP_, _xElement_ ) #define GLI_M_SendElementCone( _p_stGP_ , _xElement_ ) GLI_vSendElementCone( _p_stGP_, _xElement_ ) void GLI_vSendElementSphere ( GLI_tdstInternalGlobalValuesFor3dEngine *_p_stGP, ACP_tdxIndex _xElement ); void GLI_vSendElementAlignedBox ( GLI_tdstInternalGlobalValuesFor3dEngine *_p_stGP, ACP_tdxIndex _xElement ); void GLI_vSendElementCone ( GLI_tdstInternalGlobalValuesFor3dEngine *_p_stGP, ACP_tdxIndex _xElement ); void GLI_vDrawBoxFull (GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stMin ,MTH3D_tdstVector *p_stMax ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters); void GLI_vDrawBox (GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stMin ,MTH3D_tdstVector *p_stMax ,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters ); void GLI_vDrawSphereFull (GLD_tdstViewportAttributes *p_stVpt ,MTH_tdxReal xRadius , MTH3D_tdstVector *p_stCenter ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters); void GLI_vDrawSphere (GLD_tdstViewportAttributes *p_stVpt ,MTH_tdxReal xRadius , MTH3D_tdstVector *p_stCenter ,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters ); void GLI_vDrawConeFull (GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stSource ,MTH3D_tdstVector *p_stVector ,MTH_tdxReal xRadius ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters); void GLI_vDrawCone (GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stSource ,MTH3D_tdstVector *p_stVector ,MTH_tdxReal xRadius ,long lDrawModeMask,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters ); /*___________________________________________________________________________*/ #else #define GLI_M_SendElementSphere( _p_stGP_ , _xElement_ ) #define GLI_M_SendElementAlignedBox( _p_stGP_ , _xElement_ ) #define GLI_M_SendElementCone( _p_stGP_ , _xElement_ ) #define GLI_vDrawBoxFull(a,b,c,d,e,f) #define GLI_vDrawBox(a,b,c,d); #define GLI_vDrawSphereFull(a,b,c,d,e,f) #define GLI_vDrawSphere(a,b,c,d); #define GLI_vDrawConeFull(a,b,c,d,e,f,g) #define GLI_vDrawCone(a,b,c,d,e,f); #endif #ifdef __cplusplus extern "C" { #endif #ifdef FRFFRFRrfss }}}}}}} #endif /**********************************************************************************************/ /* Name: Set & Get Globa Alphs*/ /* Goal: */ /* Code: Philippe Vimont */ /* OPTIMMIZED : No*/ /**********************************************************************************************/ void GLI_vSetGlobalAlpha(float Alpha) { GLI_BIG_GLOBALS->xGlobalAlpha = Alpha * (1.0f / 255.0f); if (GLI_BIG_GLOBALS->xGlobalAlpha > 1.0f) GLI_BIG_GLOBALS->xGlobalAlpha = 1.0f; if (GLI_BIG_GLOBALS->xGlobalAlpha < 0.0f) GLI_BIG_GLOBALS->xGlobalAlpha = 0.0f; } float GLI_vGetGlobalAlpha() { return (GLI_BIG_GLOBALS->xGlobalAlpha * 255.0f); } /* ---------------------------------------------------------------------------------------- Description : compute UV coordinates for chrome effect ---------------------------------------------------------------------------------------- */ void fn_vComputeChromeEffect( GLI_tdstInternalGlobalValuesFor3dEngine *p_stBG) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MTH3D_tdstVector *p_stLast, *p_stNormal; ACP_tdst2DUVValues *p_stUV; float *fCamMat; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* * get camera orientation in object system axis */ /* this method can be better with scaled object, but it's slowler POS_tdstCompletePosition stMatrix; POS_fn_vInvertIsoMatrix(&stMatrix,&p_stBG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix); fCamMat = (float *) &stMatrix.stTransformMatrix; */ fCamMat = (float *) &p_stBG->gs_st_CurrentMatrixMultiplyedWithCameraMatrix.stRotationMatrix; p_stNormal = p_stBG->p_stObj->d_stListOfPointsNormals; p_stLast = p_stNormal + p_stBG->p_stObj->xNbPoints; p_stUV = p_stBG->GLI_aDEF_stEnvUV; for ( ; p_stNormal < p_stLast; p_stNormal++, p_stUV++ ) { /* use this line in case we use inversed matrix p_stUV->xX = 0.5f * ( 1.0f + (fCamMat[0] * p_stNormal->xX + fCamMat[1] * p_stNormal->xY + fCamMat[2] * p_stNormal->xZ) ); p_stUV->xY = 0.5f * ( 1.0f - (fCamMat[3] * p_stNormal->xX + fCamMat[4] * p_stNormal->xY + fCamMat[5] * p_stNormal->xZ) ); */ p_stUV->xU = 0.5f * ( 1.0f + (fCamMat[0] * p_stNormal->xX + fCamMat[3] * p_stNormal->xY + fCamMat[6] * p_stNormal->xZ) ); p_stUV->xV = 0.5f * ( 1.0f - (fCamMat[1] * p_stNormal->xX + fCamMat[4] * p_stNormal->xY + fCamMat[7] * p_stNormal->xZ) ); } } /* ---------------------------------------------------------------------------------------- Description : GLI_vDoMaterialSelection ---------------------------------------------------------------------------------------- */ void GLI_vDoMaterialSelection(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ unsigned long ulColorinit; float fColorInit; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ if ((!(GLI_C_lIsNotForceDefaultMaterial & p_stGlobaleMT -> lHierachDrawMask)) || (p_stGlobaleMT -> hCurrentMaterial == NULL) ) p_stGlobaleMT -> hCurrentMaterial = gs_hDefaultMaterial; p_stGlobaleMT->lCurrentDrawMask = p_stGlobaleMT->hCurrentMaterial->xMaterialType & p_stGlobaleMT->lHierachDrawMask; GLI_xRefreshAnimatedTexture ( p_stGlobaleMT -> hCurrentMaterial ); p_stGlobaleMT->p_stCurrentTexture = p_stGlobaleMT->hCurrentMaterial->p_stTexture; GLI_DRV_vDoOpaqueTextureSelection( p_stGlobaleMT); /* * chrome effect */ if (!(p_stGlobaleMT->lCurrentDrawMask & GLI_C_lIsNotChromed)) { fn_vComputeChromeEffect( p_stGlobaleMT ); } if (p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsNotGrided) { ulColorinit = 0xffffffff; fColorInit = 1.0f; } else { /* STM - XGlobalAlpha == 1 devrait donner ulColorinit = 0xffffffff*/ /* sinon, c'est jamais une tres bonne idee de faire des compar. entre flottantes*/ if (p_stGlobaleMT->xGlobalAlpha == 1.0) { ulColorinit = 0xffffffff; fColorInit = 0.5f; } else { *(float *)&ulColorinit = p_stGlobaleMT->xGlobalAlpha + 32768.0f + 16384.0f; ulColorinit <<= 24; /* ulColorinit |= ulColorinit >> 8; ulColorinit |= ulColorinit >> 16; */ ulColorinit |= ((long) (p_stGlobaleMT->hCurrentMaterial->stAmbient.xR * 255) & 0xFF) << 16; ulColorinit |= ((long) (p_stGlobaleMT->hCurrentMaterial->stAmbient.xG * 255) & 0xFF) << 8; ulColorinit |= ((long) (p_stGlobaleMT->hCurrentMaterial->stAmbient.xB * 255) & 0xFF); fColorInit = p_stGlobaleMT->xGlobalAlpha * 0.5f; } } if ( (p_stGlobaleMT->p_stCurrentTexture) && (p_stGlobaleMT->p_stCurrentTexture->lTextureCaps & GLI_C_lAAATexture) ) { ulColorinit &= 0xFF000000; ulColorinit |= ((long) (p_stGlobaleMT->hCurrentMaterial->stAmbient.xR * 255) & 0xFF) << 16; ulColorinit |= ((long) (p_stGlobaleMT->hCurrentMaterial->stAmbient.xG * 255) & 0xFF) << 8; ulColorinit |= ((long) (p_stGlobaleMT->hCurrentMaterial->stAmbient.xB * 255) & 0xFF); } p_stGlobaleMT->ulColorInitForSprite = ulColorinit; p_stGlobaleMT->GLI_stColorsAdd = p_stGlobaleMT->hCurrentMaterial->stAmbient; p_stGlobaleMT->GLI_stColorsMul = p_stGlobaleMT->hCurrentMaterial->stDiffuse; p_stGlobaleMT->GLI_stColorsAdd.xR += p_stGlobaleMT->GLI_aDEF_stColorsRLIA.xR * p_stGlobaleMT->GLI_stColorsMul.xR; p_stGlobaleMT->GLI_stColorsAdd.xG += p_stGlobaleMT->GLI_aDEF_stColorsRLIA.xG * p_stGlobaleMT->GLI_stColorsMul.xG; p_stGlobaleMT->GLI_stColorsAdd.xB += p_stGlobaleMT->GLI_aDEF_stColorsRLIA.xB * p_stGlobaleMT->GLI_stColorsMul.xB; p_stGlobaleMT->GLI_stColorsAdd.xA += p_stGlobaleMT->GLI_aDEF_stColorsRLIA.xA * p_stGlobaleMT->GLI_stColorsMul.xA; if (p_stGlobaleMT->lCurrentDrawMask & GLI_C_lIsNotGrided) { p_stGlobaleMT->GLI_stColorsMul . xA = 0.0f; p_stGlobaleMT->GLI_stColorsAdd . xA = 1.0f; } else if (p_stGlobaleMT->lCurrentDrawMask & GLI_C_lIsNotLightAlphaSensitive) { p_stGlobaleMT->GLI_stColorsMul.xA = 0.0f; p_stGlobaleMT->GLI_stColorsAdd.xA = fColorInit; } #ifdef GLI_GLOBAL_MATERIAL if (p_stGlobaleMT -> p_stCurrentTexture != (GLI_tdstTexture *) 1) if ((p_stGlobaleMT -> p_stCurrentTexture) && (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & GLI_C_lAddTransparencyTexture) && (p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsNotLightAlphaSensitive)) { p_stGlobaleMT->GLI_stColorsMul.xR = 0.0f; p_stGlobaleMT->GLI_stColorsMul.xG = 0.0f; p_stGlobaleMT->GLI_stColorsMul.xB = 0.0f; p_stGlobaleMT->GLI_stColorsMul.xA = 0.0f; p_stGlobaleMT->GLI_stColorsAdd.xR = fColorInit; p_stGlobaleMT->GLI_stColorsAdd.xG = fColorInit; p_stGlobaleMT->GLI_stColorsAdd.xB = fColorInit; p_stGlobaleMT->GLI_stColorsAdd.xA = fColorInit; } #endif /* * Brightness */ { p_stGlobaleMT->GLI_stColorsAdd.xR += GLI_g_xBrightness - 0.5f; p_stGlobaleMT->GLI_stColorsAdd.xG += GLI_g_xBrightness - 0.5f; p_stGlobaleMT->GLI_stColorsAdd.xB += GLI_g_xBrightness - 0.5f; p_stGlobaleMT->GLI_stColorsMul.xR += GLI_g_xBrightness - 0.5f; p_stGlobaleMT->GLI_stColorsMul.xG += GLI_g_xBrightness - 0.5f; p_stGlobaleMT->GLI_stColorsMul.xB += GLI_g_xBrightness - 0.5f; } } /* ---------------------------------------------------------------------------------------- Description : Compute Clipping Mask ---------------------------------------------------------------------------------------- */ void GLI_ComputeClippingMask(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MTH3D_tdstVector stLocalCenter; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* get center of BV in world coordinates, and radius including scale */ POS_fn_vMulMatrixVertex( &p_stGlobaleMT->stCenterOfCurrentBoundingSphere, p_stGlobaleMT->gs_st_CurrentMatrix, &p_stGlobaleMT->p_stObj->xBoudingSphereCenter); p_stGlobaleMT->stRadiusOfCurrentBoundingSphere = p_stGlobaleMT->p_stObj->xBoudingSphereRadius * POS_fn_xGetMaxScale( p_stGlobaleMT->gs_st_CurrentMatrix ); p_stGlobaleMT->lClippingModeMask = 0; /* if no bounding volume on object, clip in every direction */ if (p_stGlobaleMT->stRadiusOfCurrentBoundingSphere == 0.0f) { p_stGlobaleMT->lClippingModeMask = GLI_C_ClipMaskZ | GLI_C_ClipMaskXMin | GLI_C_ClipMaskXMax | GLI_C_ClipMaskYMin | GLI_C_ClipMaskYMax ; return; } /* get center of BV in camera coordinates */ POS_fn_vMulMatrixVertex ( &stLocalCenter , &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &p_stGlobaleMT -> p_stObj -> xBoudingSphereCenter); /* clip Z if BV intersect near plane */ if (!( stLocalCenter.xZ - (p_stGlobaleMT -> stRadiusOfCurrentBoundingSphere ) > GLI_BIG_GLOBALS->p_stCurrentCamera->xNear ) ) p_stGlobaleMT -> lClippingModeMask |= GLI_C_ClipMaskZ; /* clip x,y if BV intersect camera planes */ if (!(MTH3D_M_xDotProductVector( &stLocalCenter, &p_stGlobaleMT -> p_stCurrentCamera -> stNormPlaneLeft) < p_stGlobaleMT -> p_stCurrentCamera -> xDistPlaneLeft - p_stGlobaleMT -> stRadiusOfCurrentBoundingSphere )) p_stGlobaleMT -> lClippingModeMask |= GLI_C_ClipMaskXMax ; if (!(MTH3D_M_xDotProductVector( &stLocalCenter, &p_stGlobaleMT -> p_stCurrentCamera -> stNormPlaneRight) < GLI_BIG_GLOBALS -> p_stCurrentCamera -> xDistPlaneRight - p_stGlobaleMT -> stRadiusOfCurrentBoundingSphere )) p_stGlobaleMT -> lClippingModeMask |= GLI_C_ClipMaskXMin ; if (!(MTH3D_M_xDotProductVector( &stLocalCenter, &p_stGlobaleMT -> p_stCurrentCamera -> stNormPlaneUp ) < GLI_BIG_GLOBALS -> p_stCurrentCamera -> xDistPlaneUp - p_stGlobaleMT -> stRadiusOfCurrentBoundingSphere )) p_stGlobaleMT -> lClippingModeMask |= GLI_C_ClipMaskYMin ; if (!(MTH3D_M_xDotProductVector( &stLocalCenter, &p_stGlobaleMT -> p_stCurrentCamera -> stNormPlaneDown ) < p_stGlobaleMT -> p_stCurrentCamera -> xDistPlaneDown - p_stGlobaleMT -> stRadiusOfCurrentBoundingSphere )) p_stGlobaleMT -> lClippingModeMask |= GLI_C_ClipMaskYMax ; } /**********************************************************************************************/ /* Name: GLI_vSetDefaultMaterial */ /* Goal : Set the material used when drawmask is marked as forcedefaultmaterial*/ /* Code: Philippe Vimont */ /* OPTIMMIZED : */ /**********************************************************************************************/ void GLI_vSetDefaultMaterial ( struct GLD_tdstViewportAttributes_ *p_stVpt ,ACP_tdxHandleOfMaterial hMaterial) { gs_hDefaultMaterial = hMaterial; } /**********************************************************************************************/ /* Name: GLI_xSendObjectToViewportWithLights */ /* Code: Philippe Vimont */ /* OPTIMMIZED : */ /**********************************************************************************************/ void GLI_xSendObjectToViewport ( struct GLD_tdstViewportAttributes_ *p_stVpt ,GEO_tdstGeometricObject *p_stObj ,GLI_tdstLight *p_stLight ,long lDrawModeMask) { GLI_tdstLight stLight; float fGlobalAlphaTemp; stLight.lTypeOfLight = GLI_C_lAmbientLight; stLight.b_lOnOff = 1; stLight.bValid = 1; stLight.stColor.xR = 0.0f; stLight.stColor.xG = 0.0f; stLight.stColor.xB = 0.02f; fGlobalAlphaTemp = GLI_vGetGlobalAlpha(); GLI_vSetGlobalAlpha( 255.0 ); GLI_vClearListOfLightInViewport (p_stVpt); GLI_vAddLightToViewport(p_stVpt , p_stLight ); GLI_vAddLightToViewport(p_stVpt , &stLight ); GLI_xSendObjectToViewportWithLights ( p_stVpt ,p_stObj ,lDrawModeMask); GLI_vSetGlobalAlpha( fGlobalAlphaTemp ); GLI_vClearListOfLightInViewport (p_stVpt); } /**********************************************************************************************/ /* Name: GLI_xSetRLIForNextObjectToDraw.*/ /* Code: Philippe Vimont */ /* OPTIMMIZED : */ /**********************************************************************************************/ void GLI_xSetRLIForNextObjectToDraw ( ISI_tdstColor *p_ListOfRLI,GEO_tdstGeometricObject *p_stObj) { p_stRLIForNextObjectToDraw = p_ListOfRLI; } /* ======================================================================================= ======================================================================================= DRAW OBJECT FUNCTION ======================================================================================= ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : draw a sprite element ---------------------------------------------------------------------------------------- */ static void GLI_fn_vSendElementSpriteToViewportWithLights(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParameters, ACP_tdxIndex xElementCounter) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GEO_tdstElementSprite *p_stLocalElementSprite; long lSpriteIndex; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ PRF_fn_vStartChrono( PRF_C_ulFctDisplaySprite , NULL); p_stLocalElementSprite = ((GEO_tdstElementSprite *) p_stGlobalsParameters -> p_stObj -> d_stListOfElements[xElementCounter]); for ( lSpriteIndex = 0 ; lSpriteIndex < p_stLocalElementSprite -> xNbSprites; lSpriteIndex ++) { GLI_vDrawIndexedSprite ( p_stGlobalsParameters -> p_stVpt , p_stGlobalsParameters -> p_stObj , &p_stLocalElementSprite -> d_stListOfSprites[lSpriteIndex], p_stGlobalsParameters); GLI_M_vAddDisplayedVisualMaterialForSprite( p_stLocalElementSprite ); } PRF_fn_vStopChrono( PRF_C_ulFctDisplaySprite, NULL); PRF_fn_vIncreaseVariable( PRF_C_ulVarFaces + PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvComputed, p_stLocalElementSprite->xNbSprites * 2 ); PRF_fn_vIncreaseVariable( PRF_C_ulVarElements + PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvComputed, 1 ); } /* ---------------------------------------------------------------------------------------- Description : draw an indexed triangle element ---------------------------------------------------------------------------------------- */ static void GLI_fn_vSendElementIndexedTriangleToViewportWithLights(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParameters, ACP_tdxIndex xElementCounter) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GEO_tdstElementIndexedTriangles *p_stEIT; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GEO_vGetMaterialOfIndexedTriangles (p_stGlobalsParameters -> p_stObj , xElementCounter,&p_stGlobalsParameters -> hCurrentMaterial); GLI_vDoMaterialSelection( p_stGlobalsParameters ); p_stEIT = (GEO_tdstElementIndexedTriangles *) (p_stGlobalsParameters -> p_stObj -> d_stListOfElements[xElementCounter]); if (p_stGlobalsParameters->lCurrentDrawMask & GLI_C_lIsNotLightAlphaSensitive) { if ( p_stEIT->d_stListOfIndexUsedByThisElement ) GLI_vSerialComputeVertexColorIndexedNoAlpha(p_stGlobalsParameters ,p_stEIT->xNumberOfIndexsUsed, p_stEIT->d_stListOfIndexUsedByThisElement); else GLI_vSerialComputeVertexColor2NoAlpha(p_stGlobalsParameters ,p_stGlobalsParameters->p_stObj->xNbPoints); } else { /* there is alpha*/ if ( p_stEIT->d_stListOfIndexUsedByThisElement ) GLI_vSerialComputeVertexColorIndexedAlpha(p_stGlobalsParameters ,p_stEIT->xNumberOfIndexsUsed, p_stEIT->d_stListOfIndexUsedByThisElement); else GLI_vSerialComputeVertexColor2Alpha(p_stGlobalsParameters ,p_stGlobalsParameters->p_stObj->xNbPoints); } GLI_DRV_xSendElementTIToClip_TRIANGLES((GEO_tdstElementIndexedTriangles *)p_stGlobalsParameters -> p_stObj -> d_stListOfElements[xElementCounter],p_stGlobalsParameters); PRF_fn_vIncreaseVariable( PRF_C_ulVarFaces + PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvComputed, p_stEIT->xNbFaces ); PRF_fn_vIncreaseVariable( PRF_C_ulVarElements + PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvComputed, 1 ); GLI_M_vAddDisplayedVisualMaterialForEltIndexedTriangle( p_stEIT ); } /* ---------------------------------------------------------------------------------------- Description : draw all object elements ---------------------------------------------------------------------------------------- */ void GLI_xSendObjectElement( GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ACP_tdxIndex xElementCounter; int iElementType; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* send all the elements*/ for (xElementCounter = 0 ;xElementCounter < p_stGlobalsParrameters -> p_stObj->xNbElements ;xElementCounter ++ ) { PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDisplayedFaces, 0 ); iElementType = p_stGlobalsParrameters->p_stObj->d_xListOfElementsTypes [xElementCounter]; if (iElementType == GEO_C_xElementIndexedTriangles) { GLI_fn_vSendElementIndexedTriangleToViewportWithLights(p_stGlobalsParrameters, xElementCounter); } else if (iElementType == GEO_C_xElementSprites) { GLI_fn_vSendElementSpriteToViewportWithLights(p_stGlobalsParrameters, xElementCounter); } #ifdef _DEBUG else { switch (iElementType) { case GEO_C_xElementNULL: case GEO_C_xElementPoints: case GEO_C_xElementLines: case GEO_C_xElementFaceMapDescriptors : case GEO_C_xElementTMeshes: break; case GEO_C_xElementSpheres: GLI_M_SendElementSphere( p_stGlobalsParrameters, xElementCounter ); break; case GEO_C_xElementAlignedBoxes: GLI_M_SendElementAlignedBox( p_stGlobalsParrameters, xElementCounter ); break; case GEO_C_xElementCones: GLI_M_SendElementCone(p_stGlobalsParrameters, xElementCounter ); break; } /* Element switch*/ } #endif #ifdef USE_PROFILER if( PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDisplayedFaces ) ) /* at least one face has been displayed*/ { PRF_fn_vIncreaseVariable( PRF_C_ulVarElements + PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvDisplayed, 1 ); /* update number of displayed objects*/ PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDisplayedElements, 1 ); } #endif /* USE_PROFILER */ } } /**********************************************************************************************/ /* Name: GLI_xSendObjectToViewportWithLightsMultiThreads*/ /* Goal: Call the thread which draw objects*/ /* Code: Philippe Vimont */ /* OPTIMMIZED : */ /* Modif 12/08/98 : keep the original matrix for lookAt - Carlos Torres*/ /**********************************************************************************************/ extern MTH3D_tdstVector stSinEffectAmp ; void GLI_xSendObjectToViewportWithLights ( GLD_tdstViewportAttributes *p_stVpt ,GEO_tdstGeometricObject *p_stObj ,long lDrawModeMask) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GLI_tdstSpecificAttributesFor3D *p_stSpecifAttrib3D; POS_tdstCompletePosition stPrevMatrix; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ if ( p_stObj -> xNbPoints > C_lMaxVertexPerObject ) return; /* * initialize global data */ lDrawModeMask |= GLI_C_lNotHideWhatIsUnderWater; p_stSpecifAttrib3D = ( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD; GLI_BIG_GLOBALS->p_stVpt = p_stVpt; GLI_BIG_GLOBALS->lHierachDrawMask = lDrawModeMask; GLI_BIG_GLOBALS->lClippingModeMask = 0; GLI_BIG_GLOBALS->p_stObj = p_stObj; GLI_BIG_GLOBALS->gs_st_CurrentMatrix = g_p_stCurrentMatrix; GLI_BIG_GLOBALS->gs_st_CameraMatrix = &p_stSpecifAttrib3D->p_stCam->stMatrix; GLI_BIG_GLOBALS->p_stCurrentCamera = p_stSpecifAttrib3D->p_stCam ; GLI_DRV_vSetZClip( GLI_BIG_GLOBALS->p_stCurrentCamera->xNear, GLI_BIG_GLOBALS); GLI_DRV_vSetClipWindow( (float)p_stVpt->dwClipLeftInPix, (float)p_stVpt->dwClipRightInPix, (float)p_stVpt->dwClipTopInPix, (float)p_stVpt->dwClipBottomInPix, GLI_BIG_GLOBALS ); /* * Special treatment for look at object : turn matrix to look at object */ if ( GEO_bIsLookAt (p_stObj) ) { stPrevMatrix = *g_p_stCurrentMatrix; GEO_vTurnLookAt (p_stObj, p_stVpt, g_p_stCurrentMatrix) ; POS_fn_vMulMatrixMatrix(&GLI_BIG_GLOBALS->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, &p_stSpecifAttrib3D->p_stCam->stMatrix, GLI_BIG_GLOBALS->gs_st_CurrentMatrix); } else { POS_fn_vCopyMatrix(&GLI_BIG_GLOBALS->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, g_p_stCurrentInCamCoordsMatrix); } /* * transformation of points to get it in 2D coords * there's 4 case : * sinus effect, Z clipping * sinus effect, no Z clipping * no sinus effect, Z clipping * no sinus effect, no Z clipping */ if ( ( (g_cSinusEffectState == 1) && ((lDrawModeMask & GLI_C_lHasNotSinusEffect) == 0) ) || ( (g_cSinusEffectState == 2) && (lDrawModeMask & GLI_C_lHasNotSinusEffect) ) || (g_cSinusEffectState == 3) ) { MTH_tdxReal xTmp ; xTmp = GLI_BIG_GLOBALS->p_stObj->xBoudingSphereRadius ; GLI_BIG_GLOBALS->p_stObj->xBoudingSphereRadius += 2 * ( stSinEffectAmp.xX + stSinEffectAmp.xY + stSinEffectAmp.xZ) ; GLI_ComputeClippingMask(GLI_BIG_GLOBALS); GLI_BIG_GLOBALS->p_stObj->xBoudingSphereRadius = xTmp ; if (GLI_BIG_GLOBALS->lClippingModeMask & GLI_C_ClipMaskZ) GLI_xSerialLinearProjOpZClipWithEffect (GLI_BIG_GLOBALS); else GLI_xSerialLinearProjOpNoZClipWithEffect (GLI_BIG_GLOBALS); } else { GLI_ComputeClippingMask(GLI_BIG_GLOBALS); if (GLI_BIG_GLOBALS->lClippingModeMask & GLI_C_ClipMaskZ) GLI_xNewSerialLinearProjOpZClip (GLI_BIG_GLOBALS); else GLI_xNewSerialLinearProjOpNoZClip (GLI_BIG_GLOBALS); } /* * initialize color on points * in case of RLI, we init color with RLI and do eventually sinus effect on them * else we set color to 0 */ if ( (p_stRLIForNextObjectToDraw != NULL) && (lDrawModeMask & GLI_C_lIsUseRLI) ) { /* translate ISI colors to GEO colors, and copy to the global structure */ GLI_vCopyRLI2ComputeBufferISI(GLI_BIG_GLOBALS, p_stRLIForNextObjectToDraw, 0, GLI_BIG_GLOBALS->p_stObj->xNbPoints); if ( !(lDrawModeMask & GLI_C_lIsNotSinusEffectOnRLI) || (g_cSinusEffectState == 3) ) GLI_DoSinusEffetOnRLI(GLI_BIG_GLOBALS, 0, GLI_BIG_GLOBALS->p_stObj->xNbPoints); p_stRLIForNextObjectToDraw = NULL; } else { long *pStart, *pEnd; pStart = (long *) GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLID; pEnd = pStart + (GLI_BIG_GLOBALS->p_stObj->xNbPoints << 2); while ( pStart < pEnd ) *pStart++ = 0; } /* * Compute lights effect on each point */ GLI_vSendObjectToLights ( gs_aDEF_p_CurrentListOfLight , GLI_BIG_GLOBALS->p_stObj , GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLID , GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLIS , &GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLIA , gs_CurrentNumberOfLightInViewport, GLI_BIG_GLOBALS ); /* * compute fog effect */ GLI_DRV_vComputeFogEffect( GLI_BIG_GLOBALS ); /* DETECT SHADOW FOR SORTING BUG*/ if (!(GLI_BIG_GLOBALS -> lHierachDrawMask & GLI_C_lNotForceZSorting)) { GLI_tdstAligned2DVector *pFirst , *pLast; pFirst = GLI_BIG_GLOBALS -> GLI_ScreenPoint ; pLast = pFirst + GLI_BIG_GLOBALS -> p_stObj->xNbPoints ; for ( ; pFirst < pLast ; pFirst++) pFirst -> xOoZ += 0.0001f; } /* DETECT MENU FOR SORTING BUG*/ if (GLI_BIG_GLOBALS->lDisplayMenuIsDetected) { GLI_tdstAligned2DVector *pFirst , *pLast; pFirst = GLI_BIG_GLOBALS -> GLI_ScreenPoint ; pLast = pFirst + GLI_BIG_GLOBALS -> p_stObj->xNbPoints ; for ( ; pFirst < pLast ; pFirst++) pFirst->xOoZ += 0.9f; } /* Draw IT*/ GLI_xSendObjectElement( GLI_BIG_GLOBALS ); /* * restore current matrix in case of look at object */ if ( GEO_bIsLookAt (p_stObj) ) { *g_p_stCurrentMatrix = stPrevMatrix; } } /* ======================================================================================= ======================================================================================= Only debug function (to display geometric element) (Editors and debug display) ======================================================================================= ======================================================================================= */ #ifdef _DEBUG /* ---------------------------------------------------------------------------------------- Description : Send an element sphere to viewport ---------------------------------------------------------------------------------------- */ void GLI_vSendElementSphere( GLI_tdstInternalGlobalValuesFor3dEngine *_p_stGP, ACP_tdxIndex _xElement ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GEO_tdstElementSpheres *p_stES; long lSphere; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ p_stES = (GEO_tdstElementSpheres*) _p_stGP->p_stObj->d_stListOfElements[ _xElement ]; if ((GLI_C_lIsNotDrawCollideInformation & _p_stGP->lHierachDrawMask) == 0) { for ( lSphere = 0; lSphere < p_stES->xNbSpheres; lSphere++ ) { GLI_vDrawSphereFull( _p_stGP-> p_stVpt , p_stES->d_stListOfSpheres[ lSphere ].xRadius, _p_stGP->p_stObj->d_stListOfPoints + p_stES->d_stListOfSpheres[ lSphere ].xCenterPoint, _p_stGP->lHierachDrawMask, _p_stGP->p_stObj->xNbPoints , _p_stGP ); } return; } if ( (GLI_C_lIsNotDrawCollideInformationLight & _p_stGP->lHierachDrawMask) == 0 ) { for ( lSphere = 0 ; lSphere < p_stES->xNbSpheres ; lSphere++ ) { if (_p_stGP->lCurrentDrawMask & GLI_C_lIsNotLightAlphaSensitive) GLI_vSerialComputeVertexColor2NoAlpha( _p_stGP, _p_stGP->p_stObj->xNbPoints); else /* there is alpha*/ GLI_vSerialComputeVertexColor2Alpha( _p_stGP, _p_stGP->p_stObj->xNbPoints); GLI_vDrawSphere( _p_stGP->p_stVpt , p_stES->d_stListOfSpheres[ lSphere ].xRadius, _p_stGP->p_stObj->d_stListOfPoints + p_stES->d_stListOfSpheres[ lSphere ].xCenterPoint, _p_stGP ); } } } /* ---------------------------------------------------------------------------------------- Description : Send an element aligned box to viewport (only use to display zone ) ---------------------------------------------------------------------------------------- */ void GLI_vSendElementAlignedBox( GLI_tdstInternalGlobalValuesFor3dEngine *_p_stGP, ACP_tdxIndex _xElement ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GEO_tdstElementAlignedBoxes *p_stEAB; long lBox; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ p_stEAB = ((GEO_tdstElementAlignedBoxes *) _p_stGP->p_stObj->d_stListOfElements[ _xElement ]); if ((GLI_C_lIsNotDrawCollideInformation & _p_stGP->lHierachDrawMask) == 0) { for ( lBox = 0 ; lBox< p_stEAB->xNbAlignedBoxes; lBox++ ) { GLI_vDrawBoxFull ( _p_stGP->p_stVpt , _p_stGP->p_stObj->d_stListOfPoints + p_stEAB->d_stListOfAlignedBoxes[lBox].xMinPoint, _p_stGP->p_stObj->d_stListOfPoints + p_stEAB->d_stListOfAlignedBoxes[lBox].xMaxPoint, _p_stGP->lHierachDrawMask , _p_stGP->p_stObj->xNbPoints , _p_stGP ); } return; } if ( (GLI_C_lIsNotDrawCollideInformationLight & _p_stGP->lHierachDrawMask) == 0 ) { for ( lBox = 0 ; lBox < p_stEAB->xNbAlignedBoxes; lBox++ ) { GLI_vDrawBox(_p_stGP->p_stVpt ,_p_stGP->p_stObj->d_stListOfPoints + p_stEAB->d_stListOfAlignedBoxes[ lBox ].xMinPoint,_p_stGP->p_stObj->d_stListOfPoints + p_stEAB->d_stListOfAlignedBoxes[ lBox ].xMaxPoint,_p_stGP ); } } } /* ---------------------------------------------------------------------------------------- Description : Send an element aligned box to viewport (only use to display zone ) ---------------------------------------------------------------------------------------- */ void GLI_vSendElementCone( GLI_tdstInternalGlobalValuesFor3dEngine *_p_stGP, ACP_tdxIndex _xElement ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GEO_tdstElementCones *p_stEC; long lCone; MTH3D_tdstVector stLocalConeCompute; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ p_stEC = ((GEO_tdstElementCones *) _p_stGP->p_stObj->d_stListOfElements[_xElement]); if ((GLI_C_lIsNotDrawCollideInformation & _p_stGP->lHierachDrawMask) == 0) { for ( lCone = 0; lCone < p_stEC -> xNbCones; lCone ++ ) { MTH3D_M_vSubVector( &stLocalConeCompute, _p_stGP->p_stObj->d_stListOfPoints + p_stEC->d_stListOfCones[lCone].xBasePoint, _p_stGP->p_stObj->d_stListOfPoints + p_stEC->d_stListOfCones[lCone].xTopPoint ); GLI_vDrawConeFull ( _p_stGP->p_stVpt , _p_stGP->p_stObj->d_stListOfPoints + p_stEC->d_stListOfCones[lCone].xTopPoint, &stLocalConeCompute, p_stEC->d_stListOfCones[lCone].xBaseRadius, _p_stGP->lHierachDrawMask, _p_stGP->p_stObj->xNbPoints, _p_stGP ); } return; } if ((GLI_C_lIsNotDrawCollideInformationLight & _p_stGP->lHierachDrawMask) == 0) { for( lCone= 0 ; lCone < p_stEC->xNbCones; lCone++ ) { MTH3D_M_vSubVector( &stLocalConeCompute, _p_stGP->p_stObj->d_stListOfPoints + p_stEC->d_stListOfCones[lCone].xBasePoint, _p_stGP->p_stObj->d_stListOfPoints + p_stEC->d_stListOfCones[lCone].xTopPoint ); GLI_vDrawCone ( _p_stGP->p_stVpt , _p_stGP->p_stObj->d_stListOfPoints + p_stEC->d_stListOfCones[ lCone ] . xTopPoint, &stLocalConeCompute, p_stEC-> d_stListOfCones[ lCone ] . xBaseRadius, _p_stGP->lHierachDrawMask , _p_stGP ); } } } /* ---------------------------------------------------------------------------------------- Description : Draw a sphere (wired) ---------------------------------------------------------------------------------------- */ void GLI_vDrawSphere(GLD_tdstViewportAttributes *p_stVpt ,MTH_tdxReal xRadius , MTH3D_tdstVector *p_stCenter ,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GLI_tdstSpecificAttributesFor3D *p_stSpecifAttrib3D; MTH3D_tdstVector aDEF_stVertex [GLI_C_lCircleArcs] ; GLI_tdstAligned3DVector aDEF_stVertexTrans [GLI_C_lCircleArcs] ; GLI_tdstAligned2DVector aDEF_st2DVertex [GLI_C_lCircleArcs] ; MTH3D_tdstVector stXVector, stYVector , stXVectorVar , stYVectorVar , stI , stJ , stK ; MTH_tdxReal xCosAlpha, xSinAlpha; MTH_tdxReal xX , xY ; static MTH_tdxReal xXS ; /* Why static? Else there is a strange bug with visual C++5.*/ ACP_tdxIndex xArcCounter ; POS_tdstCompletePosition stMatrix; GEO_tdstColor stColor; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ p_stSpecifAttrib3D = (GLI_tdstSpecificAttributesFor3D *) p_stGlobalsParrameters->p_stVpt -> p_vSpecificToXD; POS_fn_vGetRotationMatrix ( &p_stGlobalsParrameters->gs_st_CurrentMatrixMultiplyedWithCameraMatrix , &stI , &stJ , &stK); stXVector.xX = stI.xX; stXVector.xY = stJ.xX; stXVector.xZ = stK.xX; stYVector.xX = stI.xY; stYVector.xY = stJ.xY; stYVector.xZ = stK.xY; /* stXVectorVar <- circle center Position */ POS_fn_vSetIdentityMatrix ( &stMatrix ); POS_fn_vSetRotationMatrix ( &stMatrix , &stI , &stJ , &stK); POS_fn_vMulMatrixVertex ( &stXVectorVar , &p_stGlobalsParrameters->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, p_stCenter ); POS_fn_vInvertIsoMatrix ( &stMatrix, &stMatrix ); POS_fn_vMulMatrixVertex ( &stXVectorVar , &stMatrix, &stXVectorVar ); MTH3D_M_vCrossProductVector( &stXVector , &stYVector , &stXVectorVar ); MTH3D_M_vCrossProductVector( &stYVector , &stXVectorVar , &stXVector ); MTH3D_M_vNormalizeVector ( &stYVector , &stYVector ); MTH3D_M_vNormalizeVector ( &stXVector , &stXVector ); xXS = MTH3D_M_xNormVector( &stXVectorVar ); if ( xRadius < xXS ) xX = xRadius * xXS / MTH_M_xSqrt ( (xXS * xXS - xRadius * xRadius) ) ; else return ; xY = 0.0 ; xCosAlpha = MTH_M_xCos( GLI_C_lCircleArcsAlpha ); xSinAlpha = MTH_M_xSin( GLI_C_lCircleArcsAlpha ); /* Build a circle in front of camera */ for (xArcCounter = 0; xArcCounter < GLI_C_lCircleArcs ; xArcCounter ++) { MTH3D_M_vMulScalarVector ( &stXVectorVar , xX , &stXVector ); MTH3D_M_vMulScalarVector ( &stYVectorVar , xY , &stYVector ); MTH3D_M_vAddVector( (aDEF_stVertex + xArcCounter ) , &stXVectorVar , &stYVectorVar ); MTH3D_M_vAddVector( (aDEF_stVertex + xArcCounter ) , p_stCenter , (aDEF_stVertex + xArcCounter ) ); xXS = xX * xCosAlpha + xY * xSinAlpha; xY = -xX * xSinAlpha + xY * xCosAlpha; xX = xXS; } /* Transform vertices */ GLI_xSerialLinearOp( GLI_C_lCircleArcs, aDEF_stVertex, aDEF_stVertexTrans ,&p_stGlobalsParrameters -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix); GLI_xSerialProjection( p_stSpecifAttrib3D -> p_stCam, GLI_C_lCircleArcs, aDEF_stVertexTrans, aDEF_st2DVertex ) ; stColor.xR = 255.0f; stColor.xG = 255.0f; stColor.xB = 255.0f; /* Draw lines (unoptipmized)*/ for (xArcCounter = 0 ; xArcCounter < GLI_C_lCircleArcs - 1; xArcCounter ++ ) { GLI_DRV_vSendSingleLineToClip ( p_stVpt , aDEF_stVertexTrans + xArcCounter , aDEF_st2DVertex + xArcCounter , aDEF_stVertexTrans + 1 + xArcCounter , aDEF_st2DVertex + 1 + xArcCounter , p_stGlobalsParrameters, C_lBoldLineElement | GLI_C_lIsNotDoted, &stColor ); } } /* ---------------------------------------------------------------------------------------- Description : Draw a box (wired) ---------------------------------------------------------------------------------------- */ void GLI_vDrawBox(GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stMin ,MTH3D_tdstVector *p_stMax ,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters ) { GLI_tdstSpecificAttributesFor3D *p_stSpecifAttrib3D; MTH3D_tdstVector aDEF_stVertex [8] ; GLI_tdstAligned3DVector aDEF_stVertexTrans [8] ; GLI_tdstAligned2DVector aDEF_st2DVertex [8] ; ACP_tdxIndex xCounter ,xCounter2 ,xVertexDetector ; GEO_tdstColor stColor; p_stSpecifAttrib3D = (GLI_tdstSpecificAttributesFor3D *) p_stVpt -> p_vSpecificToXD; for (xCounter = 0 ; xCounter < 8 ; xCounter ++) { aDEF_stVertex[xCounter].xX = (xCounter & 1) ? p_stMin->xX : p_stMax->xX; aDEF_stVertex[xCounter].xY = (xCounter & 2) ? p_stMin->xY : p_stMax->xY; aDEF_stVertex[xCounter].xZ = (xCounter & 4) ? p_stMin->xZ : p_stMax->xZ; } GLI_xSerialLinearOp ( 8 , aDEF_stVertex , aDEF_stVertexTrans ,&p_stGlobalsParrameters -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix) ; GLI_xSerialProjection (p_stSpecifAttrib3D -> p_stCam ,8,aDEF_stVertexTrans,aDEF_st2DVertex); /*g_stCurLLInterface.p_fnSerialSnap2DVertices(aDEF_st2DVertex,8);*/ stColor.xR = stColor.xG = stColor.xB = 255.0f; /* Draw outline effect (unoptipmized)*/ for ( xCounter = 0; xCounter < 7; xCounter ++ ) { for (xCounter2 = xCounter + 1; xCounter2 < 8; xCounter2 ++ ) { xVertexDetector = 0; if (aDEF_stVertex[xCounter].xX == aDEF_stVertex[xCounter2].xX) xVertexDetector ++; if (aDEF_stVertex[xCounter].xY == aDEF_stVertex[xCounter2].xY) xVertexDetector ++; if (aDEF_stVertex[xCounter].xZ == aDEF_stVertex[xCounter2].xZ) xVertexDetector ++; if (xVertexDetector==2) { GLI_DRV_vSendSingleLineToClip ( p_stVpt , aDEF_stVertexTrans + xCounter , aDEF_st2DVertex + xCounter , aDEF_stVertexTrans + xCounter2 , aDEF_st2DVertex + xCounter2 , p_stGlobalsParrameters, C_lBoldLineElement | GLI_C_lIsNotDoted, &stColor ); } } } } /* ---------------------------------------------------------------------------------------- Description : Draw a cone (wired) ---------------------------------------------------------------------------------------- */ void GLI_vDrawCone(GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stSource ,MTH3D_tdstVector *p_stVector ,MTH_tdxReal xRadius ,long lDrawModeMask,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ GLI_tdstSpecificAttributesFor3D *p_stSpecifAttrib3D; MTH3D_tdstVector aDEF_stVertex[GLI_C_lCircleArcs+2] ; GLI_tdstAligned3DVector aDEF_stVertexTrans[GLI_C_lCircleArcs+2] ; GLI_tdstAligned2DVector aDEF_st2DVertex[GLI_C_lCircleArcs+2] ; MTH3D_tdstVector stXRef,stYRef,stXRefVar,stYRefVar,CZVect; MTH_tdxReal xLocalValue,xLocalValue2,xX,xY,xXS,xCosAlpha,xSinAlpha; ACP_tdxIndex xArcCounter ; GEO_tdstColor stColor; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ p_stSpecifAttrib3D = (GLI_tdstSpecificAttributesFor3D *) p_stVpt -> p_vSpecificToXD; MTH3D_M_vSetVectorElements( &CZVect, MTH_C_ZERO, MTH_C_ZERO, MTH_C_ONE ); MTH3D_M_vCrossProductVector( &stXRef , p_stVector , &CZVect); xLocalValue = MTH3D_M_xNormVector( &stXRef ); if (xLocalValue < 0.001f) { MTH3D_M_vSetVectorElements( &stYRef, MTH_C_ZERO, xRadius, MTH_C_ZERO ); MTH3D_M_vSetVectorElements( &stXRef, xRadius, MTH_C_ZERO, MTH_C_ZERO ); } else { xLocalValue = xRadius * MTH_M_xInv( xLocalValue ); MTH3D_M_vMulScalarVector( &stXRef , xLocalValue , &stXRef ); MTH3D_M_vCrossProductVector( &stYRef , p_stVector , &stXRef ); xLocalValue = MTH3D_M_xNormVector( &stYRef ); xLocalValue = xRadius * MTH_M_xInv( xLocalValue ); MTH3D_M_vMulScalarVector( &stYRef , xLocalValue , &stYRef ); } xCosAlpha = MTH_M_xCos( GLI_C_lCircleArcsAlpha ); xSinAlpha = MTH_M_xSin( GLI_C_lCircleArcsAlpha ); xX = 1.0f; xY = 0.0f; /* Build a circle (Top of the cone) */ for (xArcCounter = 0; xArcCounter < GLI_C_lCircleArcs ; xArcCounter ++) { MTH3D_M_vMulScalarVector ( &stXRefVar, xX, &stXRef ); MTH3D_M_vMulScalarVector ( &stYRefVar, xY, &stYRef ); MTH3D_M_vAddVector( &aDEF_stVertex [ xArcCounter ] , &stYRefVar , &stXRefVar ); MTH3D_M_vAddVector( &aDEF_stVertex [ xArcCounter ] , p_stVector , &aDEF_stVertex [ xArcCounter ] ); MTH3D_M_vAddVector( &aDEF_stVertex [ xArcCounter ] , p_stSource , &aDEF_stVertex [ xArcCounter ] ); xXS = xX * xCosAlpha + xY * xSinAlpha; xY = -xX * xSinAlpha + xY * xCosAlpha; xX = xXS; } aDEF_stVertex [ xArcCounter ] = *p_stSource ; MTH3D_M_vAddVector( &aDEF_stVertex [ xArcCounter + 1] , p_stSource , p_stVector ); GLI_xSerialLinearOp ( GLI_C_lCircleArcs + 2 , aDEF_stVertex , aDEF_stVertexTrans ,&p_stGlobalsParrameters -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix) ; GLI_xSerialProjection (p_stSpecifAttrib3D -> p_stCam ,GLI_C_lCircleArcs + 2 ,aDEF_stVertexTrans,aDEF_st2DVertex); stColor.xR = stColor.xG = stColor.xB = 255.0f; /* Draw lines (unoptipmized)*/ for (xArcCounter = 0 ; xArcCounter < GLI_C_lCircleArcs - 1 ; xArcCounter ++ ) { GLI_DRV_vSendSingleLineToClip ( p_stVpt , aDEF_stVertexTrans + xArcCounter , aDEF_st2DVertex + xArcCounter , aDEF_stVertexTrans + 1 + xArcCounter , aDEF_st2DVertex + 1 + xArcCounter , p_stGlobalsParrameters, C_lBoldLineElement | GLI_C_lIsNotDoted, &stColor ); } xArcCounter = 0 ; xLocalValue =(aDEF_st2DVertex[GLI_C_lCircleArcs].xX - aDEF_st2DVertex[xArcCounter].xX) * (aDEF_st2DVertex[xArcCounter].xY - aDEF_st2DVertex[xArcCounter+1].xY) - (aDEF_st2DVertex[GLI_C_lCircleArcs].xY - aDEF_st2DVertex[xArcCounter].xY) * (aDEF_st2DVertex[xArcCounter].xX - aDEF_st2DVertex[xArcCounter+1].xX); for (; xArcCounter < GLI_C_lCircleArcs - 1 ; xArcCounter ++ ) { xLocalValue2 =(aDEF_st2DVertex[GLI_C_lCircleArcs].xX - aDEF_st2DVertex[xArcCounter].xX) * (aDEF_st2DVertex[xArcCounter].xY - aDEF_st2DVertex[xArcCounter+1].xY) - (aDEF_st2DVertex[GLI_C_lCircleArcs].xY - aDEF_st2DVertex[xArcCounter].xY) * (aDEF_st2DVertex[xArcCounter].xX - aDEF_st2DVertex[xArcCounter+1].xX); if ((xLocalValue2 * xLocalValue) <= 0.f) { GLI_DRV_vSendSingleLineToClip ( p_stVpt , aDEF_stVertexTrans + xArcCounter , aDEF_st2DVertex + xArcCounter , aDEF_stVertexTrans + GLI_C_lCircleArcs , aDEF_st2DVertex + GLI_C_lCircleArcs , p_stGlobalsParrameters, C_lBoldLineElement | GLI_C_lIsNotDoted, &stColor ); } xLocalValue = xLocalValue2; } GLI_DRV_vSendSingleLineToClip ( p_stVpt , aDEF_stVertexTrans + GLI_C_lCircleArcs , aDEF_st2DVertex + GLI_C_lCircleArcs , aDEF_stVertexTrans + GLI_C_lCircleArcs +1, aDEF_st2DVertex + GLI_C_lCircleArcs +1, p_stGlobalsParrameters, C_lBoldLineElement | GLI_C_lIsNotDoted, &stColor ); } /* ---------------------------------------------------------------------------------------- Description : draw a 3D object reference (spher, box or cone) ---------------------------------------------------------------------------------------- */ void GLI_vDrawObjectFull(GLD_tdstViewportAttributes *p_stVpt ,GEO_tdstGeometricObject *p_stObj,MTH3D_tdstVector *p_stListOfPoints ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters) { MTH3D_tdstVector *p_stSaveListOfPoints; p_stSaveListOfPoints = p_stObj->d_stListOfPoints; p_stObj->d_stListOfPoints = p_stListOfPoints; GLI_xSendObjectToViewportWithLights ( p_stVpt ,p_stObj ,lDrawModeMask); p_stObj->d_stListOfPoints = p_stSaveListOfPoints; } /* ---------------------------------------------------------------------------------------- Description : draw sphere (gouraud, not wired) ---------------------------------------------------------------------------------------- */ void GLI_vDrawSphereFull(GLD_tdstViewportAttributes *p_stVpt ,MTH_tdxReal xRadius , MTH3D_tdstVector *p_stCenter ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MTH3D_tdstVector aDEF_xSpherePoints[GLI_C_lNbPointsInSphere]; ACP_tdxIndex xCounter; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* * compute vertices */ for (xCounter = 0;xCounter < GLI_C_lNbPointsInSphere;xCounter ++) { MTH3D_M_vMulScalarVector( (aDEF_xSpherePoints + xCounter),xRadius , p_stObjectSphereReference -> d_stListOfPoints + xCounter ); MTH3D_M_vAddVector( (aDEF_xSpherePoints + xCounter),(aDEF_xSpherePoints + xCounter),p_stCenter ); } /* * Set bouding volume */ p_stObjectSphereReference->xBoudingSphereRadius = xRadius; MTH3D_M_vCopyVector( &p_stObjectSphereReference->xBoudingSphereCenter, p_stCenter ); /* * Draw object */ GLI_vDrawObjectFull( p_stVpt, p_stObjectSphereReference, aDEF_xSpherePoints, lDrawModeMask, xBase, p_stGlobalsParrameters); } /* ---------------------------------------------------------------------------------------- Description : draw box (gouraud, not wired) ---------------------------------------------------------------------------------------- */ void GLI_vDrawBoxFull(GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stMin ,MTH3D_tdstVector *p_stMax ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MTH3D_tdstVector aDEF_xBoxPoints[8]; MTH3D_tdstVector xRotatRef; ACP_tdxIndex xCounter; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ for (xCounter = 0 ; xCounter < 8 ; xCounter ++ ) { xRotatRef .xX = (xCounter & 1) ? p_stMin -> xX : p_stMax -> xX; xRotatRef .xY = (xCounter & 2) ? p_stMin -> xY : p_stMax -> xY; xRotatRef .xZ = (xCounter & 4) ? p_stMin -> xZ : p_stMax -> xZ; aDEF_xBoxPoints[ xCounter ] = xRotatRef; } /* * Set bouding volume */ MTH3D_M_vSubVector( &p_stObjectBoxReference->xBoudingSphereCenter, p_stMax, p_stMin ); p_stObjectBoxReference->xBoudingSphereRadius = MTH3D_M_xNormVector( &p_stObjectBoxReference->xBoudingSphereCenter ) * MTH_C_Inv2; MTH3D_M_vMiddleVector( &p_stObjectBoxReference->xBoudingSphereCenter, p_stMin, p_stMax ); GLI_vDrawObjectFull( p_stVpt, p_stObjectBoxReference, aDEF_xBoxPoints, lDrawModeMask, xBase, p_stGlobalsParrameters); } /* ---------------------------------------------------------------------------------------- Description : draw cone (gouraud, not wired) ---------------------------------------------------------------------------------------- */ void GLI_vDrawConeFull(GLD_tdstViewportAttributes *p_stVpt ,MTH3D_tdstVector *p_stSource ,MTH3D_tdstVector *p_stVector ,MTH_tdxReal xRadius ,long lDrawModeMask ,ACP_tdxIndex xBase,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobalsParrameters) { MTH3D_tdstVector aDEF_xConePoints[GLI_C_lNbConeEdges + 1]; MTH3D_tdstVector st3dSinus,st3dCosinus,st3DX,st3DY,stAdd; MTH_tdxReal xNormeCos,xCosAlpha,xSinAlpha,xXrot,xYrot,xLocalSave; ACP_tdxIndex xCounter; MTH3D_tdstVector *p_stSaveListOfPoints; MTH3D_M_vSetVectorElements( &st3dCosinus, MTH_C_ZERO, MTH_C_ZERO, MTH_C_ONE ); MTH3D_M_vAddVector( &stAdd , p_stVector , p_stSource ); xXrot = 1.0f; xYrot = 0.0f; xCosAlpha = (p_stObjectConeReference -> d_stListOfPoints + 2) -> xX; xSinAlpha =-(p_stObjectConeReference -> d_stListOfPoints + 2) -> xY; aDEF_xConePoints[0] = *p_stSource ; MTH3D_M_vCrossProductVector(&st3dSinus, p_stVector , &st3dCosinus); xNormeCos = MTH3D_M_xNormVector( &st3dSinus ); if (xNormeCos < 0.001f) { MTH3D_M_vSetVectorElements( &st3dSinus, xRadius, MTH_C_ZERO, MTH_C_ZERO ); MTH3D_M_vSetVectorElements( &st3dCosinus, MTH_C_ZERO, xRadius, MTH_C_ZERO ); } else { xNormeCos = xRadius * MTH_M_xInv( xNormeCos ); MTH3D_M_vMulScalarVector( &st3dSinus , xNormeCos , &st3dSinus ); MTH3D_M_vCrossProductVector(&st3dCosinus , p_stVector , &st3dSinus ); MTH3D_M_vNormalizeVector( &st3dCosinus , &st3dCosinus ); MTH3D_M_vMulScalarVector( &st3dCosinus , xRadius , &st3dCosinus ); } for ( xCounter = 0 ; xCounter < GLI_C_lNbConeEdges ; xCounter ++) { xLocalSave = xXrot ; xXrot = xCosAlpha * xLocalSave + xSinAlpha * xYrot ; xYrot =-xSinAlpha * xLocalSave + xCosAlpha * xYrot ; MTH3D_M_vMulScalarVector( &st3DX , xXrot , &st3dSinus ) ; MTH3D_M_vMulScalarVector( &st3DY , xYrot , &st3dCosinus ) ; MTH3D_M_vAddVector(&st3DX ,&st3DX ,&st3DY ); MTH3D_M_vAddVector((aDEF_xConePoints + xCounter + 1),&st3DX ,&stAdd); } /* * compute bounding volume */ p_stSaveListOfPoints = p_stObjectConeReference->d_stListOfPoints; p_stObjectConeReference->d_stListOfPoints = aDEF_xConePoints; p_stObjectConeReference->xBoudingSphereCenter = *(p_stObjectConeReference->d_stListOfPoints); p_stObjectConeReference->xBoudingSphereRadius = 0.0f; GEO_fn_vAddObjectToSphere( p_stObjectConeReference , &p_stObjectConeReference->xBoudingSphereCenter , &p_stObjectConeReference->xBoudingSphereRadius ); p_stObjectConeReference->d_stListOfPoints = p_stSaveListOfPoints; GLI_vDrawObjectFull( p_stVpt, p_stObjectConeReference, aDEF_xConePoints , lDrawModeMask, xBase, p_stGlobalsParrameters ); } #endif /* ---------------------------------------------------------------------------------------- Description : Create geometric 3D object reference (sphere, box and cone) ---------------------------------------------------------------------------------------- */ void GLI_vCreateObjectsReference() { #ifdef _DEBUG /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MTH_tdxReal xCosAlpha,xSinAlpha,xAlphaLatitude,xAlphaLongitude; ACP_tdxIndex xCounter1,xCounter2,xTriangleToCreate,xCounter2P1,xA,xB,xC; ACP_tdxHandleOfElement hElement; MTH3D_tdstVector aDEF_stProfile[GLI_C_lNbLatitudes]; MTH3D_tdstVector xRotatRef; MTH_tdxReal xLocalSave; GEO_tdstColor stColor ; ACP_tdxHandleOfMaterial hMaterial; GMT_tdxHandleToGameMaterial hGameMaterial; ACP_tdst2DUVValues stUV; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* * Create Sphere */ xTriangleToCreate = 0; stUV.xU = stUV.xV = 0.0f; GEO_vCreateGeometricObject (&p_stObjectSphereReference, GLI_C_lNbPointsInSphere, 1); xAlphaLatitude = MTH_C_Pi / (GLI_C_lNbLatitudes - 1); xCosAlpha = MTH_M_xCos( xAlphaLatitude ); xSinAlpha = MTH_M_xSin( xAlphaLatitude ); MTH3D_M_vSetVectorElements( &xRotatRef, MTH_C_ZERO, MTH_C_ZERO, MTH_C_MinusONE ); GEO_vSetPointOfObject ( p_stObjectSphereReference, &xRotatRef , 1 ); xRotatRef.xZ = MTH_C_ONE; GEO_vSetPointOfObject ( p_stObjectSphereReference, &xRotatRef , 0 ); for (xCounter1 = 0 ; xCounter1 < GLI_C_lNbLatitudes-2 ; xCounter1 ++ ) { xLocalSave = xRotatRef.xY ; xRotatRef.xY = xLocalSave * xCosAlpha + xRotatRef.xZ * xSinAlpha; xRotatRef.xZ = -xLocalSave * xSinAlpha + xRotatRef.xZ * xCosAlpha; aDEF_stProfile[ xCounter1 ] = xRotatRef ; GEO_vSetPointOfObject ( p_stObjectSphereReference, &xRotatRef , (ACP_tdxIndex)(xCounter1 + 2) ); } xAlphaLongitude = MTH_C_2Pi / (GLI_C_lNbLongitudes); xCosAlpha = MTH_M_xCos( xAlphaLongitude ); xSinAlpha = MTH_M_xSin( xAlphaLongitude ); for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbLongitudes-1 ; xCounter2 ++ ) { for (xCounter1 = 0 ; xCounter1 < GLI_C_lNbLatitudes-2 ; xCounter1 ++ ) { xRotatRef = aDEF_stProfile [ xCounter1 ] ; xLocalSave = xRotatRef . xY ; xRotatRef . xY = xLocalSave * xCosAlpha + xRotatRef . xX * xSinAlpha; xRotatRef . xX = -xLocalSave * xSinAlpha + xRotatRef . xX * xCosAlpha; aDEF_stProfile [ xCounter1 ] = xRotatRef ; GEO_vSetPointOfObject ( p_stObjectSphereReference, &xRotatRef , (ACP_tdxIndex)(xCounter1 + 2 + ((xCounter2+1) * (GLI_C_lNbLatitudes-2)) )); } } for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbPointsInSphere; xCounter2 ++ ) { GEO_vGetPointOfObject ( p_stObjectSphereReference, &xRotatRef , xCounter2 ); stColor.xR = MTH_M_xRealToFloat( (xRotatRef.xX + 1.0f )/ 2.0f); stColor.xG = MTH_M_xRealToFloat( (xRotatRef.xY + 1.0f )/ 2.0f); stColor.xB = MTH_M_xRealToFloat( (xRotatRef.xZ + 1.0f )/ 2.0f); stColor . xA = 0.5; GEO_vSetPointReceivedLightIntensityOfObject( p_stObjectSphereReference, &stColor , xCounter2 ); } GEO_vCreateElementIndexedTriangles ( p_stObjectSphereReference, &hElement ,GLI_C_lNbTrianglesInSphere, 1); GEO_vSetUVOfIndexedTriangles (p_stObjectSphereReference, hElement , 0, &stUV); GLI_xCreateMaterial ( &hMaterial ); hGameMaterial = GMT_fn_hCreateGameMaterial(); GMT_fn_vSetVisualMaterial(hGameMaterial,hMaterial); GLI_xSetMaterialType( hMaterial , C_lGouraudElement - GLI_C_lIsNotGrided - GLI_C_lIsNotOutlined ); stColor.xR = stColor.xG = stColor.xB = 1.0f ; GLI_xSetMaterialDiffuseCoef ( hMaterial,&stColor ); GLI_xSetMaterialColor ( hMaterial,&stColor ); stColor.xR = stColor.xG = stColor.xB = 0.0f ; GLI_xSetMaterialAmbientCoef ( hMaterial,&stColor ); GEO_vSetGameMaterialOfIndexedTriangles ( p_stObjectSphereReference, hElement ,hGameMaterial); for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbTrianglesInSphere; xCounter2 ++ ) { GEO_vSetIndexedUVOfFaceOfIndexedTriangles ( p_stObjectSphereReference, hElement ,xCounter2,0,0,0); GEO_vSetFaceOfIndexedTriangles ( p_stObjectSphereReference, hElement ,xCounter2,0,0,0); } for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbLongitudes ; xCounter2 ++ ) { xCounter2P1 = (xCounter2 + 1) % (GLI_C_lNbLongitudes); GEO_vSetFaceOfIndexedTriangles (p_stObjectSphereReference, hElement ,xTriangleToCreate ++, 0, (ACP_tdxIndex)(xCounter2 * ( GLI_C_lNbLatitudes - 2) + 2), (ACP_tdxIndex)(xCounter2P1 * ( GLI_C_lNbLatitudes - 2) + 2 )); for (xCounter1 = 0 ; xCounter1 < ( GLI_C_lNbLatitudes - 3) ; xCounter1 ++ ) { GEO_vSetFaceOfIndexedTriangles ( p_stObjectSphereReference, hElement , xTriangleToCreate ++, (ACP_tdxIndex)(xCounter2 * ( GLI_C_lNbLatitudes - 2) + 2 + xCounter1 + 1), (ACP_tdxIndex)(xCounter2P1 * ( GLI_C_lNbLatitudes - 2) + 2 + xCounter1 ), (ACP_tdxIndex)(xCounter2 * ( GLI_C_lNbLatitudes - 2) + 2 + xCounter1 ) ); GEO_vSetFaceOfIndexedTriangles ( p_stObjectSphereReference, hElement , xTriangleToCreate ++, (ACP_tdxIndex)(xCounter2P1 * ( GLI_C_lNbLatitudes - 2) + 2 + xCounter1 ), (ACP_tdxIndex)(xCounter2 * ( GLI_C_lNbLatitudes - 2) + 2 + xCounter1 + 1), (ACP_tdxIndex)(xCounter2P1 * ( GLI_C_lNbLatitudes - 2) + 2 + xCounter1 + 1) ); } GEO_vSetFaceOfIndexedTriangles ( p_stObjectSphereReference, hElement , xTriangleToCreate ++, 1, (ACP_tdxIndex)(xCounter2P1 * ( GLI_C_lNbLatitudes - 2) + GLI_C_lNbLatitudes - 1 ), (ACP_tdxIndex)(xCounter2 * ( GLI_C_lNbLatitudes - 2) + GLI_C_lNbLatitudes - 1 ) ); } for (xCounter1 = 0 ; xCounter1 < GLI_C_lNbTrianglesInSphere ; xCounter1 ++ ) { GEO_vGetFaceOfIndexedTriangles (p_stObjectSphereReference,hElement ,xCounter1 ,&xA,&xB,&xC); } GEO_vEndModifyObject(p_stObjectSphereReference); GLI_xSetMaterialTexture ( hMaterial , NULL); /* * Create Box */ GEO_vCreateGeometricObject (&p_stObjectBoxReference,8,2); for (xCounter1 = 0 ; xCounter1 < 8 ; xCounter1 ++ ) { xRotatRef.xX = (xCounter1 & 1) ? MTH_C_ZERO : MTH_C_ONE; xRotatRef.xY = (xCounter1 & 2) ? MTH_C_ZERO : MTH_C_ONE; xRotatRef.xZ = (xCounter1 & 4) ? MTH_C_ZERO : MTH_C_ONE; GEO_vSetPointOfObject ( p_stObjectBoxReference, &xRotatRef , xCounter1 ); stColor.xR = MTH_M_xRealToFloat( xRotatRef.xX ); stColor.xG = MTH_M_xRealToFloat( xRotatRef.xY ); stColor.xB = MTH_M_xRealToFloat( xRotatRef.xZ ); GEO_vSetPointReceivedLightIntensityOfObject ( p_stObjectBoxReference, &stColor , xCounter1 ); } GEO_vCreateElementIndexedTriangles ( p_stObjectBoxReference,&hElement ,12,1); GEO_vSetGameMaterialOfIndexedTriangles ( p_stObjectBoxReference, hElement ,hGameMaterial); GEO_vSetUVOfIndexedTriangles (p_stObjectBoxReference , hElement , 0, &stUV); for (xCounter1 = 0 ; xCounter1 < 12 ; xCounter1 ++ ) { GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xCounter1 ,0,0,0); GEO_vSetIndexedUVOfFaceOfIndexedTriangles ( p_stObjectBoxReference, hElement ,xCounter1,0,0,0); } xTriangleToCreate = 0; GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,4,6,7); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,4,7,5); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,0,3,2); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,0,1,3); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,0,4,5); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,0,5,1); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,1,5,7); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,1,7,3); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,2,7,6); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,2,3,7); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,0,2,6); GEO_vSetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xTriangleToCreate ++,0,6,4); for (xCounter1 = 0 ; xCounter1 < 12 ; xCounter1 ++ ) { GEO_vGetFaceOfIndexedTriangles (p_stObjectBoxReference,hElement ,xCounter1 ,&xA,&xB,&xC); } GEO_vEndModifyObject(p_stObjectBoxReference); /* * Create Cone */ GEO_vCreateGeometricObject (&p_stObjectConeReference, GLI_C_lNbConeEdges + 1, 2); xAlphaLatitude = MTH_C_2Pi / (GLI_C_lNbConeEdges); xCosAlpha = MTH_M_xCos( xAlphaLatitude ); xSinAlpha = MTH_M_xSin( xAlphaLatitude ); MTH3D_M_vNullVector( &xRotatRef ); GEO_vSetPointOfObject( p_stObjectConeReference, &xRotatRef , 0 ); MTH3D_M_vSetVectorElements( &xRotatRef, MTH_C_ONE, MTH_C_ZERO, MTH_C_ONE ); for (xCounter1 = 0 ; xCounter1 < GLI_C_lNbConeEdges ; xCounter1 ++ ) { GEO_vSetPointOfObject ( p_stObjectConeReference, &xRotatRef , (ACP_tdxIndex)(xCounter1 + 1 )); xLocalSave = xRotatRef . xY ; xRotatRef . xY = xLocalSave * xCosAlpha + xRotatRef . xX * xSinAlpha; xRotatRef . xX = -xLocalSave * xSinAlpha + xRotatRef . xX * xCosAlpha; } stColor.xR = stColor.xG = stColor.xB = 1.0f ; GEO_vSetPointReceivedLightIntensityOfObject ( p_stObjectConeReference, &stColor , 0); for (xCounter2 = 1 ; xCounter2 < GLI_C_lNbConeEdges + 1; xCounter2 ++ ) { GEO_vGetPointOfObject ( p_stObjectConeReference, &xRotatRef , xCounter2 ); stColor.xR = MTH_M_xRealToFloat( (xRotatRef . xX + 1.0f )/ 2.0f); stColor.xG = MTH_M_xRealToFloat( (xRotatRef . xY + 1.0f )/ 2.0f); stColor.xB = MTH_M_xRealToFloat( 1.0f ); GEO_vSetPointReceivedLightIntensityOfObject( p_stObjectConeReference, &stColor , xCounter2 ); } GEO_vCreateElementIndexedTriangles ( p_stObjectConeReference,&hElement ,GLI_C_lNbConeEdges*2 - 2 ,1); GEO_vSetUVOfIndexedTriangles (p_stObjectConeReference, hElement , 0, &stUV); GLI_xSetMaterialType( hMaterial , C_lGouraudElement - GLI_C_lIsNotGrided - GLI_C_lIsNotOutlined ); GEO_vSetGameMaterialOfIndexedTriangles ( p_stObjectConeReference, hElement ,hGameMaterial); for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbConeEdges*2 - 2; xCounter2 ++ ) { GEO_vSetIndexedUVOfFaceOfIndexedTriangles ( p_stObjectConeReference, hElement ,xCounter2,0,0,0); GEO_vSetFaceOfIndexedTriangles ( p_stObjectConeReference, hElement ,xCounter2,0,0,0); } xTriangleToCreate = 0; for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbConeEdges ; xCounter2 ++ ) { xCounter2P1 = (xCounter2 + 1) % (GLI_C_lNbConeEdges); GEO_vSetFaceOfIndexedTriangles (p_stObjectConeReference, hElement , xTriangleToCreate ++, (ACP_tdxIndex)(xCounter2 + 1), 0, (ACP_tdxIndex)(xCounter2P1 + 1)); } for (xCounter2 = 0 ; xCounter2 < GLI_C_lNbConeEdges - 2; xCounter2 ++ ) { xCounter2P1 = (xCounter2 + 2) % (GLI_C_lNbConeEdges ); GEO_vSetFaceOfIndexedTriangles (p_stObjectConeReference, hElement , xTriangleToCreate ++, (ACP_tdxIndex)(xCounter2 + 2), (ACP_tdxIndex)(xCounter2P1 + 1), 1); } for (xCounter1 = 0 ; xCounter1 < GLI_C_lNbConeEdges*2 - 2 ; xCounter1 ++ ) { GEO_vGetFaceOfIndexedTriangles (p_stObjectConeReference,hElement ,xCounter1 ,&xA,&xB,&xC); } GEO_vEndModifyObject(p_stObjectConeReference); GLI_xSetMaterialTexture ( hMaterial , NULL); #endif } /* ---------------------------------------------------------------------------------------- Description : pick sprites ---------------------------------------------------------------------------------------- */ long GLI_lPickSprites ( GLD_tdstViewportAttributes *p_stVpt ,GEO_tdstGeometricObject *p_stObj ,MTH2D_tdstVector *p_stMouseCoords,ACP_tdxIndex xNbMaxElements,ACP_tdxIndex *p_xNbElements,GLI_tdstDataOfElement *d_stDataOfElement,MTH3D_tdstVector *p_stVertexA,ACP_tdxBool bBack) { #ifdef _DEBUG /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ACP_tdxIndex lTriangleIndex ; long lReturnValue; GLI_tdstSpecificAttributesFor3D *p_stSpecifAttrib3D; GEO_tdstElementSprite *p_stLocalElementSprite; ACP_tdxIndex xElementCounter; POS_tdstCompletePosition *p_stFatherMatrix; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ lReturnValue = 0; p_stSpecifAttrib3D = ( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD; p_stFatherMatrix=g_p_stCurrentMatrix; GLI_BIG_GLOBALS -> p_stVpt = p_stVpt; GLI_BIG_GLOBALS -> p_stObj = p_stObj; GLI_BIG_GLOBALS -> gs_st_CurrentMatrix = g_p_stCurrentMatrix; GLI_BIG_GLOBALS -> gs_st_CameraMatrix = &p_stSpecifAttrib3D->p_stCam->stMatrix; GLI_BIG_GLOBALS -> stRadiusOfCurrentBoundingSphere = 0.0f; POS_fn_vMulMatrixMatrix( &GLI_BIG_GLOBALS->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, GLI_BIG_GLOBALS->gs_st_CameraMatrix, GLI_BIG_GLOBALS -> gs_st_CurrentMatrix); /* Turn the object*/ if (GLI_BIG_GLOBALS->lClippingModeMask & GLI_C_ClipMaskZ) GLI_xNewSerialLinearProjOpZClip (GLI_BIG_GLOBALS); else GLI_xNewSerialLinearProjOpNoZClip (GLI_BIG_GLOBALS); for (xElementCounter = 0 ; xElementCounter < p_stObj->xNbElements ; xElementCounter ++ ) switch (p_stObj -> d_xListOfElementsTypes [xElementCounter] ) { default:break; case GEO_C_xElementSprites: p_stLocalElementSprite = ((GEO_tdstElementSprite *) p_stObj -> d_stListOfElements[xElementCounter]); for ( lTriangleIndex = 0 ;lTriangleIndex < p_stLocalElementSprite -> xNbSprites; lTriangleIndex ++) if(GLI_vPickIndexedSprite ( p_stVpt ,p_stObj ,&p_stLocalElementSprite -> d_stListOfSprites[lTriangleIndex],p_stMouseCoords,GLI_BIG_GLOBALS)) { lReturnValue = 1; INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement, p_stVertexA, bBack, p_stObj->d_stListOfPoints + p_stLocalElementSprite -> d_stListOfSprites[lTriangleIndex] . xCenterPoint, xElementCounter, lTriangleIndex ); } g_p_stCurrentMatrix = p_stFatherMatrix; break; } /* Element switch*/ g_p_stCurrentMatrix = p_stFatherMatrix; return lReturnValue; #endif return 0; } /* ---------------------------------------------------------------------------------------- Description : Compute lights for one object. (RLI) ---------------------------------------------------------------------------------------- */ void GLI_xComputeLightForObject(GEO_tdstGeometricObject *p_stObj,GEO_tdstColor *Tab_stColor) { #ifdef _DEBUG /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ long lVertex; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ if ( p_stObj -> xNbPoints > C_lMaxVertexPerObject ) return; GLI_BIG_GLOBALS -> p_stVpt = NULL; GLI_BIG_GLOBALS -> lHierachDrawMask = GLI_C_lAllIsEnable; GLI_BIG_GLOBALS -> lClippingModeMask = 0; GLI_BIG_GLOBALS -> p_stObj = p_stObj; GLI_BIG_GLOBALS -> gs_st_CurrentMatrix = g_p_stCurrentMatrix; GLI_BIG_GLOBALS -> stRadiusOfCurrentBoundingSphere = 0.0f; POS_fn_vMulMatrixMatrix( &GLI_BIG_GLOBALS->gs_st_CurrentMatrixMultiplyedWithCameraMatrix, GLI_BIG_GLOBALS->gs_st_CameraMatrix, GLI_BIG_GLOBALS -> gs_st_CurrentMatrix); /* Turn the object*/ GLI_xNewSerialLinearOp ( GLI_BIG_GLOBALS ); /* Compute RLI*/ if (p_stRLIForNextObjectToDraw != NULL) { GLI_vCopyRLI2ComputeBufferISI(GLI_BIG_GLOBALS , p_stRLIForNextObjectToDraw , 0 , GLI_BIG_GLOBALS -> p_stObj -> xNbPoints); p_stRLIForNextObjectToDraw = NULL; } else { memset( (void *) GLI_BIG_GLOBALS -> GLI_aDEF_stColorsRLID, 0, GLI_BIG_GLOBALS -> p_stObj -> xNbPoints * sizeof( GEO_tdstColor ) ); } /* Compute All The lights*/ GLI_vSendObjectToLights ( gs_aDEF_p_CurrentListOfLight , GLI_BIG_GLOBALS -> p_stObj , GLI_BIG_GLOBALS -> GLI_aDEF_stColorsRLID , GLI_BIG_GLOBALS -> GLI_aDEF_stColorsRLIS , &GLI_BIG_GLOBALS -> GLI_aDEF_stColorsRLIA , gs_CurrentNumberOfLightInViewport, GLI_BIG_GLOBALS ); for (lVertex = 0; lVertex < GLI_BIG_GLOBALS->p_stObj->xNbPoints; lVertex++) { Tab_stColor[lVertex].xR = GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLID[lVertex].xR + GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLIA.xR; Tab_stColor[lVertex].xG = GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLID[lVertex].xG + GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLIA.xG; Tab_stColor[lVertex].xB = GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLID[lVertex].xB + GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLIA.xB; Tab_stColor[lVertex].xA = GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLID[lVertex].xA + GLI_BIG_GLOBALS->GLI_aDEF_stColorsRLIA.xA; } #endif } #ifdef __cplusplus } /*extern "C"*/ #endif