/************************************************************************************************ * * * Collisio.c * * * * High level collision functions * * * * * ************************************************************************************************/ #include "ToolsCPA.h" #include "Options/Options.h" #include "Macros.h" #include "Actions/AllActs.h" #include "structur/objects.h" #include "STRUCTUR/StdObjSt.h" #include "Structur/EngMode.h" #include "Collisio.h" #include "GameEng.h" #include "ZdxStuff.h" #include "ToolCam.h" #include "PhysiCol.h" #include "Family.h" #include "PO.h" #include "ChanList.h" #include "always.h" #include "mainchar.h" #include "PRF.h" #define C_wStaticObject 0 #define C_wMobileObject 1 /* ANNECY AV {*/ #define C_ulCustomBit_Projectile 0x00000008 /* END ANNECY AV }*/ #define C_xHalfSqr3 MTH_M_xDoubleToReal(.8660254037844) /* jt 260599 */ long COL_g_lMaxNumberOfCollisions = COL_C_xMaxNumberOfCollisions; /* anthony */ extern COL_tdstCollisionCase COL_g_stCollisionCase [COL_C_xMaxNumberOfCollisions]; extern COL_tdstCollisionCase *COL_g_stCollisionCaseReal; extern long COL_g_lNbElementsInTable; extern ACP_tdxBool HISPEED; /* end anthony*/ /* end jt 260599 */ /*-----------------------------------------------------------------------------*/ /* fn_eGetLimbTypeFromGameMaterial*/ /*-----------------------------------------------------------------------------*/ /*DNM_tdeLimbType fn_eGetLimbTypeFromGameMaterial (GMT_tdxHandleToGameMaterial _hGMT) { if( GMT_fn_xMultipleTestCollideIdentifierFromGameMaterial(_hGMT,GMT_C_uwPieds) ) return DNM_eLTFoot; else if( GMT_fn_xMultipleTestCollideIdentifierFromGameMaterial(_hGMT,GMT_C_uwCorps) ) return DNM_eLTTrunk; else if( GMT_fn_xMultipleTestCollideIdentifierFromGameMaterial(_hGMT,GMT_C_uwTete) ) return DNM_eLTHead; else if( GMT_fn_xMultipleTestCollideIdentifierFromGameMaterial(_hGMT,GMT_C_uwMains) ) return DNM_eLTHand; else return DNM_eLTError; }*/ /*-----------------------------------------------------------------------------*/ /* fn_bIsGeometricObjectValidForCollision*/ /*-----------------------------------------------------------------------------*/ ACP_tdxBool fn_bIsGeometricObjectValidForCollision (ACP_tdxHandleOfObject _hGeoObj) { /* IMPORTANT : if the geometric objet has no point, it is not necessary to call the collision*/ return (ACP_tdxBool) (GEO_xGetGeometricObjectNumberOfPoints(_hGeoObj) >= 1); } /*-----------------------------------------------------------------------------*/ /* COL_lHaveITakeSThgIntoTheMug*/ /**/ /* The main function for the collisions :*/ /* Test the collision between one super object and the rest of the world*/ /*-----------------------------------------------------------------------------*/ /* used*/ long COL_lHaveITakeSThgIntoTheMug(DNM_tdstMecObstacle _a_stResultObstacle [COL_C_xMaxNumberOfCollisions] , HIE_tdxHandleToSuperObject _p_stSupObj , POS_tdstCompletePosition * _p_stStartPosition , POS_tdstCompletePosition * _p_stEndPosition) { static MTH_tdxReal xSlideCoef = MTH_C_ZERO; static MTH_tdxReal xReboundCoef = MTH_C_ZERO; /* ACP_tdxBool bCollision;*/ ACP_tdxIndex i; MTH3D_tdstVector * p_stAxis = DNM_M_p_stObstacleGetNorm(& _a_stResultObstacle [0]); MTH3D_tdstVector stDummy; long lResult = 0; long lParameter2 = 0; /* COL_tdstCollisionCase a_stCollisionCase [COL_C_xMaxNumberOfCollisions];*/ /* COL_tdstCollisionCase * p_stCollisionCase; */ DNM_tdxHandleToMecMatCharacteristics hCollidedMechanicMaterial; DNM_tdstMecMatCharacteristics *p_stMechanicMaterial; #if defined(USE_PROFILER) && !defined(PRESS_DEMO) unsigned char ucDNMRunning , ucIARunning; void *p_vCurrentAIData = NULL; void *p_vCurrentDNMData = NULL; ucDNMRunning = (unsigned char) (( PRF_fn_iGetFunctionNumberOfStart( PRF_C_ulFctDNM, &p_vCurrentDNMData ) > 0 ) ? 1 : 0); ucIARunning = (unsigned char) (( PRF_fn_iGetFunctionNumberOfStart( PRF_C_ulFctAI, &p_vCurrentAIData ) > 0 ) ? 1 : 0); if( ucDNMRunning ) PRF_fn_vStopChrono( PRF_C_ulFctDNM, p_vCurrentDNMData ); if( ucIARunning ) PRF_fn_vStopChrono( PRF_C_ulFctAI, p_vCurrentAIData ); PRF_fn_vStartChrono( PRF_C_ulFctCollisions, _p_stSupObj ); #endif MTH3D_M_vSetVectorElements(&stDummy,MTH_C_ZERO,MTH_C_ZERO,MTH_M_xFloatToReal(0.1f)); /* NOCLIP Ghost Mode*/ if(g_ucIsEdInGhostMode && CAM_fn_bSuperObjectIsACamera(_p_stSupObj)) { /* DNM_M_eObstacleSetType(& _a_stResultObstacle [0] ,DNM_ObsType_Nothing);*/ DNM_M_eObstacleSetType(& _a_stResultObstacle [0] ,0); #if defined(USE_PROFILER) && !defined(PRESS_DEMO) PRF_fn_vStopChrono( PRF_C_ulFctCollisions, _p_stSupObj ); if( ucDNMRunning ) PRF_fn_vStartChrono( PRF_C_ulFctDNM, p_vCurrentDNMData ); if( ucIARunning ) PRF_fn_vStartChrono( PRF_C_ulFctAI, p_vCurrentAIData ); #endif return 0; } /* Dealing whit changes of sectors*/ /*prabaly useless, because the sector in which we are new is most certainly in the collision list of our current sector,*/ /*and will be tested for collisions anyway...*/ /*GAM_fn_vSectInfoTestChangeSectorForCharacter(_p_stSupObj); */ /* If character has a Collision Set and has at least one Zdm*/ if (M_GetMSHandle (_p_stSupObj , CollSet) && CS_fn_hGetZdxList (C_ucTypeZdm , _p_stSupObj)) { /* Do collision computation*/ /* COL_tdstCollisionCase *p_stCurrentCollisionCase;*/ DNM_tdstMecObstacle *p_stCurrentResultObstacle; /* Warning anthony */ COL_g_stCollisionCaseReal = (COL_tdstCollisionCase *)_a_stResultObstacle; /* replace bcollision = COL_fn_bGetMultipleResultCollision (& p_stCollisionCase);*/ /* Test the collisions with all zones (hand and no hand)*/ /*if (!HISPEED)*/ COL_fn_vInitCollisionTable(); COL_fn_vNewStaticCollisionForCharacter (_p_stSupObj, fn_h_SectInfoGetCurrentSector(M_GetMSHandle(_p_stSupObj,SectInfo)), _p_stStartPosition, _p_stEndPosition); /*bCollision = COL_fn_bGetMultipleResultCollision (& p_stCollisionCase);*/ for ( i = 0, /*p_stCurrentCollisionCase = p_stCollisionCase, */ p_stCurrentResultObstacle = _a_stResultObstacle; i < COL_g_lNbElementsInTable; /*COL_g_lMaxNumberOfCollisions;*/ i ++, /*p_stCurrentCollisionCase ++,*/ p_stCurrentResultObstacle ++ ) /* if (p_stCurrentCollisionCase->bCollisionState) */ { /* comment by jt 071098*/ /* DNM_M_p_stObstacleSetDNMObject(p_stCurrentResultObstacle, NULL);*/ lParameter2 = ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->sParameter2; /* In case of collision between two characters*/ // if( (((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->sParameter2 & 0x1) == C_wMobileObject ) if( (lParameter2 & 0x1) == C_wMobileObject ) { HIE_tdxHandleToSuperObject hSOInCollision; hSOInCollision = (HIE_tdxHandleToSuperObject)((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->p_vParameter1; DNM_M_eObstacleSetType(p_stCurrentResultObstacle, DNM_ObsType_Mobile); /* Add this test in case of global ZDR*/ /* comment by jt 071098*/ /* if( HIE_fn_ulGetSuperObjectType(hSOInCollision)==HIE_C_ulActor ) { if((h_Dynam = M_GetMSHandle(hSOInCollision,Dynam)) != NULL ) if((p_stDynamics = fn_p_stDynamGetDynamics(h_Dynam)) != NULL) DNM_M_p_stObstacleSetDNMObject(p_stCurrentResultObstacle, p_stDynamics); } else { hFather = HIE_fn_hGetSuperObjectFather(hSOInCollision); if(HIE_fn_bIsSuperObjectValid(hFather)) if(HIE_fn_ulGetSuperObjectType(hFather) == HIE_C_ulActor) if((h_Dynam = M_GetMSHandle(hFather,Dynam)) != NULL ) if((p_stDynamics = fn_p_stDynamGetDynamics(h_Dynam)) != NULL) DNM_M_p_stObstacleSetDNMObject(p_stCurrentResultObstacle, p_stDynamics); }*/ } else DNM_M_eObstacleSetType(p_stCurrentResultObstacle, DNM_ObsType_Scenery); /* jt 060199*/ /* double edge report */ // if ( ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->sParameter2 & 0x2 ) if ( lParameter2 & 0x2 ) DNM_M_eObstacleSetType ( p_stCurrentResultObstacle, DNM_M_eObstacleGetType(p_stCurrentResultObstacle) | DNM_ObsType_DoubleEdge ); /* end jt*/ /* Partie collisionnée */ if(((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->hStaticMaterial != NULL) { hCollidedMechanicMaterial = GMT_fn_hGetMechanicsMaterial( ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->hStaticMaterial ); if(DNM_fn_bIsMatCharacteristicsValid(hCollidedMechanicMaterial)) { p_stMechanicMaterial = DNM_fn_p_stMecMatCharacteristicsGiveBackSemantic(hCollidedMechanicMaterial); DNM_M_xObstacleSetSlide(p_stCurrentResultObstacle, DNM_M_xMatCharacteristicsGetSlide(p_stMechanicMaterial)); DNM_M_xObstacleSetRebound(p_stCurrentResultObstacle, DNM_M_xMatCharacteristicsGetRebound(p_stMechanicMaterial)); } else { DNM_M_xObstacleSetSlide(p_stCurrentResultObstacle, xSlideCoef); DNM_M_xObstacleSetRebound(p_stCurrentResultObstacle, xReboundCoef); } } else { DNM_M_xObstacleSetSlide(p_stCurrentResultObstacle, xSlideCoef); DNM_M_xObstacleSetRebound(p_stCurrentResultObstacle, xReboundCoef); } /* anthony */ /*DNM_M_p_stObstacleSetObject(p_stCurrentResultObstacle, (HIE_tdxHandleToSuperObject)((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->p_vParameter1); DNM_M_vObstacleSetCollidedMaterial(p_stCurrentResultObstacle, ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->hStaticMaterial); DNM_M_vObstacleSetMyMaterial(p_stCurrentResultObstacle, ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->hDynamicMaterial); DNM_M_xObstacleSetMyEntity(p_stCurrentResultObstacle, ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->xDynamicGeomEntity); DNM_M_xObstacleSetCollidedEntity(p_stCurrentResultObstacle, ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->xStaticGeomEntity);*/ /*anthony end */ /* if( p_stCurrentCollisionCase->hDynamicMaterial )*/ /* DNM_M_eObstacleSetLimbType(p_stCurrentResultObstacle, fn_eGetLimbTypeFromGameMaterial(p_stCurrentCollisionCase->hDynamicMaterial));*/ /* else DNM_M_eObstacleSetLimbType(p_stCurrentResultObstacle, DNM_eLTDefault);*/ /* anthony */ /* p_stAxis = DNM_M_p_stObstacleGetNorm(p_stCurrentResultObstacle); *p_stAxis = ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->stCollisionNormal; p_stAxis = DNM_M_p_stObstacleGetContact(p_stCurrentResultObstacle); *p_stAxis = ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->stCollisionPoint; DNM_M_xObstacleSetRate(p_stCurrentResultObstacle,((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->xCollisionTime); DNM_M_xObstacleSetTranslation (p_stCurrentResultObstacle, & ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->stTranslation); DNM_M_xObstacleSetZoneMove (p_stCurrentResultObstacle, & ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->stMovement); DNM_M_xObstacleSetZoneRadius (p_stCurrentResultObstacle, ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->xSphereRadius); DNM_M_xObstacleSetZonePosition (p_stCurrentResultObstacle, & ((COL_tdstCollisionCase *)p_stCurrentResultObstacle)->stEndPosition);*/ lResult = i + 1; } /* End if (p_stCurrentCollisionCase->bCollisionState)*/ /* else break; /* No collision : it is not necessary to test the next elements of the array*/ } /* End if M_GetMSHandle(_p_stSupObj,CollSet) : if the character has a Collision Set*/ #if defined(USE_PROFILER) && !defined(PRESS_DEMO) PRF_fn_vStopChrono( PRF_C_ulFctCollisions, _p_stSupObj ); if( ucDNMRunning ) PRF_fn_vStartChrono( PRF_C_ulFctDNM, p_vCurrentDNMData ); if( ucIARunning ) PRF_fn_vStartChrono( PRF_C_ulFctAI, p_vCurrentAIData ); #endif return lResult; } /*-----------------------------------------------------------------------------*/ /* fn_vCollideStaticCharacterWithStaticPhysicals*/ /* test static collisions between a character and a static physical object*/ /*-----------------------------------------------------------------------------*/ /* used*/ void fn_vCollideStaticCharacterWithStaticPhysicals ( HIE_tdxHandleToSuperObject _hDynamicCharacter , ACP_tdxHandleOfObject _hDynamicGeoCol , HIE_tdxHandleToSuperObject _hModule , POS_tdstCompletePosition * p_stStartMatrix , POS_tdstCompletePosition * p_stEndMatrix ) { PCS_tdxHandleToPhysicalCollSet hStaticCollSet = PO_fn_hGetCollideSet ( ( PO_tdxHandleToPhysicalObject ) HIE_fn_hGetSuperObjectObject ( _hModule ) ) ; /* Down with module ZDR*/ if ( hStaticCollSet ) { GEO_tdstGeometricObject * p_stStaticGeoColl = PCS_fn_hGetGeoObjOfPhysicalCollSet ( C_ucTypeZdr , hStaticCollSet ) ; if ( p_stStaticGeoColl ) { COL_fn_vCollideStaticGeomObj1WithStaticGeomObj2 ( _hDynamicGeoCol , p_stStartMatrix , p_stEndMatrix , p_stStaticGeoColl , HIE_fn_hGetSuperObjectGlobalMatrix ( _hModule ) , ( void * ) _hModule , C_wMobileObject , ( ACP_tdxBool ) HIE_fn_SO_bHasNoTransformationMatrix ( _hModule ) , ( ACP_tdxBool ) HIE_fn_SO_bHasZoomInsteadOfScale ( _hDynamicCharacter ) ); } } } /*-------------------------------------------------------------------- * Test static collisions between 2 characters, taking in account Zdr, * modules and priority. *--------------------------------------------------------------------*/ /* used*/ void fn_vNewTestStaticCollideFor2Characters (HIE_tdxHandleToSuperObject hCharacter , ACP_tdxHandleOfObject _hDynamicZdm , HIE_tdxHandleToSuperObject hStaticCharacter , POS_tdstCompletePosition * p_stStartMatrix , POS_tdstCompletePosition * p_stEndMatrix) { GEO_tdxHandleToBoundingSphere hBoundingVolumeCharacter = NULL; GEO_tdxHandleToBoundingSphere hBoundingVolumeStaticCharacter = NULL; CHN_tdxHandleToChannel hChannel; MS_tdxHandleToCollSet hStaticCollSet; MS_tdxHandleToCollSet hDynamicCollSet; HIE_tdxHandleToSuperObject hMainChar ; /* ACP_tdxIndex xIndex;*/ /* ANNECY AV {*/ /* Is static character active ?*/ if (! M_ObjectIsActive ((struct tdstEngineObject_ *) HIE_fn_hGetSuperObjectObject (hStaticCharacter))) /* END ANNECY AV }*/ { return; } /* Is static character collidable ?*/ if ( HIE_fn_SO_bIsNotPickable ( hStaticCharacter ) ) { return; } hDynamicCollSet = M_GetMSHandle (hCharacter, CollSet); hStaticCollSet = M_GetMSHandle (hStaticCharacter, CollSet); /* Test the priority : the dynamic priority must be >= than the static priority*/ if ( CS_fn_ucGetCharacterPriority ( hDynamicCollSet ) < ( hStaticCollSet ? CS_fn_ucGetCharacterPriority( hStaticCollSet ) : 0 ) ) { return; } hMainChar = MC_fn_hGetCharacterInMainCharacterNode ( MC_fn_hGetFirstMainCharNode ( ) ) ; if ( hDynamicCollSet ) { /* Test if the dynamic character can collide projectiles*/ if ( fn_bCollSetGetCharacterNoCollisionWithProjectile (hDynamicCollSet) && (fn_ulStandardGameGetCustomBitsSO (hStaticCharacter) & C_ulCustomBit_Projectile) ) { return; } if ( hStaticCharacter == hMainChar ) { /* Test if the dynamic character can collide the main character*/ if ( fn_bCollSetGetCharacterNoCollisionWithMainCharacter ( hDynamicCollSet ) ) return ; } else { /* Test if the dynamic character can collide the secondary characters*/ if ( fn_bCollSetGetCharacterNoCollisionWithSecondaryCharacter ( hDynamicCollSet ) && ! fn_ucIsAnAlwaysObject ( ( tdstEngineObject *) HIE_fn_hGetSuperObjectObject ( hStaticCharacter ) ) ) return ; } } if ( hStaticCollSet ) { /* Test if the static character can collide projectiles*/ if ( fn_bCollSetGetCharacterNoCollisionWithProjectile (hStaticCollSet) && (fn_ulStandardGameGetCustomBitsSO (hCharacter) & C_ulCustomBit_Projectile) ) { return; } if ( hMainChar == hCharacter ) { /* Test if the dynamic character can collide the main character*/ if ( fn_bCollSetGetCharacterNoCollisionWithMainCharacter ( hStaticCollSet ) ) return ; } else { /* Test if the dynamic character can collide the secondary characters */ if ( fn_bCollSetGetCharacterNoCollisionWithSecondaryCharacter ( hStaticCollSet ) && ! fn_ucIsAnAlwaysObject ( ( tdstEngineObject * ) HIE_fn_hGetSuperObjectObject ( hCharacter ) ) ) return ; } } /* Testing bounding volumes*/ hBoundingVolumeCharacter = ( GEO_tdxHandleToBoundingSphere ) HIE_fn_hGetSuperObjectBoundingVolume( hCharacter ) ; hBoundingVolumeStaticCharacter = ( GEO_tdxHandleToBoundingSphere ) HIE_fn_hGetSuperObjectBoundingVolume ( hStaticCharacter ) ; if ( hBoundingVolumeCharacter && hBoundingVolumeStaticCharacter ) if ( ! COL_fn_bDetectCollisionStaticGeomObjWithStaticGeomObj ( hBoundingVolumeCharacter, p_stEndMatrix, (void *) hBoundingVolumeStaticCharacter , HIE_fn_hGetSuperObjectGlobalMatrix ( hStaticCharacter ) , ( ACP_tdxBool ) HIE_fn_SO_bHasNoTransformationMatrix ( hStaticCharacter ) , ( ACP_tdxBool ) HIE_fn_SO_bHasZoomInsteadOfScale ( hCharacter ) , FALSE /* The Static Character Has NOT a Box Bounding Volume*/ ) ) { return; } /* Here, we have to test the collisions*/ PRF_fn_vIncreaseVariable( PRF_C_ulVarDynColl, hCharacter, 1 ); /* Dynamic global Zdm Vs Static global Zdr*/ if ( hStaticCollSet ) { GEO_tdstGeometricObject * hStaticZdr = fn_hStaticMakeOneObjectFromManyZdx ( C_ucTypeZdr , hStaticCharacter ) ; if ( fn_bIsGeometricObjectValidForCollision (hStaticZdr) ) { COL_fn_vCollideStaticGeomObj1WithStaticGeomObj2( _hDynamicZdm, p_stStartMatrix, p_stEndMatrix, hStaticZdr, HIE_fn_hGetSuperObjectGlobalMatrix (hStaticCharacter), (void *) hStaticCharacter, C_wMobileObject, (ACP_tdxBool) HIE_fn_SO_bHasNoTransformationMatrix(hStaticCharacter), (ACP_tdxBool) HIE_fn_SO_bHasZoomInsteadOfScale(hCharacter) ); } } /* Dynamic global Zdm Vs static modular Zdr */ hChannel = fn_h3dDataGetFirstActiveChannel (M_GetMSHandle (hStaticCharacter , 3dData)); while ( hChannel ) { HIE_tdxHandleToSuperObject hModule = hChannel->hZoomSupObject ? hChannel->hZoomSupObject : hChannel->hSupObject ; /* check if module position is up to date*/ /* check if there is a zdr */ if ( ( HIE_fn_ulGetSuperObjectType (hModule) == HIE_C_ulPO ) && ( ! ( HIE_M_xGetSuperObjectMember(hModule, ulFlags) & HIE_C_Flag_ulHidden ) ) /* don't use a zone when its channel is deactivated */ ) { #ifdef ACTIVE_EDITOR unsigned char ucChannelNumber; GEO_tdstGeometricObject * p_stStaticGeoColl; MTH_tdxReal xScaleX,xScaleY,xScaleZ; static BOOL s_bColBox = FALSE; if ( PO_fn_hGetCollideSet ((PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject (hModule))) { p_stStaticGeoColl = PCS_fn_hGetGeoObjOfPhysicalCollSet (C_ucTypeZdr , PO_fn_hGetCollideSet ((PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject (hModule))); if ( p_stStaticGeoColl ) { /* ok, zdr found, check that position is up to date*/ ucChannelNumber = (unsigned char) (hChannel - fn_h3dDataGetChannelSOList(M_GetMSHandle(hStaticCharacter, 3dData))); fn_vCheckModuleAccessGam(hStaticCharacter, ucChannelNumber); /* now, check if the module global matrix has a scale or a zoom*/ if ( ! s_bColBox ) { /* if it is a scale, error because scale is not compatible with zdr-itself!*/ MTH3D_tdstVector stI,stJ,stK; POS_fn_vGetScaleMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(hModule),&stI,&stJ,&stK); xScaleX = stI.xX; xScaleY = stJ.xY; xScaleZ = stK.xZ; if ( ! s_bColBox && ! ( MTH_M_bEqualWithEpsilon ( xScaleX , xScaleY , 0.1f ) && MTH_M_bEqualWithEpsilon( xScaleX , xScaleZ , 0.1f ) ) ) { /* error !*/ char cText[1000]; sprintf(cText, "a ZDR_itself module has a scale !! This is forbidden!\n" "this module belongs to : %s\n" "who is currently in state : %s\n" "The number of the channel you try to access is : %i\n" "ScaleX = %f, scaleY = %f, scaleZ = %f\n", M_GetMSHandle(hStaticCharacter,Brain) ? (M_pstGetMindOfBrain(M_GetMSHandle(hStaticCharacter,Brain)))->szPersoName : "**unknown**", fn_p_szGetStateName(fn_h3dDataGetCurrentState(M_GetMSHandle(hStaticCharacter,3dData))), (unsigned char) (hChannel - fn_h3dDataGetChannelSOList(M_GetMSHandle(hStaticCharacter, 3dData))), xScaleX,xScaleY,xScaleZ ); if (hChannel->hZoomSupObject) { strcat(cText,"\nThis module is a symetric module\n"); } MessageBox(NULL,cText,"Module collision error",MB_OK|MB_ICONWARNING); s_bColBox = TRUE; } } } } #endif /* ! ACTIVE_EDITOR */ fn_vCollideStaticCharacterWithStaticPhysicals ( hCharacter , _hDynamicZdm , hModule , p_stStartMatrix , p_stEndMatrix ) ; } hChannel = hChannel -> p_stNextActiveChannel ; } } /*-----------------------------------------------------------------------------*/ /* New function of collision for a character.*/ /*-----------------------------------------------------------------------------*/ /*used*/ void COL_fn_vNewStaticCollisionForCharacter (HIE_tdxHandleToSuperObject _hCharacter, HIE_tdxHandleToSuperObject _hSector, POS_tdstCompletePosition *_p_stStartMatrix, POS_tdstCompletePosition *_p_stEndMatrix) { MS_tdxHandleToCollSet hCollSet; SECT_tdxHandleOfElementLstCharacter hCharacterList; SECT_tdxHandleOfElementLstCollisionInteraction hCollisionList; ACP_tdxHandleOfObject hDynamicZDM; HIE_tdxHandleToSuperObject hStaticCharacter ; GEO_tdxHandleToParallelBox hParallelBoxStatic = NULL; GEO_tdxHandleToBoundingSphere hBoundingSphereStatic = NULL; MTH3D_tdstVector stMove; GEO_tdstParallelBox stBackupParallelBox; MTH_tdxReal xBackupSphereRadius; long i , j; hDynamicZDM = fn_hMakeOneObjectFromManyZdx (C_ucTypeZdm , _hCharacter); PRF_fn_vStartChrono( PRF_C_ulFctCollisionsChar, _hCharacter ); hCollSet = M_GetMSHandle (_hCharacter, CollSet); /* jt 270599 */ /* Enlarge bounding volume */ /* compute move */ MTH3D_M_vSubVector ( &stMove, POS_fn_p_stGetTranslationVector(_p_stEndMatrix), POS_fn_p_stGetTranslationVector(_p_stStartMatrix) ); if(HIE_fn_SO_bHasABoxBoundingVolume (_hCharacter)) { hParallelBoxStatic = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hCharacter); memcpy(&stBackupParallelBox,hParallelBoxStatic,sizeof(GEO_tdstParallelBox)); if (MTH_M_bGreaterZero(MTH3D_M_xGetXofVector(&stMove))) MTH3D_M_vSetXofVector ( &(hParallelBoxStatic->stMaxPoint), MTH_M_xAdd ( MTH3D_M_xGetXofVector(&(hParallelBoxStatic->stMaxPoint)), MTH3D_M_xGetXofVector(&stMove) ) ) else MTH3D_M_vSetXofVector ( &(hParallelBoxStatic->stMinPoint), MTH_M_xAdd ( MTH3D_M_xGetXofVector(&(hParallelBoxStatic->stMinPoint)), MTH3D_M_xGetXofVector(&stMove) ) ) if (MTH_M_bGreaterZero(MTH3D_M_xGetYofVector(&stMove))) MTH3D_M_vSetYofVector ( &(hParallelBoxStatic->stMaxPoint), MTH_M_xAdd ( MTH3D_M_xGetYofVector(&(hParallelBoxStatic->stMaxPoint)), MTH3D_M_xGetYofVector(&stMove) ) ) else MTH3D_M_vSetYofVector ( &(hParallelBoxStatic->stMinPoint), MTH_M_xAdd ( MTH3D_M_xGetYofVector(&(hParallelBoxStatic->stMinPoint)), MTH3D_M_xGetYofVector(&stMove) ) ) if (MTH_M_bGreaterZero(MTH3D_M_xGetZofVector(&stMove))) MTH3D_M_vSetZofVector ( &(hParallelBoxStatic->stMaxPoint), MTH_M_xAdd ( MTH3D_M_xGetZofVector(&(hParallelBoxStatic->stMaxPoint)), MTH3D_M_xGetZofVector(&stMove) ) ) else MTH3D_M_vSetZofVector ( &(hParallelBoxStatic->stMinPoint), MTH_M_xAdd ( MTH3D_M_xGetZofVector(&(hParallelBoxStatic->stMinPoint)), MTH3D_M_xGetZofVector(&stMove) ) ) } else { hBoundingSphereStatic = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hCharacter); xBackupSphereRadius = hBoundingSphereStatic->xRadius; hBoundingSphereStatic->xRadius = MTH_M_xAdd ( hBoundingSphereStatic->xRadius, MTH3D_M_xNormVector(&stMove) ); } /* end jt 270599 */ /* The collisions with the other characters*/ if (! fn_bCollSetGetCharacterNoCollisionWithProjectile (hCollSet) || ! fn_bCollSetGetCharacterNoCollisionWithSecondaryCharacter (hCollSet) || ! fn_bCollSetGetCharacterNoCollisionWithMainCharacter (hCollSet)) { /* Deal with interactions between characters*/ /* First, the Active Sector*/ SECT_M_ForEachCharListInSector ( _hSector, hCharacterList, i ) { hStaticCharacter = SECT_GetCharacterInList ( hCharacterList ) ; if ( _hCharacter != hStaticCharacter ) { fn_vNewTestStaticCollideFor2Characters ( _hCharacter , hDynamicZDM , hStaticCharacter , _p_stStartMatrix , _p_stEndMatrix ) ; } } /* And now, the collision list*/ if (! fn_bCollSetGetCharacterNoCollisionWithOtherSectors (hCollSet)) { SECT_M_ForEachCollisionNodeInCollisionInteractionList ( _hSector , hCollisionList , i ) { SECT_M_ForEachCharListInSector ( SECT_GetSectorInCollisionList ( hCollisionList ) , hCharacterList, j ) { hStaticCharacter = SECT_GetCharacterInList ( hCharacterList ) ; /* Coz hCharacter may have changed of sector*/ if ( _hCharacter != hStaticCharacter ) { fn_vNewTestStaticCollideFor2Characters ( _hCharacter , hDynamicZDM , hStaticCharacter , _p_stStartMatrix , _p_stEndMatrix ) ; } } } } } PRF_fn_vStopChrono( PRF_C_ulFctCollisionsChar, _hCharacter ); /* The collisions with the map*/ if (! fn_bCollSetGetCharacterNoCollisionWithMap (hCollSet) && ! SECT_fn_bIsThisSectorVirtual (_hSector)) { /* Deal with the static world*/ COL_fn_vStaticCollisionWithPartOfTreeForSector (_hCharacter, _hSector, hDynamicZDM, _p_stStartMatrix, _p_stEndMatrix); /* Testing sectors in collision interaction*/ if (! fn_bCollSetGetCharacterNoCollisionWithOtherSectors (hCollSet)) { SECT_M_ForEachCollisionNodeInCollisionInteractionList ( _hSector, hCollisionList, i ) { HIE_tdxHandleToSuperObject hSectorToCollide = SECT_GetSectorInCollisionList (hCollisionList); if (! SECT_fn_bIsThisSectorVirtual (hSectorToCollide)) { COL_fn_vStaticCollisionWithPartOfTreeForSector (_hCharacter, hSectorToCollide, hDynamicZDM, _p_stStartMatrix, _p_stEndMatrix); } } } } /* restore initial Bounding Volume */ if(HIE_fn_SO_bHasABoxBoundingVolume (_hCharacter)) { hParallelBoxStatic = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hCharacter); memcpy(hParallelBoxStatic,&stBackupParallelBox,sizeof(GEO_tdstParallelBox)); } else { hBoundingSphereStatic = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hCharacter); hBoundingSphereStatic->xRadius = xBackupSphereRadius; } return; } /*-----------------------------------------------------------------------------*/ /* COL_fn_vStaticCollisionWithPartOfTreeForSector*/ /* New exploration of the static tree with use of sectors*/ /*-----------------------------------------------------------------------------*/ /* used*/ void COL_fn_vStaticCollisionWithPartOfTreeForSector (HIE_tdxHandleToSuperObject _p_stEngineObj, HIE_tdxHandleToSuperObject _p_stSuperObj, GEO_tdstGeometricObject * _p_stDynamicGeoColl, POS_tdstCompletePosition * _p_stStartMatrix, POS_tdstCompletePosition * _p_stEndMatrix) { unsigned long p; HIE_tdxHandleToSuperObject pChild; GEO_tdstGeometricObject * p_stStaticGeoColl; PO_tdxHandleToPhysicalObject hPhysicalObject; PCS_tdxHandleToPhysicalCollSet hPhyCollSet; GEO_tdxHandleToBoundingSphere hBoundingVolumeCharacter = NULL; GEO_tdxHandleToParallelBox hParallelBoxStatic = NULL; GEO_tdxHandleToBoundingSphere hBoundingSphereStatic = NULL; void * hBoundingVolumeStatic; long lType; if (HIE_fn_SO_bIsNotPickable( _p_stSuperObj ) ) { return; } hBoundingVolumeCharacter = HIE_fn_hGetSuperObjectBoundingVolume (_p_stEngineObj); if(HIE_fn_SO_bHasABoxBoundingVolume (_p_stSuperObj)) { hParallelBoxStatic = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_p_stSuperObj); hBoundingVolumeStatic = (void *)hParallelBoxStatic; } else { hBoundingSphereStatic = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_p_stSuperObj); hBoundingVolumeStatic = (void *)hBoundingSphereStatic; } if (hBoundingVolumeCharacter && hBoundingVolumeStatic) { if (! COL_fn_bDetectCollisionStaticGeomObjWithStaticGeomObj (hBoundingVolumeCharacter , _p_stEndMatrix , hBoundingVolumeStatic, HIE_fn_hGetSuperObjectGlobalMatrix (_p_stSuperObj), (ACP_tdxBool) HIE_fn_SO_bHasNoTransformationMatrix (_p_stSuperObj), (ACP_tdxBool) HIE_fn_SO_bHasZoomInsteadOfScale (_p_stEngineObj), (ACP_tdxBool) HIE_fn_SO_bHasABoxBoundingVolume (_p_stSuperObj))) { if(HIE_fn_SO_bCheckChildren(_p_stSuperObj)) { HIE_M_ForEachChildOf ( _p_stSuperObj, pChild, p ) { COL_fn_vStaticCollisionWithPartOfTreeForSector (_p_stEngineObj, pChild, _p_stDynamicGeoColl, _p_stStartMatrix, _p_stEndMatrix); } return; } else return; } } PRF_fn_vSetIndependantVariable( PRF_C_ulIdpCollComputed, 0 ); lType = HIE_fn_ulGetSuperObjectType(_p_stSuperObj); #ifdef D_THROW_IPO if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror )) { hPhysicalObject = (PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_p_stSuperObj); hPhyCollSet = PO_fn_hGetCollideSet(hPhysicalObject); if ( hPhyCollSet ) /* GIZMO 070897*/ { p_stStaticGeoColl = PCS_fn_hGetZdrGeoObjOfPhysicalCollSet(hPhyCollSet); COL_fn_vCollideStaticGeomObj1WithStaticGeomObj2 (_p_stDynamicGeoColl, _p_stStartMatrix, _p_stEndMatrix, p_stStaticGeoColl, HIE_fn_hGetSuperObjectGlobalMatrix(_p_stSuperObj), (void *) _p_stSuperObj , C_wStaticObject , (ACP_tdxBool) HIE_fn_SO_bHasNoTransformationMatrix(_p_stSuperObj), (ACP_tdxBool) HIE_fn_SO_bHasZoomInsteadOfScale(_p_stEngineObj)); } } #else /*D_THROW_IPO*/ if (lType & ( HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) { hPhysicalObject = IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_p_stSuperObj)); hPhyCollSet = PO_fn_hGetCollideSet(hPhysicalObject); if ( hPhyCollSet ) /* GIZMO 070897*/ { p_stStaticGeoColl = PCS_fn_hGetZdrGeoObjOfPhysicalCollSet(hPhyCollSet); COL_fn_vCollideStaticGeomObj1WithStaticGeomObj2 (_p_stDynamicGeoColl, _p_stStartMatrix, _p_stEndMatrix, p_stStaticGeoColl, HIE_fn_hGetSuperObjectGlobalMatrix(_p_stSuperObj), (void *) _p_stSuperObj , C_wStaticObject , (ACP_tdxBool) HIE_fn_SO_bHasNoTransformationMatrix(_p_stSuperObj), (ACP_tdxBool) HIE_fn_SO_bHasZoomInsteadOfScale(_p_stEngineObj)); } } #endif /* D_THROW_IPO */ /*End XB*/ #ifdef USE_PROFILER if( PRF_fn_lGetIndependantVariable( PRF_C_ulIdpCollComputed ) ) PRF_fn_vIncreaseVariable( PRF_C_ulVarStaColl, _p_stEngineObj, 1 ); #endif /* USE_PROFILER */ /* test all objects in sector*/ HIE_M_ForEachChildOf ( _p_stSuperObj, pChild, p ) { COL_fn_vStaticCollisionWithPartOfTreeForSector (_p_stEngineObj, pChild, _p_stDynamicGeoColl, _p_stStartMatrix, _p_stEndMatrix); } }