 
/* Oliv' - DEBUG*/
#ifdef U64
	#define U64_NO_PUSH_MATRIX
#endif /* U64 */
/* EndOfOliv'*/
 
/* (c) Ubi Studios 1996-97*/
/* See Vincent Greco for any comment or question*/
 
#include "ACP_base.h"
#include "cpa_std.h"
#include "GEO.h"
#include "GLI.h"
#include "PCS.h"
#include "PO.h"
/*XB980821*/
#ifndef D_THROW_IPO
#include "IPO.h"
#endif /* D_THROW_IPO */
/*End XB*/
#include "POS.h"
 
#include "PRF.h"
#include "LST.h"
 
 
 
 
#include "SPO/HieMtStk.h"
#include "SPO/HieConst.h"
#include "SPO/HieExt.h"
#ifdef U64
	#include "SPO/Specif/HieFunc.h"
#else
#include "SPO/HieDef.h"
#include "SPO/HieMacro.h"
#endif
#include "SPO/HieDraw.h"
#include "HieDrw.h"
 
#ifdef PSX
	/*Specific PSX : TEMP (will be done in MTH)*/
	#define MTH_tdxReal SCA_td_sl12
#endif /* PSX */
 
#include "SCT.h"
#ifndef D_THROW_PRT
#include "PRT.h"
#endif /* D_THROW_PRT */
#include "FIL.h"
#include "COL.h"
#include "MEC.h"
#include "GAM.h"
 
/*ANNECY MF BV test for whole perso {*/
extern GLI_tdstLight *gs_aDEF_p_CurrentListOfLight[C_lMaxLightInViewport];
extern long gs_CurrentNumberOfLightInViewport;
/*ENDANNECY MF}*/
 
/*HP 220698*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
extern GEO_tdstGeometricObject *HIE_fn_p_stGetGeometricObjectFromSuperObject( HIE_tdxHandleToSuperObject  h_SuperObject );
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/*.-----------------------------------------------------------------.*/
/*| Used to avoid several MulMatrixMatrix in the Rendering Pipeline |*/
/*'-----------------------------------------------------------------'*/
POS_tdstCompletePosition  *g_p_stCurrentInCamCoordsMatrix;
 
/*ENDANNECY*/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
MTH_tdxReal					VoidReal;
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
ACP_tdxHandleOfObject		GeoHandle;
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
HIE_tdxHandleToSuperObject	gd_hFixSPO[HIE_C_MaxNumberOfSPOInTheFix] ;
HIE_tdxHandleToSuperObject	gd_hFixSPOSave[HIE_C_MaxNumberOfSPOInTheFix] ;
ACP_tdxIndex g_xFixIndex	= 0;
ACP_tdxIndex g_xFixIndexSave	= 0;
 
 
#ifndef D_THROW_VISUAL_SET
#define New_M_hGetFirstLodOfVisualSetFromPo(Po)	\
(GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle)
#else
#define New_M_hGetFirstLodOfVisualSetFromPo(Po)	PO_fn_hGetGeometricObject(Po)
#endif /* D_THROW_VISUAL_SET */
 
#ifndef D_THROW_VISUAL_SET
#define New_M_hGetRepositionZoneFromPo(Po)	\
(GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle)
#else
#define New_M_hGetRepositionZoneFromPo(Po)	PO_fn_hGetGeometricObject(Po)
#endif /* D_THROW_VISUAL_SET */
 
#define SPO_M_UpdateLightsBeforeSending(_hSO,_hLight,_hVpt) \
{                                                           \
    if (HIE_fn_bGetSuperObjectExcluLight(_hSO))             \
        GLI_xSetViewportLightsOnOff(0);                     \
    _hLight=HIE_fn_hGetSuperObjectLight(_hSO);              \
    if(_hLight)                                             \
        GLI_vAddLightToViewport(_hVpt,_hLight);             \
}
 
#define SPO_M_UpdateLightsAfterSending(_hSO,_hLight,_hVpt)  \
{                                                           \
    if(_hLight)                                             \
    {                                                       \
        GLI_vPopLightsInViewport(_hVpt , 1);                \
    }                                                       \
    if (HIE_fn_bGetSuperObjectExcluLight(_hSO))             \
        GLI_xSetViewportLightsOnOff(1);                     \
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
 
/***********************************************************************************************/
/*  Name        : HIE_hRetrieveCurrentMatrix*/
/*  Description : Returns the Current Matrix*/
/*  Rq          : This function will be the only exported one.*/
/***********************************************************************************************/
POS_tdstCompletePosition * HIE_hRetrieveCurrentMatrix()
{
  return g_p_stCurrentInCamCoordsMatrix;
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
 
#if defined(ACTIVE_EDITOR) /* {*/
 
/*
 *=================================================================================================
 *=================================================================================================
 */
void HIE_fn_vSendSuperObjectToViewport
(
  GLD_tdxHandleToViewportAttributes _hVpt,
  HIE_tdxHandleToSuperObject        _hSprObj,
  long                              _DrawMask
)
{
	ACP_tdxIndex                i;
	HIE_tdxHandleToSuperObject  hChild;
	GLI_tdxHandleToLight        hLight;
 
	assert(0);
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPushMatrix (_hSprObj);
#endif
	HIE_fn_vPushOnCameraMatrixStack(_hSprObj);
 
	hLight = HIE_fn_hGetSuperObjectLight(_hSprObj);
	if(hLight)
		GLI_vAddLightToViewport(_hVpt,hLight);
 
	if(fn_bSendOneSuperObjectToViewport(_hVpt ,_hSprObj , &_DrawMask , GEO_C_lCullingOut))
	{
		if (HIE_fn_ulGetSuperObjectType(_hSprObj) == HIE_C_ulActor)
		{
			HIE_M_ForEachChildOf(_hSprObj, hChild, i)
				HIE_fn_vSendSuperObjectToViewport(_hVpt, hChild, HIE_fn_lGetSuperObjectDrawMask(_hSprObj));
		}
		else
		{
			HIE_M_ForEachChildOf(_hSprObj, hChild, i)
				HIE_fn_vSendSuperObjectToViewport(_hVpt, hChild, HIE_fn_lGetSuperObjectDrawMask(_hSprObj)&_DrawMask);
		}
	}
	if(hLight)
		GLI_vPopLightsInViewport(_hVpt , 1);
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPopMatrix();
#endif
	HIE_fn_vPopOnCameraMatrixStack();
}
 
#endif /* ACTIVE_EDITOR }*/
 
/*
 *=================================================================================================
 *=================================================================================================
 */
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void HIE_fn_vSelectSuperObject(HIE_tdxHandleToSuperObject _hSprObj)
{
	HIE_fn_vSetSuperObjectDrawMask(_hSprObj, HIE_fn_lGetSuperObjectDrawMask(_hSprObj)&(GLI_C_lAllIsEnable-(GLI_C_lIsNotOutlined)));
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
void HIE_fn_vUnselectSuperObject(HIE_tdxHandleToSuperObject   _hSprObj)
{
  HIE_fn_vSetSuperObjectDrawMask(_hSprObj, HIE_fn_lGetSuperObjectDrawMask(_hSprObj)|(GLI_C_lIsNotOutlined));
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/*
 *=================================================================================================
 *=================================================================================================
 */
#if defined(_U64_GLI_BENCH_)
	extern ACP_tdxBool GLIBENCH_g_bBVBox;
	extern ACP_tdxBool GLIBENCH_g_bColMap;
	extern void	GLIBENCH_fn_vSendParallelBoxToViewport(GLD_tdxHandleToViewportAttributes,MTH3D_tdstVector*,MTH3D_tdstVector*);
#endif /* _U64_GLI_BENCH_ */
 
/* called only if relevant!*/
void HIE_fn_vSendStaticWorldToViewport
(
	GLD_tdxHandleToViewportAttributes	_hVpt,
  HIE_tdxHandleToSuperObject _hSprObj,
  long _DrawMask,
	long _lCullingResult
)
{
	ACP_tdxIndex				i;
	HIE_tdxHandleToSuperObject	hChild;
	long lCullingResult;
	GEO_tdxHandleToParallelBox hParallelBox;
	MTH3D_tdstVector *p_stBdvMinPoint, *p_stBdvMaxPoint;
	MTH3D_tdstVector stMinPoint,stMaxPoint;
	/* the drawmask doesnt change for the children, so compute it once and for all*/
	_DrawMask &= HIE_fn_lGetSuperObjectDrawMask(_hSprObj);
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPushMatrix(_hSprObj);
#endif
	HIE_fn_vPushOnCameraMatrixStack(_hSprObj);
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
 
  if ( _lCullingResult != GEO_C_lCullingOut )
  {
/* Oliv' - 25/05/1999 - always draw collision object for ColMap even if it's not visible */
#if defined(_U64_GLI_BENCH_)
    if(HIE_M_MustBeDisplayed(_DrawMask) && (!HIE_fn_SO_bIsHidden(_hSprObj) || GLIBENCH_g_bColMap) )
#else
    if(HIE_M_MustBeDisplayed(_DrawMask) && !HIE_fn_SO_bIsHidden( _hSprObj ))
#endif /* _U64_GLI_BENCH */
/* EndOfOliv' */
    {
      fn_vSendOneModuleToViewPort(_hVpt ,_hSprObj, _DrawMask);
    }
  }
 
	HIE_M_ForEachChildOf(_hSprObj, hChild, i)
	{
	  hParallelBox = (GEO_tdxHandleToParallelBox) HIE_fn_hGetSuperObjectBoundingVolume(hChild);
		if ( hParallelBox ) {
			POS_tdstCompletePosition * hMatrix;
 
			/*get the bounding volume extremities*/
			p_stBdvMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
			p_stBdvMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
 
			/* add translation if object wasn't centered*/
			hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(hChild);
			if(!POS_fn_ulIsIdentityMatrix(hMatrix)) {
				MTH3D_M_vAddVector(&stMinPoint ,&hMatrix->stTranslationVector, p_stBdvMinPoint);
				MTH3D_M_vAddVector(&stMaxPoint ,&hMatrix->stTranslationVector, p_stBdvMaxPoint);
				p_stBdvMinPoint = &stMinPoint;
				p_stBdvMaxPoint = &stMaxPoint;
			}
 
			lCullingResult = GEO_lCullingBox(_hVpt, p_stBdvMinPoint, p_stBdvMaxPoint, _lCullingResult);
#if defined(_U64_GLI_BENCH_)
			if( GLIBENCH_g_bBVBox )
			{
				GLIBENCH_fn_vSendParallelBoxToViewport(
					_hVpt,
					p_stBdvMinPoint,
					p_stBdvMaxPoint
				);
			}
#endif /* _U64_GLI_BENCH_ */
		}
		else
		{
			lCullingResult = GEO_C_lCullingIntersect;
		}
		if ( (lCullingResult != GEO_C_lCullingOut) || HIE_fn_SO_bCheckChildren(hChild) )
		{
			HIE_fn_vSendStaticWorldToViewport(
				_hVpt,
				hChild,
				_DrawMask,
				lCullingResult
			);
		}
	}
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
 
#if !defined(U64_NO_PUSH_MATRIX)
  HIE_fn_vPopMatrix ();
#endif
	HIE_fn_vPopOnCameraMatrixStack();
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
}
/*END fbolefeysot}*/
 
/*
 *=================================================================================================
 *=================================================================================================
 */
 
/* FQ*/
#ifdef U64
 
/* Light computation for Ultra64 function proto*/
void fn_vComputeLightsForCharacter(HIE_tdxHandleToSuperObject _hSprObj,
								   GLD_tdstViewportAttributes *_p_stViewport);
 
/* flag to determine wether the lights have been copied or not...*/
extern char g_HaveLightsBeenCopied;
extern Gfx *g_CharacterNonTransparentLightsBegin;
 
#endif
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
static int  gs_iModuleCounterForChar = 0;
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
void HIE_fn_vSendCharacterModulesToViewPort
(
	GLD_tdxHandleToViewportAttributes	_hVpt,
    HIE_tdxHandleToSuperObject			_hSprObj,
    long								_DrawMask
/*	ACP_tdxBool							_bUselessCulling*/
)
{
	ACP_tdxIndex						i;
	HIE_tdxHandleToSuperObject			hChild;
	GLI_tdxHandleToLight				hLight;
 
 
	/*
	* test if it isn't a superimposed SPO
	* superimposed SPO go only in the fix viewport
	*/
	if ( HIE_fn_SO_bIsSuperimposed (_hSprObj) )
	{
		return ;
	}
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPushMatrix (_hSprObj);
#endif
	HIE_fn_vPushOnCameraMatrixStack(_hSprObj);
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
 
  SPO_M_UpdateLightsBeforeSending(_hSprObj , hLight , _hVpt);
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
 
  _DrawMask &= HIE_fn_lGetSuperObjectDrawMask(_hSprObj);
  if ( HIE_M_MustBeDisplayed(_DrawMask) && !HIE_fn_SO_bIsHidden( _hSprObj ) )
	  fn_vSendOneModuleToViewPort(_hVpt ,_hSprObj , _DrawMask);
 
	HIE_M_ForEachChildOf(_hSprObj, hChild, i)
	if (HIE_fn_ulGetSuperObjectType(hChild)!=HIE_C_ulActor)
		HIE_fn_vSendCharacterModulesToViewPort(_hVpt, hChild, _DrawMask/*, _bUselessCulling*/);
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
 
  SPO_M_UpdateLightsAfterSending(_hSprObj , hLight , _hVpt);
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPopMatrix ();
#endif
	HIE_fn_vPopOnCameraMatrixStack();
 
  PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
  PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
}
 
 
 
 
unsigned char fn_ucGetNumberOfRLIFromCharacter (HIE_tdxHandleToSuperObject, unsigned char *, unsigned char *, MTH_tdxReal * );
 
void HIE_fn_vSendCharacterToViewport
(
	GLD_tdxHandleToViewportAttributes	_hVpt,
	HIE_tdxHandleToSuperObject			_hSprObj,
	long								_DrawMask,
	long							_lCullingResult /*culling result of the parent sector*/
)
{
	ACP_tdxIndex						i;
	HIE_tdxHandleToSuperObject			hChild;
	GLI_tdxHandleToLight				hLight;
	GEO_tdxHandleToBoundingSphere		hBoundingSphere = NULL;
	ACP_tdxBool                         bCanComputeLight , bDisplayed , bOnPlatform;
	MTH_tdxReal							xTransparencyZoneLevel,xTransparencyZoneMax,xMaxZone,xMinZone;
	unsigned long						ulCustomBit , ulFlags , ulDrawMask;
	unsigned char						ucIndex1, ucIndex2, ucNbRLIUse ;
	MTH_tdxReal							xPercent ;
	MTH3D_tdstVector *p_stSphereCenter;
	MTH_tdxReal							xSphereRadius;
	HIE_tdxHandleToSuperObject			hFather;
	
	/* FQ : This allows us to copy the lights*/
	/* on the "translucent" gfx list only when required :-)*/
#ifdef U64
	g_CharacterNonTransparentLightsBegin=NULL;
	g_HaveLightsBeenCopied=0;
#endif
	
	/*
	* test if it isn't a superimposed SPO or an inactive object
	* superimposed SPO go only in the fix viewport
	*/
	if ( HIE_fn_SO_bIsSuperimposed (_hSprObj) || !M_ObjectIsActive((struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(_hSprObj)) )
	{
		return ;
	}
 
	/* get custom bit*/
	ulCustomBit = fn_ulStandardGameGetCustomBitsSO(_hSprObj);
 
	/* compute distance to Main character if needed */
	/*
	 * now computed for all active actors in the fn_vUpdateTooFarFlagOfAllActiveActors() function of GAM module 
	 *
	if( ulCustomBit & (GAM_C_CustBitNoAnimPlayerWhenTooFar|GAM_C_CustBitNoAIWhenTooFar|GAM_C_CustBitNoMecaWhenTooFar))
	{
		HIE_tdxHandleToSuperObject hMainChar = MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());
		if(hMainChar == _hSprObj)
		{
			fn_vStandardGameSetTooFar(M_GetMSHandle(_hSprObj,StandardGame),FALSE);
		}
		else
		{
			MTH3D_tdstVector stDist;
			
			MTH3D_M_vSubVector( &stDist , POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj)) , POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hMainChar)) );
			
			if( MTH_M_bLess(MTH3D_M_xNorm1Vector(&stDist) , (MTH_tdxReal)fn_ucStandardGameGetTooFarLimitSO(_hSprObj)) )
			{
				fn_vStandardGameSetTooFar(M_GetMSHandle(_hSprObj,StandardGame),FALSE);
			}
			else
			{
				fn_vStandardGameSetTooFar(M_GetMSHandle(_hSprObj,StandardGame),TRUE);
			}
		}
	}
	*/
	/**/
	if( HIE_fn_SO_bIsHidden(_hSprObj) )
	{
		MS_tdxHandleToStandardGame hStdGame = M_GetMSHandle(_hSprObj,StandardGame);
		/* MT 26/03/99: a nouveau necessaire */
		fn_vStandardGameSetCustomBits(hStdGame, ulCustomBit | GAM_C_CustBitOutOfVisibility);
		fn_vStandardGameSetUselessCulling(hStdGame, FALSE);
		return;
	}
	
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	
	bOnPlatform = FALSE;
	hFather = HIE_M_hGetSuperObjectFather(_hSprObj);
	if( hFather && (HIE_fn_ulGetSuperObjectType(hFather) == HIE_C_ulActor) && (fn_ucStandardGameGetPlatFormType(M_GetMSHandle(hFather, StandardGame)) != 0) )
	{
		bOnPlatform = TRUE;
#if !defined(U64_NO_PUSH_MATRIX)
		HIE_fn_vPushMatrix (hFather);
#endif
		HIE_fn_vPushOnCameraMatrixStack(hFather);
	}
	
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPushMatrix (_hSprObj);
#endif
	HIE_fn_vPushOnCameraMatrixStack(_hSprObj);
	
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
	
	hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
	if (hBoundingSphere)
	{
		p_stSphereCenter = GEO_fn_pGetCenterPointOfBoundingSphere(hBoundingSphere);
		xSphereRadius = GEO_fn_xGetRadiusOfBoundingSphere(hBoundingSphere);
	}
 
	/* // Transparency Zone*/
	if( ulCustomBit & GAM_C_CustBitUsesTransparencyZone )
	{
		xTransparencyZoneMax    = GEO_xGetZFar();
		xTransparencyZoneLevel  = GEO_xGetZFarTransparencyZone();
		xMaxZone				= (MTH_tdxReal)fn_ucStandardGameGetTransparencyZoneMaxSO(_hSprObj);
		xMinZone				= (MTH_tdxReal)fn_ucStandardGameGetTransparencyZoneMinSO(_hSprObj);
		
		if( MTH_M_bIsNull(xTransparencyZoneMax) )
		{
			GEO_vSetZFar( xMaxZone );
			GEO_vSetZFarTransparencyZone( MTH_M_xSub( xMaxZone , xMinZone ) );
		}
		else if( MTH_M_bLess( xMinZone , xTransparencyZoneMax ) )
		{
			GEO_vSetZFar( MTH_M_xMin(xTransparencyZoneMax , xMaxZone) );
			GEO_vSetZFarTransparencyZone( MTH_M_xSub( GEO_xGetZFar() , xMinZone ) );
		}
		ulFlags = HIE_fn_SO_ulGetFlags(_hSprObj);
		HIE_fn_SO_vSetFlags(_hSprObj, ulFlags | HIE_C_Flag_ModuleTransparency);
		ulDrawMask = HIE_fn_lGetSuperObjectDrawMask(_hSprObj);
		HIE_fn_vSetSuperObjectDrawMask(_hSprObj , ulDrawMask & ~GLI_C_lIsNotGrided );
		/* culling must be done for near/far planes to take account transparency zone*/
		_lCullingResult &= ~(GEO_C_lCullingNear | GEO_C_lCullingFar);
	}
	
	/* culling*/
	if( (_lCullingResult != GEO_C_lCullingIn) && hBoundingSphere )
		_lCullingResult = GEO_lCullingSphereNoMMM(_hVpt, p_stSphereCenter, xSphereRadius, HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), _lCullingResult);
	else
		_lCullingResult  = GEO_C_lCullingIn; /* to force recursive culling*/
	
#ifdef U64
	/* FQ BANJO*/
	/* Note : This is for N64 only*/
	/* We can't display opaque objects as transparent ones even when using*/
	/* fCullingTransparency == 1.0f*/
	
	if (GEO_g_xZFarTransparencyLevel==1.0f)
	{
		unsigned long ulCustomBit;
		ulCustomBit = fn_ulStandardGameGetCustomBitsSO(_hSprObj);
		if ((ulCustomBit & GAM_C_CustBitUsesTransparencyZone))
		{
			/* osSyncPrintf("Superior !! GlobalAlpha=%f\n",GLI_vGetGlobalAlpha());*/
			HIE_fn_vSetSuperObjectDrawMask(_hSprObj , ulDrawMask );
		}
	}
	/*/////////////////////*/
#endif
	
	_DrawMask |= ~HIE_C_InheritableFlags;
	_DrawMask &= HIE_fn_lGetSuperObjectDrawMask(_hSprObj);
	/* invisibility bit && culling bit*/
	if ( HIE_M_MustBeDisplayed(_DrawMask) && !HIE_fn_SO_bIsHidden( _hSprObj ) && (_lCullingResult != GEO_C_lCullingOut) )
	{   /* clear*/
		ulCustomBit &= ~GAM_C_CustBitOutOfVisibility;
		bDisplayed = TRUE;
		/* set*/
		fn_vStandardGameSetUselessCulling(M_GetMSHandle(_hSprObj,StandardGame), TRUE);
		/*_bUselessCulling = TRUE;*/
	}
	else
	{   /* set*/
		/* MT 26/03/99: a nouveau necessaire */
		ulCustomBit |= GAM_C_CustBitOutOfVisibility;
		bDisplayed = FALSE;
		/* clear*/
		fn_vStandardGameSetUselessCulling(M_GetMSHandle(_hSprObj,StandardGame), FALSE);
		/*_bUselessCulling = FALSE;*/
	}
	/**/
	fn_vStandardGameSetCustomBits(M_GetMSHandle(_hSprObj,StandardGame), ulCustomBit);
	
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
	
	if( bDisplayed && (HIE_M_lGetNumberOfChildren(_hSprObj) > 0) )
	{
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
		
		ucNbRLIUse = fn_ucGetNumberOfRLIFromCharacter (_hSprObj, &ucIndex1, &ucIndex2, &xPercent) ;
		HIE_vSetCharactereRLI ( ucNbRLIUse, ucIndex1, ucIndex2, xPercent ) ;
		
#if defined(U64)
		bCanComputeLight = TRUE;
#else
		fn_v3dDataUpdateLightCounter(_hSprObj);
		bCanComputeLight = fn_b3dDataCanComputeLight(_hSprObj);
#endif
		if ( ucNbRLIUse > 0 )
		{
			GLI_xSetViewportLightsOnOff(0);
		}	
		else
		{
			SPO_M_UpdateLightsBeforeSending(_hSprObj , hLight , _hVpt);
		}
#if !defined(U64)
		
		if ( hBoundingSphere )
		{
			MTH3D_tdstVector stAbsCenter /*, stLocalCenter*/;
			int iCpt;
			POS_tdstCompletePosition *hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj);
			
			xSphereRadius = MTH_M_xMul(xSphereRadius, POS_fn_xGetMaxScale(hGlobalMatrix));
			
			POS_fn_vMulMatrixVertex( &stAbsCenter, hGlobalMatrix, p_stSphereCenter);
			
			/* for each light that has been registered at this point */
			/* look if the light affects this perso and set the result in the array */
			/* the array will be used when computing color of points */
			for ( iCpt = 0 ; iCpt < gs_CurrentNumberOfLightInViewport ; iCpt ++ )
			{
				if ( GLI_bDoesLightAffectBV( gs_aDEF_p_CurrentListOfLight[ iCpt ], &stAbsCenter, xSphereRadius ) )
					GLI_vSetLightActivityForChar( iCpt, 1 );
				else
					GLI_vSetLightActivityForChar( iCpt, 0 );
			}
			
		}
		else
		{
			/* no BV, so light always affect perso */
			GLI_vResetTableOfActiveLightsForChar( (char)(bCanComputeLight ? GLI_C_ActivateLight : GLI_C_DisactivateLight));
		}
		
#else  /* U64 */
		
		fn_vComputeLightsForCharacter(_hSprObj, _hVpt);
		
#endif /* U64 */
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
		
		HIE_M_ForEachChildOf(_hSprObj, hChild, i)
		if (HIE_fn_ulGetSuperObjectType(hChild)!=HIE_C_ulActor)
			HIE_fn_vSendCharacterModulesToViewPort(_hVpt, hChild, _DrawMask/* , _bUselessCulling*/);
			
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
		if ( ucNbRLIUse > 0 )
		{
			GLI_xSetViewportLightsOnOff(1);
		}	
		else
		{
			SPO_M_UpdateLightsAfterSending(_hSprObj , hLight , _hVpt);
		}
		
		HIE_vSetCharactereRLI ( 0, 0, 0, 0 ) ;
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
	}
	
	/* Transparency Zone*/
	if( ulCustomBit & GAM_C_CustBitUsesTransparencyZone )
	{
		GEO_vSetZFar( xTransparencyZoneMax );
		GEO_vSetZFarTransparencyZone( xTransparencyZoneLevel );
		HIE_fn_SO_vSetFlags(_hSprObj, ulFlags);
		HIE_fn_vSetSuperObjectDrawMask(_hSprObj , ulDrawMask );
	}
	
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPopMatrix();
#endif
	HIE_fn_vPopOnCameraMatrixStack();
	
	if( bOnPlatform )
	{
#if !defined(U64_NO_PUSH_MATRIX)
		HIE_fn_vPopMatrix ();
#endif
		HIE_fn_vPopOnCameraMatrixStack();
	}
	
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendToViewPort );
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
/*
HIE_tdxHandleToSuperObject HIE_fn_hFindFirstMirrorInHierarchy
(
	GLD_tdxHandleToViewportAttributes	_hVpt,
    HIE_tdxHandleToSuperObject			_hSprObj
)
{
	ACP_tdxIndex					i;
	HIE_tdxHandleToSuperObject		hRet;
	HIE_tdxHandleToSuperObject		hChild;
	GEO_tdxHandleToBoundingSphere	hBoundingSphere = NULL;
	MTH3D_tdstVector				*p_stSphereCenter;
	MTH_tdxReal						xSphereRadius;
	GEO_tdxHandleToParallelBox		hParallelBox = NULL;
	MTH3D_tdstVector				stMinPoint;
	MTH3D_tdstVector				stMaxPoint;
	POS_tdstCompletePosition		stIdentityMatrix;
	ACP_tdxBool						bHasABoxBoundingVolume;
	long							lType;
 
	lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
	hRet=NULL;
	//be careful : no push nor pop
	bHasABoxBoundingVolume = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj);
	if( bHasABoxBoundingVolume )
		hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
	else
		hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
 
 
	if ( (bHasABoxBoundingVolume) && (hParallelBox) )
	{
		MTH3D_tdstVector	*p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
		MTH3D_tdstVector	*p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
		MTH3D_tdstVector	*p_stTranslation = POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj));
 
		MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , p_stTranslation);
		MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , p_stTranslation);
 
		POS_fn_vSetIdentityMatrix(&stIdentityMatrix);
	}
	else if ( hBoundingSphere )
	{
		p_stSphereCenter = GEO_fn_pGetCenterPointOfBoundingSphere(hBoundingSphere);
		xSphereRadius = GEO_fn_xGetRadiusOfBoundingSphere(hBoundingSphere);
	}
 
 
	if
	(
		( (!hBoundingSphere) && (!hParallelBox) )
		||
		(
			(!bHasABoxBoundingVolume)
			&& (GEO_lCullingSphere(_hVpt, p_stSphereCenter, xSphereRadius,HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj)) != GEO_C_lCullingOut)
		)
		||
		(
			(bHasABoxBoundingVolume)
			&& (GEO_lCullingBox(_hVpt, &stMinPoint, &stMaxPoint) != GEO_C_lCullingOut)
		)
	)
	{
		if (lType & (HIE_C_ulMirror | HIE_C_ulPO_Mirror | HIE_C_ulIPO_Mirror))
			hRet=_hSprObj;
		else
			HIE_M_ForEachChildOf(_hSprObj, hChild, i)
		{
            if( (hRet=HIE_fn_hFindFirstMirrorInHierarchy(_hVpt, hChild)) != NULL)
                break;
		}
	}
	return hRet;
}
*/
/*
 *=================================================================================================
 *=================================================================================================
 */
 
#ifndef U64 /* no mirror on U64*/
int HIE_fn_bFindMirrorInHierarchy(HIE_tdxHandleToSuperObject _hSprObj) {
	int i;
	HIE_tdxHandleToSuperObject hChild;
 
	/* find the first mirror and stop*/
    if (HIE_fn_ulGetSuperObjectType(_hSprObj) & (HIE_C_ulMirror | HIE_C_ulPO_Mirror | HIE_C_ulIPO_Mirror))
		return TRUE;
 
	/*search in the sub hierarchy*/
	HIE_M_ForEachChildOf(_hSprObj,hChild,i) {
		if (HIE_fn_bFindMirrorInHierarchy(hChild))
			return TRUE;
	}
 
	return FALSE;
}
 
void HIE_fn_hFindAllMirrorsInHierarchy
(
	GLD_tdxHandleToViewportAttributes	_hVpt,
    HIE_tdxHandleToSuperObject			_hSprObj,
    HIE_tdxHandleToSuperObject			*p_hHandleOfMirror,
    ACP_tdxHandleOfObject				*p_hHandleOfGeometricMirror,
    short								*p_shNbOfMirrors,
    short								shNbMaxOfMirrors
)
{
	HIE_tdxHandleToSuperObject			hChild;
	GEO_tdxHandleToBoundingSphere		hBoundingSphere = NULL;
	MTH3D_tdstVector					stSphereCenter;
	MTH_tdxReal							xSphereRadius;
	GEO_tdxHandleToParallelBox			hParallelBox = NULL;
	MTH3D_tdstVector					stMinPoint;
	MTH3D_tdstVector					stMaxPoint;
	POS_tdstCompletePosition			stIdentityMatrix;
	ACP_tdxBool							bHasABoxBoundingVolume;
	ACP_tdxIndex						i;
	long								lType;
 
 
	lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
 
 
	bHasABoxBoundingVolume = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj);
	if( bHasABoxBoundingVolume )
		hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
	else
		hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
 
 
  if ((bHasABoxBoundingVolume) && (hParallelBox))
  {
    MTH3D_tdstVector	*p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
    MTH3D_tdstVector	*p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
    MTH3D_tdstVector	*p_stTranslation = POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj));
    
    MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , p_stTranslation);
    MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , p_stTranslation);
    
    POS_fn_vSetIdentityMatrix(&stIdentityMatrix);
  }
  
  if ((!bHasABoxBoundingVolume) && (hBoundingSphere))
  {
    MTH3D_M_vCopyVector(&stSphereCenter, GEO_fn_pGetCenterPointOfBoundingSphere(hBoundingSphere));
    xSphereRadius = GEO_fn_xGetRadiusOfBoundingSphere(hBoundingSphere);
  }
  
  
  if 
  (
    ( (!hBoundingSphere) && (!hParallelBox) )
  ||
    (
      (!bHasABoxBoundingVolume)
    && 
      (GEO_lCullingSphere(_hVpt, &stSphereCenter, xSphereRadius,HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), GEO_C_lCullingOut) != GEO_C_lCullingOut)
    )
  ||
    (
      (bHasABoxBoundingVolume)
    && 
      (GEO_lCullingBox(_hVpt, &stMinPoint, &stMaxPoint, GEO_C_lCullingOut) != GEO_C_lCullingOut)
    )
  ) 
  {
    if (lType & (HIE_C_ulMirror | HIE_C_ulPO_Mirror | HIE_C_ulIPO_Mirror))
    {
      if (*p_shNbOfMirrors < shNbMaxOfMirrors)
      {
        p_hHandleOfMirror[ *p_shNbOfMirrors]=_hSprObj;
        /*HIE_C_ulMirror for mirrors in static hierachy without collision*/
        if ( lType == HIE_C_ulMirror )
          p_hHandleOfGeometricMirror[*p_shNbOfMirrors]=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
        
        /*HIE_C_ulPO_Mirror for mirrors in dynamic hierachy ( Mirrors in animation of characters )*/
        else if ( lType == HIE_C_ulPO_Mirror )
          p_hHandleOfGeometricMirror[*p_shNbOfMirrors]=New_M_hGetRepositionZoneFromPo((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj));
        
        /*HIE_C_ulIPO_Mirror for mirrors in static hierachy with collision*/
        /*XB980821*/
#ifndef D_THROW_IPO
        else if ( lType == HIE_C_ulIPO_Mirror )
          p_hHandleOfGeometricMirror[*p_shNbOfMirrors]=New_M_hGetRepositionZoneFromPo(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj)));
#endif /* D_THROW_IPO */
        /*End XB*/
        
        (*p_shNbOfMirrors) ++;
      }
    }
    /*Recurrence*/
    HIE_M_ForEachChildOf(_hSprObj, hChild, i)
    {
      HIE_fn_hFindAllMirrorsInHierarchy(_hVpt, hChild,p_hHandleOfMirror,p_hHandleOfGeometricMirror,p_shNbOfMirrors,shNbMaxOfMirrors);
    }
  }
}
#endif
 
 
/*
 *=================================================================================================
 *=================================================================================================
 */
void HIE_fn_vSendSPOToFixViewport
(
	GLD_tdxHandleToViewportAttributes	_hVpt,
  HIE_tdxHandleToSuperObject			_hSprObj,
  long								_DrawMask,
	long							_lCullingResult
)
{
	ACP_tdxIndex                        i;
	HIE_tdxHandleToSuperObject          hChild;
	GLI_tdxHandleToLight                hLight;
	GEO_tdxHandleToBoundingSphere		hBoundingSphere = NULL;
	ACP_tdxBool                         bDisplayed;
	MTH3D_tdstVector					stSphereCenter;
	MTH_tdxReal							xSphereRadius;
	unsigned long						ulCustomBit;
	unsigned char						ucIndex1, ucIndex2, ucNbRLIUse ;
	MTH_tdxReal							xPercent ;
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
 
 
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPushMatrix (_hSprObj);
#endif
 
	HIE_fn_vPushOnCameraMatrixStack(_hSprObj);
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
 
	if ( HIE_fn_ulGetSuperObjectType(_hSprObj) == HIE_C_ulActor )
	{
		if( HIE_M_lGetNumberOfChildren(_hSprObj) > 0)
		{
			MS_tdxHandleToStandardGame hStdGame = M_GetMSHandle(_hSprObj,StandardGame);
 
			hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
			if ( hBoundingSphere )
			{
				MTH3D_M_vCopyVector(&stSphereCenter, GEO_fn_pGetCenterPointOfBoundingSphere(hBoundingSphere));
				xSphereRadius = GEO_fn_xGetRadiusOfBoundingSphere(hBoundingSphere);
			}
 
			if( (_lCullingResult != GEO_C_lCullingIn) && hBoundingSphere )
				_lCullingResult = GEO_lCullingSphereNoMMM(_hVpt, &stSphereCenter, xSphereRadius, HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), _lCullingResult);
			else
				_lCullingResult = GEO_C_lCullingIn; /* to force recursive culling*/
 
			_DrawMask |= ~HIE_C_InheritableFlags;
			_DrawMask &= HIE_fn_lGetSuperObjectDrawMask(_hSprObj);
			ulCustomBit = fn_ulStandardGameGetCustomBitsSO(_hSprObj);
 
			/* invisibility bit & culling bit*/
			if ( HIE_M_MustBeDisplayed(_DrawMask) && !HIE_fn_SO_bIsHidden( _hSprObj ) && (_lCullingResult != GEO_C_lCullingOut))
			{   /* clear*/
				ulCustomBit &= ~GAM_C_CustBitOutOfVisibility;
				bDisplayed = TRUE;
				/* set*/
				fn_vStandardGameSetUselessCulling(hStdGame, TRUE);
				/*_bUselessCulling = TRUE;*/
			}
			else
			{   /* set*/
				/* MT 26/03/99 : a nouveau necessaire */
				ulCustomBit |= GAM_C_CustBitOutOfVisibility;
				bDisplayed = FALSE;
				/* clear*/
				fn_vStandardGameSetUselessCulling(hStdGame, FALSE);
				/*_bUselessCulling = FALSE;*/
			}
			/**/
			fn_vStandardGameSetCustomBits(hStdGame, ulCustomBit);
 
			PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
 
			if(bDisplayed)
			{
				PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
 
				SPO_M_UpdateLightsBeforeSending(_hSprObj , hLight , _hVpt);
				ucNbRLIUse = fn_ucGetNumberOfRLIFromCharacter (_hSprObj, &ucIndex1, &ucIndex2, &xPercent) ;
				HIE_vSetCharactereRLI ( ucNbRLIUse, ucIndex1, ucIndex2, xPercent ) ;
 
 
				PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
				PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
 
				HIE_M_ForEachChildOf(_hSprObj, hChild, i)
				if (HIE_fn_ulGetSuperObjectType(hChild)!=HIE_C_ulActor)
					HIE_fn_vSendSPOToFixViewport(_hVpt, hChild, _DrawMask , _lCullingResult);
 
				PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
				PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
 
				SPO_M_UpdateLightsAfterSending(_hSprObj , hLight , _hVpt);
				HIE_vSetCharactereRLI(0, 0, 0, 0) ;
				PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvLight );
			}
		}
		else
		{
			PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
		}
	}
	else
	{
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
 
		_DrawMask &= HIE_fn_lGetSuperObjectDrawMask(_hSprObj);
		if ( HIE_M_MustBeDisplayed(_DrawMask) && !HIE_fn_SO_bIsHidden( _hSprObj ) )
			fn_vSendOneModuleToViewPort(_hVpt ,_hSprObj , _DrawMask);
 
		HIE_M_ForEachChildOf(_hSprObj, hChild, i)
		if ( HIE_fn_ulGetSuperObjectType(hChild) != HIE_C_ulActor )
			HIE_fn_vSendSPOToFixViewport(_hVpt, hChild, _DrawMask, _lCullingResult);
 
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
	}
 
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
 
#if !defined(U64_NO_PUSH_MATRIX)
	HIE_fn_vPopMatrix ();
#endif
	HIE_fn_vPopOnCameraMatrixStack();
 
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvStack );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon , PRF_C_pvSendFix );
}
/*
 *=================================================================================================
 *=================================================================================================
 */
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
extern void HIE_fn_vUpdateRasterForSuperObject( HIE_tdxHandleToSuperObject _hSuperObject,
										 unsigned long _ulRasterObject,
										 unsigned long _ulRasterFace,
										 unsigned long _ulRasterElement );
#else
	#define HIE_fn_vUpdateRasterForSuperObject(_hSuperObject,_ulRasterObject,_ulRasterFace,_ulRasterElement)
#endif
ACP_tdxBool HIE_fn_bSendSPOToFixViewport(struct GLD_tdstViewportAttributes_ *p_stFixViewportAttr, long _lDrawMask)
{
	ACP_tdxIndex				xI;
	HIE_tdxHandleToSuperObject	*hSPO;
	char						cSaveSinusEffectState;
	char						cSaveGlobalFog = GLI_cGlobalFogIsOn;
 
	GLI_cGlobalFogIsOn = 0;
	GLI_vFogOff();
	cSaveSinusEffectState = GLI_fn_SinusEffect_vGetState();
	if ( !GLI_fn_SinusEffect_cIsSecondViewportAffected() )
		GLI_fn_SinusEffect_vSetState( 0 );
 
	PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDynOrSta, PRF_C_ulFix );
 
	HIE_fn_bInitCameraMatrixStack(p_stFixViewportAttr);
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvSendToList );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendFix );
 
	for (xI=0, hSPO = gd_hFixSPO ; xI<g_xFixIndex; xI++, hSPO++)
	{
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendFix );
		PRF_fn_vStopChrono ( PRF_C_ulFctDisplay, PRF_C_pvMisc );
		PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );
 
		HIE_fn_vUpdateRasterForSuperObject( *hSPO, PRF_C_ulVarFixObjects, PRF_C_ulVarFixFaces, PRF_C_ulVarFixElements );
 
		PRF_fn_vStopChrono ( PRF_C_ulFctMainMisc, NULL );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendFix );
 
		HIE_fn_vSendSPOToFixViewport(p_stFixViewportAttr, *hSPO,
		                             HIE_fn_lGetSuperObjectDrawMask(*hSPO)&_lDrawMask , GEO_C_lCullingOut);
	}
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendFix );
	PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvSendToList );
 
	GLI_fn_SinusEffect_vSetState( cSaveSinusEffectState );
	GLI_cGlobalFogIsOn = cSaveGlobalFog;
	if(cSaveGlobalFog)
		GLI_vFogOn();
 
  return TRUE;
}
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
GEO_tdstGeometricObject *HIE_fn_p_stGetGeometricObjectFromSuperObject( HIE_tdxHandleToSuperObject  h_SuperObject )
{
    long                                        lSOType;
/*XB980821*/
#ifndef D_THROW_IPO
    IPO_tdxHandleToInstanciatedPhysicalObject   h_IPO;
#endif /* D_THROW_IPO */
/*End XB*/
    PO_tdxHandleToPhysicalObject                h_PO;
    MTH_tdxReal                                 p_xThreshold;
    GEO_tdstGeometricObject                     *p_stObject;
 
    p_stObject = NULL;
 
    lSOType = HIE_fn_ulGetSuperObjectType( h_SuperObject );
 
    if(lSOType ==HIE_C_ulEDT_Geometric)
    {
        p_stObject = (GEO_tdstGeometricObject *) HIE_fn_hGetSuperObjectObject( h_SuperObject );
    }
    else if( lSOType & (HIE_C_ulPO | HIE_C_ulPO_Mirror) )
    {
        h_PO = (PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject( h_SuperObject );
#ifndef D_THROW_VISUAL_SET
        GLI_vGetVisualSetLOD (PO_fn_hGetVisualSet( h_PO ), 0, &p_xThreshold, &p_stObject);
#else
				p_stObject=PO_fn_hGetGeometricObject( h_PO );
#endif /* D_THROW_VISUAL_SET */
    }
/*XB980821*/
#ifndef D_THROW_IPO
    else if( lSOType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror) )
    {
        h_IPO = (IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject( h_SuperObject );
        h_PO  = IPO_fn_hGetPhysicalObject( h_IPO );
        GLI_vGetVisualSetLOD (PO_fn_hGetVisualSet( h_PO ), 0, &p_xThreshold, &p_stObject);
    }
#endif /* D_THROW_IPO */
/*End XB*/
 
    return p_stObject;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
