1156 lines
44 KiB
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++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|