reman3/Rayman_X/cpa/tempgrp/GliGlou/MultiDRV/Src/VisuaSet.c

431 lines
17 KiB
C

/*
=======================================================================================
Name : VisuaSet.c
Author : philippe vimont
Description : manage visual set structure
=======================================================================================
*/
#include "Gli_st.h"
#include "GLI_Defn.h"
#include "VisuS_st.h"
#include "light_st.h"
#include "PvObj_st.h"
#include "matstack.h"
#include "VisuSet.h"
#include "proj.h"
#include "linear.h"
#include "vpt3D.h"
#include "camera.h"
#include "Object.h"
#include "pvobj_st.h"
#include "PCS.h"
#include "PO.h"
#include "IPO.h"
#include "ISI.h"
//#include "light.h"
/* See "ACP_Visualsets.DOC" for more */
#ifdef __cplusplus
extern "C"
{
#endif
/*
=======================================================================================
externals
=======================================================================================
*/
extern GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BIG_GLOBALS;
/*
=======================================================================================
Creation
=======================================================================================
*/
/*
----------------------------------------------------------------------------------------
Description : create a visual set
lNbLOD -> number of Level Of Detail
----------------------------------------------------------------------------------------
*/
GEO_tdstVisualSet *GLI_p_stCreateVisualSet( long lNbLOD )
{
GEO_tdstVisualSet *p_stLocalVS;
ACP_tdxIndex xLodCounter;
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeVisualSet , NULL);
GEO_M_CPAMalloc(p_stLocalVS ,GEO_tdstVisualSet * ,sizeof ( GEO_tdstVisualSet ) ,E_uwGEONotEnoughtMemory );
if ( p_stLocalVS == NULL)
return NULL;
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeVisualSet , NULL);
GEO_M_CPAMalloc(p_stLocalVS -> d_xThresholdsTable ,MTH_tdxReal *,sizeof ( MTH_tdxReal ) * lNbLOD,E_uwGEONotEnoughtMemory );
if ( p_stLocalVS -> d_xThresholdsTable == NULL)
return NULL;
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeVisualSet , NULL);
GEO_M_CPAMalloc(p_stLocalVS -> d_p_stLodDefinitions ,GEO_tdstGeometricObject ** ,sizeof ( GEO_tdstGeometricObject * ) * lNbLOD,E_uwGEONotEnoughtMemory );
if ( p_stLocalVS -> d_p_stLodDefinitions == NULL)
return NULL;
p_stLocalVS -> xNbLodDefinitions = (ACP_tdxIndex)lNbLOD;
for (xLodCounter = 0; xLodCounter < lNbLOD; xLodCounter ++)
{
p_stLocalVS -> d_xThresholdsTable[xLodCounter] = 0.0;
p_stLocalVS -> d_p_stLodDefinitions[xLodCounter] = NULL;
}
return (p_stLocalVS);
};
/*
----------------------------------------------------------------------------------------
Description : create a visual set in the TMP memory block
lNbLOD -> number of Level Of Detail
----------------------------------------------------------------------------------------
*/
GEO_tdstVisualSet *GLI_p_stCreateTMPVisualSet ( long lNbLOD)
{
GEO_tdstVisualSet *p_stLocalVS;
ACP_tdxIndex xLodCounter;
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeVisualSet , NULL);
GEO_M_TMPMalloc(p_stLocalVS ,GEO_tdstVisualSet * ,sizeof ( GEO_tdstVisualSet ) );
if ( p_stLocalVS == NULL)
return(NULL);
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeVisualSet , NULL);
GEO_M_TMPMalloc(p_stLocalVS -> d_xThresholdsTable ,MTH_tdxReal *,sizeof ( MTH_tdxReal ) * lNbLOD );
if ( p_stLocalVS -> d_xThresholdsTable == NULL)
return(NULL);
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeVisualSet , NULL);
GEO_M_TMPMalloc(p_stLocalVS -> d_p_stLodDefinitions ,GEO_tdstGeometricObject ** ,sizeof ( GEO_tdstGeometricObject * ) * lNbLOD );
if ( p_stLocalVS -> d_p_stLodDefinitions == NULL)
return(NULL);
p_stLocalVS -> xNbLodDefinitions = (ACP_tdxIndex)lNbLOD;
for (xLodCounter = 0; xLodCounter < lNbLOD; xLodCounter ++)
{
p_stLocalVS -> d_xThresholdsTable[xLodCounter] = 0.0;
p_stLocalVS -> d_p_stLodDefinitions[xLodCounter] = NULL;
}
return (p_stLocalVS);
};
/*
=======================================================================================
Access functions
=======================================================================================
*/
/*
----------------------------------------------------------------------------------------
Description : set / get a LOD of a visual set object
----------------------------------------------------------------------------------------
*/
void GLI_vSetVisualSetLOD ( GEO_tdstVisualSet *p_stVisualSet, long lNumberOfLodToSet, MTH_tdxReal xThreshold, GEO_tdstGeometricObject *p_stObject)
{
if (lNumberOfLodToSet < p_stVisualSet->xNbLodDefinitions)
{
p_stVisualSet -> d_xThresholdsTable[lNumberOfLodToSet] = xThreshold;
p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSet] = p_stObject;
}
}
void GLI_vGetVisualSetLOD ( GEO_tdstVisualSet *p_stVisualSet, long lNumberOfLodToGet, MTH_tdxReal *p_xThreshold, GEO_tdstGeometricObject **h_stObject )
{
if (lNumberOfLodToGet < p_stVisualSet -> xNbLodDefinitions)
{
*p_xThreshold = p_stVisualSet -> d_xThresholdsTable[lNumberOfLodToGet] ;
*h_stObject = p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToGet] ;
}
}
GEO_tdstGeometricObject *GLI_hGetVisualSetGeometricForADistance( GEO_tdstVisualSet *p_stVSE, MTH_tdxReal xThreshold )
{
long lLod;
for (lLod = 0; lLod < p_stVSE->xNbLodDefinitions - 1; lLod ++)
{
if (p_stVSE->d_xThresholdsTable[ lLod + 1 ] > xThreshold)
break;
}
return (p_stVSE->d_p_stLodDefinitions[lLod]);
}
/*
----------------------------------------------------------------------------------------
Description : get number of LOD
----------------------------------------------------------------------------------------
*/
long GLI_lGetVisualSetNumbertOfLOD ( GEO_tdstVisualSet *p_stVisualSet )
{
return (p_stVisualSet->xNbLodDefinitions);
}
/*
=======================================================================================
Display
=======================================================================================
*/
/*
----------------------------------------------------------------------------------------
Description : send object to display, with distance to camera computation, choice of LOD,
fog check, and RLI
----------------------------------------------------------------------------------------
*/
void GLI_lSendVisualSetToViewportWithRLI2
(
struct GLD_tdstViewportAttributes_ *p_stVpt ,
GEO_tdstVisualSet *p_stVisualSet,
MTH3D_tdstVector *p_xCenter,
long lDrawModeMask,
ACP_tdxHandleToRadiosity hISI
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
ACP_tdxIndex lNumberOfLodToSend;
MTH_tdxReal xDistance;
MTH3D_tdstVector stLocal;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_xSetRLIForNextObjectToDraw ( NULL , NULL );
/* if visualset has only one LOD, and no fog or infinite fog distance, then display the LOD 0 */
if (p_stVisualSet -> xNbLodDefinitions == 1 && ( GLI_BIG_GLOBALS->xFogIsOn == 0 || GLI_BIG_GLOBALS->p_stActiveFog->xInfinite >= 50000.0f ) )
{
lNumberOfLodToSend = 0;
}
else
{
/*
* compute distance from camera to center of object
*/
POS_fn_vMulMatrixVertex ( &stLocal, g_p_stCurrentMatrix,p_xCenter );
POS_fn_vMulMatrixVertex ( &stLocal, &(( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD)->p_stCam->stMatrix , &stLocal);
xDistance = MTH3D_M_xNormVector( &stLocal ) ;
/* if fog is on and object is hidden by fog, then no display */
if (GLI_BIG_GLOBALS->xFogIsOn && xDistance >= GLI_BIG_GLOBALS->p_stActiveFog->xInfinite)
return;
/* find number of LOD to use according to distance */
for (lNumberOfLodToSend = 0; lNumberOfLodToSend < p_stVisualSet -> xNbLodDefinitions - 1; lNumberOfLodToSend ++)
{
if (p_stVisualSet -> d_xThresholdsTable [ lNumberOfLodToSend+1 ] > xDistance)
break;
}
}
/* look if it exist a RLI for the chosen LOD, if yes, set it */
if ((hISI) && (lNumberOfLodToSend<=ISI_fn_xGetNbLOD(hISI)))
{
GLI_xSetRLIForNextObjectToDraw (ISI_fn_dGetVertexRLILOD(hISI,lNumberOfLodToSend), p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSend]);
}
/* look if it exist a Geometric Object for the chosen LOD (???), if yes, send it to display */
if (p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSend] != NULL)
{
GLI_xSendObjectToViewportWithLights ( p_stVpt ,p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSend],lDrawModeMask);
}
}
/*
----------------------------------------------------------------------------------------
Description : send object to display, with distance to camera computation, choice of LOD,
fog check, but no RLI
----------------------------------------------------------------------------------------
*/
void GLI_lSendVisualSetToViewportBV2( struct GLD_tdstViewportAttributes_ *p_stVpt, GEO_tdstVisualSet *p_stVisualSet, MTH3D_tdstVector *p_xCenter, MTH_tdxReal xRadiusOfSphere, long lDrawModeMask)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
long lNumberOfLodToSend;
MTH3D_tdstVector stLocal;
MTH_tdxReal xDistance;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLI_xSetRLIForNextObjectToDraw ( NULL , NULL );
/* if visualset has only one LOD, and no fog or infinite fog distance, then display the LOD 0 */
if (p_stVisualSet -> xNbLodDefinitions == 1 && ( GLI_BIG_GLOBALS->xFogIsOn == 0 || GLI_BIG_GLOBALS->p_stActiveFog->xInfinite >= 50000.0f ) )
{
lNumberOfLodToSend = 0;
}
else
{
/*
* compute distance from camera to center of object
*/
POS_fn_vMulMatrixVertex ( &stLocal, g_p_stCurrentMatrix,p_xCenter );
POS_fn_vMulMatrixVertex ( &stLocal, &(( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD)->p_stCam->stMatrix , &stLocal);
xDistance = MTH3D_M_xNormVector( &stLocal ) ;
/* if fog is on and object is hidden by fog, then no display */
if (GLI_BIG_GLOBALS->xFogIsOn && xDistance >= GLI_BIG_GLOBALS->p_stActiveFog->xInfinite)
return;
/* find number of LOD to use according to distance */
for (lNumberOfLodToSend = 0; lNumberOfLodToSend < p_stVisualSet -> xNbLodDefinitions - 1; lNumberOfLodToSend ++)
{
if (p_stVisualSet -> d_xThresholdsTable [ lNumberOfLodToSend+1 ] > xDistance)
break;
}
}
/* look if it exist a Geometric Object for the chosen LOD (???), if yes, send it to display */
if (p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSend] != NULL)
{
GLI_xSendObjectToViewportWithLights (p_stVpt, p_stVisualSet->d_p_stLodDefinitions[lNumberOfLodToSend], lDrawModeMask);
}
}
/*
----------------------------------------------------------------------------------------
Description : send object to display, with absolute distance, choice of LOD
----------------------------------------------------------------------------------------
*/
void GLI_lSendVisualSetToViewport( struct GLD_tdstViewportAttributes_ *p_stVpt, GEO_tdstVisualSet *p_stVisualSet, MTH_tdxReal xDistance, long lDrawModeMask)
{
long lNumberOfLodToSend;
/* reset RLI : no RLI for this function */
GLI_xSetRLIForNextObjectToDraw ( NULL , NULL );
/* find the right LOD for the given dstance */
for (lNumberOfLodToSend = 0; lNumberOfLodToSend < p_stVisualSet -> xNbLodDefinitions - 1; lNumberOfLodToSend ++)
{
if (p_stVisualSet -> d_xThresholdsTable [ lNumberOfLodToSend+1 ] > xDistance)
break;
}
/* LOD found, check if exist and send to drawing */
if (p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSend] != NULL)
{
GLI_xSendObjectToViewportWithLights ( p_stVpt, p_stVisualSet -> d_p_stLodDefinitions[lNumberOfLodToSend], lDrawModeMask);
}
}
/*
----------------------------------------------------------------------------------------
Description : send object to display, with distance to camera computation, choice of LOD
----------------------------------------------------------------------------------------
*/
void GLI_lSendVisualSetToViewport2( struct GLD_tdstViewportAttributes_ *p_stVpt, GEO_tdstVisualSet *p_stVisualSet, MTH3D_tdstVector *p_xCenter, long lDrawModeMask)
{
MTH3D_tdstVector stLocal;
GLI_tdstSpecificAttributesFor3D *p_stSpecifAttrib3D;
/* put object center in camera axis system (p_xCenter is in local coordinates system */
p_stSpecifAttrib3D = ( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD;
/* put center in world axis system */
POS_fn_vMulMatrixVertex ( &stLocal, g_p_stCurrentMatrix,p_xCenter );
/* and in camera axis system */
POS_fn_vMulMatrixVertex ( &stLocal, &(( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD)->p_stCam->stMatrix , &stLocal);
/* and call display function with right distance */
GLI_lSendVisualSetToViewport( p_stVpt ,p_stVisualSet ,MTH3D_M_xNormVector( &stLocal ) ,lDrawModeMask);
}
/*
=======================================================================================
RLI
=======================================================================================
*/
/*
----------------------------------------------------------------------------------------
Description : return one of RLI Table
----------------------------------------------------------------------------------------
*/
ACP_tdxHandleToRadiosity GLI_hGetRLI ( GEO_tdxHandleToVisualSet hVisualSet, unsigned char ucIndex )
{
if ( ucIndex < hVisualSet->lNumberOfRLI )
return hVisualSet->d_hRLI[ucIndex] ;
return NULL;
}
/*
----------------------------------------------------------------------------------------
Description : compute a new RLI table that is a blend of two other table
----------------------------------------------------------------------------------------
*/
ACP_tdxHandleToRadiosity GLI_hComputeBlendRLI (GEO_tdxHandleToVisualSet hVisualSet, unsigned char ucIndex1, unsigned char ucIndex2, ACP_tdxIndex xNumISILOD, MTH_tdxReal xPercent)
{
if ( ucIndex1 < hVisualSet->lNumberOfRLI && ucIndex2 < hVisualSet->lNumberOfRLI )
{
return ISI_hComputeBlendRLI ( hVisualSet->d_hRLI[ucIndex1], hVisualSet->d_hRLI[ucIndex2], xNumISILOD, xPercent );
}
return NULL;
}
/*
----------------------------------------------------------------------------------------
Description : Set RLI table of a visual set
----------------------------------------------------------------------------------------
*/
void GLI_vVisualSetSetRLITable (GEO_tdxHandleToVisualSet hVisualSet, ACP_tdxHandleToRadiosity *d_hRLI, long lNumberOfTable)
{
if ( d_hRLI )
{
hVisualSet->d_hRLI = d_hRLI ;
hVisualSet->lNumberOfRLI = lNumberOfTable ;
}
}
/*
----------------------------------------------------------------------------------------
Description : Load the RLI section of the VSE of a charactere
----------------------------------------------------------------------------------------
*/
ACP_tdxHandleToRadiosity *GLI_vVisualSetLoadRLI (char *szSection, long *lNumberOfTable)
{
ACP_tdxHandleToRadiosity *d_hRLI ;
SCR_tdst_Cxt_Values *p_stVal=NULL;
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szSection, SCR_CDF_uw_Anl_Normal);
d_hRLI = (ACP_tdxHandleToRadiosity *)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
*lNumberOfTable = SCR_M_ul_RdL0_ExtractLongValue(p_stVal,1);
return (d_hRLI);
}
/*
----------------------------------------------------------------------------------------
Description : script callback for RLI section
----------------------------------------------------------------------------------------
*/
SCR_tde_Anl_ReturnValue GLI_fn_xLoadRLI(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
long lNumberOfRLI ;
ACP_tdxHandleToRadiosity *d_hRLI;
switch (cType)
{
case SCR_EA_Anl_BeginSection:
lNumberOfRLI = atol(szParams[1]) ;
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeRLI , NULL);
GEO_M_CPAMalloc(d_hRLI ,ACP_tdxHandleToRadiosity * ,sizeof ( ACP_tdxHandleToRadiosity ) ,E_uwGEONotEnoughtMemory );
SCR_M_RdL0_SetSectionLong(0,0,(long)d_hRLI);
SCR_M_RdL0_SetSectionLong(0,1,lNumberOfRLI);
SCR_M_RdL0_SetContextLong(0,0,(long)d_hRLI);
break;
}
return SCR_ERV_Anl_NormalReturn;
}
#ifdef __cplusplus
} /*extern "C"*/
#endif