/*---------------------------------------------------------------------------*/
/* Operator.c : Definition of Operator.*/
/* auteur : Olivier Didelot.*/
/* date   : 21/01/1997*/
/**/
/* 970129 : Bug in EvalOperator case eOperator_Dot	(Fabien Morales)*/
/* modify : 31/01/1997 (O.C) script & editor names + Lint*/
/* modify : Olivier Couvreur*/
/* date   : 03/02/1997  Lint 0 warnings excepted those specified at the end of AIMacros.h*/
/* modify : Olivier Couvreur*/
/* date   : 18/02/1997  CPA_EXPORT + new functions for editor*/
/* modify : Olivier Couvreur*/
/* date   : 21/02/1997  Rethink operators support*/
/*                      Add /,+=,-=,/=,*=,++,-- operators  + rewrite of sz????NameFromId*/
/* modify : Olivier Couvreur*/
/* date   : 03/04/1997  Add unary minus operator*/
/* modify : Olivier Couvreur*/
/* date   : 27/06/1997  Now operators use function pointers !*/
/*---------------------------------------------------------------------------*/
#include "AIUseCPA.h"
 
#include "specif/AIOption.h" 
#include "AIMacros.h" 
#include "AI_Erm.h"
 
#include "AI_Struc.h"
#include "StrIntel.h"
#include "DsgMem.h" 
#include "ActConst.h"
 
#include "Intell.h"
#include "GetSet.h"
 
#include "EnumOper.h"
#include "EnumFild.h"
#include "EnumKey.h"
 
#include "specif/AITools.h"
 
#include "safe.h"
 
#if defined(__DEBUG_AI__)
#include "ConvVar.h"
#endif
 
#if defined(ACTIVE_AIDEBUG)   /*** DR ***/
#include "AID_Erm.h"
#include "specif/AID_Trac.h"
#endif /*ACTIVE_AIDEBUG*/
 
/* for long*/
#define AI_MTH_M_lAdd(A,B) ( (A)+(B) )
#define AI_MTH_M_lSub(A,B) ( (A)-(B) )
#define AI_MTH_M_lMul(A,B) ( (A)*(B) )
#define AI_MTH_M_lDiv(A,B) ( (A)/(B) )
 
/* for real*/
#define AI_MTH_M_xAdd(A,B) MTH_M_xAdd(A,B)
#define AI_MTH_M_xSub(A,B) MTH_M_xSub(A,B)
#define AI_MTH_M_xMul(A,B) MTH_M_xMul(A,B)
#define AI_MTH_M_xDiv(A,B) MTH_M_xDiv(A,B)
 
#define M_Operator_Arith(ucIsThereFloat,Func,p_stParam1,p_stParam2,p_stValue) \
if ((ucIsThereFloat)) \
{ \
    M_Full_GetSetParam_Float(p_stValue, \
      AI_MTH_M_x##Func( \
      M_GetSetParam_xValue(p_stParam1), \
      M_GetSetParam_xValue(p_stParam2)  \
      ) \
    ); \
} \
else \
{ \
    M_Full_GetSetParam_Integer(p_stValue, \
      AI_MTH_M_l##Func(  \
      M_GetSetParam_lValue(p_stParam1), \
      M_GetSetParam_lValue(p_stParam2)  \
      ) \
    ); \
}
 
/************************************************************************************/
/* HERE IS THE BEGINNING                                                            */
/************************************************************************************/
#if !defined(OPTIMIZED_COMMAND)
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
tdstNodeInterpret *fn_p_stDefaultOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	p_SuperObjPerso=p_SuperObjPerso;
	p_stValue=p_stValue;
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
    M_AIFatalError(E_uwAIFatalNotValidOperator);
#endif /* _DEBUG_AI__*/
    return(p_stTree);
}
#endif /* _DEBUG_AI__*/
#endif /* OPTIMIZED_COMMAND*/
 
tdstNodeInterpret *fn_p_stScalarOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	tdstGetSetParam stParam2;
	tdeOperatorId eOperatorId = M_eOperatorIdInterpret(p_stTree-1);
	unsigned char ucIsThereFloat;
 
	/* unless this is the unary minus operator, there are two operands*/
	if ( eOperatorId == eOperator_ScalarUnaryMinus)
	{
		M_Full_GetSetParam_Integer(p_stValue,0); 
	}
	else
	{
		/* get the first one*/
		M_EvalNextParameter(p_stValue);
 
		/* in case of multiplications*/
		if ( (eOperatorId == eOperator_ScalarMulScalar) || (eOperatorId == eOperator_ScalarDivScalar) )
		{
			/* if the first operand is null, it is not necessary to evaluate the second one!*/
			if ( MTH_M_bIsNull(M_ReturnParam_xValue(p_stValue)) )
			{
				/* then just skip it! (dont worry, the exchange structure already contains 0)*/
				return fn_p_stSkipThisArgument(p_stTree);
			}
		}
	}
 
	M_EvalNextParameter(&stParam2);
 
	/* conversion in float if necessary : simplify the macro M_Operator_Arith*/
	ucIsThereFloat = fn_ucAreThereFloatIfYesConvertThem(p_stValue,&stParam2);
 
	/* do operation*/
	switch ( eOperatorId )
	{
	case eOperator_ScalarPlusScalar:
		M_Operator_Arith(ucIsThereFloat,Add,p_stValue,&stParam2,p_stValue); 
		return(p_stTree);
		break;
 
	case eOperator_ScalarUnaryMinus:
	case eOperator_ScalarMinusScalar:
		M_Operator_Arith(ucIsThereFloat,Sub,p_stValue,&stParam2,p_stValue); 
		return(p_stTree);
		break;
 
	case eOperator_ScalarMulScalar:
		M_Operator_Arith(ucIsThereFloat,Mul,p_stValue,&stParam2,p_stValue); 
		return(p_stTree);
		break;
 
	case eOperator_ScalarDivScalar:
		if
		(
			((ucIsThereFloat) && (MTH_M_bDifferentWithEpsilon(M_GetSetParam_xValue(&stParam2),MTH_C_ZERO,MTH_C_EpsilonPlus)))
			|| ((!ucIsThereFloat) && ( M_GetSetParam_lValue(&stParam2)!=0))
		)
		{
		M_Operator_Arith(ucIsThereFloat,Div,p_stValue,&stParam2,p_stValue); 
		}
		else
		{
			M_Full_GetSetParam_Integer(p_stValue,0);
			#if defined(__DEBUG_AI__)
			SAF_M_AssertWithMsg(FALSE, "Division par zéro !")
			M_AIFatalError(E_uwAIDivisionByZero);
			#endif /* __DEBUG_AI__*/
		}
		return(p_stTree);
 
	default:
		break;
	}
	#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
	M_AIFatalError(E_uwAIFatalNotValidOperator);
	#endif /* __DEBUG_AI__*/
	M_Full_GetSetParam_Integer(p_stValue,0);
	return(p_stTree);
}
 
 
/* Vector operator*/
tdstNodeInterpret *fn_p_stVectorOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  tdstGetSetParam stParam1, stParam2;
  tdeOperatorId eOperatorId=M_eOperatorIdInterpret(p_stTree-1);
  MTH3D_tdstVector *p_stVector,*p_stVector1,*p_stVector2=NULL;
  MTH_tdxReal xFactor=MTH_C_ONE;
   
  M_EvalNextParameter(&stParam1);
#if defined(__DEBUG_AI__)
  M_VerifyTypeOfParamAction(&stParam1, E_vt_Vector);
#endif
  p_stVector1=&M_GetSetParam_stVertexValue(&stParam1);
 
  if (eOperatorId!=eOperator_VectorUnaryMinus)
  {
    M_EvalNextParameter(&stParam2);
    if ( (eOperatorId==eOperator_VectorPlusVector) || (eOperatorId==eOperator_VectorMinusVector) )
	{
#if defined(__DEBUG_AI__)
      M_VerifyTypeOfParamAction(&stParam2, E_vt_Vector);
#endif /* __DEBUG_AI__*/
      p_stVector2=&M_GetSetParam_stVertexValue(&stParam2);
	}
    else
	{
      xFactor=M_ReturnParam_xValue(&stParam2);
	}
  }
 
  p_stVector=&M_GetSetParam_stVertexValue(p_stValue);
  M_GetSetParam_Type(p_stValue)=E_vt_Vector;
 
/* do operation*/
  switch(eOperatorId)
  {
	case eOperator_VectorPlusVector:
        MTH3D_M_vAddVector(p_stVector,p_stVector1,p_stVector2);
		return(p_stTree);
	case eOperator_VectorMinusVector:
        MTH3D_M_vSubVector(p_stVector,p_stVector1,p_stVector2); 
		return(p_stTree);
    case eOperator_VectorMulScalar:
		MTH3D_M_vMulScalarVector(p_stVector,xFactor,p_stVector1);
		return(p_stTree);
	case eOperator_VectorDivScalar:
		if (MTH_M_bDifferentWithEpsilon(xFactor,MTH_C_ZERO,MTH_C_EpsilonPlus))
		{
		  MTH3D_M_vDivScalarVector(p_stVector,p_stVector1,xFactor);
		}
		else
		{
#if defined(__DEBUG_AI__)
			M_AIFatalError(E_uwAIDivisionByZero);
#endif /* __DEBUG_AI__*/
            MTH3D_M_vNullVector(p_stVector);
        } 
		return(p_stTree);
    case eOperator_VectorUnaryMinus:
		MTH3D_M_vNegVector(p_stVector,p_stVector1);
		return(p_stTree);
		default:
		  break;
  }
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
  M_AIFatalError(E_uwAIFatalNotValidOperator);
#endif /* __DEBUG_AI__*/
  MTH3D_M_vNullVector(p_stVector);
  return(p_stTree);
}
 
/*********************************************************************************************************************/
/* for dot and affect and ultra operator                                                                             */
/*********************************************************************************************************************/
 
 
 
tdstNodeInterpret *fn_p_stOperatorGetPerso(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, HIE_tdxHandleToSuperObject *hSuperObjPersoFound)
{
  HIE_tdxHandleToSuperObject hSuperObjPerso;
  tdstGetSetParam stValue;
#if defined(__DEBUG_AI__)
   tdeTypeInterpret eTypeInterpret = M_GetTypeInterpret(p_stTree);
   /*M_AI_DEBUG_ASSERT*/
   SAF_M_AssertWithMsg
   (
     (eTypeInterpret==E_ti_PersoRef) || 
	 (eTypeInterpret==E_ti_DsgVarRef) ||
	 (
       (eTypeInterpret==E_ti_KeyWord) &&
  	   (
         /*(M_eKeyWordIdInterpret(p_stTree)==eKeyWord_World) ||*/
	 	 (M_eKeyWordIdInterpret(p_stTree)==eKeyWord_MainActor) ||
		 (M_eKeyWordIdInterpret(p_stTree)==eKeyWord_Me) 
	   )
	 ) ||
	 (
		(eTypeInterpret==E_ti_Operator) &&
		(
			(M_eOperatorIdInterpret(p_stTree)==eOperator_Dot) ||
			(M_eOperatorIdInterpret(p_stTree)==eOperator_ModelCast) 
		)
	 )
	 ,
   "Variable Perso invalide"
	 /*E_uwAIFatalInvalidAccessToFieldOrDsgVar*/
   );
#endif /*__DEBUG_AI__*/
	M_EvalNextParameter(&stValue);
#if defined(__DEBUG_AI__)
  /*check that we got a perso*/
	M_VerifyTypeOfParamAction(&stValue, E_vt_Perso);
  /* and that the engine object is not NULL*/
	M_AI_DEBUG_ASSERT(M_GetSetParam_p_stEngineObjValue(&stValue), E_uwAIFatalCantFindPerso);
#endif /* __DEBUG_AI__*/
 
  /*now that the engine object is checked as valid, we can get the parent superobject */
  hSuperObjPerso = M_GetSetParam_p_stSupObjValue(&stValue);
 
#if defined(__DEBUG_AI__)
  /*check that it is valid however...*/
	M_AI_DEBUG_ASSERT((hSuperObjPerso != NULL), E_uwAIFatalCantFindPerso);
#endif /* __DEBUG_AI__*/
 
	*hSuperObjPersoFound=hSuperObjPerso;
 
	return(p_stTree);
}
 
static void fn_vOperatorGetField(enum tdeFieldId_ eFieldId,HIE_tdxHandleToSuperObject hSuperObjPerso,tdstGetSetParam *p_stValue)
{
   if (fn_ucGetFieldValue(eFieldId, hSuperObjPerso, p_stValue) == C_INVALID_GET)
   {	
#if defined(__DEBUG_AI__)
	  fn_vTestGetDsgVarOrField(1,0,0,eFieldId,hSuperObjPerso ,p_stValue);
#else
	  M_AIFatalError(E_uwAIFatalInvalidAccessToField);
#endif
   }        
}
 
static void fn_vOperatorSetField(enum tdeFieldId_ eFieldId,HIE_tdxHandleToSuperObject hSuperObjPerso,tdstGetSetParam *p_stValue)
{
   if (fn_ucSetFieldValue(eFieldId, hSuperObjPerso, p_stValue) == C_INVALID_SET)
   {	
	  M_AIFatalError(E_uwAIFatalInvalidAccessToField);
   } 
}
 
static void fn_vOperatorGetDsgVar(unsigned char ucVarId,unsigned char ucIndex,HIE_tdxHandleToSuperObject hSuperObjPerso,tdstGetSetParam *p_stValue)
{
   if (fn_ucGetDsgVar(ucVarId, ucIndex, AI_M_stGetMindOfSuperObj(hSuperObjPerso), p_stValue)==C_INVALID_GET) 
   {   	
#if defined(__DEBUG_AI__)
	   
	   fn_vTestGetDsgVarOrField(0,ucVarId,ucIndex,(tdeFieldId) 0,hSuperObjPerso ,p_stValue);
#endif
   } 
}
 
static void fn_vOperatorSetDsgVar(unsigned char ucVarId,unsigned char ucIndex,HIE_tdxHandleToSuperObject hSuperObjPerso,tdstGetSetParam *p_stValue)
{
   if (fn_ucSetDsgVar(ucVarId, ucIndex, AI_M_stGetMindOfSuperObj(hSuperObjPerso), p_stValue)==C_INVALID_SET) 
   {   	
 
#if defined(__DEBUG_AI__)
		char  Message[255];
		
		sprintf(Message, "Invalid Access to Dsg Var %s ", M_GetDsgVarName(AI_M_stGetMindOfSuperObj(hSuperObjPerso),ucVarId ));
		SAF_M_AssertWithMsg(FALSE, Message );
#endif 
	   /*M_AIFatalError(E_uwAIFatalInvalidAccessToDsgVar); */
	   /* error or not ????*/
   } 
}
 
/*********************************************************************************************************************/
/* THE ARRAY OPERATOR                                                                                                  */
/*********************************************************************************************************************/
tdstNodeInterpret *fn_p_stArrayOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	unsigned char ucVarId=0;
	unsigned char ucIndex=0;
	HIE_tdxHandleToSuperObject hSuperObjPerso=p_SuperObjPerso;
	tdeTypeInterpret eTypeInterpret = M_GetTypeInterpret(p_stTree); 
	
	if (eTypeInterpret==E_ti_Operator)
	{
		#if defined(__DEBUG_AI__)
		M_AI_DEBUG_ASSERT((M_eOperatorIdInterpret(p_stTree) == eOperator_Dot) , E_uwAIFatalInvalidAccessToDsgVar);
		#endif /* __DEBUG_AI__*/
		p_stTree++;                
		p_stTree=fn_p_stOperatorGetPerso(p_SuperObjPerso,p_stTree,&hSuperObjPerso);
	}
 
	#if defined(__DEBUG_AI__)
	M_AI_DEBUG_ASSERT( (M_GetTypeInterpret(p_stTree)==E_ti_DsgVarRef) , E_uwAIFatalInvalidAccessToDsgVar);
	#endif /* __DEBUG_AI__*/
	ucVarId= (unsigned char) M_ucVarIdInterpret(p_stTree);
	p_stTree++;
 
	M_EvalNextParameter(p_stValue);
	ucIndex=(unsigned char) M_lValueInterpret(p_stValue);
 
	fn_vOperatorGetDsgVar(ucVarId,ucIndex,hSuperObjPerso,p_stValue);
 
	return(p_stTree);
}
 
/*********************************************************************************************************************/
/* THE DOT OPERATOR                                                                                                  */
/*********************************************************************************************************************/
tdstNodeInterpret *fn_p_stDotOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	HIE_tdxHandleToSuperObject hSuperObjPerso;
	tdeTypeInterpret eTypeInterpret;
	unsigned char ucIndex=0;
 
    p_stTree=fn_p_stOperatorGetPerso(p_SuperObjPerso,p_stTree,&hSuperObjPerso);
 
	eTypeInterpret = M_GetTypeInterpret(p_stTree);
#if defined(__DEBUG_AI__)
	 M_AI_DEBUG_ASSERT(
						(eTypeInterpret==E_ti_Field) || 
						(eTypeInterpret==E_ti_DsgVarRef) ||
						(
							(eTypeInterpret==E_ti_Operator) && (M_eOperatorIdInterpret(p_stTree)==eOperator_ModelCast)
						)
						, E_uwAIFatalInvalidAccessToFieldOrDsgVar);
#endif /*__DEBUG_AI__*/
	
	/* to swap*/
    if (eTypeInterpret==E_ti_DsgVarRef)
    {
       unsigned char ucVarId = (unsigned char) M_ucVarIdInterpret(p_stTree);
			 p_stTree ++; /*BBB side effect operator out of the macro argument...*/
       fn_vOperatorGetDsgVar(ucVarId,ucIndex,hSuperObjPerso,p_stValue);
#if defined( ACTIVE_AIDEBUG )
			 AIDebug_M_SetDsgVar( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, (p_stTree-1) );
#endif
    }
	else if (eTypeInterpret==E_ti_Field)
    {
       enum tdeFieldId_ eFieldId = M_eFieldIdInterpret(p_stTree);
			 p_stTree ++; /*BBB side effect operator out of the macro argument...*/
       fn_vOperatorGetField(eFieldId,hSuperObjPerso,p_stValue);
#if defined( ACTIVE_AIDEBUG )
			 AIDebug_M_SetField( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, (p_stTree-1) );
#endif
	}
	else if ( (eTypeInterpret==E_ti_Operator) && (M_eOperatorIdInterpret(p_stTree)==eOperator_ModelCast) )
	{
		/*p_stTree=fn_p_stModelCastOperator(p_SuperObjPerso, p_stTree, p_stValue);*/
		p_stTree=fn_p_stEvalTree(p_SuperObjPerso,p_stTree,p_stValue);
	}
    return(p_stTree);
}
 
/*********************************************************************************************************************/
/* THE DOT OPERATOR FOR VECTOR .X .Y .Z :                                                                             */
/*********************************************************************************************************************/
tdstNodeInterpret *fn_p_stVectorDotOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
    tdeOperatorId eOperatorId=M_eOperatorIdInterpret(p_stTree-1);
 
    M_EvalNextParameter(p_stValue);
    if (M_IsVectorType(p_stValue))
	{
    	MTH3D_tdstVector *p_stVector=&M_GetSetParam_stVertexValue(p_stValue);
 
		switch(eOperatorId)
		{
			case eOperator_GetVectorX: 
				M_Full_GetSetParam_Float(p_stValue,MTH3D_M_xGetXofVector(p_stVector) );
				return(p_stTree);
    
			case eOperator_GetVectorY: 
				M_Full_GetSetParam_Float(p_stValue,MTH3D_M_xGetYofVector(p_stVector) );
				return(p_stTree);
    
			case eOperator_GetVectorZ: 
				M_Full_GetSetParam_Float(p_stValue,MTH3D_M_xGetZofVector(p_stVector) );
				return(p_stTree);
		default:
		  break;
		}
	}
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
	M_AIFatalError(E_uwAIFatalNotValidOperator);
#endif
    return(p_stTree);
}
 
 
/* for affect operator*/
static void fn_vGetFieldOrDsgVarForAffectOperator(HIE_tdxHandleToSuperObject hSuperObjPerso,tdeTypeInterpret eTypeInterpret,unsigned char ucVarId,unsigned char ucIndex,tdeFieldId eFieldId,tdstGetSetParam *p_stValue)
{
	if (eTypeInterpret==E_ti_DsgVarRef)
	{
        /* read dsgvar value in stValue*/
        fn_vOperatorGetDsgVar(ucVarId,ucIndex,hSuperObjPerso,p_stValue);
	}
	else if (eTypeInterpret==E_ti_Field)
	{
		/* read field value in stValue*/
		fn_vOperatorGetField(eFieldId,hSuperObjPerso,p_stValue);
	}
}
 
static void fn_vSetFieldOrDsgVarForAffectOperator(HIE_tdxHandleToSuperObject hSuperObjPerso,tdeTypeInterpret eTypeInterpret,unsigned char ucVarId,unsigned char ucIndex,tdeFieldId eFieldId,tdstGetSetParam *p_stValue)
{
  if (eTypeInterpret==E_ti_DsgVarRef)
  {
	 /* write dsgvar value from p_stValue*/
    fn_vOperatorSetDsgVar(ucVarId,ucIndex,hSuperObjPerso,p_stValue);
  }
  else if (eTypeInterpret==E_ti_Field)
  {
    /* write field value from p_stValue*/
	fn_vOperatorSetField(eFieldId,hSuperObjPerso,p_stValue);
  }
}
 
static void fn_vSetVectorComponentForAffectOperator(unsigned char ucXYZflag,MTH3D_tdstVector *p_stVector,MTH_tdxReal xReal)
{
	switch(ucXYZflag)
	{
	  case 1:
		MTH3D_M_vSetXofVector(p_stVector,xReal);
		break;
	  case 2:
		MTH3D_M_vSetYofVector(p_stVector,xReal);
		break;
	  case 3:
  	    MTH3D_M_vSetZofVector(p_stVector,xReal);
	    break;
	}
}
 
static void fn_vBuildVectorForAffectOperator(unsigned char ucXYZflag,tdstGetSetParam *p_stParam,MTH_tdxReal xReal)
{
	MTH3D_tdstVector *p_stVector=&M_GetSetParam_stVertexValue(p_stParam);
	MTH3D_M_vNullVector(p_stVector);
	fn_vSetVectorComponentForAffectOperator(ucXYZflag,p_stVector,xReal);
	M_GetSetParam_Type(p_stParam)=E_vt_Vector;
}
 
 
 
tdstNodeInterpret *fn_p_stAffectOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  tdstGetSetParam stParam1, stParam2;
  tdeFieldId eFieldId=eNbField;
  unsigned char ucVarId=0xFF;
  unsigned char ucIndex=0; 
  unsigned char ucXYZflag=0;
  unsigned char ucNbParam=0;
 
#if defined(ACTIVE_AIDEBUG)
	unsigned short uwUpdateIndex = 0;
#endif /*ACTIVE_AIDEBUG*/
 
  HIE_tdxHandleToSuperObject hSuperObjPerso = p_SuperObjPerso;
  tdeOperatorId eOperatorId = M_eOperatorIdInterpret(p_stTree-1);
  tdeTypeInterpret eTypeInterpret = M_GetTypeInterpret(p_stTree);
 
  if ( eOperatorId == eOperator_AffectArray )
  {
		ucNbParam = fn_ucGetTreeNbParam(p_stTree)-1;
  }
 
	/****************************/
	/** get perso if necessary **/
	/****************************/
 
  if ( eTypeInterpret == E_ti_Operator )
  {
	/* traitement des champs et de l'opérateur ".X" ".Y" ".Z" en écriture.*/
#if defined(__DEBUG_AI__)
		M_AI_DEBUG_ASSERT(
			(M_eOperatorIdInterpret(p_stTree) == eOperator_Dot) ||
			(M_eOperatorIdInterpret(p_stTree) == eOperator_Array) ||
      (M_eOperatorIdInterpret(p_stTree) == eOperator_GetVectorX) ||
		  (M_eOperatorIdInterpret(p_stTree) == eOperator_GetVectorY) ||
			(M_eOperatorIdInterpret(p_stTree) == eOperator_GetVectorZ),
			E_uwAIWrongOperatorInLeftAffect
		);
#endif /* __DEBUG_AI__*/
		{
			register tdeOperatorId eOpId = M_eOperatorIdInterpret(p_stTree);
			if ( eOpId == eOperator_GetVectorX )
				ucXYZflag = 1;
			else if ( eOpId == eOperator_GetVectorY )
				ucXYZflag = 2;
			else if ( eOpId == eOperator_GetVectorZ )
				ucXYZflag = 3;
		}
		if ( ucXYZflag )
		{
			p_stTree ++;   
			eTypeInterpret = M_GetTypeInterpret(p_stTree);
		}
  } 
 
  if ( eTypeInterpret == E_ti_Operator )
  {
		#if defined(__DEBUG_AI__)
		M_AI_DEBUG_ASSERT((M_eOperatorIdInterpret(p_stTree) == eOperator_Array) || (M_eOperatorIdInterpret(p_stTree) == eOperator_Dot) , E_uwAIWrongOperatorInLeftAffect);
		#endif /* __DEBUG_AI__*/
 
		if ( M_eOperatorIdInterpret(p_stTree) == eOperator_Dot )
		{
			#if defined(ACTIVE_AIDEBUG)
			/* prepare without update because the return value for dot is useless*/
			AIDebug_M_PrepareOperator( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, p_stTree );
			#endif
			/*p_stTree++; it is useless to affect, because we do it just below... increment in the argument instead*/
			p_stTree=fn_p_stOperatorGetPerso(p_SuperObjPerso,p_stTree + 1,&hSuperObjPerso);
			eTypeInterpret = M_GetTypeInterpret(p_stTree); 
		}
		else /* eOperator_Array*/
		{
			#if defined(ACTIVE_AIDEBUG)
			/* prepare without update because the return value for array is useless*/
			AIDebug_M_PrepareOperator( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, p_stTree );
			#endif
			p_stTree ++;
			eTypeInterpret = M_GetTypeInterpret(p_stTree); 
			if ( eTypeInterpret == E_ti_Operator )
			{
				#if defined(__DEBUG_AI__)
				M_AI_DEBUG_ASSERT((M_eOperatorIdInterpret(p_stTree) == eOperator_Dot) , E_uwAIWrongOperatorInLeftAffect);
				#endif /* __DEBUG_AI__*/
				if ( M_eOperatorIdInterpret(p_stTree) == eOperator_Dot )
				{
					#if defined(ACTIVE_AIDEBUG)
					/* prepare without update because the return value for dot is useless*/
					AIDebug_M_PrepareOperator( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, p_stTree );
					#endif
					/*p_stTree++; it is useless to affect, because we do it just below... increment in the argument instead*/
					p_stTree = fn_p_stOperatorGetPerso(p_SuperObjPerso, p_stTree + 1, &hSuperObjPerso);
				}
			}
			ucVarId = (unsigned char) M_ucVarIdInterpret(p_stTree);
			p_stTree ++;
			eTypeInterpret = E_ti_Operator;
		}
  }
 
	/****************************/
	/** get field or dsgvarid  **/
	/****************************/
  if ( eTypeInterpret == E_ti_DsgVarRef )
  {
    ucVarId = (unsigned char) M_ucVarIdInterpret(p_stTree);
		#if defined( ACTIVE_AIDEBUG )
	  uwUpdateIndex = AIDebug_M_SetDsgVar( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, p_stTree );
		#endif /*ACTIVE_AIDEBUG*/
		p_stTree ++; 
  }
  else if ( eTypeInterpret == E_ti_Field )
  {
    eFieldId = M_eFieldIdInterpret(p_stTree);
		#if defined( ACTIVE_AIDEBUG )
	  uwUpdateIndex = AIDebug_M_SetField( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue, p_stTree );
		#endif /*ACTIVE_AIDEBUG*/
		p_stTree ++; 
  }
  else if ( eTypeInterpret == E_ti_Operator )
  {
		M_EvalNextParameter(p_stValue);
		ucIndex = (unsigned char) M_ReturnParam_lValue(p_stValue);
		eTypeInterpret = E_ti_DsgVarRef;
  }
	#if defined(__DEBUG_AI__)
  else
  {
   M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
  }
	#endif /* __DEBUG_AI__*/
 
 
	/************************/
	/** read parameters    **/
	/************************/
  if ( eOperatorId == eOperator_Affect )
  {
		if ( ucXYZflag )
		{
			/* read dsgvar or field value in stValue	*/
			fn_vGetFieldOrDsgVarForAffectOperator(hSuperObjPerso,eTypeInterpret,ucVarId,ucIndex,eFieldId,p_stValue);
 
			#if defined(__DEBUG_AI__)
			M_AI_DEBUG_ASSERT(M_IsVectorType(p_stValue), E_uwAIWrongOperatorInLeftAffect);
			#endif /* __DEBUG_AI__*/
 
			/* Eval right parameter of affect*/
			M_EvalNextParameter(&stParam1);
 
			fn_vSetVectorComponentForAffectOperator(ucXYZflag,&M_GetSetParam_stVertexValue(p_stValue),M_ReturnParam_xValue(&stParam1));
			/* voila dans p_stValue on a le Vecteur Complet surchargé avec xReal*/
		}
		else /* a simple affectation: dont check that the affected value can be null...*/
		{
#if defined(__DEBUG_AI__)
			fn_vSetDontCheckNULLFlag(1);
#endif /* __DEBUG_AI__ */

			/* Eval right parameter of affect*/
			M_EvalNextParameter(p_stValue);

#if defined(__DEBUG_AI__)		
			fn_vSetDontCheckNULLFlag(-1);
#endif /* __DEBUG_AI__ */

		}
  }
  else if ( eOperatorId == eOperator_AffectArray )
  {
		if ( ucNbParam > 0 )
		{
			#if defined(__DEBUG_AI__)
			{
				AI_tdstMind *p_stMind=AI_M_stGetMindOfSuperObj(hSuperObjPerso);
				tdeDsgVarTypeId eDsgVarType=M_GetDsgVarType(p_stMind,ucVarId);
				tdstArray *p_stArray;
				M_AI_DEBUG_ASSERT((fn_GetDsgVarType(eDsgVarType)==E_vt_Array), E_uwAIWrongOperatorInLeftAffect);
				p_stArray=(tdstArray*) M_GetDsgVarAddr(p_stMind,ucVarId);
				M_AI_DEBUG_ASSERT((ucIndex+ucNbParam<=M_ARRAY_SIZE(p_stArray)), E_uwAIWrongOperatorInLeftAffect);
			}
			#endif
			do
			{
				/* Eval right parameter of affect*/
				M_EvalNextParameter(p_stValue);
				fn_vOperatorSetDsgVar(ucVarId,ucIndex,hSuperObjPerso,p_stValue);
				ucIndex ++;
				ucNbParam --;
			}
			while ( ucNbParam );
	 }
	 M_Full_GetSetParam_ActionReturn(p_stValue,C_ACTION_ENGINE_CONTINUE);
	 return(p_stTree);
  }
  else  /* PlusAffect,MinusAffect,MulAffect,DivAffect,PlusPlusAffect,MinusMinusAffect*/
  {
		unsigned char ucIsVector=0;
		/**************************/
		/** read field or dsgvar **/
		/**************************/
		/* read dsgvar or field value in &stParam2*/
		fn_vGetFieldOrDsgVarForAffectOperator(hSuperObjPerso,eTypeInterpret,ucVarId,ucIndex,eFieldId,&stParam2);
 
		/* read right parameter in stParam1*/
		if ( (eOperatorId == eOperator_MinusMinusAffect) || (eOperatorId == eOperator_PlusPlusAffect) )
		{
			if (!ucXYZflag)
			{
				M_Full_GetSetParam_Integer(&stParam1,1);
			}
			else
			{
				/* met 1,0,0 ou 0,1,0 ou 0,0,1 dans le vecteur de stParam1*/
				fn_vBuildVectorForAffectOperator(ucXYZflag,&stParam1,MTH_C_ONE);
			}
		}
		else /* PlusAffect,LessAffect,MulAffect*/
		{
			M_EvalNextParameter(&stParam1);
 
			if (ucXYZflag)
			{
				/* met x,0,0 ou 0,x,0 ou 0,0,x dans le vecteur de stParam1*/
				fn_vBuildVectorForAffectOperator(ucXYZflag,&stParam1,M_ReturnParam_xValue(&stParam1));
			}
		}
 
	/* Vector checking*/
		ucIsVector = (unsigned char) M_IsVectorType(&stParam2);
		if ( ucIsVector )
		{
			ucIsVector=2;
			if (!M_IsVectorType(&stParam1))
			{
				if
				(
					(eOperatorId==eOperator_SetVectorX)
					||(eOperatorId==eOperator_SetVectorY) 
					||(eOperatorId==eOperator_SetVectorZ)
					||(eOperatorId==eOperator_MulAffect)
					||(eOperatorId==eOperator_DivAffect)
					||(ucXYZflag) 
				)
				{
					ucIsVector=1;
				}
				else
				{
					#if defined(__DEBUG_AI__)
					M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
					#endif
					MTH3D_M_vNullVector(&M_GetSetParam_stVertexValue(&stParam1));
				}
			}
		}
		else 
		{
			if (M_IsVectorType(&stParam1))
			{
				#if defined(__DEBUG_AI__)
				M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
				#endif
				M_Full_GetSetParam_Float(&stParam1,MTH_C_ZERO);
			}
		}
 
		/******************/
		/** do operation **/
		/******************/
		if ( ucIsVector )
		{
			MTH3D_tdstVector *p_stVector1=NULL,*p_stVector2;
			MTH_tdxReal xReal = MTH_C_ZERO;
			MTH3D_tdstVector *p_stVector=&M_GetSetParam_stVertexValue(p_stValue);
			M_GetSetParam_Type(p_stValue)=E_vt_Vector;
 
			p_stVector2=&M_GetSetParam_stVertexValue(&stParam2);
			if ( ucIsVector == 1 )
			{
				xReal=M_ReturnParam_xValue(&stParam1);
				MTH3D_M_vCopyVector(p_stVector,p_stVector2);
			}
			else
			{
				p_stVector1 = &M_GetSetParam_stVertexValue(&stParam1);
			}
			
			switch(eOperatorId)
			{
			case eOperator_SetVectorX :
				MTH3D_M_vSetXofVector(p_stVector,xReal);
				break;
 
			case eOperator_SetVectorY :
				MTH3D_M_vSetYofVector(p_stVector,xReal);
				break;
 
			case eOperator_SetVectorZ :
				MTH3D_M_vSetZofVector(p_stVector,xReal);
				break;
 
			case eOperator_MulAffect:
				if (!ucXYZflag)
				{
					MTH3D_M_vMulScalarVector(p_stVector, xReal, p_stVector2);
				}
				else
				{
					MTH3D_M_vCopyVector(p_stVector,p_stVector2);
					switch ( ucXYZflag )
					{ 
					case 1: 
						xReal = MTH3D_M_xGetXofVector(p_stVector1);
						MTH3D_M_vSetXofVector(p_stVector,MTH_M_xMul(MTH3D_M_xGetXofVector(p_stVector2),xReal));
						break;
 
					case 2:
						xReal = MTH3D_M_xGetYofVector(p_stVector1);
						MTH3D_M_vSetYofVector(p_stVector,MTH_M_xMul(MTH3D_M_xGetYofVector(p_stVector2),xReal));
						break;
 
					case 3:
						xReal = MTH3D_M_xGetZofVector(p_stVector1);
  					MTH3D_M_vSetZofVector(p_stVector,MTH_M_xMul(MTH3D_M_xGetZofVector(p_stVector2),xReal));
						break;
					}
				}
				break;
 
			case eOperator_DivAffect:
				if ( !ucXYZflag )
				{
	  			MTH3D_M_vDivScalarVector(p_stVector,p_stVector2,xReal);
				}
				else
				{
					MTH3D_M_vCopyVector(p_stVector,p_stVector2);
					switch ( ucXYZflag )
					{ 
					case 1: 
						xReal = MTH3D_M_xGetXofVector(p_stVector1);
						MTH3D_M_vSetXofVector(p_stVector,MTH_M_xDiv(MTH3D_M_xGetXofVector(p_stVector2),xReal));
						break;
 
					case 2:
						xReal = MTH3D_M_xGetYofVector(p_stVector1);
						MTH3D_M_vSetYofVector(p_stVector,MTH_M_xDiv(MTH3D_M_xGetYofVector(p_stVector2),xReal));
						break;
 
					case 3:
						xReal = MTH3D_M_xGetZofVector(p_stVector1);
  					MTH3D_M_vSetZofVector(p_stVector,MTH_M_xDiv(MTH3D_M_xGetZofVector(p_stVector2),xReal));
						break;
					}
				}
				break;
 
			case eOperator_PlusAffect:
			case eOperator_PlusPlusAffect:
  			MTH3D_M_vAddVector(p_stVector,p_stVector2,p_stVector1);
				break;
 
			case eOperator_MinusAffect:
			case eOperator_MinusMinusAffect:
				MTH3D_M_vSubVector(p_stVector,p_stVector2,p_stVector1); 
				break;
 
			default:
				#if defined(__DEBUG_AI__)
				M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
				#endif
  			MTH3D_M_vNullVector(p_stVector);
				break;
			}
		}
		else /* operator is not applied to vectors*/
		{
			/* conversion in float if necessary : simplify the macro M_Operator_Arith*/
			unsigned char ucIsThereFloat = fn_ucAreThereFloatIfYesConvertThem(&stParam1,&stParam2);
 
			M_Full_GetSetParam_Integer(p_stValue,0);
 
			switch(eOperatorId)
			{
			case eOperator_PlusAffect:
			case eOperator_PlusPlusAffect:
				M_Operator_Arith(ucIsThereFloat,Add,&stParam2,&stParam1,p_stValue); 
				break;
 
			case eOperator_MinusAffect:
			case eOperator_MinusMinusAffect:
				M_Operator_Arith(ucIsThereFloat,Sub,&stParam2,&stParam1,p_stValue); 
				break;
 
			case eOperator_MulAffect:
				M_Operator_Arith(ucIsThereFloat,Mul,&stParam2,&stParam1,p_stValue); 
				break;
			case eOperator_DivAffect:
				if
				(
					((ucIsThereFloat) && (MTH_M_bDifferentWithEpsilon(M_GetSetParam_xValue(&stParam1),MTH_C_ZERO,MTH_C_EpsilonPlus)))
					||
					((!ucIsThereFloat) && ( M_GetSetParam_lValue(&stParam1) != 0))
				)
				{
				 	M_Operator_Arith(ucIsThereFloat,Div,&stParam2,&stParam1,p_stValue); 
				}
				#if defined(__DEBUG_AI__)
				else
				{
					M_AIFatalError(E_uwAIDivisionByZero);
				}
				#endif
				break;
 
			default:
				break;
			}
		}
  }
 
 
	/****************************/
	/** affect field or dsgvar **/
	/****************************/
	fn_vSetFieldOrDsgVarForAffectOperator(hSuperObjPerso,eTypeInterpret,ucVarId,ucIndex,eFieldId,p_stValue);
 
	#if defined(ACTIVE_AIDEBUG)
	AIDebug_fn_vUpdateGetSetParam( AI_M_stGetMindOfSuperObj(p_SuperObjPerso), uwUpdateIndex, p_stValue );
	#endif /*ACTIVE_AIDEBUG*/
 
	/**********************/
	/** return to engine **/
	/**********************/
  M_Full_GetSetParam_ActionReturn(p_stValue,C_ACTION_ENGINE_CONTINUE);
  return(p_stTree);
}
 
 
 
/*old code
tdstNodeInterpret *fn_p_stAffectOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  tdstGetSetParam stParam1, stParam2;
  tdeFieldId eFieldId=eNbField;
  unsigned char ucVarId=0xFF;
 
  unsigned char ucXYZflag=0;
 
  // bSomethingDone = TRUE; // Do not make the Schedule !!!
 
  HIE_tdxHandleToSuperObject hSuperObjPerso=p_SuperObjPerso;
  tdeOperatorId eOperatorId=M_eOperatorIdInterpret(p_stTree-1);
  tdeTypeInterpret eTypeInterpret=M_GetTypeInterpret(p_stTree);
 
 
// **************************
// * get perso if necessary *
// **************************
 
  if (eTypeInterpret==E_ti_Operator)
  {
	// traitement des champs et de l'opérateur ".X" ".Y" ".Z" en écriture.
#if defined(__DEBUG_AI__)
	M_AI_DEBUG_ASSERT((M_eOperatorIdInterpret(p_stTree) == eOperator_Dot)   ||
                      (M_eOperatorIdInterpret(p_stTree) == eOperator_GetVectorX) ||														 
		              (M_eOperatorIdInterpret(p_stTree) == eOperator_GetVectorY)  ||
					  (M_eOperatorIdInterpret(p_stTree) == eOperator_GetVectorZ)  
		, E_uwAIWrongOperatorInLeftAffect);
#endif // __DEBUG_AI__
	if (M_eOperatorIdInterpret(p_stTree) != eOperator_Dot)
	{
 	  switch(M_eOperatorIdInterpret(p_stTree))
	  {
		case eOperator_GetVectorX:
			ucXYZflag=1;
			break;
		case eOperator_GetVectorY:
			ucXYZflag=2;
			break;
		case eOperator_GetVectorZ:
			ucXYZflag=3;
			break;
	  }
	  p_stTree++;   
	  eTypeInterpret = M_GetTypeInterpret(p_stTree);
	}
  } 
 
 
  if (eTypeInterpret==E_ti_Operator)
  {
	// traitement des champs et de l'opérateur "." en écriture.
#if defined(__DEBUG_AI__)
	M_AI_DEBUG_ASSERT((M_eOperatorIdInterpret(p_stTree) == eOperator_Dot), E_uwAIWrongOperatorInLeftAffect);
#endif // __DEBUG_AI__
	p_stTree++;                
    p_stTree=fn_p_stOperatorGetPerso(p_SuperObjPerso,p_stTree,&hSuperObjPerso);
	eTypeInterpret = M_GetTypeInterpret(p_stTree); 
  } 
 
// **************************
// * get field or dsgvarid  *
// **************************
  if (eTypeInterpret==E_ti_Field)
  {
    eFieldId= M_eFieldIdInterpret(p_stTree);
  }
  else if ( (eTypeInterpret==E_ti_DsgVar) || (eTypeInterpret==E_ti_DsgVarRef) )
  {
    ucVarId= (unsigned char) M_ucVarIdInterpret(p_stTree);
  }
#if defined(__DEBUG_AI__)
  else
  {
  	 M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
  }
#endif // __DEBUG_AI__
  p_stTree++;
 
// **********************
// * read parameters    *
// **********************
  if(eOperatorId==eOperator_Affect)
  {
    // Eval right parameter of affect
    M_EvalNextParameter(p_stValue);
  }
  else  // PlusAffect,MinusAffect,MulAffect,DivAffect,PlusPlusAffect,MinusMinusAffect
  {
	unsigned char ucIsVector=0;
// ************************
// * read field or dsgvar *
// ************************
    if (eTypeInterpret==E_ti_Field)
	{
		// read field value in stParam2
		fn_vOperatorGetField(eFieldId,hSuperObjPerso,&stParam2);
	}
    else if ( (eTypeInterpret==E_ti_DsgVar) || (eTypeInterpret==E_ti_DsgVarRef) )
	{
       // read dsgvar value in stParam2
       fn_vOperatorGetDsgVar(ucVarId,hSuperObjPerso,&stParam2);
	}
 
    // read right parameter in stParam1
    if ( (eOperatorId==eOperator_MinusMinusAffect) || (eOperatorId==eOperator_PlusPlusAffect) )
    {
	  if (!ucXYZflag)
	  {
		M_Full_GetSetParam_Integer(&stParam1,1);
	  }
	  else
	  {
	    MTH3D_tdstVector stVector;
        MTH3D_M_vNullVector(&stVector);
		switch (ucXYZflag)
		{ 
		  case 1: 
			MTH3D_M_vSetXofVector(&stVector,MTH_C_ONE);
			break;
		  case 2:
			MTH3D_M_vSetYofVector(&stVector,MTH_C_ONE);
			break;
		  case 3:
  		    MTH3D_M_vSetZofVector(&stVector,MTH_C_ONE);
			break;
		}
		M_Full_GetSetParam_p_stVertex(&stParam1,&stVector);
	  }
    }
    else // PlusAffect,LessAffect,MulAffect
    {
      // Eval right parameter of affect
      M_EvalNextParameter(&stParam1);
 
	  if (ucXYZflag)
	  {
	    MTH3D_tdstVector stVector;
        MTH3D_M_vNullVector(&stVector);
		switch (ucXYZflag)
		{ 
		  case 1: 
			MTH3D_M_vSetXofVector(&stVector,M_ReturnParam_xValue(&stParam1));
			break;
		  case 2:
			MTH3D_M_vSetYofVector(&stVector,M_ReturnParam_xValue(&stParam1));
			break;
		  case 3:
  		    MTH3D_M_vSetZofVector(&stVector,M_ReturnParam_xValue(&stParam1));
			break;
		}
		M_Full_GetSetParam_p_stVertex(&stParam1,&stVector);
	  }
    }
 
// Vector checking
	ucIsVector=(unsigned char) M_IsVectorType(&stParam2);
	if (ucIsVector)
	{
	  ucIsVector=2;
       if (!M_IsVectorType(&stParam1))
	   {
         if  (   
			     (eOperatorId==eOperator_SetVectorX)
			   ||(eOperatorId==eOperator_SetVectorY) 
			   ||(eOperatorId==eOperator_SetVectorZ)
			   ||(eOperatorId==eOperator_MulAffect)
			   ||(eOperatorId==eOperator_DivAffect)
			   ||(ucXYZflag) 
			 )
		 {
            ucIsVector=1;
		 }
         else
		 {
    #if defined(__DEBUG_AI__)
	 	   M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
    #endif
	  	   MTH3D_M_vNullVector(&M_GetSetParam_stVertexValue(&stParam1));
		 }
	   }
	}
	else 
	{
	  if (M_IsVectorType(&stParam1))
	  {
#if defined(__DEBUG_AI__)
	 	 M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
#endif
		 M_Full_GetSetParam_Float(&stParam1,MTH_C_ZERO);
	  }
	}
 
// ****************
// * do operation *
// ****************
    if (ucIsVector)
	{
		MTH3D_tdstVector *p_stVector1=NULL,*p_stVector2;
		MTH_tdxReal xReal=MTH_C_ZERO;
		MTH3D_tdstVector *p_stVector=&M_GetSetParam_stVertexValue(p_stValue);
		M_GetSetParam_Type(p_stValue)=E_vt_Vector;
 
		p_stVector2=&M_GetSetParam_stVertexValue(&stParam2);
		if (ucIsVector==1)
		{
		  xReal=M_ReturnParam_xValue(&stParam1);
		  MTH3D_M_vCopyVector(p_stVector,p_stVector2);
		}
		else
		{
		  p_stVector1=&M_GetSetParam_stVertexValue(&stParam1);
		}
		
		switch(eOperatorId)
		{
			case eOperator_SetVectorX :
				MTH3D_M_vSetXofVector(p_stVector,xReal);
				break;
 
			case eOperator_SetVectorY :
				MTH3D_M_vSetYofVector(p_stVector,xReal);
				break;
 
			case eOperator_SetVectorZ :
				MTH3D_M_vSetZofVector(p_stVector,xReal);
				break;
 
			case eOperator_MulAffect:
				if (!ucXYZflag)
				{
					MTH3D_M_vMulScalarVector(p_stVector, xReal, p_stVector2);
				}
				else
				{
					MTH3D_M_vCopyVector(p_stVector,p_stVector2);
					switch (ucXYZflag)
					{ 
						case 1: 
							xReal=MTH3D_M_xGetXofVector(p_stVector1);
							MTH3D_M_vSetXofVector(p_stVector,MTH_M_xMul(MTH3D_M_xGetXofVector(p_stVector2),xReal));
							break;
						case 2:
							xReal=MTH3D_M_xGetYofVector(p_stVector1);
							MTH3D_M_vSetYofVector(p_stVector,MTH_M_xMul(MTH3D_M_xGetYofVector(p_stVector2),xReal));
							break;
						case 3:
							xReal=MTH3D_M_xGetZofVector(p_stVector1);
  						MTH3D_M_vSetZofVector(p_stVector,MTH_M_xMul(MTH3D_M_xGetZofVector(p_stVector2),xReal));
							break;
					}
				}
				break;
 
			case eOperator_DivAffect:
				if (!ucXYZflag)
				{
	  	            MTH3D_M_vDivScalarVector(p_stVector,p_stVector2,xReal);
				}
				else
				{
					MTH3D_M_vCopyVector(p_stVector,p_stVector2);
					switch (ucXYZflag)
					{ 
						case 1: 
							xReal=MTH3D_M_xGetXofVector(p_stVector1);
							MTH3D_M_vSetXofVector(p_stVector,MTH_M_xDiv(MTH3D_M_xGetXofVector(p_stVector2),xReal));
							break;
						case 2:
							xReal=MTH3D_M_xGetYofVector(p_stVector1);
							MTH3D_M_vSetYofVector(p_stVector,MTH_M_xDiv(MTH3D_M_xGetYofVector(p_stVector2),xReal));
							break;
						case 3:
							xReal=MTH3D_M_xGetZofVector(p_stVector1);
  						    MTH3D_M_vSetZofVector(p_stVector,MTH_M_xDiv(MTH3D_M_xGetZofVector(p_stVector2),xReal));
							break;
					}
				}
				break;
 
			case eOperator_PlusAffect:
			case eOperator_PlusPlusAffect:
  	            MTH3D_M_vAddVector(p_stVector,p_stVector2,p_stVector1);
				break;
 
			case eOperator_MinusAffect:
			case eOperator_MinusMinusAffect:
				MTH3D_M_vSubVector(p_stVector,p_stVector2,p_stVector1); 
				break;
 
			default:
#if defined(__DEBUG_AI__)
 
				M_AIFatalError(E_uwAIFatalInvalidAccessToFieldOrDsgVar);
#endif
  			    MTH3D_M_vNullVector(p_stVector);
				break;
		}
 
	}
	else
	{
		// conversion in float if necessary : simplify the macro M_Operator_Arith
		unsigned char ucIsThereFloat=fn_ucAreThereFloatIfYesConvertThem(&stParam1,&stParam2);
 
		M_Full_GetSetParam_Integer(p_stValue,0);
 
	    switch(eOperatorId)
		{
			case eOperator_PlusAffect:
			case eOperator_PlusPlusAffect:
				M_Operator_Arith(ucIsThereFloat,Add,&stParam2,&stParam1,p_stValue); 
				break;
			case eOperator_MinusAffect:
			case eOperator_MinusMinusAffect:
				M_Operator_Arith(ucIsThereFloat,Sub,&stParam2,&stParam1,p_stValue); 
				break;
			case eOperator_MulAffect:
				M_Operator_Arith(ucIsThereFloat,Mul,&stParam2,&stParam1,p_stValue); 
				break;
			case eOperator_DivAffect:
  				if (MTH_M_bDifferentWithEpsilon(M_GetSetParam_xValue(&stParam2),MTH_C_ZERO,MTH_C_EpsilonPlus))
				{
				 	M_Operator_Arith(ucIsThereFloat,Div,&stParam2,&stParam1,p_stValue); 
				}
#if defined(__DEBUG_AI__)
		        else
				{
				  M_AIFatalError(E_uwAIDivisionByZero);
				}
#endif
				break;
		}
    }
}
 
 
// **************************
// * affect field or dsgvar *
// **************************
  if (eTypeInterpret==E_ti_Field)
  {
    // write field value from p_stValue
	fn_vOperatorSetField(eFieldId,hSuperObjPerso,p_stValue);
  }
  else if ( (eTypeInterpret==E_ti_DsgVar) || (eTypeInterpret==E_ti_DsgVarRef) )
  {
	 // write dsgvar value from p_stValue
    fn_vOperatorSetDsgVar(ucVarId,hSuperObjPerso,p_stValue);
  }
 
// ********************
// * return to engine *
// ********************
  M_Full_GetSetParam_ActionReturn(p_stValue,C_ACTION_ENGINE_CONTINUE);
  return(p_stTree);
}
*/
 
 
 
/*********************************************************************************************************************/
/* THE ULTRA OPERATOR                                                                                               */
/*********************************************************************************************************************/
HIE_tdxHandleToSuperObject g_hCurrentSuperObjPerso=NULL;
 
void fn_vSetUltraOperatorPerso(HIE_tdxHandleToSuperObject hCurrentSuperObjPerso,HIE_tdxHandleToSuperObject hNewCurrentSuperObjPerso)
{
  if (hCurrentSuperObjPerso==hNewCurrentSuperObjPerso)
  {
    g_hCurrentSuperObjPerso=NULL;
  }
  else
  {
    g_hCurrentSuperObjPerso=hNewCurrentSuperObjPerso;
  }
}
 
/* When you use this function, you must store returned hNewSuperObjPerso in a local variable : that's why this function doesn't return any value with the return instruction */
void fn_vGetUltraOperatorPerso(unsigned char bYouHaveRightToUseThisFunction,HIE_tdxHandleToSuperObject hCurrentSuperObjPerso,HIE_tdxHandleToSuperObject *hNewSuperObjPerso)
{
  if ( g_hCurrentSuperObjPerso /*&& (g_hCurrentSuperObjPerso != hCurrentSuperObjPerso)*/ )
  {
	  if (bYouHaveRightToUseThisFunction)
	  {
  	  *hNewSuperObjPerso=g_hCurrentSuperObjPerso;
      g_hCurrentSuperObjPerso=NULL;
	  }
#if defined(__DEBUG_AI__)
	  else
	  {
			M_AIFatalError(E_uwAIFatalInvalidUseOfUltraOperator);
	  }
#endif
  }
	else
	  *hNewSuperObjPerso = hCurrentSuperObjPerso;
}
 
tdstNodeInterpret *fn_p_stUltraOperator(HIE_tdxHandleToSuperObject hCurrentSuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	HIE_tdxHandleToSuperObject hNewCurrentSuperObjPerso;
 
	/* Get new current perso*/
    p_stTree=fn_p_stOperatorGetPerso(hCurrentSuperObjPerso,p_stTree,&hNewCurrentSuperObjPerso);
 
#if defined(__DEBUG_AI__)
	{
       tdeTypeInterpret eTypeInterpret = M_GetTypeInterpret(p_stTree);
	   M_AI_DEBUG_ASSERT(
						(eTypeInterpret==E_ti_Condition) ||
						(eTypeInterpret==E_ti_Function) ||
						(eTypeInterpret==E_ti_Procedure)
					 , E_uwAIFatalInvalidUseOfUltraOperator);
	}
#endif /*__DEBUG_AI__*/
 
	/* Store it*/
	fn_vSetUltraOperatorPerso(hCurrentSuperObjPerso,hNewCurrentSuperObjPerso);
	M_EvalOneParameter(hCurrentSuperObjPerso,p_stTree,p_stTree,p_stValue);
   	return(p_stTree);
}
 
 
/*********************************************************************************************************************/
/* THE MODEL CAST OPERATOR                                                                                           */
/*********************************************************************************************************************/
tdstNodeInterpret *fn_p_stModelCastOperator(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	HIE_tdxHandleToSuperObject hSuperObjPersoToCast;
	AI_tdstAIModel *p_stCastedModel;
 
	M_EvalNextParameter(p_stValue);
	p_stCastedModel=M_GetSetParam_p_stModel(p_stValue);
 
#if defined(__DEBUG_AI__)
	{
	   tdeTypeInterpret eTypeInterpret = M_GetTypeInterpret(p_stTree);	
	   M_VerifyTypeOfParamAction(p_stValue, E_vt_Model);
	   M_AI_DEBUG_ASSERT( eTypeInterpret==E_ti_DsgVarRef , E_uwAIFatalInvalidModelCast);
	}
#endif
 
	/* Get perso*/
    p_stTree=fn_p_stOperatorGetPerso(p_SuperObjPerso,p_stTree,&hSuperObjPersoToCast);
#if defined(__DEBUG_AI__)
    /* check if good model*/
	{
		AI_tdstAIModel *p_stModel=AI_M_p_stGetAIModel(AI_M_stGetMindOfSuperObj(hSuperObjPersoToCast));
		M_AI_DEBUG_ASSERT( (p_stCastedModel!=NULL) && (p_stModel==p_stCastedModel), E_uwAIFatalInvalidModelCast);
	}
#endif
	M_Full_GetSetParam_Perso(p_stValue,hSuperObjPersoToCast);
	return(p_stTree);
}
 
/************************************************************************************/
/* HERE IS THE END                                                                  */
/************************************************************************************/
 
/****************************************************************************************/
/* to call once before anything else related to Operator                              */
/****************************************************************************************/
#if !defined(OPTIMIZED_COMMAND)
#include "Convert.h"
#include "ProtOper.h"
 
void fn_vInitOperatorEntries(void)
{
/* Init*/
#if defined(__DEBUG_AI__)
	fn_vInitOperatorTable(fn_p_stDefaultOperator);
#endif
	
/* Operator definition*/
	#define M_DEFINE_OPERATOR(a,b,c,d,e,f) fn_vDefineOperatorEntry(M_OPERATOR_ENTRY(a,b,c,d,e,f));
    #include "DefOper.h"
	#undef M_DEFINE_OPERATOR
	
/* Check*/
#if defined(__DEBUG_AI__)
	fn_vCheckOperatorTable(fn_p_stDefaultOperator);
#endif /* __DEBUG_AI__*/
}
#endif /* OPTIMIZED_COMMAND*/
 
