reman3/Rayman_X/cpa/tempgrp/SHW/ShadDraw.c

1156 lines
44 KiB
C

/* ##C_FILE#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FILE : SHADDRAW.C
DESCRIPTION : Main file for SHW Module
VERSION :
1.02 / François Queinnec / Nintendo64 support
1.01 / Guenaele Mendroux / Level of detail
1.00 / Philippe Thiébaut / Creation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#define SHW_MAIN
/* FQ: This define forces shadows on every object*/
/* without checking for the custom bit..*/
/* usefull to determine wether it's the designer's fault */
/* or the programmer's one when there's no shadow.*/
/* #define SHW_FORCE_SHADOW 1*/
#define D_3dData_StructureDefine
#define D_3dData_VariableDefine
/* ##INCLUDE#----------------------------------------------------------------------------
Includes Files
---------------------------------------------------------------------------------------*/
#define D_3dData_StructureDefine
#define D_3dData_VariableDefine
#include "ACP_base.h"
#include "GAM\ToolsCPA.h"
#include "gam.h"
#include "GEO.h"
#include "GLI.h"
#include "COL.h"
#include "SPO.h"
#include "LST.h"
#include "MTH.h"
#include "SND.h"
#include "SCR.h"
#include "SCT.h"
/*This is the public section of SHW*/
#include "SHW\ShwCpa.h"
/*Important: ALL GLOBAL MY CONSTANTS ARE HERE !!!*/
#include "SHW\ShwConst.h"
#include "SHW\ShwStruc.h"
#include "SHW\ShwMacro.h"
#include "SHW\ShwHand.h"
#include "SHW\ShwFunct.h"
#include "SHW\ShwProto.h"
/*This is the private section of SHW*/
#include "ShwPriv.h"
#include "GLI\object.h"
#if (!defined(U64))
#include "SNA.h"
#endif
#include "..\..\tempgrp\AI\AiGame\CAM_Base.h"
#include "..\..\tempgrp\AI\AiGame\CAM_tool.h"
#ifdef USE_IPT_DX5
#include "IPT_DX5.h" /* InPuT (absolutely before GAM.h)*/
#else /* USE_IPT_WIN */
#include "IPT.h" /* InPuT (absolutely before GAM.h)*/
#endif /* USE_IPT_WIN */
#include "PCS.h" /* Physical Collide Set */
#include "RND.h" /* RaNDom*/
#include "FIL.h" /* SeCTor*/
#ifndef D_THROW_PRT
#include "PRT.h"
#endif /* D_THROW_PRT */
#include "Mec.h"
/*FQ*/
#ifdef U64
/* FQ SHADOW FIX*/
#include "mater_st.h"
#include "objects.h"
#include "sectinfo.h"
#include "MainChar.h"
#include "SPO\HieSpObj.h"
#include "GMT\GmtStruc.h"
/* XB 05/05/99 */
#include "GLI\Specif\u_load.h"
/* End XB 05/05/99 */
#endif
extern CPA_EXPORT unsigned long fn_ulStandardGameGetCustomBitsSO (HIE_tdxHandleToSuperObject hSupObj);
extern unsigned long g_ulSpoMask;
#include "PRF.h"
/* ************************************************************************************/
/* ****************** Nintendo64 Specific Includes & Defines **************************/
/* ************************************************************************************/
#if defined(U64)
#include "U_Elt.h" /* We include specific Nin64 Elements*/
#include "Element.h" /* We must include this to properly handle the object format conversion*/
#include "LDR\Specif\getval.h"
#include "LDR\Specif\memload.h"
#include "GLI\Specif\u_VMTLd.h"
#include "h_bitmap.h"
/* Here we declare the VTX and GFX Lists*/
Vtx *g_p_stVtxListForShadow[SHW_C_xNbMaxOfShadows];
Gfx *g_p_stGfxListForShadow[SHW_C_xNbMaxOfShadows];
MTH3D_tdstVector g_pstPickedPointArray[SHW_C_xNbMaxOfShadows];
extern unsigned short g_uwGlobalAlpha;
/* The structure for the face-definitions*/
POS_tdstCompletePosition g_stTranslationMatrixForGoodScale[SHW_C_xNbMaxOfShadows];
#define SHW_C_xNbMaxOfGfxPerShadow 13
#define SHW_C_xU64ScaleForGeometricShadow 1000.0f
#define SHW_C_xU64UVScaleForShadow 1024.0f
#define SHW_C_xZeroForComparisonForN64 0.0001f
#define SHW_C_xOneForComparisonForN64 0.9999f
ACP_tdxHandleOfObject g_hShadowObjectN64[SHW_C_xNbMaxOfShadows];
int g_MustDisplayShadow;
char g_UseNormalMatrixStack=0;
/* This is the shift Z value for the shadow not to be */
/* exactly on the ground, but just a little higher...*/
/* To prevent ZBuffer problems....*/
/* #define SHW_C_ZBiasForZBuffer 0.08f*/
#define SHW_C_ZBiasForZBuffer 0.03f
#define SHW_C_ucRedValue 50
#define SHW_C_ucGreenValue 50
#define SHW_C_ucBlueValue 50
#define SHW_C_ucAlphaValue 255
#endif /* U64 */
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
extern void HIE_fn_vUpdateRasterForObject( GEO_tdstGeometricObject *p_stObject,
unsigned long _ulRasterObject,
unsigned long _ulRasterFace,
unsigned long _ulRasterElement );
#else
#define HIE_fn_vUpdateRasterForObject(p_stObject,_ulRasterObject,_ulRasterFace,_ulRasterElement)
#endif /* USE_PROFILER */
/*****************************************************************/
/************************ Globalvariables ************************/
/*****************************************************************/
GLD_tdstDeviceAttributes g_stDevAttrib;
ACP_tdxHandleOfMaterial g_hShadowPolygonVisualMaterial;
GMT_tdxHandleToGameMaterial g_hShadowPolygonGameMaterial;
GMT_tdxHandleToGameMaterial g_hShadowPolygonGameMaterialInit;
short g_xIndexOfShadow;
/*Array of geometric object that contains the shadow faces to be drawn*/
ACP_tdxHandleOfObject p_hHandleOfGeometricShadowObject[SHW_C_xNbMaxOfShadows];
ACP_tdxHandleOfElement g_p_hHandleOfElementForShadow[SHW_C_xNbMaxOfShadows];
#define NO_COMPLEX_SHADOW
#define SHW_C_xMinZValueForShadowedFace MTH_M_xFloatToReal(0.5f)
void SHW_fn_vSentToViewPort(struct GLD_tdstViewportAttributes_ *_p_stVpt, HIE_tdxHandleToSuperObject _hHandleOfCharacter,
HIE_tdxHandleToSuperObject _hSprObjSector, long _lSectorDrawmask, ACP_tdxHandleOfObject _hHandleOfGeometricShadowObject);
extern char g_cSinusEffectState;
extern MTH3D_tdstVector stSinEffectAmp;
#ifndef NO_COMPLEX_SHADOW
#include "shaddraw.cxx" /* this file contains all functions to process complex shadows*/
#else
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
GLI_tdstTexture *g_p_stTextureOfTextureShadow;
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */
#endif
#ifdef U64
/*****************************************************************/
/************** Nintendo64 Specific Functions ********************/
/*****************************************************************/
/* ##F===================================================================================
NAME : SHW_fn_vCreateElementU64IndexedTriangles
DESCRIPTION : Create the structure of the element U64IndexedTriangles
WARNING: ONLY FOR SHW MODULE !!!
=========================================================================================
CREATION : Philippe Thiébaut
=======================================================================================*/
void SHW_fn_vCreateElementU64IndexedTriangles (ACP_tdxHandleOfObject hU64ObjectForShadow,
unsigned long uiElement)
{
GEO_tdstElementU64IndexedTriangles *p_stLocalElement;
hU64ObjectForShadow->d_xListOfElementsTypes[uiElement]=GEO_C_xElementU64IndexedTriangles;
GEO_M_CPAMalloc(hU64ObjectForShadow->d_stListOfElements[uiElement],
void * ,
sizeof (GEO_tdstElementU64IndexedTriangles),
E_uwGEONotEnoughtMemory);
p_stLocalElement = (GEO_tdstElementU64IndexedTriangles *) hU64ObjectForShadow->d_stListOfElements[uiElement];
p_stLocalElement->p_stVtxList=NULL;
p_stLocalElement->p_stGfxList=NULL;
p_stLocalElement->hMaterial=NULL;
#if defined(_U64_GLI_BENCH_)
p_stLocalElement->uwNbFaces = 0L;
p_stLocalElement->uwSizeOfFacesInBytes = 0L;
#endif /* _U64_GLI_BENCH_ */
}
/* ##F===================================================================================
NAME : SHW_fn_vAddPointToVtxList
DESCRIPTION : Add a geometric 3D Vector with UV in the indexed VtxList
=========================================================================================
CREATION : Philippe Thiébaut
=======================================================================================*/
/* ANTI-BUG*/
/* Sometimes, the PC version sends me some really weird coordinates*/
/* Then, we simply don't draw shadows !!!*/
/* if (((ft1>32760.0f) && (ft1<-32760.0f)) || ((ft2>32760.0f) && (ft2<-32760.0)) || ((ft3>32760.0) && (ft3<-32760.0)))
{
g_MustDisplayShadow=0; return;
}
*/
/* ##F===================================================================================
NAME : SHW_fn_vAddAllFacesToGfxList
DESCRIPTION : Add all faces of the shadow or the footstep in the indexed GfxList
=========================================================================================
CREATION : Philippe Thiébaut
=======================================================================================*/
/*
=========================================================================================
NAME : SHW_ConvertPCtoN64GeometricObject
DESCRIPTION : converts a PC geometric Object to a U64 Geometric object
NOTE : It's only for shadows, with only 1 element
(GEO_tdstElementIndexedTriangles -> GEO_tdstElementU64IndexedTriangles)
=========================================================================================
CREATION : François Queinnec
=======================================================================================*/
/*/////////////////////////*/
/* MEGA ANTI-BUG !!!*/
/*/////////////////////////*/
/*
{
long lExposant;
#define MIN_VALUE_FOR_EXPOSANT 125
lExposant=(((*((long *)&(pvPoints->xX)))>>23)&0xFF);
if (lExposant<MIN_VALUE_FOR_EXPOSANT) { g_MustDisplayShadow=0; return g_hShadowObjectN64[g_xIndexOfShadow]; }
lExposant=(((*((long *)&(pvPoints->xY)))>>23)&0xFF);
if (lExposant<MIN_VALUE_FOR_EXPOSANT) { g_MustDisplayShadow=0; return g_hShadowObjectN64[g_xIndexOfShadow]; }
lExposant=(((*((long *)&(pvPoints->xZ)))>>23)&0xFF);
if (lExposant<MIN_VALUE_FOR_EXPOSANT) { g_MustDisplayShadow=0; return g_hShadowObjectN64[g_xIndexOfShadow]; }
}
*/
/*****************************************************************/
/***************** END OF U64 SPECIFIC FUNCTIONS *****************/
/*****************************************************************/
#endif
/* ##F===================================================================================
NAME : SHW_fn_vInitShadow
DESCRIPTION : Init of the Array of Geometric Objects for the Characters' shadows
=========================================================================================
CREATION : Philippe Thiébaut
=======================================================================================*/
/* FQ : */
/* Since the Ultra64 uses VTX and GFX lists*/
/* The GeometricObjects and the Material loading are differents.*/
/* that's why I use an almost completely different function*/
#if defined( U64)
/* FQ SHADOW FIX*/
GMT_tdstGameMaterial g_stShadowMaterial;
GMT_tdxHandleToGameMaterial g_p_stShadowMaterial=&g_stShadowMaterial;
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void SHW_InitGeometric(ACP_tdxHandleOfObject hShadowObject)
{
register MTH3D_tdstVector *pvPoints;
register long i;
register long lNbPoints;
pvPoints=hShadowObject->d_stListOfPoints;
lNbPoints=SHW_C_xNbMaxOfPointsPerShadow;
for(i=0;i<lNbPoints;i++)
{
pvPoints->xX=-33000.0f;
pvPoints->xY=-33000.0f;
pvPoints->xZ=-33000.0f;
}
for(i=0;i<SHW_C_xNbMaxOfShadows;i++)
{
g_pstPickedPointArray[i].xX=0.0f;
g_pstPickedPointArray[i].xY=0.0f;
g_pstPickedPointArray[i].xZ=0.0f;
}
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
void SHW_fn_vInitShadow(GLD_tdhDevice _hGLDDevice)
{
ACP_tdxIndex xNbMaxOfPoints=SHW_C_xNbMaxOfPointsPerShadow;
ACP_tdxIndex xNbMaxOfFaces=SHW_C_xNbMaxOfFacesPerShadow;
ACP_tdxIndex i;
ACP_tdxHandleOfObject *p_hHandleGeoShwObj;
ACP_tdxHandleOfElement *p_hHandleOfElementForShadow;
ACP_tdxHandleOfMaterial hVisualMaterial ;
/* FQ SHADOW FIX*/
U64_tdstFix *p_stFix;
M_PrintfN64(("Initializing Shadows in Fix\n"));
/* XB 23/06/99 */
//unused _hGLDDevice is NULL
//if (_hGLDDevice!=NULL) GLD_bGetDeviceAttributes(_hGLDDevice,&g_stDevAttrib);
/* End XB 23/06/99 */
p_stFix =
(U64_tdstFix *)
fn_pvLoadFromRomTmpWithSize(
/*XB for new fixfix*/
/* D_BINSCR_StructFix,*/
D_BINSCR_StructFixData,
/* 0*/
0|D_BINSCR_IsInFixFixFat,
/*End XB*/
sizeof(U64_tdstFix));
g_p_stShadowMaterial->hVisualMaterial=NULL;
g_p_stShadowMaterial->hMechanicsMaterial=NULL;
g_p_stShadowMaterial->hSoundMaterial=NULL;
g_p_stShadowMaterial->hCollideMaterial=NULL;
/* fbolefeysot - 01/10/98*/
/* remove init values in GMT{*/
/* g_p_stShadowMaterial->p_stInitialValues=NULL;//END fbolefeysot}*/
#ifdef SECTOR_IN_GMT
g_p_stShadowMaterial->hSectorMaterial=NULL;
#endif
GLI_xCreateMaterial(&(g_p_stShadowMaterial->hVisualMaterial));
hVisualMaterial=g_p_stShadowMaterial->hVisualMaterial;
hVisualMaterial->xMaterialType = 2047;
#ifndef CONST_VMT
hVisualMaterial->lSpecularExponent=5;
#endif
if (p_stFix->xShadowTextureId==D_BINSCR_InvalidId)
M_PrintfN64(("p_stFix->xShadowTextureId==D_BINSCR_InvalidId\n"));
g_p_stShadowMaterial->hVisualMaterial->p_stTexture = (struct GLI_tdstTexture_ *)fn_p_stLoadTexture(p_stFix->xShadowTextureId);
g_p_stShadowMaterial->hVisualMaterial->ulGouraudColor=0;
fn_vFreeRomTmp( (void *)p_stFix ); /* Oliv'*/
/* The material has been loaded, so now we can really initialize */
/* the shadow variables*/
g_hShadowPolygonVisualMaterial = g_p_stShadowMaterial->hVisualMaterial;
g_hShadowPolygonGameMaterial=g_p_stShadowMaterial;
p_hHandleGeoShwObj = p_hHandleOfGeometricShadowObject;
p_hHandleOfElementForShadow = g_p_hHandleOfElementForShadow;
for (i=0;i<SHW_C_xNbMaxOfShadows;i++, p_hHandleGeoShwObj++, p_hHandleOfElementForShadow++)
{
GEO_vCreateGeometricObject(p_hHandleGeoShwObj,xNbMaxOfPoints,1);
GEO_vCreateElementIndexedTriangles(*p_hHandleGeoShwObj,p_hHandleOfElementForShadow,xNbMaxOfFaces,xNbMaxOfPoints);
GEO_vSetGameMaterialOfIndexedTriangles(*p_hHandleGeoShwObj,*p_hHandleOfElementForShadow,g_hShadowPolygonGameMaterial);
g_p_stVtxListForShadow[i]=NULL;
g_p_stGfxListForShadow[i]=NULL;
g_hShadowObjectN64[i]=NULL;
}
g_hShadowPolygonGameMaterialInit=g_hShadowPolygonGameMaterial;
/* END OF FQ SHADOW FIX*/
}/*SHW_fn_vInitShadow*/
void SHW_fn_vReInitShadowForMapChange(void)
{
int i;
for(i=0;i<SHW_C_xNbMaxOfShadows;i++)
{
g_p_stVtxListForShadow[i]=NULL;
g_p_stGfxListForShadow[i]=NULL;
g_hShadowObjectN64[i]=NULL;
}
} /*SHW_fn_vReInitShadowForMapChange*/
#else /* U64*/
/* FQ : This is the PC / General version*/
void SHW_fn_vReInitShadowForMapChange(void)
{
}
void SHW_fn_vInitShadow(GLD_tdhDevice _hGLDDevice)
{
ACP_tdxIndex xNbMaxOfPoints=SHW_C_xNbMaxOfPointsPerShadow;
ACP_tdxIndex xNbMaxOfFaces=SHW_C_xNbMaxOfFacesPerShadow;
GLI_tdstColor stShadowPolygonColor;
ACP_tdxIndex i;
ACP_tdxHandleOfObject *p_hHandleGeoShwObj;
ACP_tdxHandleOfElement *p_hHandleOfElementForShadow;
if (SNA_fn_ucGetLoadType()!=SNA_LOAD_SNAPSHOT)
{
GLI_xCreateMaterial(&g_hShadowPolygonVisualMaterial);
stShadowPolygonColor.xR=MTH_C_ZERO;
stShadowPolygonColor.xG=MTH_C_ZERO;
stShadowPolygonColor.xB=MTH_C_ZERO;
stShadowPolygonColor.xA=MTH_C_ZERO;
#ifndef CONST_VMT
GLI_xSetMaterialAmbientCoef(g_hShadowPolygonVisualMaterial,&stShadowPolygonColor);
GLI_xSetMaterialDiffuseCoef(g_hShadowPolygonVisualMaterial,&stShadowPolygonColor);
#endif
GLI_xSetMaterialSpecularCoef(g_hShadowPolygonVisualMaterial,2,&stShadowPolygonColor);
GLI_xSetMaterialType(g_hShadowPolygonVisualMaterial,GLI_C_lAllIsEnable);
}
GLD_bGetDeviceAttributes(_hGLDDevice,&g_stDevAttrib);
if (SNA_fn_ucGetLoadType()!=SNA_LOAD_SNAPSHOT)
{
GLI_xSetMaterialTexture(g_hShadowPolygonVisualMaterial,g_p_stTextureOfTextureShadow);
g_hShadowPolygonGameMaterial=GMT_fn_hCreateGameMaterial();
GMT_fn_vSetVisualMaterial(g_hShadowPolygonGameMaterial,g_hShadowPolygonVisualMaterial);
p_hHandleGeoShwObj = p_hHandleOfGeometricShadowObject;
p_hHandleOfElementForShadow = g_p_hHandleOfElementForShadow;
/*Creation of geometric objects*/
for (i=0;i<SHW_C_xNbMaxOfShadows;i++, p_hHandleGeoShwObj++, p_hHandleOfElementForShadow++)
{
GEO_vCreateGeometricObject(p_hHandleGeoShwObj,xNbMaxOfPoints,1);
GEO_vCreateElementIndexedTriangles(*p_hHandleGeoShwObj,p_hHandleOfElementForShadow,xNbMaxOfFaces,xNbMaxOfPoints);
GEO_vSetGameMaterialOfIndexedTriangles(*p_hHandleGeoShwObj,*p_hHandleOfElementForShadow,g_hShadowPolygonGameMaterial);
}
}
g_hShadowPolygonGameMaterialInit=g_hShadowPolygonGameMaterial;
} /* SHW_fn_vInitShadow*/
#endif /* U64*/
/* ##F===================================================================================
NAME : SHW_fn_vInitShadowCounter
DESCRIPTION : Initialization of the Counter for the Characters' shadows.
MUST BE RUN AT EACH FRAME
=========================================================================================
CREATION : Philippe Thiébaut
=======================================================================================*/
void SHW_fn_vInitShadowCounter(void)
{
g_xIndexOfShadow=0;
}
/* ##F===================================================================================
NAME : SHW_fn_vSentToViewPort
DESCRIPTION : Sent Shadow to the viewport
=========================================================================================
CREATION : Yann Le Guyader
=======================================================================================*/
void SHW_fn_vSentToViewPort
(
struct GLD_tdstViewportAttributes_ *_p_stVpt,
HIE_tdxHandleToSuperObject _hHandleOfCharacter,
HIE_tdxHandleToSuperObject _hSprObjSector,
long _lSectorDrawmask,
ACP_tdxHandleOfObject _hHandleOfGeometricShadowObject
)
{
register long lAdditionnalDrawMask = 0;
register ACP_tdxBool bTransparenceSetting = FALSE;
register float fGlobalAlphaTemp;
#if defined(U64) /* FQ: Here we need a special Ultra64 Object...*/
/* XB 05/05/99 */
/* ACP_tdxHandleOfObject _hHandleOfGeometricShadowObjectN64; */
/* End XB 05/05/99 */
g_hShadowPolygonGameMaterial = g_hShadowPolygonGameMaterialInit;
#else /* defined(U64)*/
g_hShadowPolygonGameMaterial = fn_x3dDataGetShadowMaterialFromSO(_hHandleOfCharacter);
GEO_vSetGameMaterialOfIndexedTriangles(_hHandleOfGeometricShadowObject,g_p_hHandleOfElementForShadow[g_xIndexOfShadow],g_hShadowPolygonGameMaterial);
#endif
HIE_fn_bLoadIdentity();
#ifndef U64
/* Transparence */
/* if char uses ZFar transparency */
if( fn_ulStandardGameGetCustomBitsSO(_hHandleOfCharacter) & GAM_C_CustBitUsesTransparencyZone )
{
fGlobalAlphaTemp = GLI_vGetGlobalAlpha();
GLI_vSetGlobalAlpha(
MTH_M_xRealToFloat( GEO_xGetZFarTransparencyLevel() ) *
HIE_fn_fGetSuperObjectTransparenceLevel(_hHandleOfCharacter) );
_lSectorDrawmask &= ~GLI_C_lIsNotGrided & ~GLI_C_lNotForceZSorting;
bTransparenceSetting = TRUE;
}
/* else if char is transparent */
else if ((HIE_fn_lGetSuperObjectDrawMask(_hHandleOfCharacter) & GLI_C_lIsNotGrided) == 0)
{
_lSectorDrawmask &= ~GLI_C_lIsNotGrided & ~GLI_C_lNotForceZSorting;
fGlobalAlphaTemp = GLI_vGetGlobalAlpha();
GLI_vSetGlobalAlpha( HIE_fn_fGetSuperObjectTransparenceLevel(_hHandleOfCharacter) );
bTransparenceSetting = TRUE;
}
else
#endif
{
lAdditionnalDrawMask = - GLI_C_lNotForceZSorting - GLI_C_lIsWriteZBuffer;
}
PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvShadow );
PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );
HIE_fn_vUpdateRasterForObject( _hHandleOfGeometricShadowObject, PRF_C_ulVarShwObjects, PRF_C_ulVarShwFaces, PRF_C_ulVarShwElements );
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDynOrSta, PRF_C_ulShadow );
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDisplayedObjects, 0 );
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDisplayedElements, 0 ); /* init flag "faces displayed"*/
PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );
PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvMisc );
#if defined(U64)
/* FQ: Here, we need to convert the Geometric Object on Nintendo64, before we send it to GLI*/
/* On the U64, we need to convert the coordinates*/
/* using the Translation vector defined by the picked point.*/
POS_fn_vSetIdentityMatrix(&g_stTranslationMatrixForGoodScale[g_xIndexOfShadow]);
/* We actualy convert the geometric Object*/
//_hHandleOfGeometricShadowObjectN64=SHW_ConvertPCtoN64GeometricObject(_hHandleOfGeometricShadowObject);
// _hHandleOfGeometricShadowObjectN64=;
if (g_MustDisplayShadow)
{
int OldValue;
POS_fn_vSetTranslationVector(&g_stTranslationMatrixForGoodScale[g_xIndexOfShadow],&g_pstPickedPointArray[g_xIndexOfShadow]);
HIE_fn_bStoreMatrix(&g_stTranslationMatrixForGoodScale[g_xIndexOfShadow]);
/* Then we can send it*/
OldValue=g_UseNormalMatrixStack;
g_UseNormalMatrixStack=1;
GLI_xSendObjectToViewportWithLights (_p_stVpt ,_hHandleOfGeometricShadowObject,(((_lSectorDrawmask | lAdditionnalDrawMask) | 0x4000 /* Forcing Priority Bit 14 */ ) & (~GLI_C_lIsNotGrided))); /* we pop the additionnal matrix */
g_UseNormalMatrixStack=OldValue;
/* we pop the additionnal matrix*/
HIE_fn_vPopMatrix();
}
#else /* On PC, we simply call the GLI_xSendObjectToViewportWithLights function*/
GLI_xSendObjectToViewportWithLights (_p_stVpt ,_hHandleOfGeometricShadowObject,_lSectorDrawmask | lAdditionnalDrawMask);
#endif /* U64*/
PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvMisc );
PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
/*PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendActor );*/
PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvShadow );
if( PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDisplayedElements ) ) /* at least one face has been displayed*/
/* END ANNECY MT }*/
{
PRF_fn_vIncreaseVariable( PRF_C_ulVarObjects + PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvDisplayed, 1 ); /* update number of displayed objects*/
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDisplayedObjects, 1 ); /* set flag "object displayed" for sector*/
}
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDynOrSta, PRF_C_ulDynamic );
/* restore the old transparence coefficient */
if (bTransparenceSetting)
GLI_vSetGlobalAlpha(fGlobalAlphaTemp);
HIE_fn_vPopMatrix();
}
/* ##F===================================================================================
NAME : SHW_fn_vComputeShadowRectangle
DESCRIPTION : compute the coordinates of shadow in quality = 1
=========================================================================================
CREATION : Fabien Bole-Feysot
=======================================================================================*/
MTH_tdxReal SHW_fn_vComputeZofShadowPoint (MTH3D_tdstVector *_p_stPickedPoint,
MTH3D_tdstVector *_p_stGlobalNormalOfPickedFace,
MTH_tdxReal _xInvGlobalNormalxZ,
MTH_tdxReal _xOffsetX,
MTH_tdxReal _xOffsetY)
{
return (MTH_M_xSub (_p_stPickedPoint->xZ,
MTH_M_xMul(_xInvGlobalNormalxZ,
MTH_M_xAdd(
MTH_M_xMul(_p_stGlobalNormalOfPickedFace->xX,
MTH_M_xSub(_xOffsetX,_p_stPickedPoint->xX)),
MTH_M_xMul(_p_stGlobalNormalOfPickedFace->xY,
MTH_M_xSub(_xOffsetY,_p_stPickedPoint->xY))
)
)
)
);
}
/* ##F===================================================================================
NAME : SHW_fn_vDrawShadow
DESCRIPTION : Draw a Fake Shadow for a Character
=========================================================================================
CREATION : Philippe Thiébaut
=======================================================================================*/
void SHW_fn_vDrawShadow ( struct GLD_tdstViewportAttributes_ *_p_stVpt,
HIE_tdxHandleToSuperObject _hHandleOfCharacter,
HIE_tdxHandleToSuperObject _hSprObjSector,
long _lSectorDrawmask)
{
MTH3D_tdstVector stGlobalNormalOfPickedFace,stStartPicking,stVertexAB,stPickedPoint;
GEO_tdxHandleToMatrix hGlobalMatrixOfCharacter;
MTH_tdxReal xCoefAltitude;
#ifndef U64
GEO_tdstElementIndexedTriangles *p_stIndexedTriangle;
#endif
MTH_tdxReal xScaleX;
MTH_tdxReal xScaleY;
ACP_tdxHandleOfObject hHandleOfGeometricShadowObject = NULL;
HIE_tdxHandleToSuperObject hTest;
/* PRF_fn_vStartChrono(PRF_C_ulGLI8, NULL);*/
#ifndef U64
/* if there is no material for the shadow, there is no shadow*/
if (fn_x3dDataGetShadowMaterialFromSO(_hHandleOfCharacter) == NULL)
return;
#endif
/* if bad viewport or not active, no shadow*/
if( HIE_fn_SO_bIsSuperimposed(_hHandleOfCharacter) ||
!fn_bf1StandardGameGetIsActive(M_GetMSHandle(_hHandleOfCharacter,StandardGame))
)
return;
/* If character uses ZFar transparency and is too far, no shadow. */
if( ( fn_ulStandardGameGetCustomBitsSO(_hHandleOfCharacter) & GAM_C_CustBitUsesTransparencyZone )
&& ( GEO_xGetZFarTransparencyLevel() == MTH_C_ZERO ) )
return;
#ifdef NO_COMPLEX_SHADOW
/* if quality of shadow is 0, no shadow*/
/*XB ShadowQuality is always 2*/
#ifndef U64
if (fn_x3dDataGetShadowQualityFromSO(_hHandleOfCharacter) == 0)
return;
#endif /* U64 */
/*End XB*/
#else
/* if quality of shadow is 0, no shadow*/
g_xLevelOfQualityOfShadows = fn_x3dDataGetShadowQualityFromSO(_hHandleOfCharacter);
if (g_xLevelOfQualityOfShadows == 0)
return;
if (g_xGeneralLevelOfQualityOfShadows<g_xLevelOfQualityOfShadows)
g_xLevelOfQualityOfShadows = g_xGeneralLevelOfQualityOfShadows;
#endif
#if defined(U64)
g_MustDisplayShadow = 1;
if (g_hShadowPolygonGameMaterialInit == NULL)
{
M_PrintfN64(("No shadow material loaded at first pass of DrawShadow !!!!\n"));
}
/*Allocate memory for Gfxlists and VtxLists if not done*/
if (g_p_stVtxListForShadow[g_xIndexOfShadow]==NULL)
{
Vtx *pVtxList;
Gfx *pGfx;
g_p_stVtxListForShadow[g_xIndexOfShadow]=(Vtx *)TMP_M_p_Malloc(4*sizeof(Vtx));
g_p_stGfxListForShadow[g_xIndexOfShadow]=(Gfx *)TMP_M_p_Malloc(5*sizeof(Gfx));
pVtxList=g_p_stVtxListForShadow[g_xIndexOfShadow];
pGfx=g_p_stGfxListForShadow[g_xIndexOfShadow];
pVtxList->v.tc[0]=0;
pVtxList->v.tc[1]=0;
pVtxList->v.flag=0;
pVtxList->v.cn[0]=255;
pVtxList->v.cn[1]=255;
pVtxList->v.cn[2]=255;
pVtxList->v.cn[3]=255;
pVtxList++;
pVtxList->v.tc[0]=SHW_C_xU64UVScaleForShadow*2;
pVtxList->v.tc[1]=0;
pVtxList->v.flag=0;
pVtxList->v.cn[0]=255;
pVtxList->v.cn[1]=255;
pVtxList->v.cn[2]=255;
pVtxList->v.cn[3]=255;
pVtxList++;
pVtxList->v.tc[0]=SHW_C_xU64UVScaleForShadow*2;
pVtxList->v.tc[1]=SHW_C_xU64UVScaleForShadow*2;
pVtxList->v.flag=0;
pVtxList->v.cn[0]=255;
pVtxList->v.cn[1]=255;
pVtxList->v.cn[2]=255;
pVtxList->v.cn[3]=255;
pVtxList++;
pVtxList->v.tc[0]=0;
pVtxList->v.tc[1]=SHW_C_xU64UVScaleForShadow*2;
pVtxList->v.flag=0;
pVtxList->v.cn[0]=255;
pVtxList->v.cn[1]=255;
pVtxList->v.cn[2]=255;
pVtxList->v.cn[3]=255;
pVtxList=g_p_stVtxListForShadow[g_xIndexOfShadow];
gSPClearGeometryMode(pGfx++,G_CULL_BOTH);
gSPVertex(pGfx++,OS_K0_TO_PHYSICAL(pVtxList),4,0);
gDPPipeSync(pGfx++);
gSP2Triangles(pGfx++,0,3,1,0,1,3,2,0);
gSPEndDisplayList(pGfx++);
}
#endif
if (g_xIndexOfShadow < SHW_C_xNbMaxOfShadows)
{
HIE_tdxHandleToSuperObject hCurrentPerso,hHandleOfFather;
SECT_tdxHandleOfElementLstCharacter hCharacterList;
SECT_tdxHandleOfElementLstCollisionInteraction hCollisionElement;
SECT_tdxHandleOfElementLstActivityInteraction hInteractionElement;
long i,j;
BOOL bFound = FALSE;
/* XB 05/05/99 */
/* BOOL bSectorLimit = FALSE; */
/* End XB 05/05/99 */
#ifndef NO_COMPLEX_SHADOW
if (g_xLevelOfQualityOfShadows == 2)
{
SHW_fn_vDrawComplexShadow(_p_stVpt,_hHandleOfCharacter,_hSprObjSector,_lSectorDrawmask);
return;
}
#endif
hGlobalMatrixOfCharacter=HIE_fn_hGetSuperObjectGlobalMatrix(_hHandleOfCharacter);
POS_fn_vGetTranslationVector(hGlobalMatrixOfCharacter, &stStartPicking ) ;
hHandleOfGeometricShadowObject = p_hHandleOfGeometricShadowObject[g_xIndexOfShadow];
xScaleX = MTH_M_xAbs(fn_x3dDataGetShadowScaleXFromSO(_hHandleOfCharacter));
xScaleY = MTH_M_xAbs(fn_x3dDataGetShadowScaleYFromSO(_hHandleOfCharacter));
/* object detection starts 1.8m upper the actor*/
stStartPicking.xZ = MTH_M_xAdd(stStartPicking.xZ,MTH_M_xFloatToReal(1.8f));
/* object are detected 14.5 meters below the actor*/
MTH3D_M_vSetVectorElements(&stVertexAB,MTH_C_ZERO,MTH_C_ZERO,MTH_M_xFloatToReal(-14.5f));
/* begin with tests on a perso, so reset the mask to scan all objects:*/
g_ulSpoMask = 0;
/* first, look if the perso is on a platform...*/
hHandleOfFather = HIE_fn_hGetSuperObjectFather(_hHandleOfCharacter);
if (HIE_fn_ulGetSuperObjectType(hHandleOfFather) & HIE_C_ulActor)
{
/* The perso is on a platform...*/
/* so detect only on the platform and nowhere else !*/
if ( (fn_ulStandardGameGetCustomBitsSO(hHandleOfFather) & GAM_C_CustBitShadowOnMe) && /* actor accepts shadows*/
(fn_bf1StandardGameGetIsActive(M_GetMSHandle(hHandleOfFather,StandardGame))) ) /* active*/
{
if (HIE_bIntersectSegmentWithFirstSuperObject(&stStartPicking,&stVertexAB,hHandleOfFather,&stPickedPoint,&stGlobalNormalOfPickedFace,&hTest))
{
/* intersection found, check normal*/
bFound |= MTH_M_bGreater(stGlobalNormalOfPickedFace.xZ,SHW_C_xMinZValueForShadowedFace);
}
}
}
else
{
/* search in dynamic hierarchy of sector*/
SECT_M_ForEachCharListInSector(_hSprObjSector,hCharacterList,i)
{
hCurrentPerso = SECT_GetCharacterInList(hCharacterList);
if (hCurrentPerso != _hHandleOfCharacter)
{
if ( (fn_ulStandardGameGetCustomBitsSO(hCurrentPerso) & GAM_C_CustBitShadowOnMe) && /* actor accepts shadows*/
(fn_bf1StandardGameGetIsActive(M_GetMSHandle(hCurrentPerso,StandardGame))) ) /* active*/
{
if (HIE_bIntersectSegmentWithFirstSuperObject(&stStartPicking,&stVertexAB,hCurrentPerso,&stPickedPoint,&stGlobalNormalOfPickedFace,&hTest))
{
/* intersection found, check normal*/
bFound |= MTH_M_bGreater(stGlobalNormalOfPickedFace.xZ,SHW_C_xMinZValueForShadowedFace);
}
}
}
}
/* test on a sector, so set global mask to check SPO shadow flag :*/
g_ulSpoMask = HIE_C_Flag_ulNoShadowOnMe;
/* search in static hierarchy of sector*/
if (HIE_bIntersectSegmentWithFirstSuperObject(&stStartPicking,&stVertexAB,_hSprObjSector,&stPickedPoint,&stGlobalNormalOfPickedFace,&hTest))
{
bFound |= (MTH_M_bGreater(stGlobalNormalOfPickedFace.xZ,SHW_C_xMinZValueForShadowedFace));
}
/* if (!bFound)*/
/* {*/
/* didn't find in first sector!!!*/
/* search in all active sectors for actors...*/
/* test on actors, so reset global mask*/
g_ulSpoMask = 0;
SECT_M_ForEachActivityNodeInActivityInteractionList(_hSprObjSector,hInteractionElement,i)
{
MTH3D_tdstVector stMin, stMax;
HIE_tdxHandleToSuperObject hSector;
SECT_tdxHandleOfSectorObject hSectorObject;
/* scan every collision sector*/
hSector = SECT_GetSectorInActivityList(hInteractionElement);
hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hSector);
/* if the sector border is not in intersection with the segment, don't scan its characters*/
/* get the border box of the sector*/
SECT_fn_vGetMinPointInBorder(hSectorObject, &stMin);
SECT_fn_vGetMaxPointInBorder(hSectorObject, &stMax);
if (INT_fn_bDetectIntersectSegmentWithBox (&stStartPicking,&stVertexAB,&stMin,&stMax,NULL))
{
/* ok, intersection with segment*/
SECT_M_ForEachCharListInSector(hSector,hCharacterList,j)
{
/* scan every character of the collision sector*/
hCurrentPerso = SECT_GetCharacterInList(hCharacterList);
if ((fn_ulStandardGameGetCustomBitsSO(hCurrentPerso) & GAM_C_CustBitShadowOnMe) && /* accept shadow*/
(fn_bf1StandardGameGetIsActive(M_GetMSHandle(hCurrentPerso,StandardGame)))) /* active*/
{
if( HIE_bIntersectSegmentWithFirstSuperObject(&stStartPicking,&stVertexAB,hCurrentPerso,&stPickedPoint,&stGlobalNormalOfPickedFace,&hTest) )
{
/* intersection found, check normal*/
bFound |= MTH_M_bGreater(stGlobalNormalOfPickedFace.xZ,SHW_C_xMinZValueForShadowedFace);
}
}
}
}
}
/* and then in all collision sectors for decor*/
/* test on a sector, so set global mask to check SPO shadow flag :*/
g_ulSpoMask = HIE_C_Flag_ulNoShadowOnMe;
SECT_M_ForEachCollisionNodeInCollisionInteractionList(_hSprObjSector,hCollisionElement,i)
{
HIE_tdxHandleToSuperObject hSector;
hSector = SECT_GetSectorInCollisionList(hCollisionElement);
if (HIE_bIntersectSegmentWithFirstSuperObject(&stStartPicking,&stVertexAB,hSector,&stPickedPoint,&stGlobalNormalOfPickedFace,&hTest))
{
/* intersection found, check normal*/
bFound |= MTH_M_bGreater(stGlobalNormalOfPickedFace.xZ,SHW_C_xMinZValueForShadowedFace);
}
}
}
/* }*/
if (bFound && MTH_M_bGreater(stGlobalNormalOfPickedFace.xZ,SHW_C_xMinZValueForShadowedFace) )
{
/*Temporary point of shadow*/
MTH3D_tdstVector stPointOfShadowRectangle;
/*Vectors used for the orientation of the shadow*/
MTH3D_tdstVector stCharacterRotation;
/*Vectors used to compute picked point * 2*/
MTH3D_tdstVector stDblPicked;
#ifndef U64
/*UV of the points of the shadow*/
ACP_tdst2DUVValues stUV;
/*Reals used to simplify the calcul of coordinates*/
MTH_tdxReal xAX,xAY,xBX;
#endif
MTH_tdxReal xBY;
/*Real to simplify the next calcul*/
MTH_tdxReal xInvGlobalNormalxZ=MTH_M_xInv(stGlobalNormalOfPickedFace.xZ);
POS_fn_vGetRotationMatrix(hGlobalMatrixOfCharacter ,&stCharacterRotation,&stPointOfShadowRectangle,&stPointOfShadowRectangle) ;
#ifndef U64
/*Important: Rotation doesn't have to take in account the Z coef*/
stCharacterRotation.xZ=MTH_C_ZERO;
/*If the orientation is only in Z*/
if ((MTH_M_bLess(MTH_M_xAbs(stCharacterRotation.xX),MTH_M_xFloatToReal(0.1f)))&&
(MTH_M_bLess(MTH_M_xAbs(stCharacterRotation.xY),MTH_M_xFloatToReal(0.1f))))
{
stCharacterRotation.xX=MTH_C_InvSqrt2;
stCharacterRotation.xY=MTH_C_InvSqrt2;
}
MTH3D_M_vNormalizeVector(&stCharacterRotation,&stCharacterRotation);
/*Formula for scale*/
xCoefAltitude=MTH_M_xInv(MTH_M_xAdd(MTH_C_ONE,MTH_M_xMul(MTH_M_xFloatToReal(0.3f),MTH_M_xSub(stStartPicking.xZ,stPickedPoint.xZ))));
xScaleX=MTH_M_xMul(xScaleX,xCoefAltitude);
xScaleY=MTH_M_xMul(xScaleY,xCoefAltitude);
xAX = MTH_M_xMul(xScaleX,stCharacterRotation.xX);
xAY = MTH_M_xMul(xScaleY,stCharacterRotation.xX);
xBX = MTH_M_xMul(xScaleX,stCharacterRotation.xY);
xBY = MTH_M_xMul(xScaleY,stCharacterRotation.xY);
if ( ( (g_cSinusEffectState == 1) && ((HIE_fn_lGetSuperObjectDrawMask(hTest) & GLI_C_lHasNotSinusEffect) == 0) ) ||
( (g_cSinusEffectState == 2) && (HIE_fn_lGetSuperObjectDrawMask(hTest) & GLI_C_lHasNotSinusEffect) ) ||
(g_cSinusEffectState == 3)
)
{
/* sinus effect --> set shadow at the top of sinus*/
stPickedPoint.xZ = MTH_M_xAdd(stPickedPoint.xZ,MTH_M_xFloatToReal(stSinEffectAmp.xY));
/* if shadow higher than rayman, set shadow under rayman*/
/* 0.3 is distance between rayman and shadow when raymn walks*/
if (MTH_M_bLess(MTH_M_xSub(stStartPicking.xZ,stPickedPoint.xZ),MTH_M_xFloatToReal(0.3)))
{
stPickedPoint.xZ = MTH_M_xSub(stStartPicking.xZ,MTH_M_xFloatToReal(0.3f));
}
}
stPickedPoint.xZ = MTH_M_xAdd(stPickedPoint.xZ,MTH_M_xFloatToReal(0.03f));
/*First Point*/
stPointOfShadowRectangle.xX = MTH_M_xAdd(stPickedPoint.xX,MTH_M_xSub(xAX,xBY));
stPointOfShadowRectangle.xY = MTH_M_xAdd(stPickedPoint.xY,MTH_M_xAdd(xBX,xAY));
stPointOfShadowRectangle.xZ = SHW_fn_vComputeZofShadowPoint(&stPickedPoint,&stGlobalNormalOfPickedFace,xInvGlobalNormalxZ,stPointOfShadowRectangle.xX,stPointOfShadowRectangle.xY);
#else /* U64 */
if (xScaleY>xScaleX) xScaleX=xScaleY;
/* Since Shadows are always round */
/*Formula for scale*/
xCoefAltitude=MTH_M_xInv(MTH_M_xAdd(MTH_C_ONE,MTH_M_xMul(MTH_M_xFloatToReal(0.3f),MTH_M_xSub(stStartPicking.xZ,stPickedPoint.xZ))));
xScaleX=MTH_M_xMul(xScaleX,xCoefAltitude);
/*xAX */ xBY = xScaleX*(MTH_C_InvSqrt2*2.0f);
/* xBY = xAX+xAX; */
stPickedPoint.xZ = MTH_M_xAdd(stPickedPoint.xZ,MTH_M_xFloatToReal(0.03f));
/*First Point*/
stPointOfShadowRectangle.xX = stPickedPoint.xX;
stPointOfShadowRectangle.xY = MTH_M_xAdd(stPickedPoint.xY,xBY);
stPointOfShadowRectangle.xZ = SHW_fn_vComputeZofShadowPoint(&stPickedPoint,&stGlobalNormalOfPickedFace,xInvGlobalNormalxZ,stPointOfShadowRectangle.xX,stPointOfShadowRectangle.xY);
#endif /* U64 */
/*
Now we automatically create the N64 Geometric object so that we don't have to
convert it in N64 format anymore =o)
*/
#ifndef U64 /*
PC VERSION :
Please inform Francois Queinnec when modifying this part of code !
*/
GEO_vSetPointOfObject(hHandleOfGeometricShadowObject,&stPointOfShadowRectangle,0);
stUV.xU=MTH_C_ZERO;
stUV.xV=MTH_C_ZERO;
GEO_vSetUVOfIndexedTriangles(hHandleOfGeometricShadowObject,0,0,&stUV);
/*End of First Point*/
MTH3D_M_vMulScalarVector(&stDblPicked,MTH_M_xFloatToReal(2.0f),&stPickedPoint);
/*Third Point*/
stPointOfShadowRectangle.xX = MTH_M_xSub(stDblPicked.xX,stPointOfShadowRectangle.xX);
stPointOfShadowRectangle.xY = MTH_M_xSub(stDblPicked.xY,stPointOfShadowRectangle.xY);
stPointOfShadowRectangle.xZ = MTH_M_xSub(stDblPicked.xZ,stPointOfShadowRectangle.xZ);
GEO_vSetPointOfObject(hHandleOfGeometricShadowObject,&stPointOfShadowRectangle,2);
stUV.xU=MTH_C_ONE;
stUV.xV=MTH_C_ONE;
GEO_vSetUVOfIndexedTriangles(hHandleOfGeometricShadowObject,0,2,&stUV);
/*End of Third Point*/
/*Second Point*/
stPointOfShadowRectangle.xX = MTH_M_xAdd(stPickedPoint.xX,MTH_M_xAdd(xAX,xBY));
stPointOfShadowRectangle.xY = MTH_M_xAdd(stPickedPoint.xY,MTH_M_xSub(xBX,xAY));
stPointOfShadowRectangle.xZ = SHW_fn_vComputeZofShadowPoint(&stPickedPoint,&stGlobalNormalOfPickedFace,xInvGlobalNormalxZ,stPointOfShadowRectangle.xX,stPointOfShadowRectangle.xY);
GEO_vSetPointOfObject(hHandleOfGeometricShadowObject,&stPointOfShadowRectangle,1);
stUV.xU=MTH_C_ONE;
stUV.xV=MTH_C_ZERO;
GEO_vSetUVOfIndexedTriangles(hHandleOfGeometricShadowObject,0,1,&stUV);
/*End of Second Point*/
/*Fourth Point*/
stPointOfShadowRectangle.xX = MTH_M_xSub(stDblPicked.xX,stPointOfShadowRectangle.xX);
stPointOfShadowRectangle.xY = MTH_M_xSub(stDblPicked.xY,stPointOfShadowRectangle.xY);
stPointOfShadowRectangle.xZ = MTH_M_xSub(stDblPicked.xZ,stPointOfShadowRectangle.xZ);
GEO_vSetPointOfObject(hHandleOfGeometricShadowObject,&stPointOfShadowRectangle,3);
stUV.xU=MTH_C_ZERO;
stUV.xV=MTH_C_ONE;
GEO_vSetUVOfIndexedTriangles(hHandleOfGeometricShadowObject,0,3,&stUV);
/*End of Fourth Point*/
/*I create my two faces of my shadow*/
GEO_vSetFaceOfIndexedTriangles(hHandleOfGeometricShadowObject,0,0,0,3,1);
GEO_vSetIndexedUVOfFaceOfIndexedTriangles(hHandleOfGeometricShadowObject,0,0,0,3,1);
GEO_vSetFaceOfIndexedTriangles(hHandleOfGeometricShadowObject,0,1,1,3,2);
GEO_vSetIndexedUVOfFaceOfIndexedTriangles(hHandleOfGeometricShadowObject,0,1,1,3,2);
hHandleOfGeometricShadowObject->xNbPoints=4;
p_stIndexedTriangle = (GEO_tdstElementIndexedTriangles *)hHandleOfGeometricShadowObject->d_stListOfElements[0];
p_stIndexedTriangle->xNbFaces=2;
SHW_fn_vSentToViewPort(_p_stVpt,_hHandleOfCharacter,_hSprObjSector,_lSectorDrawmask,hHandleOfGeometricShadowObject);
#else /* U64 Version : */
{
GEO_tdstElementU64IndexedTriangles *pElem;
Vtx *pVtxList;
Gfx *pGfx;
/* First, we create, if necessary, the geometric object */
if (g_hShadowObjectN64[g_xIndexOfShadow]==NULL)
{
GEO_vCreateGeometricObject(&g_hShadowObjectN64[g_xIndexOfShadow],0,1);
SHW_fn_vCreateElementU64IndexedTriangles(g_hShadowObjectN64[g_xIndexOfShadow],0);
((GEO_tdstElementU64IndexedTriangles *)(g_hShadowObjectN64[g_xIndexOfShadow]->d_stListOfElements[0]))->hMaterial=(GMT_tdxHandleToGameMaterial)g_hShadowPolygonVisualMaterial;
(g_hShadowObjectN64[g_xIndexOfShadow])->fScale=SHW_C_xU64ScaleForGeometricShadow;
g_hShadowObjectN64[g_xIndexOfShadow]->uwSymType=0xFFFF;
g_hShadowObjectN64[g_xIndexOfShadow]->uwRliFlag=0;
g_hShadowObjectN64[g_xIndexOfShadow]->xNbPoints=4;
pElem=((GEO_tdstElementU64IndexedTriangles **)(g_hShadowObjectN64[g_xIndexOfShadow]->d_stListOfElements))[0];
#if defined(_U64_GLI_BENCH_)
pElem->uwNbFaces=2;
pElem->uwSizeOfFacesInBytes=6;
#endif
pElem->ulNbVertices=2;
pElem->p_stVtxList=g_p_stVtxListForShadow[g_xIndexOfShadow];
pElem->p_stGfxList=g_p_stGfxListForShadow[g_xIndexOfShadow];
}
pElem=((GEO_tdstElementU64IndexedTriangles **)(g_hShadowObjectN64[g_xIndexOfShadow]->d_stListOfElements))[0];
pVtxList=g_p_stVtxListForShadow[g_xIndexOfShadow];
pGfx=g_p_stGfxListForShadow[g_xIndexOfShadow];
/* First Point */
pVtxList->v.ob[0]=(short)((stPointOfShadowRectangle.xX-stPickedPoint.xX)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[1]=(short)((stPointOfShadowRectangle.xY-stPickedPoint.xY)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[2]=(short)((stPointOfShadowRectangle.xZ-stPickedPoint.xZ+SHW_C_ZBiasForZBuffer)*SHW_C_xU64ScaleForGeometricShadow);
/*End of First Point*/
/*Third Point*/
MTH3D_M_vMulScalarVector(&stDblPicked,MTH_M_xFloatToReal(2.0f),&stPickedPoint);
stPointOfShadowRectangle.xX = MTH_M_xSub(stDblPicked.xX,stPointOfShadowRectangle.xX);
stPointOfShadowRectangle.xY = MTH_M_xSub(stDblPicked.xY,stPointOfShadowRectangle.xY);
stPointOfShadowRectangle.xZ = MTH_M_xSub(stDblPicked.xZ,stPointOfShadowRectangle.xZ);
pVtxList+=2;
pVtxList->v.ob[0]=(short)((stPointOfShadowRectangle.xX-stPickedPoint.xX)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[1]=(short)((stPointOfShadowRectangle.xY-stPickedPoint.xY)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[2]=(short)((stPointOfShadowRectangle.xZ-stPickedPoint.xZ+SHW_C_ZBiasForZBuffer)*SHW_C_xU64ScaleForGeometricShadow);
/*End of Third Point*/
/*Second Point*/
stPointOfShadowRectangle.xX = MTH_M_xAdd(stPickedPoint.xX,xBY);
stPointOfShadowRectangle.xY = stPickedPoint.xY;
stPointOfShadowRectangle.xZ = SHW_fn_vComputeZofShadowPoint(&stPickedPoint,&stGlobalNormalOfPickedFace,xInvGlobalNormalxZ,stPointOfShadowRectangle.xX,stPointOfShadowRectangle.xY);
pVtxList--;
pVtxList->v.ob[0]=(short)((stPointOfShadowRectangle.xX-stPickedPoint.xX)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[1]=(short)((stPointOfShadowRectangle.xY-stPickedPoint.xY)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[2]=(short)((stPointOfShadowRectangle.xZ-stPickedPoint.xZ+SHW_C_ZBiasForZBuffer)*SHW_C_xU64ScaleForGeometricShadow);
/*End of Second Point*/
/*Fourth Point*/
stPointOfShadowRectangle.xX = MTH_M_xSub(stDblPicked.xX,stPointOfShadowRectangle.xX);
stPointOfShadowRectangle.xY = MTH_M_xSub(stDblPicked.xY,stPointOfShadowRectangle.xY);
stPointOfShadowRectangle.xZ = MTH_M_xSub(stDblPicked.xZ,stPointOfShadowRectangle.xZ);
pVtxList+=2;
pVtxList->v.ob[0]=(short)((stPointOfShadowRectangle.xX-stPickedPoint.xX)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[1]=(short)((stPointOfShadowRectangle.xY-stPickedPoint.xY)*SHW_C_xU64ScaleForGeometricShadow);
pVtxList->v.ob[2]=(short)((stPointOfShadowRectangle.xZ-stPickedPoint.xZ+SHW_C_ZBiasForZBuffer)*SHW_C_xU64ScaleForGeometricShadow);
g_pstPickedPointArray[g_xIndexOfShadow].xX=stPickedPoint.xX;
g_pstPickedPointArray[g_xIndexOfShadow].xY=stPickedPoint.xY;
g_pstPickedPointArray[g_xIndexOfShadow].xZ=stPickedPoint.xZ;
g_uwGlobalAlpha=255;
SHW_fn_vSentToViewPort(_p_stVpt,_hHandleOfCharacter,_hSprObjSector,_lSectorDrawmask,g_hShadowObjectN64[g_xIndexOfShadow]);
}
#endif /* U64*/
g_xIndexOfShadow++;
}
}
}