/* ------------------------------------------------------------------------------------------ IMPLEMENTATION FILE FOR WP: WayPoint.c Creation Date : January,1997 Author : Jacques (Annecy) ------------------------------------------------------------------------------------------ Modifications : January, 1997 Alb Many modification in all file to conform it with 3DOS ------------------------------------------------------------------------------------------ This file implements functions used to manage waypoints and ways in the engine ------------------------------------------------------------------------------------------ Remarks : WP and Way are allocated inside the AI memory module. AI has access to WP through handles Way are contained inside a specific actor's MS AI has access to Way through indexes. These indexes are used in common with the MS to retrieve an handle on the effective way. ------------------------------------------------------------------------------------------ */ #include "stdafx.h" #include "ACP_Base.h" //#include "ToolsCPA.h" #include "CPALib.h" #include "Hie.h" //#ifdef _AI_LIB_ #include "AIUseCPA.h" #include "Options\Options.h" #include "Macros.h" #include "Structur\StdObjSt.h" #include "Structur\MemGame.h" #include "ZeMem.h" #include "GameEng.h" /*#include "IntelLib.h"*/ #include "IAOption.h" #include "IAMacros.h" /* AI memory and error management */ #include "MemIA.h" #include "ErrIA.h" /*#else #include "stdafx.h" #include "ACP_Base.h" // #include "ToolsCPA.h" #include "CPALib.h" #include "Hie.h" #include "MemIA.h" #include "ErrIA.h" #endif*/ unsigned char g_ucIAModuleId; //------ pour compiler en mode editeur sans MemIA et ErrIA /* #define M_IAAlloc(pointer,cast,size) (pointer=(cast)malloc(size)) #define M_IA_MemSet memset #define M_IAFree free #define M_IA_DEBUG_ASSERT ASSERT #define M_IAFatalError(x); #define M_IARealloc(pointerDest,pointerSrc,cast,size) (pointerDest=(cast)realloc(pointerSrc,size)) */ #define WP_GLOBALS // #include "WayPoint.h" #undef WP_GLOBALS #include "dynamic.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ //-------------------------------- static counter for script load static long gs_lScriptWayCounter = 0; static long gs_lScriptLinkCounter = 0; /* ------------------------------------------------------------------------------------------ WAYPOINT MANAGEMENT : ------------------------------------------------------------------------------------------ */ // construction, destruction, copy ACP_tdxHandleOfWaypoint fn_hConstructWaypoint (void) { ACP_tdxHandleOfWaypoint hNewWP; /* allocate the WP :*/ M_IAAlloc ( hNewWP, /* Var to allocate*/ ACP_tdxHandleOfWaypoint, /* var type */ sizeof(tdst_WayPoint) /* size in bytes*/ ); /* initialise all field to default value :*/ M_IA_MemSet( hNewWP, 0, sizeof(tdst_WayPoint)); return hNewWP; } void fn_vDestroyWaypoint (ACP_tdxHandleOfWaypoint _hWP) { M_IAFree(_hWP); } ACP_tdxHandleOfWaypoint fn_hDuplicateWaypoint (ACP_tdxHandleOfWaypoint _hWP) { ACP_tdxHandleOfWaypoint hCopyWP = fn_hConstructWaypoint (); (*hCopyWP) = (*_hWP); // ok return hCopyWP; } void fn_vCopyWaypoint (ACP_tdxHandleOfWaypoint _hDestWP, ACP_tdxHandleOfWaypoint _hSrcWP) { *_hDestWP=*_hSrcWP; } void fn_vInvalidateWaypoint(ACP_tdxHandleOfWaypoint* _hWP) { *_hWP = ACP_C_InvalidWayPointHandle; } ACP_tdxBool fn_bIsWaypointValid (ACP_tdxHandleOfWaypoint _hWP) { return _hWP==ACP_C_InvalidWayPointHandle; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_hAddRefWaypoint Increase the used count //////////////////////////////////////////////////////////////////////////////// Input : a handle on the waypoint //////////////////////////////////////////////////////////////////////////////// Output : the handle of the waypoint //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 22,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ ACP_tdxHandleOfWaypoint fn_hAddRefWaypoint(ACP_tdxHandleOfWaypoint _hWayPoint) { // ANNECY AV { // M_ucGetWPUsedCount(_hWayPoint)++; // END ANNECY AV } return _hWayPoint; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_hReleaseWaypoint Decrease the used count of the waypoint. If it reachs zero, the WP is destroyed //////////////////////////////////////////////////////////////////////////////// Input : A handle to the waypoint //////////////////////////////////////////////////////////////////////////////// Output : The handle to the WP if it has not been destroyed otherwise ACP_C_InvalidWayPointHandle //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 22,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ ACP_tdxHandleOfWaypoint fn_hReleaseWaypoint(ACP_tdxHandleOfWaypoint _hWayPoint) { //M_ucGetWPUsedCount(_hWayPoint)--; ///* if it is zero, then destroy it :*/ //if(!M_ucGetWPUsedCount(_hWayPoint)) // { //fn_vDestroyWaypoint(_hWayPoint); //_hWayPoint = ACP_C_InvalidWayPointHandle; //} return _hWayPoint; } void fn_vSetVertexWaypoint (ACP_tdxHandleOfWaypoint _hWP, MTH3D_tdstVector* _pstVertex) { M_stGetVertex(_hWP) = *_pstVertex; } void fn_vSetRadiusWaypoint (ACP_tdxHandleOfWaypoint _hWP, GLI_tdxValue _xRadius) { M_xGetWPRadius(_hWP) = _xRadius; } void fn_vSetSuperObjetWaypoint (ACP_tdxHandleOfWaypoint _hWP, HIE_tdxHandleToSuperObject _hSuperObject) { M_hGetSuperObject(_hWP) = _hSuperObject; } void fn_vGetVertexWaypoint (ACP_tdxHandleOfWaypoint _hWP, MTH3D_tdstVector* _pstVertex) { (*_pstVertex) = M_stGetVertex(_hWP); } void fn_vGetRadiusWaypoint (ACP_tdxHandleOfWaypoint _hWP, GLI_tdxValue* _pxRadius ) { *_pxRadius = M_xGetWPRadius(_hWP); } HIE_tdxHandleToSuperObject fn_pGetSuperObjetWaypoint (ACP_tdxHandleOfWaypoint _hWP) { return M_hGetSuperObject(_hWP); } SCRIPT_tdeReturnValue fn_eScriptCallBackLoadWaypoint(FILE *p_fFile, char *szAction, char *szParams[], SCRIPT_tdeAction cType) { #ifdef toto HIE_tdxHandleToSuperObject hSuperObjParent; ACP_tdxHandleOfWaypoint hWaypoint; MTH3D_tdstVector stVertex; switch (cType) { case C_SCRIPT_Section: hWaypoint = fn_hConstructWaypoint(); /* Set father to an invalid value :*/ fn_vSetSuperObjetWaypoint (hWaypoint,NULL); SCRIPT_vSetResult ((long)hWaypoint); break; case C_SCRIPT_Entry: hWaypoint = (ACP_tdxHandleOfWaypoint) SCRIPT_ulGetResult(); if (strcmp(szAction,"Vertex")==0) { /* load the vertex*/ stVertex.xX = MTH_M_xFloatToReal(atof(szParams[0])); stVertex.xY = MTH_M_xFloatToReal(atof(szParams[1])); stVertex.xZ = MTH_M_xFloatToReal(atof(szParams[2])); fn_vSetVertexWaypoint (hWaypoint, &stVertex); } else if (strcmp(szAction,"Radius")==0) { /* load the radius */ fn_vSetRadiusWaypoint (hWaypoint,MTH_M_xFloatToReal(atof(szParams[0]))); } else if (strcmp(szAction,"Father")==0) { // load the father SCRIPT_vSetResultSubSection((unsigned long)NULL); hSuperObjParent = (HIE_tdxHandleToSuperObject) (SCRIPT_ulAnalyseSection(szParams[0],szParams[1])); fn_vSetSuperObjetWaypoint (hWaypoint,hSuperObjParent); /* HIE :* HIE_fn_vSuperObjectAddTail(hSuperObjParent,hSuperObjWP);*/ } break; case C_SCRIPT_EndSection: /* if it is a static WP, the handle to the belonger is NULL*/ break; } #endif return R_SCRIPT_NormalReturn; } //---------------- location of the waypoint void fn_vComputeLocationWaypoint ( ACP_tdxHandleOfWaypoint _hWP, MTH3D_tdstVector* _pstVertex ) { if (M_hGetSuperObject(_hWP)) { GEO_tdxHandleToMatrix hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (M_hGetSuperObject(_hWP)); POS_fn_vMulMatrixVertex ( _pstVertex, hGlobalMatrix, &(M_stGetVertex(_hWP)) ); } else *_pstVertex = M_stGetVertex(_hWP); } //---------------- Retrieve a handle on the WP when loading //---------------- Albert PAIS //---------------- January 15, 1997 ACP_tdxHandleOfWaypoint fn_hGetHWPLoaded(char *_p_szFileName, char*_p_szWPName) { #ifdef toto /* check parameter validity :*/ if ( (!_p_szFileName) ||(!_p_szWPName) ) { /* Raise an error :*/ M_IAFatalError(E_uwIAFatalInvalidParameter); } char *p_szSectionName; ACP_tdxHandleOfWaypoint hReturned; M_IAAlloc ( p_szSectionName, /* Var to allocate*/ char*, /* var type */ strlen("Waypoint_") + strlen(_p_szWPName) /* size in bytes*/ ); sprintf(p_szSectionName,"WayPoint_%s",_p_szWPName); hReturned = (ACP_tdxHandleOfWaypoint ) (SCRIPT_ulAnalyseSection(_p_szFileName,p_szSectionName)); /* free the sz :*/ M_IAFree(p_szSectionName); return hReturned; #endif return 0; } /* ------------------------------------------------------------------------------------------ LINK MANAGEMENT : ------------------------------------------------------------------------------------------ */ /* Some macros : */ #define M_bIsLinkTypeStaticLine(_p_szTerm)\ (!strcmpi(_p_szTerm,"StaticLine")) #define M_bIsLinkTypeDynamicLine(_p_szTerm)\ (!strcmpi(_p_szTerm,"DynamicLine")) #define M_bIsLinkTypeBezier(_p_szTerm)\ (!strcmpi(_p_szTerm,"Bezier")) #define M_bIsLinkTypeCircle(_p_szTerm)\ (!strcmpi(_p_szTerm,"Circle")) #define M_bIsLinkDynTypeNone(_p_szTerm)\ (!strcmpi(_p_szTerm,"None")) #define M_bIsLinkDynTypeConstant(_p_szTerm)\ (!strcmpi(_p_szTerm,"Constant")) #define M_bIsLinkDynTypeLinear(_p_szTerm)\ (!strcmpi(_p_szTerm,"Linear")) #define M_bIsLinkDynTypeSinus(_p_szTerm)\ (!strcmpi(_p_szTerm,"Sinus")) // construction, destruction, copy ACP_tdxHandleOfLink fn_hConstructLink (void) { ACP_tdxHandleOfLink hNewLink; M_IAAlloc ( hNewLink, /* var */ ACP_tdxHandleOfLink, /* cast */ sizeof(tdst_Link) /* size */ ); #ifdef __DEBUG_IA__ /* initialise data :*/ M_IA_MemSet(hNewLink, 0, sizeof(tdst_Link) ); M_eucGetLinkConnectionType(hNewLink) = ACP_ConnType_ucInvalid; M_eucGetLinkConnectionDynType(hNewLink) = ACP_ConDynType_ucInvalid; #endif /* __DEBUG_IA__ */ return hNewLink; } void fn_vDestroyLink (ACP_tdxHandleOfLink _hLink) { /* destroy information buffer :*/ fn_vFreeLink(_hLink); M_IAFree(_hLink); } ACP_tdxHandleOfLink fn_hDuplicateLink (ACP_tdxHandleOfLink hLink) { ACP_tdxHandleOfLink hCopyLink = fn_hConstructLink (); fn_vCopyLink (hCopyLink, hLink); return hCopyLink; } void fn_vCopyLink (ACP_tdxHandleOfLink _hDestLink, ACP_tdxHandleOfLink _hSrcLink) { fn_vAllocLink ( _hDestLink, M_eucGetLinkConnectionType(_hSrcLink), M_eucGetLinkConnectionDynType(_hSrcLink) ); /* Just set the pointer :*/ M_pvGetLinkConnTypeInfo(_hDestLink) = M_pvGetLinkConnTypeInfo(_hSrcLink); /* copy dynam info :*/ memcpy ( &M_stGetLinkConnDynTypeInfo(_hDestLink), /* dest buffer*/ &M_stGetLinkConnDynTypeInfo(_hSrcLink), /* src buffer*/ sizeof(ACP_tdstDynaParam) /* Number of bytes to copy*/ ); } void fn_vInvalidateLink (ACP_tdxHandleOfLink* _hLink) { *_hLink = ACP_C_InvalidLinkHandle; } ACP_tdxBool fn_bIsLinkValid (ACP_tdxHandleOfLink _hLink) { return _hLink==ACP_C_InvalidLinkHandle; } void fn_vAllocLink (ACP_tdxHandleOfLink _hLink,ACP_tde_ucConnectionType _eucConnType,ACP_tde_ucConnectionDynamicType _eucConnDynType) { /* First the connection type :*/ M_eucGetLinkConnectionType(_hLink) = _eucConnType; switch (_eucConnType) { case ACP_ConnType_ucStaticLine: /* For static lines, a vector is needed to store the Wp at the execution :*/ M_IAAlloc ( M_stGetLinkConnTypeStaticVector(_hLink), MTH3D_tdstVector *, sizeof(MTH3D_tdstVector) ); break; case ACP_ConnType_ucDynamicLine : /* No information is needed for dynamic lines :*/ M_pvGetLinkConnTypeInfo(_hLink) = NULL; break; case ACP_ConnType_ucBezier: /* following structure describes Bezier curve :*/ M_IAAlloc ( M_stGetLinkConnTypeBezierObject(_hLink), tdstBezierObject *, sizeof(tdstBezierObject) ); break; case ACP_ConnType_ucCircle : /* Certainly something TODO :*/ break; #ifdef __DEBUG_IA__ default : /* Raise an error :*/ M_IAFatalError(E_uwIAFatalTypeLinkInvalid); M_pvGetLinkConnTypeInfo(_hLink) = NULL; #endif /*__DEBUG_IA__*/ } /* Dynamic information is directly inside the structure, so there is nothing to allocate */ /* Just check that the type is valid :*/ M_IA_DEBUG_ASSERT(M_bIsValidDynTypeLink(_eucConnDynType),E_uwIAFatalDynTypeLinkInvalid); M_eucGetLinkConnectionDynType(_hLink) = _eucConnDynType; // M_IA_MemSet(&M_stGetLinkConnDynTypeInfo(_hLink),0xaa,sizeof(ACP_tdstDynaParam)); } void fn_vFreeLink(ACP_tdxHandleOfLink _hLink) { /* May be things to free depending on connection type :*/ if(M_pvGetLinkConnTypeInfo(_hLink)) { M_IAFree(M_pvGetLinkConnTypeInfo(_hLink)); } M_eucGetLinkConnectionType(_hLink) = ACP_ConnType_ucInvalid; M_eucGetLinkConnectionDynType(_hLink) = ACP_ConDynType_ucInvalid; } ACP_tde_ucConnectionType fn_eucGetConTypeLink(ACP_tdxHandleOfLink _hLink) { return M_eucGetLinkConnectionType(_hLink); } ACP_tde_ucConnectionDynamicType fn_eucGetConDynTypeLink(ACP_tdxHandleOfLink _hLink) { return M_eucGetLinkConnectionDynType(_hLink); } void* fn_pvGetLinkConTypeInfo(ACP_tdxHandleOfLink _hLink) { return M_pvGetLinkConnTypeInfo(_hLink); } ACP_tdstDynaParam *fn_pvGetLinkConDynTypeInfo(ACP_tdxHandleOfLink _hLink) { return &M_stGetLinkConnDynTypeInfo(_hLink); } void fn_vSetLinkConTypeInfo(ACP_tdxHandleOfLink _hLink, void* _pLinkConTypeInfo) { M_pvGetLinkConnTypeInfo(_hLink)=_pLinkConTypeInfo; } void fn_vSetConTypeLink(ACP_tdxHandleOfLink _hLink,ACP_tde_ucConnectionType _eucType) { /* Only change if it is not the same :*/ if(M_eucGetLinkConnectionType(_hLink) != _eucType) { M_eucGetLinkConnectionType(_hLink) = _eucType; /* if there was previous data :erase it */ if(M_pvGetLinkConnTypeInfo(_hLink)) { M_IAFree(M_pvGetLinkConnTypeInfo(_hLink)); } /* now, allocate depending on the type :*/ switch (M_eucGetLinkConnectionType(_hLink)) { case ACP_ConnType_ucStaticLine: /* For static lines, a vector is needed to store the Wp at the execution :*/ M_IAAlloc ( M_stGetLinkConnTypeStaticVector(_hLink), MTH3D_tdstVector *, sizeof(MTH3D_tdstVector) ); break; case ACP_ConnType_ucDynamicLine : /* No information is needed for dynamic lines :*/ M_pvGetLinkConnTypeInfo(_hLink) = NULL; break; case ACP_ConnType_ucBezier: /* following structure describes Bezier curve :*/ M_IAAlloc ( M_stGetLinkConnTypeBezierObject(_hLink), tdstBezierObject *, sizeof(tdstBezierObject) ); break; case ACP_ConnType_ucCircle : /* Certainly something TODO :*/ break; #ifdef __DEBUG_IA__ default : /* Raise an error :*/ M_IAFatalError(E_uwIAFatalTypeLinkInvalid); M_pvGetLinkConnTypeInfo(_hLink) = NULL; #endif /*__DEBUG_IA__*/ } } } void fn_vSetConDynTypeLink(ACP_tdxHandleOfLink _hLink,ACP_tde_ucConnectionDynamicType eucType) { /* Nothing to check or change since the dynamic structure is not allocated but it is directly contained inside the Link structure :*/ M_eucGetLinkConnectionDynType(_hLink) = eucType; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_hAddRefLink Increase the used count //////////////////////////////////////////////////////////////////////////////// Input : a handle on the link //////////////////////////////////////////////////////////////////////////////// Output : the handle of the link //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 22,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ ACP_tdxHandleOfLink fn_hAddRefLink(ACP_tdxHandleOfLink _hLink) { M_ucGetLinkUsedCount(_hLink)++; return _hLink; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_hReleaseLink Increase the used count //////////////////////////////////////////////////////////////////////////////// Input : a handle on the link //////////////////////////////////////////////////////////////////////////////// Output : the handle of the link //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 22,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ ACP_tdxHandleOfLink fn_hReleaseLink(ACP_tdxHandleOfLink _hLink) { // Jack enlevé car BOOM // M_ucGetLinkUsedCount(_hLink)--; // if(!M_ucGetLinkUsedCount(_hLink)) // {/* it is time to free the object :*/ // fn_vDestroyLink(_hLink); // return NULL; // } return _hLink; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_vBuildLinkFromszParams Builds the link data from information contained in the array of zero terminated strings //////////////////////////////////////////////////////////////////////////////// Input : a handle on the link an array to szStrings //////////////////////////////////////////////////////////////////////////////// Output : None //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 23,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// szParam should be : LinkType,LinkDynType[,LinkTypeParam][,LinkDynTypeParam] //////////////////////////////////////////////////////////////////////////////// */ void fn_vBuildLinkFromszParams ( ACP_tdxHandleOfLink _hLink, char *szParams[], ACP_tdxHandleOfWaypoint _hWayPointBefore, ACP_tdxHandleOfWaypoint _hWayPointAfter ) { unsigned char ucCurrentParam; ACP_tde_ucConnectionType eucConnType; ACP_tde_ucConnectionDynamicType eucConnDynType; /* information for dynamic :*/ unsigned char ucSamplingRate = 0; unsigned char ucDynamicType = 0; MTH_tdxReal xFirst = MTH_C_ZERO; MTH_tdxReal xSecond = MTH_C_ZERO; MTH_tdxReal xThird = MTH_C_ZERO; /* information for lynik type :*/ MTH3D_tdstVector stVFirst,stVSecond; /* first parameter should be the type of the link :*/ if(M_bIsLinkTypeStaticLine(szParams[0])) { eucConnType = ACP_ConnType_ucStaticLine; } else if(M_bIsLinkTypeDynamicLine(szParams[0])) { eucConnType = ACP_ConnType_ucDynamicLine; } else if(M_bIsLinkTypeBezier(szParams[0])) { eucConnType = ACP_ConnType_ucBezier; } else if(M_bIsLinkTypeCircle(szParams[0])) { eucConnType = ACP_ConnType_ucCircle; } else { eucConnType = ACP_ConnType_ucInvalid; M_IAFatalError(E_uwIAFatalTypeLinkInvalid); } /* Second parameter should be the dynamic type of the link :*/ if(M_bIsLinkDynTypeNone(szParams[1])) { eucConnDynType = ACP_ConDynType_ucNone; } else if(M_bIsLinkDynTypeConstant(szParams[1])) { eucConnDynType = ACP_ConDynType_ucConstant; } else if(M_bIsLinkDynTypeLinear(szParams[1])) { eucConnDynType = ACP_ConDynType_ucLinear; } else if(M_bIsLinkDynTypeSinus(szParams[1])) { eucConnDynType = ACP_ConDynType_ucSinus; } else { eucConnDynType = ACP_ConDynType_ucInvalid; M_IAFatalError(E_uwIAFatalDynTypeLinkInvalid); } /* allocate link according to the type and the dynamic type :*/ fn_vAllocLink ( _hLink, eucConnType, eucConnDynType ); ucCurrentParam =2; /* Now, depending on the type of the link, read parameter(s) : */ switch(M_eucGetLinkConnectionType(_hLink)) { /* No parameter is needed for the Static and Dynamic line type : case ACP_ConnType_ucStaticLine : case ACP_ConnType_ucDynamicLine : break;*/ case ACP_ConnType_ucBezier : /* M_IA_DEBUG_ASSERT ( (_hWayPointBefore!=ACP_C_InvalidWayPointHandle)&&(_hWayPointAfter!=ACP_C_InvalidWayPointHandle), E_uwIAFaralWayFirstLinkMustBeLine );*/ /* Parameters for Bezier curve :*/ /* SamplingRate, StartVector->X, StartVertor->Y, StartVector->Z, EndVector->X, EndVertor->Y, EndVector->Z, */ /* first param contains the sampling rate :*/ ucSamplingRate = (tduc_SamplingRate)(atoi(szParams[ucCurrentParam])); ucCurrentParam++; /* First vertor tangeant : */ MTH3D_M_vSetVectorElements ( &stVFirst, MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])), MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])), MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])) ); /* Second Vector tangeant :*/ MTH3D_M_vSetVectorElements ( &stVSecond, MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])), MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])), MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])) ); /* Create the object : */ fn_vBezierObject_Create ( M_stGetLinkConnTypeBezierObject(_hLink),/* Bezier object */ ucSamplingRate,/* ucSamplingRate */ &M_stGetVertex(_hWayPointBefore),/* Starting point */ &M_stGetVertex(_hWayPointAfter),/* Ending point */ &stVFirst, /* Start Vector */ &stVSecond, /* End Vector */ C_ucModeNoObject,/* ucObjectMode */ &M_stGetLinkConnDynTypeInfo(_hLink)/* DynamParam*/ ); break; case ACP_ConnType_ucCircle : /* TODO, but probably something like previous*/ break; } /* Now, depending on the dynamic type of the link, read parameter(s) : */ switch(M_eucGetLinkConnectionDynType(_hLink)) { case ACP_ConDynType_ucNone : ucDynamicType = C_ucNone; break; case ACP_ConDynType_ucConstant : ucDynamicType = C_ucConst; /* contains the speed :*/ xFirst = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam])); ucCurrentParam++; break; case ACP_ConDynType_ucLinear : ucDynamicType = C_ucLinear; /* contains the starting speed :*/ xFirst = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam])); ucCurrentParam++; /* contains the ending speed :*/ xSecond = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam])); ucCurrentParam++; break; case ACP_ConDynType_ucSinus : ucDynamicType = C_ucSinus; /* contains the statring angle : */ xFirst = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam])); ucCurrentParam++; /* contains the ending angle : */ xSecond = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam])); ucCurrentParam++; /* contains the maximum speed :*/ xThird = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam])); ucCurrentParam++; break; } /* if there is a sampling rate : */ if(ucSamplingRate) { fn_vDynamicObject_Create ( &M_stGetLinkConnDynTypeInfo(_hLink), ucSamplingRate, ucDynamicType, xFirst, xSecond, xThird ); } else {/* Dynamic object should not be sampled :*/ fn_vDynamicObject_CreateNotSampled ( &M_stGetLinkConnDynTypeInfo(_hLink), ucDynamicType, xFirst, xSecond, xThird ); } } /* ------------------------------------------------------------------------------------------ WAY MANAGEMENT : ------------------------------------------------------------------------------------------ */ ACP_tdxHandleOfWay fn_hConstructWay (void) { ACP_tdxHandleOfWay hNewWay; /* allocate a way structure and return it :*/ M_IAAlloc ( hNewWay, /* Var to allocate*/ ACP_tdxHandleOfWay, /* var type */ sizeof(tdst_Way) /* size in bytes*/ ); /* initialize it to a default value :*/ M_IA_MemSet(hNewWay, 0, sizeof(tdst_Way) ); return hNewWay; } void fn_vDestroyWay(ACP_tdxHandleOfWay _hWay) { fn_vFreeWay(_hWay); M_IAFree(_hWay); } ACP_tdxHandleOfWay fn_hDuplicateWay (ACP_tdxHandleOfWay _hWay) { /* construction of a new structure :*/ ACP_tdxHandleOfWay hCopyWay = fn_hConstructWay (); /* copy data to the new Way :*/ fn_vCopyWay(hCopyWay/* dest */,_hWay /* Src */); return hCopyWay; } void fn_vCopyWay (ACP_tdxHandleOfWay _hWayDst, ACP_tdxHandleOfWay _hWaySrc) { /* allocate the new way :*/ fn_vAllocWay (_hWayDst, M_ucGetWaySizeWay(_hWaySrc)); /* copy the current WP Index :*/ M_ucGetWayCurrentWPIndex(_hWayDst) = M_ucGetWayCurrentWPIndex(_hWaySrc); /* copy the WP handle array :*/ memcpy ( M_dhGetWayWPHandleArray(_hWayDst), M_dhGetWayWPHandleArray(_hWaySrc), M_ucWayNbrOfWP(_hWaySrc) * sizeof(ACP_tdxHandleOfWaypoint ) ); /* Copy the link handle array :*/ memcpy ( M_dhGetWayLinkHandleArray(_hWayDst), M_dhGetWayLinkHandleArray(_hWaySrc), M_ucWayNbrOfLink(_hWaySrc) * sizeof(ACP_tdxHandleOfLink) ); } void fn_vInvalidateWay(ACP_tdxHandleOfWay* _hWay) {/* ?? Warning, before using this function, Way should be free */ *_hWay = ACP_C_InvalidWayHandle; } ACP_tdxBool fn_bIsWayValid (ACP_tdxHandleOfWay _hWay) { return _hWay == ACP_C_InvalidWayHandle; } void fn_vInitWay (ACP_tdxHandleOfWay _hWay) { // M_IA_MemSet(_hWay, 0xaa, sizeof (tdst_Way) ); } void fn_vAllocWay (ACP_tdxHandleOfWay _hWay, tducWPIndex _ucSizeWay) { M_ucGetWaySizeWay(_hWay) = _ucSizeWay; M_ucGetWayCurrentWPIndex(_hWay) = 0; /* allocate WP array :*/ M_IAAlloc ( M_dhGetWayWPHandleArray(_hWay), /* Var to allocate*/ ACP_tdxHandleOfWaypoint *, /* var type */ M_ucWayNbrOfWP(_hWay)*sizeof(ACP_tdxHandleOfWaypoint) /* size in bytes*/ ); // M_IA_MemSet(M_dhGetWayWPHandleArray(_hWay),0xaa,M_ucWayNbrOfWP(_hWay)*sizeof(ACP_tdxHandleOfWaypoint)); /* allocate link array :*/ M_IAAlloc ( M_dhGetWayLinkHandleArray(_hWay), /* Var to allocate*/ ACP_tdxHandleOfLink*, /* var type */ (M_ucWayNbrOfLink(_hWay))*sizeof(ACP_tdxHandleOfLink) /* size in bytes*/ ); // M_IA_MemSet(M_dhGetWayLinkHandleArray(_hWay),0xaa,M_ucWayNbrOfLink(_hWay)*sizeof(ACP_tdxHandleOfLink)); } void fn_vFreeWay (ACP_tdxHandleOfWay _hWay) { while(M_ucGetWaySizeWay(_hWay)) {/* Erase previous data :*/ fn_vDeleteWayPoint(_hWay,M_ucGetWaySizeWay(_hWay)-1, NULL); } /* set other fields to 0 */ M_ucGetWayCurrentWPIndex(_hWay) = 0; } void fn_vReallocWay (ACP_tdxHandleOfWay _hWay, tducWPIndex _ucNewSizeWay) { if(M_ucGetWaySizeWay(_hWay) != _ucNewSizeWay) fn_vAllocWay (_hWay, 2); { // jack if (!M_ucGetWaySizeWay(_hWay)) /* set new size :*/ M_ucGetWaySizeWay(_hWay) = _ucNewSizeWay; /* reallocate the WP dynamic array :*/ if(_ucNewSizeWay) {/* if it is a non zero value :*/ M_IARealloc ( M_dhGetWayWPHandleArray(_hWay), M_dhGetWayWPHandleArray(_hWay), ACP_tdxHandleOfWaypoint*, M_ucWayNbrOfWP(_hWay)*sizeof(ACP_tdxHandleOfWaypoint) ); M_IARealloc ( M_dhGetWayLinkHandleArray(_hWay), M_dhGetWayLinkHandleArray(_hWay), ACP_tdxHandleOfLink*, M_ucWayNbrOfLink(_hWay)*sizeof(ACP_tdxHandleOfLink) ); } else { if(M_ucGetWaySizeWay(_hWay)) {/* if there was previously elements in the arrays :*/ M_IAFree(M_dhGetWayWPHandleArray(_hWay)); M_IAFree(M_dhGetWayLinkHandleArray(_hWay)); } } } /* else : nothing to do... */ } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_hAddRefWay Increase the used count //////////////////////////////////////////////////////////////////////////////// Input : a handle on the way //////////////////////////////////////////////////////////////////////////////// Output : the handle of the way //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 22,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ ACP_tdxHandleOfWay fn_hAddRefWay(ACP_tdxHandleOfWay _hWay) { M_ucGetWayCurrentUsedCount(_hWay)++; return _hWay; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_hReleaseWay Decrease the used count of the way. If it reachs zero, the way is destroyed //////////////////////////////////////////////////////////////////////////////// Input : A handle to the way //////////////////////////////////////////////////////////////////////////////// Output : The handle to the way if it has not been destroyed otherwise ACP_C_InvalidWayHandle //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 22,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ ACP_tdxHandleOfWay fn_hReleaseWay(ACP_tdxHandleOfWay _hWay) { // M_ucGetWayCurrentUsedCount(_hWay)--; // /* if it is zero, then destroy it :*/ // if(!M_ucGetWayCurrentUsedCount(_hWay)) // { // fn_vDestroyWay(_hWay); // _hWay = ACP_C_InvalidWayHandle; // } return _hWay; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_vInsertWayPoint Inserts a new waypoint in the way //////////////////////////////////////////////////////////////////////////////// Input : A handle to the way a handle on the new WP a handle on the connected link before a handle on the connected link after the position where to insert the new WP //////////////////////////////////////////////////////////////////////////////// Output : None //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 1997 Author : Jacques Ternoz (annecy) //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Modification date : January 30,1997 Author : Albert Pais Adding management depending on whether there is as much link as WP or not //////////////////////////////////////////////////////////////////////////////// Modification date : February 10,1997 Author : Jacques Ternoz Adding the modification of links due to the add WP //////////////////////////////////////////////////////////////////////////////// */ void fn_vInsertWayPoint ( ACP_tdxHandleOfWay _hWay, ACP_tdxHandleOfWaypoint _hNewWP, ACP_tdxHandleOfLink _hNewLinkBefore, ACP_tdxHandleOfLink _hNewLinkAfter, tducWPIndex _ucPosWP ) { tducWPIndex c_ucCount; /* M_IA_DEBUG_ASSERT ( _ucPosWP < M_ucGetWaySizeWay(_hWay), E_uwIAFatalWayPositionInvalid );*/ /* First of all, re-allocate the way :*/ fn_vReallocWay (_hWay, M_ucGetWaySizeWay(_hWay)+1); #ifdef _WAY_FirstLinkIsFirstWaypoint_ /* No problemo....*/ for (c_ucCount=M_ucGetWaySizeWay(_hWay)-1; c_ucCount>_ucPosWP; c_ucCount--) { M_hGetWPAtPositionWay(_hWay,c_ucCount)=M_hGetWPAtPositionWay(_hWay,c_ucCount-1); M_hGetLinkAtPositionWay(_hWay,c_ucCount)=M_hGetLinkAtPositionWay(_hWay,c_ucCount-1); } #else /*_WAY_FirstLinkIsFirstWaypoint_*/ /* now shift arrays :*/ for (c_ucCount=M_ucGetWaySizeWay(_hWay)-1; c_ucCount>_ucPosWP+1; c_ucCount--) { M_hGetWPAtPositionWay(_hWay,c_ucCount)=M_hGetWPAtPositionWay(_hWay,c_ucCount-1); M_hGetLinkAtPositionWay(_hWay,c_ucCount-1)=M_hGetLinkAtPositionWay(_hWay,c_ucCount-2); } /* since there is one more WP to shift :*/ /* here,, c_ucCount = _ucPosWP + 1:*/ M_hGetWPAtPositionWay(_hWay,c_ucCount)=M_hGetWPAtPositionWay(_hWay,c_ucCount-1); #endif /*_WAY_FirstLinkIsFirstWaypoint_*/ /* insert the new WP :*/ M_hGetWPAtPositionWay(_hWay,_ucPosWP)=_hNewWP; if (_hNewLinkBefore) M_hGetLinkAtPositionWay(_hWay,_ucPosWP-1)=_hNewLinkBefore; if (_hNewLinkAfter) M_hGetLinkAtPositionWay(_hWay,_ucPosWP)=_hNewLinkAfter; } void fn_vDeleteWayPoint (ACP_tdxHandleOfWay _hWay, tducWPIndex _ucPosWP, ACP_tdxHandleOfLink _hNewLink) { tducWPIndex ucWP; /* M_IA_DEBUG_ASSERT ( _ucPosWP < M_ucGetWaySizeWay(_hWay), E_uwIAFatalWayPositionInvalid );*/ /* Release WP and link :*/ fn_hReleaseWaypoint(M_hGetWPAtPositionWay(_hWay,ucWP)); #ifndef _WAY_FirstLinkIsFirstWaypoint_ if(_ucPosWP < M_ucWayNbrOfLink(_hWay)) { #endif /*_WAY_FirstLinkIsFirstWaypoint_*/ fn_hReleaseLink(M_hGetLinkAtPositionWay(_hWay,ucWP)); #ifndef _WAY_FirstLinkIsFirstWaypoint_ } else {/* the last WP is currently been removed. So release the last link :*/ fn_hReleaseLink(M_hGetLinkAtPositionWay(_hWay,ucWP-1)); } #endif /* _WAY_FirstLinkIsFirstWaypoint_ */ /* shift the end of the arrays :*/ for ( ucWP=_ucPosWP; #ifdef _WAY_FirstLinkIsFirstWaypoint_ ucWP=(tducWPIndex)0)&&(_ucCurrentWP M_stGetLinkConnTypeBezierObject(hLink)->ucSamplingRate) {/* test wether it is the last Wp or not :*/ if(M_bWayIsLastWayPoint(_hWay,M_ucGetWayCurrentWPIndex(_hWay))) { /* it is finished :*/ return (unsigned char)0; } b_ucGoToNext = 1; } break; case ACP_ConnType_ucCircle: /* TODO */ /* Certainly something like for Bezier curves : */ default: M_IAFatalError(E_uwIAFatalTypeLinkInvalid); return (unsigned char)-1; break; } #ifndef _WAY_FirstLinkIsFirstWaypoint_ } else { b_ucGoToNext = 1; } #endif /* _WAY_FirstLinkIsFirstWaypoint_ */ /* if it is time to go to the next WP :*/ if(b_ucGoToNext) {/* go to the next Wp :*/ fn_hNextWayPoint(_hWay); hLink = M_hGetWayCurrentLink(_hWay); /* here we know that it is not the last :*/ switch(M_eucGetLinkConnectionType(hLink)) {/* concerning the connection type :*/ case ACP_ConnType_ucStaticLine: fn_vComputeLocationWaypoint ( M_hGetWayCurrentWP(_hWay),/* it is assumed that the current WP is the wp to reach */ M_stGetLinkConnTypeStaticVector(hLink) /* receive the position of the WP at the moment we begin following this link */ ); /*break;*/ /* commented in order to process dynamic info for both cases :*/ case ACP_ConnType_ucDynamicLine : /* nothing to do concerning the type*/ /* But for the dynamic :*/ POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_p_SuperObjPerso),&stVector); MTH3D_M_vSubVector((&stVector),(&stVector),(&M_stGetVertex(M_hGetWayCurrentWP(_hWay)))); fn_vDynamicObject_CalculateNotSampled ( &M_stGetLinkConnDynTypeInfo(hLink), MTH3D_M_xNormVector((&stVector)) ); break; case ACP_ConnType_ucBezier: case ACP_ConnType_ucCircle: /* unused to do it each time : fn_vDynamicObject_Calculate(&M_stGetLinkConnDynTypeInfo(hLink));*/ /* set the current sampling to 0 : */ M_ucGetLinkCurrentSample(hLink) = 0; break; } } return (unsigned char)1; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_tdxGetSpeedWay Return the speed according to the current position of the object, the current link dynamic type and the current WP to reach //////////////////////////////////////////////////////////////////////////////// Input : a handle to the super object a handle on the way //////////////////////////////////////////////////////////////////////////////// Output : A MTH_tdxReal containing the speed //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 23,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ MTH_tdxReal fn_tdxGetSpeedWay ( HIE_tdxHandleToSuperObject _p_SuperObjPerso, ACP_tdxHandleOfWay _hWay ) { ACP_tdxHandleOfLink hLink; MTH3D_tdstVector xPersoVertex; MTH_tdxReal xCurrentDist; #ifndef _WAY_FirstLinkIsFirstWaypoint_ /* we have one WP more than links */ /* so if current Wp is the first return 0 :*/ if(M_ucGetWayCurrentWPIndex(_hWay)==0) { /* the speed return is zero :*/ return MTH_C_ZERO; } #endif hLink = M_hGetWayCurrentLink(_hWay); switch(M_eucGetLinkConnectionType(hLink)) { case ACP_ConnType_ucStaticLine: case ACP_ConnType_ucDynamicLine: /* dist between the perso and the WP to reach :*/ POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_p_SuperObjPerso),&xPersoVertex); MTH3D_M_vSubVector((&xPersoVertex),(&xPersoVertex),(&M_stGetVertex(M_hGetWayCurrentWP(_hWay)))); xCurrentDist = MTH3D_M_xNormVector((&xPersoVertex)); return fn_xDynamicObject_GetSpeedNotSampled ( &M_stGetLinkConnDynTypeInfo(hLink), xCurrentDist ); break; case ACP_ConnType_ucBezier: case ACP_ConnType_ucCircle : return fn_xDynamicObject_GetSpeed ( &M_stGetLinkConnDynTypeInfo(hLink), M_ucGetLinkCurrentSample(hLink) ); break; } return MTH_C_ZERO; } /* //////////////////////////////////////////////////////////////////////////////// Description :fn_vGetNextPointWay Return the point to reach according to the current position of the object, the current link type and the current WP to reach //////////////////////////////////////////////////////////////////////////////// Input : a handle to the super object a handle on the way a pointer to the vector that receives the coordinates of the point to reach a pointer to a MTH_tdxReal that contains the min dist a pointer to the args //////////////////////////////////////////////////////////////////////////////// Output : None //////////////////////////////////////////////////////////////////////////////// Error raised: None //////////////////////////////////////////////////////////////////////////////// Creation date : January 23,1997 Author : Albert Pais //////////////////////////////////////////////////////////////////////////////// */ void fn_vGetNextPointWay ( HIE_tdxHandleToSuperObject _p_SuperobjPerso, ACP_tdxHandleOfWay _hWay, MTH3D_tdstVector* _pstVertex, MTH_tdxReal* _p_stMinDist ) { ACP_tdxHandleOfLink hLink; #ifndef _WAY_FirstLinkIsFirstWaypoint_ if(M_ucGetWayCurrentWPIndex(_hWay)) {/* current wp is not the first wp of the way :*/ #endif /* _WAY_FirstLinkIsFirstWaypoint_ */ hLink = M_hGetWayCurrentLink(_hWay); switch(M_eucGetLinkConnectionType(hLink)) { case ACP_ConnType_ucStaticLine : /* retrive the vertex from the type information :*/ *_pstVertex = *M_stGetLinkConnTypeStaticVector(hLink); break; case ACP_ConnType_ucDynamicLine : /* compute the current position of the Wp :*/ fn_vComputeLocationWaypoint ( M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay)), _pstVertex ); break; case ACP_ConnType_ucBezier : fn_vBezierObject_GetPoint ( M_stGetLinkConnTypeBezierObject(hLink), M_ucGetLinkCurrentSample(hLink), _pstVertex ); break; case ACP_ConnType_ucCircle : /* TODO */ /* Certainly something like for Bezier Curves */ break; } #ifndef _WAY_FirstLinkIsFirstWaypoint_ } else {/* current wp is the first wp of the way */ fn_vComputeLocationWaypoint ( M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay)), _pstVertex ); } #endif /* _WAY_FirstLinkIsFirstWaypoint_ */ *_p_stMinDist = M_xGetWPRadius(M_hGetWayCurrentWP(_hWay)); } #ifdef __cplusplus } #endif /* __cplusplus */