reman3/Rayman_X/cpa/tempgrp/MEC/MECPfm.c

215 lines
7.5 KiB
C

/*
*=======================================================================================
* Name : MecPfm.c
* Author : J Thénoz Date : 01/05/98
* Description : Mechanic platform functions
*=======================================================================================
*/
#include "cpa_expt.h"
#include "ACP_Base.h"
#include "MEC/MECInc.h"
#include "MEC/DnmDynam.h"
#include "MEC/ParsData.h"
#include "MEC/DNMSurSt.h"
#include "MEC/mbase.h"
#include "Extheade.h"
#include "COL.h"
#include "MEC/MecDef.h"
#include "MEC/MECPfm.h"
#include "MEC/MECTools.h"
#include "PCS.h" /* Physical Collide Set */
#include "SCT.h" /* SeCTor*/
#include "FIL.h" /* SeCTor*/
#include "PRT.h" /* PaRTicules*/
#include "GAM.h" /* GAMe*/
void MEC_fn_vUpdatePlatform (DNM_tdstDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj, POS_tdxHandleToPosition hPreviousReferenceMatrix, POS_tdxHandleToPosition hInvPreviousReferenceMatrix )
{
POS_tdxHandleToPosition hCurrentMatrix;
HIE_tdxHandleToSuperObject hChild;
DNM_tdxHandleToMecIdentityCard hIdCard;
ACP_tdxIndex i;
hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic);
HIE_M_ForEachChildOf (hSupObj,hChild,i)
{
DNM_tdstDynamics* p_stChildDynamic;
/* child is an actor ? */
if (HIE_fn_ulGetSuperObjectType(hChild)==HIE_C_ulActor)
{
/* only if son has a base mechanic */
p_stChildDynamic = fn_p_stDynamGetDynamicsSO (hChild);
if (p_stChildDynamic)
{
hIdCard = DNM_M_pDynamicsGetCurrentIdCard (p_stChildDynamic);
if (hIdCard)
{
if (DNM_fn_eIdentityCardGetType(hIdCard)==DNM_eBase)
MEC_fn_vDynamicComputeAbsoluteMatrix (p_stChildDynamic,hChild,hPreviousReferenceMatrix,hInvPreviousReferenceMatrix,hCurrentMatrix);
}
}
}
}
}
ACP_tdxBool MEC_fn_vBasePlatformManagement ( struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj )
{
DNM_tdstMecObstacle* p_stObstacle;
HIE_tdxHandleToSuperObject hGeomSuperObject;
HIE_tdxHandleToSuperObject hObstacleSuperObject;
/* only for base mechanic */
if (!MEC_fn_bIsBaseMechanic(p_stDynamic)) return FALSE;
if ( DNM_M_ulReportGetSurfaceState (&g_stReport) & C_WOT_ulMobile )
{
p_stObstacle = DNM_M_p_stReportGetCharacter (&g_stReport);
hGeomSuperObject = DNM_M_p_stObstacleGetObject (p_stObstacle);
/* GI -> ceil Climb -> wall else -> ground */
if (DNM_M_bDynamicsIsGi(p_stDynamic))
{
if (!MEC_fn_bCeilObstacle(p_stDynamic,p_stObstacle)) return FALSE;
}
else if (DNM_M_bDynamicsIsClimb(p_stDynamic))
{
if (!MEC_fn_bWallObstacle(p_stDynamic,p_stObstacle) ) return FALSE;
}
else if (!MEC_fn_bGroundObstacle (p_stDynamic,p_stObstacle)) return FALSE;
if (HIE_fn_bIsSuperObjectValid(hGeomSuperObject))
{
hObstacleSuperObject = MEC_fn_hGetFatherActor (hGeomSuperObject);
if (HIE_fn_bIsSuperObjectValid(hObstacleSuperObject))
{
if (fn_bStandardGameIsAPlatform(hObstacleSuperObject))
{
if (fn_bStandardGameIsAPlatform(hSupObj) /* && ( fn_ucCollSetGetColliderPrioritySO(hSupObj) < fn_ucCollSetGetColliderPrioritySO(hObstacleSuperObject) )*/ ) return FALSE;
if (MEC_fn_bIsPlatform(p_stDynamic))
{
if (DNM_M_hDynamicsGetPlatformSO(p_stDynamic)==hObstacleSuperObject) return FALSE;
MEC_fn_vCutPlatformLink (p_stDynamic,hSupObj);
MEC_fn_vSetPlatformLink (p_stDynamic,hSupObj,hObstacleSuperObject);
return TRUE;
}
MEC_fn_vSetPlatformLink (p_stDynamic,hSupObj,hObstacleSuperObject);
return TRUE;
}
}
}
}
if (MEC_fn_bIsPlatform(p_stDynamic))
{
MEC_fn_vCutPlatformLink (p_stDynamic,hSupObj);
return TRUE;
}
return FALSE;
}
void MEC_fn_vSetPlatformLink (struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj, HIE_tdxHandleToSuperObject hFatherSupObj)
{
if (DNM_M_bDynamicsIsLockPlatform (p_stDynamic)) return;
DNM_M_vDynamicsSetPlatformSO (p_stDynamic,hFatherSupObj);
HIE_M_vIsolate(hSupObj); /* make sure its current father is no longer there*/
HIE_fn_vSuperObjectAddTail(hFatherSupObj, hSupObj); /* this is not a platform, so addtail*/
}
void MEC_fn_vCutPlatformLink (struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj)
{
if (DNM_M_bDynamicsIsLockPlatform (p_stDynamic)) return;
HIE_fn_vInvalidateSuperObject (&DNM_M_hDynamicsGetPlatformSO (p_stDynamic));
fn_vReputCharacterSuperObjectAtTheWorld (hSupObj);
}
void MEC_fn_vForcePlatformLink (struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj, HIE_tdxHandleToSuperObject hFatherSupObj)
{
MEC_fn_vSetPlatformLink ( p_stDynamic, hSupObj, hFatherSupObj);
DNM_M_bDynamicsSetLockPlatform (p_stDynamic, TRUE);
}
void MEC_fn_vFreePlatformLink (struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj )
{
DNM_M_bDynamicsSetLockPlatform (p_stDynamic, FALSE);
MEC_fn_vCutPlatformLink ( p_stDynamic, hSupObj );
}
/* Compute dynamics matrix when father move */
/* Author bq: J Thénoz */
/* Date : 1998-01-22 */
/* Version : 1.b00 */
/* Modify : yyyy-mm-dd */
void MEC_fn_vDynamicComputeAbsoluteMatrix
(
struct DNM_stDynamics *p_stDynamic,
HIE_tdxHandleToSuperObject hSupObj,
POS_tdxHandleToPosition hPreviousMatrix,
POS_tdxHandleToPosition hInvPreviousMatrix,
POS_tdxHandleToPosition hCurrentMatrix
)
{
POS_tdstCompletePosition stMatrix;
POS_tdxHandleToPosition hMatrix;
POS_tdxHandleToPosition hPreviousDynamicMatrix, hCurrentDynamicMatrix;
MTH3D_tdstVector stVector;
MTH3D_tdstVector *p_stI, *p_stJ, *p_stK;
MTH3D_tdstVector *p_stContact;
hPreviousDynamicMatrix = DNM_M_p_stDynamicsGetPreviousMatrix (p_stDynamic);
hCurrentDynamicMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic);
/* compute hMatrix to pass from previous reference of the platform to the current reference */
hMatrix = (POS_tdxHandleToPosition)&stMatrix;
POS_fn_vMulMatrixMatrix (hMatrix, hCurrentMatrix, hInvPreviousMatrix);
/* compute Z of actor in platform reference */
p_stContact = DNM_M_pDynamicsGetContact (p_stDynamic);
POS_fn_vGetTranslationVector ( hCurrentDynamicMatrix, &stVector );
MTH3D_M_vSubVector (&stVector,&stVector,p_stContact);
MTH3D_M_vSetXofVector ( &stVector, MTH_C_ZERO );
MTH3D_M_vSetYofVector ( &stVector, MTH_C_ZERO );
/* compute previous and current matrix of the actor due to platform move */
POS_fn_vMulMatrixMatrix ( hPreviousDynamicMatrix, hMatrix, hPreviousDynamicMatrix );
POS_fn_vMulMatrixMatrix ( hCurrentDynamicMatrix, hMatrix, hCurrentDynamicMatrix );
/* if option 'stick on platform' is not active, we correct rotation matrix of actor because we wants him to stay vertical */
if (!DNM_M_bDynamicsIsStickOnPlatform(p_stDynamic) && !MEC_fn_bIsEqualRotationMatrix (hPreviousMatrix,hCurrentMatrix) )
{
POS_fn_vGetRotationVector ( hPreviousDynamicMatrix, &p_stI, &p_stJ, &p_stK );
MTH3D_M_vSetZofVector ( p_stJ, MTH_C_ZERO );
MTH3D_M_vNormalizeVector ( p_stJ, p_stJ );
MTH3D_M_vSetBaseKVector( p_stK );
MTH3D_M_vCrossProductVectorWithoutBuffer(p_stI, p_stJ, p_stK);
MTH3D_M_vNormalizeVector ( p_stI, p_stI );
MEC_fn_vUpdateMatrix ( p_stDynamic, hPreviousDynamicMatrix );
POS_fn_vGetRotationVector ( hCurrentDynamicMatrix, &p_stI, &p_stJ, &p_stK );
MTH3D_M_vSetZofVector ( p_stJ, MTH_C_ZERO );
MTH3D_M_vNormalizeVector ( p_stJ, p_stJ );
MTH3D_M_vSetBaseKVector( p_stK );
MTH3D_M_vCrossProductVectorWithoutBuffer(p_stI, p_stJ, p_stK);
MTH3D_M_vNormalizeVector ( p_stI, p_stI );
MEC_fn_vUpdateMatrix ( p_stDynamic, hCurrentDynamicMatrix );
}
/* Update object matrix */
POS_fn_vCopyMatrix ( HIE_fn_hGetSuperObjectGlobalMatrix (hSupObj), hCurrentDynamicMatrix );
HIE_fn_vComputeNewRelativeMatrix (hSupObj);
}