431 lines
17 KiB
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
|