/*=========================================================================
* 3dData.cpp : 3dData's functions
*
*
*
*         3dData MUST BE REPLACE BY THE C FILENAME
*
*
* Version              1.0
* Creation date        01/10/96
* Revision date
*
* That file needs to be compatible for all platforms.
*
* (c) Ubi Studios 1996
*=======================================================================*/
 
/*******************************************************/
/**** For the structures and variables declarations ****/
/*******************************************************/
#define D_3dData_StructureDefine
#define D_3dData_VariableDefine
 
#include "ToolsCPA.h"
 
#include "Options/Options.h"
#include "Macros.h"
 
#include "Structur/StdObjSt.h"
 
#include "Actions/AllActs.h"
 
#include "Structur/3DOSLkTb.h"
#include "Structur/MemGame.h"
#include "Structur/ErrGame.h"
#include "Structur/GameScpt.h"
#include "Structur/EngMode.h"
#include "Structur/Objects.h"
#include "Structur/State.h"
#include "Structur/Anim_s.h"
#include "Structur/objstbls.h"
 
#include "PlayAnim/PlayAnim.h"
 
#include "GameEng.h"
#include "Basic.h"
#include "ChanList.h"
#include "ObjInit.h"
#include "ObjType.h"
#include "ZdxStuff.h"
#include "ZeMem.h"
#include "Family.h"
#include "TBLLoad.h"
 
/*-----------------------------------------------------------------------------
*  Description : 3dData object action script callback
*-----------------------------------------------------------------------------
*  Input :         Object pointer
*  Output :        None
*-----------------------------------------------------------------------------
*  Creation date : 01/10/96            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
#if defined(GAM_USE_SCRIPT)
SCR_tde_Anl_ReturnValue fn_e3dDataScriptCallBack(SCR_tdst_File_Description *_p_stFile,char *_p_szName,char *_ap_szParams[],SCR_tde_Anl_Action	_eAction)
{
	SCR_tde_Anl_ReturnValue eReturnValue = SCR_ERV_Anl_NormalReturn;
	MS_tdxHandleTo3dData h_3dData;
	struct tdstEngineObject_ *p_stEngineObject;
	GLD_tdstDeviceAttributes stDevAttrib;
 
	_p_stFile=_p_stFile;
 
	SCR_M_RdL0_GetSectionLong(C_ParentSection,0,struct tdstEngineObject_ *, p_stEngineObject);
 
	if (M_IsTitle)
	{
        MMG_fn_vBeginMemoryInfo (MMG_C_lTypeMiniStructure , MMG_C_lSubType3dData , p_stEngineObject);
		h_3dData = fn_h_3dDataRealAlloc();
        MMG_fn_vEndMemoryInfo ();
		p_stEngineObject->h_3dData = h_3dData;
		SCR_M_RdL0_SetContextLong(C_ParentContext,0,NULL);
		SCR_M_RdL0_SetSectionLong(C_ThisSection,0,h_3dData);
	}
	else if (M_IsEntry)
	{
		SCR_M_RdL0_GetSectionLong(C_ThisSection,0,MS_tdxHandleTo3dData,h_3dData);
		if (M_ActionIs(C_Entry3dDataInitialState))
		{
			char szCompletFileName[_MAX_PATH];
			tdxHandleToState h_InitialState;
 
			strcpy(szCompletFileName,fn_szGetFamiliesDataPath());
			strcat(szCompletFileName,"\\");
			strcat(szCompletFileName,_ap_szParams[0]);
            MMG_fn_vAddMemoryInfo( MMG_C_lTypeMiniStructure , MMG_C_lSubType3dData , p_stEngineObject);
			h_InitialState = (tdxHandleToState) TMP_M_p_Malloc(strlen(szCompletFileName)+1);
			strcpy((char *)h_InitialState,szCompletFileName);
			fn_v3dDataSetInitialState(h_3dData,h_InitialState);
		}
		else if (M_ActionIs(C_Entry3dDataInitialObjectsTable))
		{
			/*char szFileName[_MAX_PATH];*/
			/*SCR_tdst_Link_Value * _p_stLinkValue;*/
/*			SCR_tdst_Cxt_Values *p_stVal;*/
 
			/*p_stFamily = fn_h3dDataGetFamily(h_3dData);*/
// Shaitan => module list in the level
			char * p_szInitialObjectTable;
// End Shaitan => module list in the level
 
			/*sprintf(szFileName,"%s\\%s.tbl",fn_szFindFamilyTypeNameOfFamilyType(p_stFamily->otObjectFamilyType),_ap_szParams[0]);*/
			if (SCR_fn_c_RdL0_IsSectionExists(_ap_szParams[0]))
			{
// Shaitan => module list in the level
				p_szInitialObjectTable = (char *) malloc (strlen(_ap_szParams[0]) * sizeof (char));
				strcpy(p_szInitialObjectTable, _ap_szParams[0]);
				SCR_M_RdL0_SetContextLong(C_ParentContext,0,(long)p_szInitialObjectTable);
/*
				p_stVal = SCR_fnp_st_RdL0_AnalyseSection(_ap_szParams[0], SCR_CDF_uw_Anl_Normal);
				SCR_M_RdL0_SetContextLong(C_ParentContext,0,SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0));
*/
// End Shaitan => module list in level
			}
		}
		else if( M_ActionIs(C_Entry3dDataShadowTexture) )
		{
			M_CheckScriptParamNumber(3);
			GLD_bGetDeviceAttributes(
				g_stEngineStructure.hGLDDevice,&stDevAttrib);
			GLI_xLoadTexture( &h_3dData->p_stShadowTexture,&stDevAttrib,
				_ap_szParams[0],
				fn_lAToI(_ap_szParams[1]),
				fn_lAToI(_ap_szParams[2]) );
		}
		else if( M_ActionIs(C_Entry3dDataShadowMaterial) )
		{
			SCR_tdst_Cxt_Values *p_stVal;
 
			M_CheckScriptParamNumber(1);
			p_stVal = SCR_fnp_st_RdL0_AnalyseSection(_ap_szParams[0],
				SCR_CDF_uw_Anl_Normal);
			h_3dData->p_stShadowMaterial = (GMT_tdxHandleToGameMaterial) SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
            
            /*
             * VL : to manage with mirrored shadow texture
             */
            {
                ACP_tdxHandleOfMaterial hVisualMat;
                GLI_tdstTexture         *p_stTexture;
                unsigned char           ucCyclingMode;
 
                hVisualMat = GMT_fn_hGetVisualMaterial( h_3dData->p_stShadowMaterial );
                if (hVisualMat)
                {
                    GLI_xGetMaterialTexture( hVisualMat, &p_stTexture );
                    if (p_stTexture)
                    {
                        ucCyclingMode = TEX_ucGetTextureCyclingMode( p_stTexture );
                        ucCyclingMode |= GLI_C_lSpecialMirrorForShadow;
                        TEX_vSetTextureCyclingMode( p_stTexture, ucCyclingMode );
                    }
                }
            }
		}
		else if( M_ActionIs(C_Entry3dDataShadowScale) )
		{
			M_CheckScriptParamNumber(2);
			fn_v3dDataSetShadowScaleX(h_3dData, fn_fAToF(_ap_szParams[0]));
			fn_v3dDataSetShadowScaleY(h_3dData, fn_fAToF(_ap_szParams[1]));
		}
		else if( M_ActionIs(C_Entry3dDataShadowHeight) )
		{
			M_CheckScriptParamNumber(1);
			h_3dData->xSHWHeight = fn_fAToF(_ap_szParams[0]);
		}
		else if( M_ActionIs(C_Entry3dDataDrawMask) )
		{
			M_CheckScriptParamNumber(1);
			h_3dData->lDrawMaskInit = h_3dData->lDrawMask = fn_lAToI(_ap_szParams[0]);
		}
/* ANNECY MT - 09/11/98 {
		else if( M_ActionIs(C_Entry3dDataBrainComputationFrequency))
		{
			M_CheckScriptParamNumber(1);
			fn_v3dDataSetBrainComputationFrequency(h_3dData,(unsigned char)fn_lAToI(_ap_szParams[0]));
		}
   END ANNECY MT }	*/
		else if( M_ActionIs(C_Entry3dDataLightComputationFrequency))
		{
			M_CheckScriptParamNumber(1);
			fn_v3dDataSetLightComputationFrequency(h_3dData,(unsigned char)fn_lAToI(_ap_szParams[0]));
		}
	}
 
	return(eReturnValue);
}
#endif /* GAM_USE_SCRIPT */
 
/*-----------------------------------------------------------------------------
*  Description : 3dData's mini-structure sizeof
*-----------------------------------------------------------------------------
*  Input :         None
*  Output :        Size of
*-----------------------------------------------------------------------------
*  Creation date : 14/10/96            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
 
/*-----------------------------------------------------------------------------
*  Description : 3dData object action allocation
*-----------------------------------------------------------------------------
*  Input :         Object pointer
*  Output :        None
*-----------------------------------------------------------------------------
*  Creation date : 01/10/96            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
void fn_v3dDataAlloc(struct tdstEngineObject_ *p_stObject)
{
	if (p_stObject==NULL)
		M_GameFatalError(E_uwGameMiniStructObjectNull);
 
	if (p_stObject->h_3dData!=NULL)
		M_GameFatalError(E_uwGameMiniStructAllocAlreadyAlloc);
 
    MMG_fn_vBeginMemoryInfo (MMG_C_lTypeMiniStructure , MMG_C_lSubType3dData , p_stObject);
	p_stObject->h_3dData = fn_h_3dDataRealAlloc();
    MMG_fn_vEndMemoryInfo ();
	fn_v3dDataInitValueSAI(p_stObject->h_3dData);
}
 
/*HP 271098*/
#ifdef U64 
static unsigned short uwBrainMainCounter=0;
#endif
/*----------------------------------------------------*/
MS_tdxHandleTo3dData fn_h_3dDataRealAlloc()
{
	MS_tdxHandleTo3dData h_3dData;
 
	h_3dData = (MS_tdxHandleTo3dData)M_p_GameMallocInHLM(fn_ul3dDataSizeOf());
	POS_fn_vSetIdentityMatrix(fn_p_st3dDataGetMatrix(h_3dData));
 
	fn_v3dDataSetFlagEndState(h_3dData,FALSE);
	fn_v3dDataSetFlagEndOfAnim(h_3dData,FALSE);
	fn_v3dDataSetFlagModifState(h_3dData,FALSE);
	fn_v3dDataSetForcedFrame(h_3dData,0);
 
/* ANNECY MT - 22/09/98 {*/
	fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d = NULL;
	fn_v3dDataSetSizeOfArrayOfElts3d (h_3dData , 0);
	h_3dData->hMorphChannelList = NULL;
/* END ANNECY MT }*/
 
	fn_v3dDataSetStateInLastFrame(h_3dData,NULL);
	fn_v3dDataSetWantedState(h_3dData,NULL);
	fn_v3dDataSetCurrentState(h_3dData,NULL);
 
	fn_v3dDataSetCurrentObjectsTable(h_3dData,NULL);
	fn_v3dDataSetInitialObjectsTable(h_3dData,NULL);
 
	h_3dData->ulStartTime=g_stEngineStructure.stEngineTimer.ulCurrentTimerCount;
	h_3dData->bSkipCurrentFrame=FALSE;
	h_3dData->ulTimeDelay=0;
	h_3dData->sLastFrame=-1;
	h_3dData->bStateJustModified=FALSE;
	h_3dData->uwNbEngineFrameSinceLastMechEvent=LME_INVALID;
	h_3dData->ucFrameRate=0;
	/* Zdx drawing management */
	#if defined (_DEBUG)
		h_3dData->lZdxMask = C_lAllZdxAreOn;
	#endif
 
	/* Draw mask initialisation */
	h_3dData->lDrawMask = GLI_C_lAllIsEnable;
	h_3dData->lDrawMaskInit = GLI_C_lAllIsEnable;
#ifdef D_USE_LIPSYNC
	h_3dData->hLipsTable=NULL;
#endif
	fn_v3dDataSetShadowScaleX(h_3dData, 1.0f);
	fn_v3dDataSetShadowScaleY(h_3dData, 1.0f);
/*XB unused field in U64 engine*/
#ifndef U64
	fn_v3dDataSetShadowQuality(h_3dData, 2);
	fn_v3dDataSetShadowTexture(h_3dData, NULL);
	fn_v3dDataSetShadowMaterial(h_3dData, NULL);
#endif /* U64 */
/*End XB*/
 
#if !defined(U64)
	MTH3D_M_vNullVector(fn_p_st3dDataGetSHWDeformationVector(h_3dData));
	*fn_p_x3dDataGetSHWHeight(h_3dData) = MTH_M_xFloatToReal(0.2f);
#endif /* U64*/
 
/* ANNECY MT - 12/06/98 {*/
	fn_v3dDataSetBrainComputationFrequency(h_3dData,1);
	h_3dData->cBrainCounter = -1;
 
#ifdef U64
	uwBrainMainCounter=uwBrainMainCounter%16;
	h_3dData->uwBrainMainCounter = ++uwBrainMainCounter;
#else	
	h_3dData->uwBrainMainCounter = (unsigned short) RND_fn_lGetLongRandomValue(0,1,(long) 17);
#endif
 
 
#if !defined(U64)
	fn_v3dDataSetLightComputationFrequency(h_3dData,1);
	h_3dData->cLightCounter = -1;
#endif /* U64*/
/* END ANNECY MT }*/
 
	h_3dData->ucTransparency = 255;

	return(h_3dData);
}
 
/*-----------------------------------------------------------------------------
*  Description : 3dData object action free
*-----------------------------------------------------------------------------
*  Input :         Object pointer
*  Output :        None
*-----------------------------------------------------------------------------
*  Creation date : 01/10/96            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
void fn_v3dDataFree(struct tdstEngineObject_ *p_stObject)
{
	if (p_stObject==NULL)
		M_GameFatalError(E_uwGameMiniStructObjectNull);
 
	if (p_stObject->h_3dData==NULL)
		M_GameFatalError(E_uwGameMiniStructNull);
 
	fn_v3dDataFreeInitValueSAI(p_stObject->h_3dData);
 
	PLA_fn_vDesInitAllChildOfCharacter(NULL,p_stObject);
	fn_vFreeMorphList(&(p_stObject->h_3dData->hMorphChannelList));
 
    MMG_fn_vAddMemoryInfo( MMG_C_lTypeMiniStructure , MMG_C_lSubType3dData , p_stObject );
	M_GameFreeInHLM(p_stObject->h_3dData);
}
/*-----------------------------------------------------------------------------
*  Description : 3dData object action initialisation
*-----------------------------------------------------------------------------
*  Input :         When this function's called (see ObjInit.h)
*  Output :        None
*-----------------------------------------------------------------------------
*  Creation date : 01/10/96            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications : 24/05/98 break link with a Father-Perso Carlos Torres
*  Modifications : 28/08/98 Destroy hierarchy module when reinit the map - Carlos Torres
*---------------------------------------------------------------------------*/
void fn_v3dDataInit(struct tdstEngineObject_ *p_stObject,enum tdeObjectTreeInit_ eObjectInit)
{
	tdxHandleToObjectsTablesList hOTLE;	/* MR0707*/
/*	tdstAChannel *p_stChannel, *p_stChannelStop;*/
 
	if (p_stObject==NULL)
		M_GameFatalError(E_uwGameMiniStructObjectNull);
 
	if (p_stObject->h_3dData==NULL)
		M_GameFatalError(E_uwGameMiniStructNull);
	
	/*stdgame uses the global matrix to initialize itself, so reinit it as well, is possible*/
 
	if ( (eObjectInit == OTI_LoadSavedGame) || (eObjectInit == OTI_Always) )
	{
		HIE_tdxHandleToSuperObject hFather,hCharacter;
		
		/*reset the local matrix*/
		fn_v3dDataSetMatrix(p_stObject->h_3dData,fn_p_st3dDataGetMatrixInit(p_stObject->h_3dData));
 
		hCharacter = fn_h_StandardGameGetSuperObject(p_stObject->h_StandardGame);
		
		/*we have to test for this because Always dont have a back pointer to their superobjects...*/
		if ( hCharacter && (hFather = HIE_fn_hGetSuperObjectFather(hCharacter)) != NULL ) /*VOLUNTARY ASSIGNMENT!!!*/
		{
			/*compute the global matrix from the local matrix and the position of the actor's father*/
			POS_fn_vMulMatrixMatrix(
				fn_p_st3dDataGetAbsoluteMatrix(p_stObject->h_3dData),
				HIE_fn_hGetSuperObjectGlobalMatrix(hFather),
				fn_p_st3dDataGetMatrix(p_stObject->h_3dData)
				);
			/*
			// prevent link with another charcter disturbing position init
			if (HIE_fn_ulGetSuperObjectType(hFather)==C_ucCharacter)
				fn_vReputCharacterSuperObjectAtTheWorld(hCharacter);
			*/
		}
	}
 
 
    /****  Reinit the initial transparency ****/
    {
        HIE_tdxHandleToSuperObject   h_SupObject;
 
        h_SupObject = M_GetSuperObject(p_stObject);
        if (h_SupObject)
        {
            h_SupObject->fTransparenceLevel = (float)p_stObject->h_3dData->ucTransparency;
        }
    }
 
	switch(eObjectInit)
	{
    case OTI_WhenGameStart:
		break;
    case OTI_MapLoaded:
		fn_v3dDataInitValueSAI(p_stObject->h_3dData);
		fn_v3dDataSavedValueSAI(p_stObject->h_3dData);
		p_stObject->h_3dData->hArrayOfChannels = NULL;
		p_stObject->h_3dData->ulNumberOfChannels = p_stObject->h_3dData->h_Family->ulNumberOfChannels;
 
    case OTI_LoadSavedGame:
    case OTI_PlayerDead:
    case OTI_ReinitTheMap:
		p_stObject->h_3dData->bAnimMatrixChanged = TRUE;
		fn_vTakeControlOfChannel(p_stObject, (unsigned short) -1, FALSE); /*ANNECY BBB*/
		fn_v3dDataSetStartTime(p_stObject->h_3dData,0);
		fn_v3dDataSetTimeDelay(p_stObject->h_3dData,0);
		fn_v3dDataSetTimePreviousFrame(p_stObject->h_3dData,0);
		/* remove all hierarchy links*/
		PLA_fn_vDesInitAllChildOfCharacter(M_GetSuperObject(p_stObject),p_stObject);
		
#ifdef U64 
		/*HP 301098*/
		uwBrainMainCounter=0;
#endif
		
		memset(&p_stObject->h_3dData->stFrame3d,0,sizeof(struct tdstFrame3d_));
				
		fn_v3dDataSetCurrentHieCouples(p_stObject->h_3dData,NULL);
		fn_v3dDataSetCurrentHieNbCouples(p_stObject->h_3dData,0);
		fn_v3dDataSetSizeOfArrayOfElts3d(p_stObject->h_3dData,0);
 
		p_stObject->h_3dData->lLastComputeFrame=0;
 
		p_stObject->h_3dData->bStateJustModified=FALSE;
		fn_v3dDataSetFrameRate(p_stObject->h_3dData,0);
#ifdef D_USE_LIPSYNC
		fn_v3dDataSetLipsTable(p_stObject->h_3dData,NULL);
#endif
 
		fn_v3dDataSetCurrentState(p_stObject->h_3dData,NULL);
 
		p_stObject->h_3dData->stFrame3d.p_stArrayOfElts3d = NULL;
		p_stObject->h_3dData->stFrame3d.p_stAnim = NULL;
 
		p_stObject->h_3dData->lDrawMask = p_stObject->h_3dData->lDrawMaskInit;
		p_stObject->h_3dData->cBrainCounter = -1;
		p_stObject->h_3dData->bSkipCurrentFrame = FALSE;
#if !defined(U64)
		p_stObject->h_3dData->cLightCounter = -1;
#endif /* U64*/
 
    case OTI_AlwaysCreated:
		fn_vInitMorphList(&(p_stObject->h_3dData->hMorphChannelList));
		hOTLE=fn_h3dDataGetInitialObjectsTable(p_stObject->h_3dData);
#if !defined(U64)
		if (hOTLE&&fn_d_hGetInitObjectsTable(hOTLE))  fn_vReInitObjectTable(hOTLE);
#endif /* U64*/
 
#ifdef U64
		uwBrainMainCounter=uwBrainMainCounter%16;
		p_stObject->h_3dData->uwBrainMainCounter = ++uwBrainMainCounter;
#else
		p_stObject->h_3dData->uwBrainMainCounter = (unsigned short) RND_fn_lGetLongRandomValue(0,1,(long) 17);
#endif
 
/* ANNECY MT - 09/11/98 {*/
		fn_v3dDataSetBrainComputationFrequency(p_stObject->h_3dData,1);
/* END ANNECY MT }*/
		break;
	}
 
	if (M_GetSuperObject(p_stObject)!=NULL)
	{
		PLA_fn_vInitNewState(M_GetSuperObject(p_stObject),fn_h3dDataGetInitialState(p_stObject->h_3dData));
		HIE_fn_vSetSuperObjectDrawMask(M_GetSuperObject(p_stObject),p_stObject->h_3dData->lDrawMask);
	}
}
/*-----------------------------------------------------------------------------
*  Description : 3dData object action desinitialisation
*-----------------------------------------------------------------------------
*  Input :         When this function's called (see ObjInit.h)
*  Output :        None
*-----------------------------------------------------------------------------
*  Creation date : 01/10/96            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
 
void fn_v3dDataDesinit(struct tdstEngineObject_ *p_stObject,enum tdeObjectTreeInit_ eObjectInit)
{
	if (p_stObject==NULL)
		M_GameFatalError(E_uwGameMiniStructObjectNull);
 
	if (p_stObject->h_3dData==NULL)
		M_GameFatalError(E_uwGameMiniStructNull);
 
 
 
/*	if (p_stObject->h_3dData->stFrame3d.p_stArrayOfElts3d)
	{
        //MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , p_stObject->h_3dData->h_Family);
		//TMP_M_Free(p_stObject->h_3dData->stFrame3d.p_stArrayOfElts3d);
		//fn_v3dDataSetSizeOfArrayOfElts3d(p_stObject->h_3dData,0);
		//p_stObject->h_3dData->stFrame3d.p_stArrayOfElts3d = NULL;
		p_stObject->h_3dData->stFrame3d.p_stAnim = NULL;
		fn_vFreeArrayOfElts3d(p_stObject -> h_3dData);
	}
*/
 
 
	/* Olivier Didelot le 1 juillet 1998*/
/*	PLA_fn_vDesInitAllChildOfCharacterByEngineobject(p_stObject);*/
	switch(eObjectInit)
	{
	case OTI_ReinitTheMap:
		break;
	case OTI_MapLoaded:
		PLA_fn_vDesInitAllChildOfCharacter(M_GetSuperObject(p_stObject),p_stObject);
		fn_vFreeMorphList(&(p_stObject->h_3dData->hMorphChannelList));
		break;
	case OTI_PlayerDead:
		break;
	default:
		break;
	}
}
 
 
unsigned long fn_ul3dDataSizeOf()
{
	return(sizeof(struct tdst3dData_));
}
 
 
/*************************************************************************/
/*#define M_3dData_SAIFlags	(SAI_eInitWhenPlayerDead|SAI_eInitWhenReinitTheMap|SAI_eInitWhenMapLoaded|SAI_eInitWhenPlayerGameSavedLoaded)*/
 
void fn_v3dDataInitValueSAI(MS_tdxHandleTo3dData h_3dData)
{
	SAI_fn_bInsertArrayInTable((void*)&h_3dData->stGLIObjectMatrix,sizeof(POS_tdstCompletePosition),M_3dData_SAIFlags);
/* ANNECY AV {*/
/* We don't need to save these variables
// ANNECY MT - 12/06/98 {
	SAI_fn_bInsertCharInTable((void*)&h_3dData->ucBrainComputationFrequency,M_3dData_SAIFlags);
	SAI_fn_bInsertCharInTable((void*)&h_3dData->ucLightComputationFrequency,M_3dData_SAIFlags);
// END ANNECY MT }
*/
/* END ANNECY AV }*/
}
/*************************************************************************/
void fn_v3dDataSavedValueSAI(MS_tdxHandleTo3dData h_3dData)
{
}
/*************************************************************************/
void fn_v3dDataFreeInitValueSAI(MS_tdxHandleTo3dData h_3dData)
{
	SAI_fn_bRemoveValueFromTable((void*)&h_3dData->stGLIObjectMatrix,M_3dData_SAIFlags);
/* ANNECY AV {*/
/* We don't need to save these variables
// ANNECY MT - 12/06/98 {
	SAI_fn_bRemoveValueFromTable((void*)&h_3dData->ucBrainComputationFrequency,M_3dData_SAIFlags);
	SAI_fn_bRemoveValueFromTable((void*)&h_3dData->ucLightComputationFrequency,M_3dData_SAIFlags);
// END ANNECY MT }
*/
/* END ANNECY AV }*/
}
/*************************************************************************/
 
/*************************************/
/**** Access functions for Editor ****/
/*************************************/
/*************************************************************************/
/* END ANNECY MT }*/
 
/*#undef M_3dData_SAIFlags*/
/*************************************************************************/
 
/*-----------------------------------------------------------------------------
*  Description : 3dData copy clone action
*-----------------------------------------------------------------------------
*  Input :         Handle to destination, handle to source
*  Output :        None
*-----------------------------------------------------------------------------
*  Creation date : 30/06/97            Author : Olivier Jourdan
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
void fn_v3dDataCopyClone(struct tdstEngineObject_ * _p_stObjectDest,struct tdstEngineObject_ * _p_stObjectSrc)
{
	void *			pv_tmp1 = _p_stObjectDest->h_3dData->hArrayOfChannels;
	void *			pv_tmp2 = _p_stObjectDest->h_3dData->stFrame3d.p_stArrayOfElts3d;
	void *			pv_tmp3 = _p_stObjectDest->h_3dData->hFirstActiveChannel;
	void *			pv_tmp4 = _p_stObjectDest->h_3dData->hMorphChannelList;
	unsigned short	wSize	= fn_w3dDataGetSizeOfArrayOfElts3d(_p_stObjectDest->h_3dData);
 
	/* If 3dData doesn't contains pointers to structure that may be*/
	/* changed during the game, this function must only be a :*/
	memcpy(_p_stObjectDest->h_3dData,_p_stObjectSrc->h_3dData,fn_ul3dDataSizeOf());
 
	/* to hold these values...*/
	_p_stObjectDest->h_3dData->hArrayOfChannels = pv_tmp1;
	_p_stObjectDest->h_3dData->stFrame3d.p_stArrayOfElts3d = pv_tmp2;
	_p_stObjectDest->h_3dData->hFirstActiveChannel = pv_tmp3;
	_p_stObjectDest->h_3dData->hMorphChannelList = pv_tmp4;
	fn_v3dDataSetSizeOfArrayOfElts3d(_p_stObjectDest->h_3dData,wSize);
}
/*-----------------------------------------------------------------------------
*  Description : 3dData access functions
*-----------------------------------------------------------------------------
*  Input :         MS_tdxHandleTo3dData + (value)
*  Output :        (value or pointer)
*-----------------------------------------------------------------------------
*  Creation date : 29/01/97            Author : Francois
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
/****************************/
#if defined (ACTIVE_EDITOR)
MTH_tdxReal fn_v3dDataGetMatrixElement(MS_tdxHandleTo3dData h_3dData,unsigned char ucInitOrLocalOrAbsolute,unsigned char ucWhichMatrix,unsigned char ucWhichVector,unsigned char ucWhichElement)
{
	MTH_tdxReal xReturn = 0.0;
	MTH3D_tdstVector stI;
	MTH3D_tdstVector stJ;
	MTH3D_tdstVector stK;
 
	if (ucWhichMatrix==0) /* Translation*/
	{
		if (ucInitOrLocalOrAbsolute==0) /*Init*/
		{
			POS_fn_vGetTranslationVector(fn_p_st3dDataGetMatrixInit(h_3dData),&stI);
			POS_fn_vGetTranslationVector(fn_p_st3dDataGetMatrixInit(h_3dData),&stJ);
			POS_fn_vGetTranslationVector(fn_p_st3dDataGetMatrixInit(h_3dData),&stK);
		}
		else if (ucInitOrLocalOrAbsolute==1) /*Local*/
		{
			POS_fn_vGetTranslationVector(&(h_3dData->stGLIObjectMatrix),&stI);
			POS_fn_vGetTranslationVector(&(h_3dData->stGLIObjectMatrix),&stJ);
			POS_fn_vGetTranslationVector(&(h_3dData->stGLIObjectMatrix),&stK);
		}
		else if (ucInitOrLocalOrAbsolute==2) /*Absolute*/
		{
			POS_fn_vGetTranslationVector((h_3dData->p_stGLIObjectAbsoluteMatrix),&stI);
			POS_fn_vGetTranslationVector((h_3dData->p_stGLIObjectAbsoluteMatrix),&stJ);
			POS_fn_vGetTranslationVector((h_3dData->p_stGLIObjectAbsoluteMatrix),&stK);
		}
	}
	else if (ucWhichMatrix==1) /* Rotation*/
	{
		if (ucInitOrLocalOrAbsolute==0) /*Init*/
		{
			POS_fn_vGetRotationMatrix(fn_p_st3dDataGetMatrixInit(h_3dData),&stI,&stJ,&stK);
		}
		else if (ucInitOrLocalOrAbsolute==1) /*Local*/
		{
			POS_fn_vGetRotationMatrix(&(h_3dData->stGLIObjectMatrix),&stI,&stJ,&stK);
		}
		else if (ucInitOrLocalOrAbsolute==2) /*Absolute*/
		{
			POS_fn_vGetRotationMatrix((h_3dData->p_stGLIObjectAbsoluteMatrix),&stI,&stJ,&stK);
		}
	}
	else if (ucWhichMatrix==2) /* Scale*/
	{
		if (ucInitOrLocalOrAbsolute==0) /*Init*/
		{
			POS_fn_vGetScaleMatrix(fn_p_st3dDataGetMatrixInit(h_3dData),&stI,&stJ,&stK);
		}
		else if (ucInitOrLocalOrAbsolute==1) /*Local*/
		{
			POS_fn_vGetScaleMatrix(&(h_3dData->stGLIObjectMatrix),&stI,&stJ,&stK);
		}
		else if (ucInitOrLocalOrAbsolute==2) /*Absolute*/
		{
			POS_fn_vGetScaleMatrix((h_3dData->p_stGLIObjectAbsoluteMatrix),&stI,&stJ,&stK);
		}
		if (MTH_M_bEqualWithEpsilon(stI.xX,MTH_C_ONE,MTH_M_xFloatToReal(0.001f)))
			MTH3D_M_vSetBaseIVector(&stI);
 
		if (MTH_M_bEqualWithEpsilon(stJ.xY,MTH_C_ONE,MTH_M_xFloatToReal(0.001f)))
			MTH3D_M_vSetBaseJVector(&stJ);
 
		if (MTH_M_bEqualWithEpsilon(stK.xZ,MTH_C_ONE,MTH_M_xFloatToReal(0.001f)))
			MTH3D_M_vSetBaseKVector(&stK);
 
	}
	if (ucWhichVector==0) /* I*/
	{
		if (ucWhichElement==0) /* X*/
			xReturn=MTH3D_M_xGetXofVector(&stI);
		else if (ucWhichElement==1) /* Y*/
			xReturn=MTH3D_M_xGetYofVector(&stI);
		else if (ucWhichElement==2) /* Z*/
			xReturn=MTH3D_M_xGetZofVector(&stI);
	}
	else if (ucWhichVector==1) /* J*/
	{
		if (ucWhichElement==0) /* X*/
			xReturn=MTH3D_M_xGetXofVector(&stJ);
		else if (ucWhichElement==1) /* Y*/
			xReturn=MTH3D_M_xGetYofVector(&stJ);
		else if (ucWhichElement==2) /* Z*/
			xReturn=MTH3D_M_xGetZofVector(&stJ);
	}
	else if (ucWhichVector==2) /* K*/
	{
		if (ucWhichElement==0) /* X*/
			xReturn=MTH3D_M_xGetXofVector(&stK);
		else if (ucWhichElement==1) /* Y*/
			xReturn=MTH3D_M_xGetYofVector(&stK);
		else if (ucWhichElement==2) /* Z*/
			xReturn=MTH3D_M_xGetZofVector(&stK);
	}
 
	return(xReturn);
}
#endif	/*ACTIVE_EDITOR*/
 
#if defined (ACTIVE_EDITOR)
 
/*void fn_v3dDataSetChannelActivationList(MS_tdxHandleTo3dData h_3dData,CHN_tdxHandleToCASList hCASList)
{
	h_3dData->hChannelActivationList=hCASList;
}
*/#endif	/*ACTIVE_EDITOR*/
 
 
void fn_v3dDataSetFrameRate(MS_tdxHandleTo3dData h_3dData,unsigned char ucFrameRate)
{
	unsigned long ulNbFrames;
	if (ucFrameRate>1)	/* Change the Start Time of the anim in order to preserve the current frame*/
	{
		ulNbFrames=(g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-h_3dData->ulStartTime)*h_3dData->ucFrameRate;
		h_3dData->ulStartTime=g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-ulNbFrames/ucFrameRate;
	}
	h_3dData->ucFrameRate=ucFrameRate;
}
 
void fn_v3dDataFactorFrameRate(MS_tdxHandleTo3dData _h3dData,unsigned long _ulFactor100)
{
	unsigned long ulNbFrames;
	unsigned char ucFrameRate = (unsigned char) (fn_scGetSpeedInState(fn_h3dDataGetCurrentState(_h3dData))*_ulFactor100/100L);
 
	if (ucFrameRate > 1)	/* Change the Start Time of the anim in order to preserve the current frame*/
	{
		ulNbFrames = (g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-_h3dData->ulStartTime)*_h3dData->ucFrameRate;
		_h3dData->ulStartTime = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-ulNbFrames/ucFrameRate;
 
		_h3dData->ucFrameRate = ucFrameRate;
	}
}
 
 
/* The following function is only used in OAC*/
#if defined (ACTIVE_EDITOR)
GMT_tdxHandleToGameMaterial fn_p_st3dDataGetShadowMaterial(MS_tdxHandleTo3dData _h3dData)
{
	return _h3dData->p_stShadowMaterial;
}
#endif
 
 
#if defined (ACTIVE_EDITOR)
/****************************/
long fn_l3dDataGetDrawMaskInit(MS_tdxHandleTo3dData _h3dData)
{
	return _h3dData->lDrawMaskInit;
}
#endif	/*ACTIVE_EDITOR*/
 
/****************************/
 
/****************************/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vSetCharacterInvisible(HIE_tdxHandleToSuperObject _hCharacter)
{
	if( !M_GetMSHandle(_hCharacter,3dData) )
		return;
	M_GetMSHandle(_hCharacter,3dData)->lDrawMask =
		M_GetMSHandle(_hCharacter,3dData)->lDrawMask &
		(GLI_C_lAllIsEnable-GLI_C_lDrawNothing);
	HIE_fn_vSetSuperObjectDrawMask(_hCharacter,
		M_GetMSHandle(_hCharacter,3dData)->lDrawMask);
 
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/****************************/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vSetCharacterVisible(HIE_tdxHandleToSuperObject _hCharacter)
{
	if( !M_GetMSHandle(_hCharacter,3dData) )
		return;
	M_GetMSHandle(_hCharacter,3dData)->lDrawMask =
		M_GetMSHandle(_hCharacter,3dData)->lDrawMask | GLI_C_lDrawNothing;
	HIE_fn_vSetSuperObjectDrawMask(_hCharacter,
		M_GetMSHandle(_hCharacter,3dData)->lDrawMask);
 
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/* ANNECY MT - 12/06/98 {*/
/****************************/
void fn_v3dDataSetBrainComputationFrequency(MS_tdxHandleTo3dData h_3dData,unsigned char _ucFrequency)
{
	h_3dData->ucBrainComputationFrequency = _ucFrequency;
	if(h_3dData->cBrainCounter >= h_3dData->ucBrainComputationFrequency)
		h_3dData->cBrainCounter = 0;
}
/****************************/
/****************************/
void fn_v3dDataUpdateBrainCounter(HIE_tdxHandleToSuperObject _hCharacter)
{
	if(_hCharacter && M_GetMSHandle(_hCharacter,3dData))
	{
		MS_tdxHandleTo3dData h_3dData = M_GetMSHandle(_hCharacter,3dData);
 
		h_3dData->cBrainCounter ++;
		if (h_3dData->cBrainCounter >= h_3dData->ucBrainComputationFrequency)
			h_3dData->cBrainCounter = 0;
	}
}
/****************************/
ACP_tdxBool fn_b3dDataCanComputeBrain(HIE_tdxHandleToSuperObject _hCharacter)
{
	if(_hCharacter && M_GetMSHandle(_hCharacter,3dData))
	{
		MS_tdxHandleTo3dData h_3dData = M_GetMSHandle(_hCharacter,3dData);
 
		return (ACP_tdxBool)(h_3dData->cBrainCounter==0);
	}
	return TRUE;	/* default*/
}
 
/****************************/
/****************************/
#if !defined(U64) /* MT {*/
 
void fn_v3dDataSetLightComputationFrequency(MS_tdxHandleTo3dData h_3dData,unsigned char _ucFrequency)
{
	h_3dData->ucLightComputationFrequency = _ucFrequency;
	if(h_3dData->cLightCounter >= h_3dData->ucLightComputationFrequency)
		h_3dData->cLightCounter = 0;
}
/****************************/
void fn_v3dDataUpdateLightCounter(HIE_tdxHandleToSuperObject _hCharacter)
{
	if(_hCharacter && M_GetMSHandle(_hCharacter,3dData))
	{
		MS_tdxHandleTo3dData h_3dData = M_GetMSHandle(_hCharacter,3dData);
 
		h_3dData->cLightCounter ++;
		if (h_3dData->cLightCounter == h_3dData->ucLightComputationFrequency)
			h_3dData->cLightCounter = 0;
	}
}
/****************************/
ACP_tdxBool fn_b3dDataCanComputeLight(HIE_tdxHandleToSuperObject _hCharacter)
{
	/*
	if(_hCharacter && M_GetMSHandle(_hCharacter,3dData))
	{
		MS_tdxHandleTo3dData h_3dData = M_GetMSHandle(_hCharacter,3dData);
 
		return (ACP_tdxBool)(h_3dData->cLightCounter==0);
	}
	return TRUE;	// default
	*/
	return TRUE;
}
#endif /* U64 - MT }*/
 
/* END ANNECY MT }*/
/****************************/
 
BOOL fn_b3dDataGetUserEventFlag(MS_tdxHandleTo3dData h_3dData, unsigned char _ucFlagIndex, MTH3D_tdstVector *_p_stPosition )
{
	unsigned char ucMask = (unsigned char) (1 << _ucFlagIndex);
	if ( _p_stPosition )
		*_p_stPosition = h_3dData->stLastEventGlobalPosition;
	return (h_3dData->ucUserEventFlags & ucMask);
}
 
void fn_v3dDataSetUserEventFlag( MS_tdxHandleTo3dData h_3dData,unsigned char _ucFlagIndex, BOOL _bSet, MTH3D_tdstVector *_p_stPosition )
{
	unsigned char ucMask = (unsigned char) (1 << _ucFlagIndex);
	if (_bSet)
		h_3dData->ucUserEventFlags |= ucMask;
	else
		h_3dData->ucUserEventFlags &= ~ucMask;
	if ( _p_stPosition )
		h_3dData->stLastEventGlobalPosition = *_p_stPosition;
}
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
unsigned long fn_ul3dDataSetNumberOfChannels(MS_tdxHandleTo3dData h_3dData, unsigned long ulNumberOfChannels)
{
	return (h_3dData->ulNumberOfChannels = ulNumberOfChannels);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
/* Oliv' - remove wNumRom - 22/06/1999 */
/*
#if defined (U64)
#ifndef RETAIL
short fn_wGet3dDataNumRom(tdstEngineObject * p_stEngineObject)
{
	if (p_stEngineObject == NULL)
		return -1;
	if (((struct tdst3dData_*)((p_stEngineObject)->h_3dData)) == NULL)
		return -2;
	return (((struct tdst3dData_*)((p_stEngineObject)->h_3dData))->wNumRom);
}
 
void fn_wSet3dDataNumRom(tdstEngineObject * p_stEngineObject, short wNum)
{
	if (p_stEngineObject == NULL)
		return;
	if (((struct tdst3dData_*)((p_stEngineObject)->h_3dData)) == NULL)
		return;
	(((struct tdst3dData_*)((p_stEngineObject)->h_3dData))->wNumRom) = wNum;
}
#endif *//* !RETAIL *//*
#endif *//* U64*//*
*/
/* EndOfOliv' */
 
/****************************/
/* ANNECY MT - 22/09/98 {*/
void fn_vAllocArrayOfElts3d(MS_tdxHandleTo3dData h_3dData, unsigned short _wNumberOfElts3d)
{
	unsigned short wCurrentSize = fn_w3dDataGetSizeOfArrayOfElts3d (h_3dData);
 
	if(_wNumberOfElts3d > wCurrentSize)
	{
		if(fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d)
		{
			MMG_fn_vAddMemoryInfo (MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_3dData -> h_Family);
			TMP_M_Free (fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d);
		}
		MMG_fn_vAddMemoryInfo (MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_3dData -> h_Family);
		fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d = (tdstElement3d*)TMP_M_p_Malloc (sizeof (tdstElement3d) * _wNumberOfElts3d);
/*		memset (fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d , 0 , sizeof (tdstElement3d) * _wNumberOfElts3d); AR9904 Already done in the alloc function */
		fn_v3dDataSetSizeOfArrayOfElts3d (h_3dData , _wNumberOfElts3d);
	}
}
 
void fn_vFreeArrayOfElts3d(MS_tdxHandleTo3dData h_3dData)
{
	tdstElement3d* p_stElts3d = fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d;
 
	if (p_stElts3d)
	{
		MMG_fn_vAddMemoryInfo (MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , h_3dData -> h_Family);
		TMP_M_Free (p_stElts3d);
	}
	fn_p_st3dDataGetCurrentFrame (h_3dData) -> p_stArrayOfElts3d = NULL;
	fn_v3dDataSetSizeOfArrayOfElts3d (h_3dData , 0);
}
/* END ANNECY MT }*/
/****************************/
