/*=========================================================================
* LoadFmlCB.cpp : This module contain all functions used to load 
*               a family type, this states, and all over
* This is a part of the Game project.
*
* That file needs to be compatible for all platforms.
*
* (c) Ubi Studios 1996-1998
*=======================================================================*/
 
#if defined (WIN32)
#include <stdio.h>
#endif /* WIN32 */
 
#define D_State_Define
#define D_ObjsTbls_Define
 
#include "ToolsCPA.h"
 
#include "structur\ObjsTbls.h"
 
#include "Options/Options.h"
#include "Macros.h"
 
#include "Actions/AllActs.h"
 
#include "Structur/3DOSLkTb.h"
#include "Structur/Objects.h"
#include "Structur/ErrGame.h"
#include "Structur/GameScpt.h"
#include "Structur/MemGame.h"
#include "Structur/StdObjSt.h"
#include "Structur/EngMode.h"
 
#include "PlayAnim/PLA_dbg.h"
#include "Structur/State.h"
#include "Structur/Anim_s.h"
 
#include "LoadLvl.h"
 
#include "Basic.h"
#include "Family.h"
#include "LoadAni.h"
#include "LoadFml.h"
#include "ObjType.h"
#include "ZeMem.h"
/*#include "LoadA3B.h"*/
extern ACP_tdxBool g_xA3bOff;
 
#include "Structur/ObjsTbls.h"
#include "TBLLoad.h"
#include "CHLLoad.h"
#include "ChanList.h"
#include "LoadBin.h"
 
/* anim interpolated*/
#include "PlayAnim/Interpol/a3x_mem.h"
#include "PlayAnim/Interpol/a3x_intn.h"
#include "PlayAnim/Interpol/a3x_load.h"
 
#define _USE_BINARY_ANIM_BUFFER
#define MAX_FAMILY_ELEMENT_SIZE 128*1024
 
#define C_szConvertA3dToA3i "MakeAnim"
 
#include <direct.h>
#include "ldt.h"
 
#define lTagAnimation 'minA'
#define lTagNextState 'txeN'
#define lTagSpeed 'eepS'
#define lTagRepeat 'epeR'
#define lTagTransitionStatusFlag 'narT'
#define lTagProhibitedTargetState 'horP'
#define lTagAddTargetState 'TddA'
#define lTagLinkMechanics 'kniL'
#define lTagTestPointsList 'tseT'
 
 
#define OS_CB
#define MP_LDT_CB
 
 
HREF hRefBDV;
HREF g_hRefSTA;
 
 
/*****************************************************************
Function name   : fn_iLoadStateFile
Description     : 
Author          : Ovidiu Scripa (oscripa@ubisoft.ro) - ROMTEAM
Creation Date   : 13-Oct-98
Modified        : 
Return type     : int 
Argument        : LDT_tdst_Link *pLink
*****************************************************************/
int fn_iLoadStateFile( LDT_tdst_Link *pLink ) /* for .sta files*/
{
  LDT_tdeParseResult result=ParseResult_BeginSection;
	struct tdstFamilyList_ * p_stFamily;  
	char szFileName[_MAX_PATH];
	tdxHandleToState h_State;
	tdxHandleToTransition h_Transition;
	tdxHandleToProhibit h_Prohibit;
	char szSectionName[_MAX_PATH];
	char szSectionPreName[_MAX_PATH];
	SCR_tdst_Link_Value * _p_stLinkValue;
	long i,j;
 
 
  p_stFamily = 	(struct tdstFamilyList_ *)LDT_GetLinkValue(pLink);		
  LDT_SetFileLong( 11, (unsigned long)p_stFamily );  
 
  while( result!=ParseResult_EndSection ) 
  {
  	result=LDT_GetNextEntry();
  	switch( result )
  	{
			case ParseResult_BeginSection: /* a subsection - CreateNewState*/
			{
				LDT_LoadSection( NULL );
			}
			break;
  	}
  }
 
		sprintf(szFileName,"%s\\%s.sta",fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType),fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
 		
		LST2_M_StaticForEachElementOf(&p_stFamily->hForStateArray,h_State,i)
		{
			/* Init handle to NextState ***********/
			SCR_fn_v_RdL0_ComputeSectionName(szSectionPreName,szFileName,C_SectionCreateNewState,(char *)(h_State->h_NextState));
			
			strcpy(szSectionName,fn_szGetFamiliesDataPath());
			strcat(szSectionName,"\\");	strcat(szSectionName,szSectionPreName);
			_p_stLinkValue = SCR_fnp_st_Link_SearchKey(&g_st3DOSLinkTable.stState,szSectionName);
			
			fn_vGameTestMemory();
 
			if(_p_stLinkValue != NULL)
			{
                MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
				TMP_M_Free(h_State->h_NextState);
				h_State->h_NextState = (tdxHandleToState)SCR_M_ul_Link_GetValue(_p_stLinkValue);
			}
			else
			{
				if( !strcmpi(C_szNoState,(char *)(h_State->h_NextState)) )
				{
                    MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
					TMP_M_Free(h_State->h_NextState);
					h_State->h_NextState = NULL;  /* NoState_EndOfAction*/
				}
				else
				{
				/*	TMP_M_Free(h_State->h_NextState);*/
					M_GameFatalError(E_uwGameScriptCallBackCreateNewStateBadNextState);
				}
			}
			/* ************************************/
 
			/* Init All handles To Transitions ****/
			LST2_M_StaticForEachElementOf(&h_State->hForTransitionArray,h_Transition,j)
			{
				/* Target State*/
				SCR_fn_v_RdL0_ComputeSectionName(szSectionPreName,szFileName,C_SectionCreateNewState,(char *)(h_Transition->h_TargetState));
				strcpy(szSectionName,fn_szGetFamiliesDataPath());
				strcat(szSectionName,"\\");	strcat(szSectionName,szSectionPreName);
				_p_stLinkValue = SCR_fnp_st_Link_SearchKey(&g_st3DOSLinkTable.stState,szSectionName);
                MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
				TMP_M_Free(h_Transition->h_TargetState);
				if(_p_stLinkValue != NULL)
				{
					h_Transition->h_TargetState = (tdxHandleToState)SCR_M_ul_Link_GetValue(_p_stLinkValue);
				}
				else
				{
					M_GameFatalError(E_uwGameScriptCallBackCreateNewStateBadTargetState);
				}
				/* State To Go*/
				SCR_fn_v_RdL0_ComputeSectionName(szSectionPreName,szFileName,C_SectionCreateNewState,(char *)(h_Transition->h_StateToGo));
				strcpy(szSectionName,fn_szGetFamiliesDataPath());
				strcat(szSectionName,"\\");	strcat(szSectionName,szSectionPreName);
				_p_stLinkValue = SCR_fnp_st_Link_SearchKey(&g_st3DOSLinkTable.stState,szSectionName);
                MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
				TMP_M_Free(h_Transition->h_StateToGo);
				if(_p_stLinkValue != NULL)
				{
					h_Transition->h_StateToGo = (tdxHandleToState)SCR_M_ul_Link_GetValue(_p_stLinkValue);
				}
				else
				{
					M_GameFatalError(E_uwGameScriptCallBackCreateNewStateBadStateToGo);
				}
			}
			/* ************************************/
 
			/* Init All handles To Prohibited States ****/
			LST2_M_StaticForEachElementOf(&h_State->hForProhibitArray,h_Prohibit,j)
			{
				/* Prohibited State*/
				SCR_fn_v_RdL0_ComputeSectionName(szSectionPreName,szFileName,C_SectionCreateNewState,(char *)(h_Prohibit->h_ProhibitedState));
				strcpy(szSectionName,fn_szGetFamiliesDataPath());
				strcat(szSectionName,"\\");	strcat(szSectionName,szSectionPreName);
				_p_stLinkValue = SCR_fnp_st_Link_SearchKey(&g_st3DOSLinkTable.stState,szSectionName);
                MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
				TMP_M_Free(h_Prohibit->h_ProhibitedState);
				if(_p_stLinkValue != NULL)
				{
					h_Prohibit->h_ProhibitedState = (tdxHandleToState)SCR_M_ul_Link_GetValue(_p_stLinkValue);
				}
				else
				{
					M_GameFatalError(E_uwGameScriptCallBackCreateNewStateBadTargetState);
				}
			}
		}
 
  return 0;
}
 
 
/*****************************************************************
Function name   : fn_iCreateNewState
Description     : 
Author          : Ovidiu Scripa (oscripa@ubisoft.ro) - ROMTEAM
Creation Date   : 13-Oct-98
Modified        : 
Return type     : int 
Argument        : LDT_tdst_Link *pLink
*****************************************************************/
int fn_iCreateNewState( LDT_tdst_Link *pLink )
{
	tdxHandleToState h_State;
	struct tdstFamilyList_ * p_stFamily;  
 
  VIG_fn_vAddToProgressBar(1);
 
		MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily );
  h_State = fn_h_StateAlloc();
	pLink->pObject = h_State;
	
 
  p_stFamily = 	(struct tdstFamilyList_ *)LDT_GetFileLong(11);
 
  LST2_M_StaticAddTail(&p_stFamily->hForStateArray, h_State);
 
	#ifdef _DEBUG_STRING_FOR_PLA_
		strcpy(h_State->szStateName,fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
		strcat(h_State->szStateName," - ");  
		strcat(h_State->szStateName, pLink->szName);
	#endif
 
  return 0;
}
 
extern tdstAnim3d * fn_p_stLoadAnimationFile(char * szFileName,struct tdstFamilyList_ *p_stFamily); 
 
 
 
/*****************************************************************
Function name   : fn_iLoadNewState
Description     : 
Author          : Ovidiu Scripa (oscripa@ubisoft.ro) - ROMTEAM
Creation Date   : 13-Oct-98
Modified        : 
Return type     : int 
Argument        : LDT_tdst_Link *pLink
*****************************************************************/
int fn_iLoadNewState( LDT_tdst_Link *pLink )
{
  LDT_tdeParseResult result=ParseResult_BeginSection;
  DNM_tdeMechanicsID  eKindOfMechanics = DNM_eMIC_Error;
	struct tdstFamilyList_ *p_stFamily;
	tdxHandleToState h_State,h_NextState;
	char szSectionName[_MAX_PATH];
	tdxHandleToTransition h_Transition;
	tdxHandleToProhibit h_Prohibit;
	int nLen;
  struct tdstEngineObject_ *p_stEngineObject=(struct tdstEngineObject_ *)pLink->pParent->pParent->pParent->pObject;
	tdxHandleToState h_InitialState=NULL;
 
#if 0
  static int i = 0;
  char s[180], s1[300];
  LDT_ComputeSectionName( pLink , s1 );
	i++;
  sprintf(s, "%d.%s\n", i, s1);
  OutputDebugString(s);
#endif
 
	h_State = (tdxHandleToState)pLink->pObject;
 
  p_stFamily = 	(struct tdstFamilyList_ *)LDT_GetFileLong(11);
 
 
	nLen = LDT_ComputeSectionName(pLink, szSectionName);
  SCR_M_v_Link_SetAdditionalLong(SCR_fnp_st_Link_SetValue(&g_st3DOSLinkTable.stState, szSectionName, (unsigned long)h_State), 1, nLen);
 
/*
	h_InitialState = fn_h3dDataGetInitialState(p_stEngineObject->h_3dData);
	if(h_InitialState)
	{
		if (!strcmpi(h_InitialState->szStateName, szSectionName))
		{
			 TMP_M_Free(h_InitialState);
			 fn_v3dDataSetInitialState(p_stEngineObject->h_3dData, h_State);
		}
	}
*/
 
  while( result!=ParseResult_EndSection ) 
  {
  	result=LDT_GetNextEntry();
  	switch( result )
  	{
  	  case ParseResult_Entry: /* an entry */
  	  {
  	    char *szEntry=LDT_szGetEntryName();
  	    switch (*(long*)szEntry)
  	    {
  	      case  lTagAnimation : /*  */
  	      {
						/* OS Note : animation files should be loaded only after .tbl files*/
						/* Maybe I should move this loading in PostProcess.*/
						char* szAnimFile = (char*)LDT_M_malloc(_MAX_PATH+2);
						/**** load the animation file ****/
						strcpy(szSectionName,fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
						strcat(szSectionName,"\\");
						strcat(szSectionName, LDT_szGetParam(1));
						
						strcpy(szAnimFile, szSectionName);
 
						LDT_AddToRefsTable( g_hRefSTA, (void *)pLink, 0, 2, szAnimFile,  p_stFamily);  
 
 
  	      }
  	      break;
  	      case  lTagNextState : /*  */
  	      {
						char * szP;
						szP = LDT_szGetParam(1);
              MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
						h_NextState = (tdxHandleToState) TMP_M_p_Malloc(strlen(szP)+1);
						strcpy((char *)h_NextState, szP);
						fn_vSetNextStateInState(h_State,h_NextState);
  	      }
  	      break;
  	      case  lTagSpeed : /*  */
  	      {
						fn_vSetSpeedInState(h_State,(signed char)atoi(LDT_szGetParam(1)));
  	      }
  	      break;
  	      case  lTagRepeat : /*  */
  	      {
 
						fn_vSetRepeatAnimationInState(h_State,(unsigned char)(atoi(LDT_szGetParam(1)) - 1) );
  	      }
  	      break;
  	      case  lTagTransitionStatusFlag : /*  */
  	      {
						if(!strcmpi(LDT_szGetParam(1), C_Value_TransitionAllowedByDefault))
						{
							fn_vSetTransitionStatusFlagInState(h_State,0);
						}
						else
						{
							fn_vSetTransitionStatusFlagInState(h_State,1);
						}
 
  	      }
  	      break;
  	      case  lTagAddTargetState : /*  */
  	      {
						char * szP;
						h_Transition = fn_h_TransitionAlloc();
						LST2_M_StaticInitElement(h_Transition);
 
						szP = LDT_szGetParam(1);
              MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
						h_Transition->h_TargetState = (tdxHandleToState) TMP_M_p_Malloc(strlen(szP)+1);
						strcpy((char *)h_Transition->h_TargetState, szP);
						
						szP = LDT_szGetParam(2);
              MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeState , p_stFamily);
						h_Transition->h_StateToGo = (tdxHandleToState) TMP_M_p_Malloc(strlen(szP)+1);
						strcpy((char *)h_Transition->h_StateToGo, szP);
 
 
						if(LDT_iGetNbParams() > 3)  
							fn_vSetLinkingTypeInTransition(h_Transition,(unsigned char)atoi(LDT_szGetParam(3)));
						else
							fn_vSetLinkingTypeInTransition(h_Transition,C_ucStandardLink);
 
						LST2_M_StaticAddTail(&h_State->hForTransitionArray, h_Transition);
 
  	      }
  	      break;
  	      case  lTagProhibitedTargetState : /*  */
  	      {
						char * szP;
              MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeProhibit , p_stFamily );
						h_Prohibit = fn_h_ProhibitAlloc();
						LST2_M_StaticInitElement(h_Prohibit);
 						
						szP = LDT_szGetParam(1);
						h_Prohibit->h_ProhibitedState = (tdxHandleToState) TMP_M_p_Malloc(strlen(szP)+1);
						strcpy((char *)h_Prohibit->h_ProhibitedState, szP);
 
						LST2_M_StaticAddTail(&h_State->hForProhibitArray, h_Prohibit);
 
  	      }
  	      break;
  	      case  lTagLinkMechanics : /*  */
  	      {
						h_State->h_LinkedMechanicsIdCard = LDT_LoadSection(LDT_szGetParam(1));
  	      }
  	      break;
 
  	    }
  	  }
  	}
  }
 
	
  return 0;
}
 
 
/*****************************************************************
Function name   : fn_vSTAPostProcessLDT
Description     : 
Author          : Ovidiu Scripa (oscripa@ubisoft.ro) - ROMTEAM
Creation Date   : 13-Oct-98
Modified        : 
Return type     : void 
Argument        : HREF hRef
*****************************************************************/
void fn_vSTAPostProcessLDT( HREF hRef )
{
  LDT_tdst_Link *pLink;
  LDT_tdst_Link *pGetFrom;
  int iType;
  short xCount;
  long *pVal;
	struct tdstFamilyList_ *p_stFamily;
	char* szAnimFile;
	tdxHandleToState h_State;
 
  while( LDT_GetRefFromTable( hRef, &pLink, &pGetFrom, &iType, &xCount, &pVal )==0 )
  {
		h_State = (tdxHandleToState)pLink->pObject;
		szAnimFile = (char*)(*pVal);
		p_stFamily = (struct tdstFamilyList_ *)(*(pVal+1));
 
    fn_vSetAnimInState(h_State,fn_p_stLoadAnimationFile(szAnimFile,p_stFamily));
 
		if ((h_State->scSpeedAnim<=1)&&h_State->p_stAnim)
		{
			h_State->scSpeedAnim = h_State->p_stAnim->ucFrameRate;
		}
 
		LDT_M_free(szAnimFile);
    LDT_FreeRefValues( pVal );
  }
 
}
 
 
 
/*****************************************************************
Function name   : fn_vLoadFamilyLDT
Description     : 
Author          : Ovidiu Scripa (oscripa@ubisoft.ro) - ROMTEAM
Creation Date   : 13-Oct-98
Modified        : 
Return type     : void 
Argument        : struct tdstFamilyList_ *p_stFamily
*****************************************************************/
void fn_vLoadFamilyLDT(struct tdstFamilyList_ *p_stFamily)
{
	char szFileName[_MAX_PATH];
	/*char szSectionName[_MAX_PATH];*/
	/*SCR_tdst_Link_Value * _p_stLinkValue;*/
	LDT_tdst_Link* pLink;
 
	/* load of the default Objects table for this family*/
	sprintf(szFileName,"%s\\%s.tbl",fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType),fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
 
/*	if (SCR_fn_c_RdL0_IsSectionExists(szFileName))*/
	if (!LDT_SearchFile(szFileName, NULL))
	{
	  pLink = LDT_GetLink(szFileName);
	  if (pLink)
	  {
		  p_stFamily->h_DefaultObjectsTable = (tdxHandleToObjectsTablesList)pLink->pObject; 
	  }
	  else	
	  {
 
			void* p_vLS;
			p_vLS = LDT_LoadSection(szFileName);
			p_stFamily->h_DefaultObjectsTable = (tdxHandleToObjectsTablesList) p_vLS;
			fn_vAddAnObjectsTablesInList(	p_stFamily,p_stFamily->h_DefaultObjectsTable);
	  }
 
	}	
 
	/* load of the channel references for this family*/
	sprintf(szFileName,"%s\\%s.chl",fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType),fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
/*	if (SCR_fn_c_RdL0_IsSectionExists(szFileName))*/
	if (!LDT_SearchFile(szFileName, NULL))
	{
		LDT_LoadSection(szFileName);
		LDT_SetLinkValue(LDT_GetLink(szFileName), (unsigned long)p_stFamily);
	}
	else
	{
		/*M_GameFatalError(E_uwGameScriptCallBackCreateNewStateBadTargetState);*/
	}
 
	/**** Load All states ****/
	sprintf(szFileName,"%s\\%s.sta",fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType),fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
/*	if (SCR_fn_c_RdL0_IsSectionExists(szFileName))*/
	if (!LDT_SearchFile(szFileName, NULL))
	{
    LDT_tdst_Link* pLink;
		LDT_LoadSection(szFileName);
    pLink = LDT_GetLink(szFileName);
    LDT_SetLinkValue(pLink, (unsigned long)p_stFamily);
 
	}	
 
 
	/* CGHT 14/05/97*/
	/**** Load Bounding Volume ****/
	sprintf(szFileName,"%s\\%s.bdv",fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType),fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType));
/*	if (SCR_fn_c_RdL0_IsSectionExists(szFileName))*/
	if (!LDT_SearchFile(szFileName, NULL))
	{
#ifndef MP_LDT_CB
		SCR_M_RdL0_SetContextLong(C_GrandChildContext, 0, (long)p_stFamily);
		SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_Normal);
#else
	  LDT_LoadSection( szFileName ); /* MP*/
    LDT_SetLinkValue(LDT_GetLink(szFileName), (unsigned long)p_stFamily);
#endif
  }
 
}
 
 
/*****************************************************************
Name: 
Description: Load callback for LDT
Author: Mircea Petrescu
Date: 7/7/98
Modified: 
*****************************************************************/
int fn_iCreateSetBoundingVolume( LDT_tdst_Link *pLink )
{
	LDT_SetLinkValue( pLink, LDT_GetLinkValue( pLink->pParent ));
	return 0;
}
 
/*****************************************************************
Name: 
Description: Load callback for LDT
Author: Mircea Petrescu
Date: 7/7/98
Modified: 
*****************************************************************/
int fn_iLoadSetBoundingVolume( LDT_tdst_Link *pLink )
{
  LDT_tdeParseResult result=ParseResult_BeginSection;
 
  struct tdstFamilyList_ * p_stFamily=(struct tdstFamilyList_ *)LDT_GetLinkValue( pLink );
 
  VIG_fn_vAddToProgressBar(1);
 
  while( result!=ParseResult_EndSection ) 
  {
  	result=LDT_GetNextEntry();
  	switch( result )
  	{
  	  case ParseResult_Entry: /* an entry */
  	  {
  	    char *szEntry=LDT_szGetEntryName();
  	    switch (*(long*)szEntry)
  	    {
		case 'nuoB' : /* BoundingVolume */
		case 'BteS' : /* SetBoundingVolume */
 
#if defined (ACTIVE_EDITOR)
		 p_stFamily->hGeometricSphere = (ACP_tdxHandleOfObject)LDT_LoadSection( LDT_szGetParam( 1 ) );
#else 
		LDT_LoadSection( LDT_szGetParam( 1 ) );
#endif
		 LDT_AddToRefsTable( hRefBDV, pLink, 0 , 0 );
		 
		}
  	  }
  	}
  }
 
  return 0;
}
 
void GAM_vPostProcessLDT( HREF hRef )
{
  LDT_tdst_Link *pLink;
  LDT_tdst_Link *pGetFrom;
  int iType;
  short xCount;
  long *pVal;
 
	 MTH3D_tdstVector		stCenter;
	 MTH_tdxReal			xRadius;
	 ACP_tdxHandleOfObject	hGeometricSphere;
 
  while( LDT_GetRefFromTable( hRef, &pLink, &pGetFrom, &iType, &xCount, &pVal )==0 )
  {
	struct tdstFamilyList_ * p_stFamily=(struct tdstFamilyList_ *)LDT_GetLinkValue( pLink );
	 hGeometricSphere=(ACP_tdxHandleOfObject)pGetFrom->pObject;
	 GEO_fn_vGetInfoFromGeometricSphere(&stCenter, &xRadius, hGeometricSphere);
	 GEO_fn_vCreateBoundingSphere(&p_stFamily->hBoundingSphere);
	 GEO_fn_vSetBoundingSphere(p_stFamily->hBoundingSphere, &stCenter, xRadius);
  }
 
}
 
 
 
 
 
