/**********************************************************************************************/
/* Name: GeoObj2.c*/
/* Code: Philippe Vimont*/
/* Modif : 30 May 1997 - Guenaele - remove old D3D*/
/**********************************************************************************************/
#include <assert.h>
#include "cpa_std.h"
 
#include "acp_base.h"
 
#include "mth.h"
#include "GEO.h"
#include "gmt.h"
#include "mec.h"
#include "Col\OctreeGO.h"
 
/*-----------------------------------------------------------------------------
 *  Description :   Macro to update min and max point with a given point
 *-----------------------------------------------------------------------------
 *  Input :         a pointer to the min point
 *                  a pointer to the max point
 *                  a pointer to the given point
 *-----------------------------------------------------------------------------
 *  Creation date : 20/02/98            Author : Marc Trabucato
 *---------------------------------------------------------------------------*/
void GEO_fn_vUpdateMinMaxBoxWithPoint(MTH3D_tdstVector * p_stMinPoint,MTH3D_tdstVector * p_stMaxPoint,MTH3D_tdstVector * p_stPoint )
{
	MTH3D_tdstVector *p_stPointToTest = p_stPoint;
 
		if( MTH3D_M_xGetXofVector( p_stPointToTest ) < MTH3D_M_xGetXofVector( p_stMinPoint ) )        
    {																							  
        MTH3D_M_vSetXofVector( p_stMinPoint,  MTH3D_M_xGetXofVector( p_stPointToTest ) );         
    }                                                                                       	  
    else if( MTH3D_M_xGetXofVector( p_stPointToTest ) > MTH3D_M_xGetXofVector( p_stMaxPoint ) )   
    {                                                                                       	  
        MTH3D_M_vSetXofVector( p_stMaxPoint,  MTH3D_M_xGetXofVector( p_stPointToTest ) );         
    }                                                                                       	  
    if( MTH3D_M_xGetYofVector( p_stPointToTest ) < MTH3D_M_xGetYofVector( p_stMinPoint ) )       
    {                                                                                       	  
        MTH3D_M_vSetYofVector( p_stMinPoint,  MTH3D_M_xGetYofVector( p_stPointToTest ) );         
    }                                                                                       	  
    else if( MTH3D_M_xGetYofVector( p_stPointToTest ) > MTH3D_M_xGetYofVector( p_stMaxPoint ) )   
    {                                                                                       	  
        MTH3D_M_vSetYofVector( p_stMaxPoint,  MTH3D_M_xGetYofVector( p_stPointToTest ) );         
    }                                                                                       	  
    if( MTH3D_M_xGetZofVector( p_stPointToTest ) < MTH3D_M_xGetZofVector( p_stMinPoint ) )        
    {                                                                                       	  
        MTH3D_M_vSetZofVector( p_stMinPoint,  MTH3D_M_xGetZofVector( p_stPointToTest ) );         
    }                                                                                       	  
    else if( MTH3D_M_xGetZofVector( p_stPointToTest ) > MTH3D_M_xGetZofVector( p_stMaxPoint ) )   
    {                                                                                       	  
        MTH3D_M_vSetZofVector( p_stMaxPoint,  MTH3D_M_xGetZofVector( p_stPointToTest ) );         
    }                                                                                       	  
}
 
 
/*-----------------------------------------------------------------------------
 *  Description :   Compute given bounding volume
 *-----------------------------------------------------------------------------
 *  Input :         an object
 *                  the index of bounding volume to compute
 *-----------------------------------------------------------------------------
 *  Creation date : 20/02/98            Author : Marc Trabucato
 *---------------------------------------------------------------------------*/
void GEO_vComputeObjectParallelBox( ACP_tdxHandleOfObject hObject, ACP_tdxIndex xParallelBox )
{
    GEO_tdstElementIndexedTriangles     *p_stETIT;
//XB99/04/27
#ifndef U64
    GEO_tdstElementFaceMapDescriptors   *p_stEFMD;
#endif U64
//End XB99/04/27
    GEO_tdstElementPoints               *p_stEIP;
    GEO_tdstElementLines                *p_stEL;
    GEO_tdstElementSpheres              *p_stES;
    GEO_tdstElementAlignedBoxes			*p_stEAB;
    GEO_tdstElementCones                *p_stEC;
	GEO_tdstElementSprite				*p_stESt;
    ACP_tdxIndex                        xIndexElement , xIndexInElement;
    MTH3D_tdstVector                    *p_stMinPoint , *p_stMaxPoint;
    GEO_tdxHandleToParallelBox          hParallelBox;
	BOOL								bInit;
 
	bInit = FALSE;
    hParallelBox = GEO_hGetParallelBox( hObject, xParallelBox );
 
    if( hParallelBox == NULL )  return;
 
    p_stMinPoint = & hParallelBox -> stMinPoint;
    p_stMaxPoint = & hParallelBox -> stMaxPoint;
 
    for ( xIndexElement = 0 ; xIndexElement < hObject -> xNbElements ; xIndexElement++ )
    {
        if( GEO_xGetParallelBoxIndexOfElement( hObject, xIndexElement ) == xParallelBox )
        {
            switch ( hObject -> d_xListOfElementsTypes[ xIndexElement ] )
            {
            case GEO_C_xElementIndexedTriangles:
                p_stETIT = (GEO_tdstElementIndexedTriangles*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stETIT -> xNbFaces )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stETIT -> d_stListOfFacesTripled [ 0 ] . a3_xIndex[0] );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stETIT -> d_stListOfFacesTripled [ 0 ] . a3_xIndex[0] );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stETIT -> xNbFaces ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stETIT -> d_stListOfFacesTripled [ xIndexInElement ] . a3_xIndex[0] );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stETIT -> d_stListOfFacesTripled [ xIndexInElement ] . a3_xIndex[1] );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stETIT -> d_stListOfFacesTripled [ xIndexInElement ] . a3_xIndex[2] );
                }
                break;
//XB99/04/27
#ifndef U64
            case GEO_C_xElementFaceMapDescriptors:
                p_stEFMD = (GEO_tdstElementFaceMapDescriptors*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stEFMD -> xNbFaces )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stEFMD -> d_stListOfFacesQuadrupled [ 0 ] . stFaceTripled . a3_xIndex[0] );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stEFMD -> d_stListOfFacesQuadrupled [ 0 ] . stFaceTripled . a3_xIndex[0] );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stEFMD -> xNbFaces ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEFMD -> d_stListOfFacesQuadrupled [ xIndexInElement ] . stFaceTripled . a3_xIndex[0] );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEFMD -> d_stListOfFacesQuadrupled [ xIndexInElement ] . stFaceTripled . a3_xIndex[1] );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEFMD -> d_stListOfFacesQuadrupled [ xIndexInElement ] . stFaceTripled . a3_xIndex[2] );
                }
                break;
#endif U64
//End XB99/04/27
            case GEO_C_xElementSprites:
                p_stESt = (GEO_tdstElementSprite*) ( hObject -> d_stListOfElements[ xIndexElement ] );
#ifndef D_THROW_COMPLEX_SPRITE
				if( !bInit && p_stESt -> xNbSprites )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stESt -> d_stListOfSprites [ 0 ] . xCenterPoint );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stESt -> d_stListOfSprites [ 0 ] . xCenterPoint );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stESt -> xNbSprites ; xIndexInElement++ )
                {
	                GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stESt -> d_stListOfSprites [ xIndexInElement ] . xCenterPoint );
                }
#else
				if( !bInit )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stESt -> xCenterPoint );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stESt -> xCenterPoint );
					bInit = TRUE;
				}
        GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stESt -> xCenterPoint );
#endif /* D_THROW_COMPLEX_SPRITE */
                break;
//XB99/04/27
#ifndef U64
            case GEO_C_xElementTMeshes:
                break;
#endif U64
//End XB99/04/27
            case GEO_C_xElementPoints:
                p_stEIP = (GEO_tdstElementPoints*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stEIP -> xNbPoints )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stEIP -> d_xListOfPointIndex [ 0 ] );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stEIP -> d_xListOfPointIndex [ 0 ] );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stEIP -> xNbPoints ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEIP -> d_xListOfPointIndex [ xIndexInElement ] );
                }
                break;
            case GEO_C_xElementLines:
                p_stEL = (GEO_tdstElementLines*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stEL -> xNbLines )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stEL -> d_stListOfLineIndex [ 0 ] . a2_xIndex[ 0 ] );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stEL -> d_stListOfLineIndex [ 0 ] . a2_xIndex[ 0 ] );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stEL -> xNbLines ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEL -> d_stListOfLineIndex [ xIndexInElement ] . a2_xIndex[ 0 ] );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEL -> d_stListOfLineIndex [ xIndexInElement ] . a2_xIndex[ 1 ] );
                }
                break;
            case GEO_C_xElementSpheres:
                p_stES = (GEO_tdstElementSpheres*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stES -> xNbSpheres )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stES -> d_stListOfSpheres [ 0 ] . xCenterPoint );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stES -> d_stListOfSpheres [ 0 ] . xCenterPoint );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stES -> xNbSpheres ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stES -> d_stListOfSpheres [ xIndexInElement ] . xCenterPoint );
                }
                break;
            case GEO_C_xElementAlignedBoxes:
                p_stEAB = (GEO_tdstElementAlignedBoxes*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stEAB -> xNbAlignedBoxes )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stEAB -> d_stListOfAlignedBoxes [ 0 ] . xMinPoint );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stEAB -> d_stListOfAlignedBoxes [ 0 ] . xMinPoint );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stEAB -> xNbAlignedBoxes ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEAB -> d_stListOfAlignedBoxes [ xIndexInElement ] . xMinPoint );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEAB -> d_stListOfAlignedBoxes [ xIndexInElement ] . xMaxPoint );
                }
                break;
            case GEO_C_xElementCones:
                p_stEC = (GEO_tdstElementCones*) ( hObject -> d_stListOfElements[ xIndexElement ] );
				if( !bInit && p_stEC -> xNbCones )
				{
					MTH3D_M_vCopyVector( p_stMinPoint, hObject -> d_stListOfPoints + p_stEC -> d_stListOfCones [ 0 ] . xTopPoint );
					MTH3D_M_vCopyVector( p_stMaxPoint, hObject -> d_stListOfPoints + p_stEC -> d_stListOfCones [ 0 ] . xTopPoint );
					bInit = TRUE;
				}
                for ( xIndexInElement = 0 ; xIndexInElement < p_stEC -> xNbCones ; xIndexInElement++ )
                {
					GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEC -> d_stListOfCones [ xIndexInElement ] . xTopPoint );
                    GEO_fn_vUpdateMinMaxBoxWithPoint( p_stMinPoint, p_stMaxPoint, hObject -> d_stListOfPoints + p_stEC -> d_stListOfCones [ xIndexInElement ] . xBasePoint );
                }
                break;
//XB99/04/27
#ifndef U64
            case GEO_C_xElementAltimap:
                break;
#endif U64
//End XB99/04/27
            }
        }
    }
}
