reman3/Rayman_X/cpa/tempgrp/Mgt/MGTMain.c

976 lines
35 KiB
C

/**********************************************************
* *
* Magnet *
* *
* Author : Ubi China - Marc Trabucato *
* *
**********************************************************/
#include "acp_base.h"
#define D_MSMagnet_StructureDefine
#include "MTH.h"
#include "GEO.h"
#include "GLI.h"
/*XB980506*/
/*#include "incGAM.h"*/
#include "mec.h"
#include "fil.h"
#include "snd.h"
#include "pcs.h"
#include "gld.h"
#include "lst.h"
#ifdef USE_IPT_DX5
#include "IPT_DX5.h" /* InPuT (absolutely before GAM.h)*/
#else /* USE_IPT_WIN */
#include "IPT.h" /* InPuT (absolutely before GAM.h)*/
#endif /* USE_IPT_WIN */
/*#include "srf.h"*/
/*#include "env.h"*/
#include "sct.h"
#include "prt.h"
#include "gam.h"
/*#include "incSPO.h"*/
#include "pos.h"
#include "spo.h"
/*#include "incIPO.h"*/
#include "po.h"
/*XB980821*/
#ifndef D_THROW_IPO
#include "ipo.h"
#endif /* D_THROW_IPO */
/*End XB*/
/*End XB*/
#include "COL.h"
#include "MGT\MGTStruc.h"
#include "MGTInit.h"
#include "MGTMain.h"
#include "MGTmm.h"
#include "MGTmo.h"
#ifdef MGT_RASTER
#include "MGTRast.h"
#endif
#define MGT_C_NoMoveDistanceSqr MTH_M_xFloatToReal( 0.04 )
EXTERN HIE_tdxHandleToSuperObject SECT_hFatherSector;
/*************************************************************************************************/
#define MGT_M_bIsSetBit( p_cTab , xIndex ) ( p_cTab[ xIndex >> 3 ] & ( 1 << (xIndex & 0x00000007) ) )
#define MGT_M_vSetBit( p_cTab , xIndex ) ( p_cTab[ xIndex >> 3 ] |= ( 1 << (xIndex & 0x00000007) ) )
#define MGT_M_vUnSetBit( p_cTab , xIndex ) ( p_cTab[ xIndex >> 3 ] &= ~((char)( 1 << (xIndex & 0x00000007) )) )
/*
INLINE
ACP_tdxBool MGT_M_bIsSetBit( char *p_cTab , ACP_tdxIndex xIndex )
{
ACP_tdxIndex xDiv , xMod;
xDiv = xIndex >> 3;
xMod = ( xIndex & 0x00000007 );
return ( p_cTab[ xDiv ] & ( 1 << xMod ) );
}
INLINE
void MGT_M_vSetBit( char *p_cTab , ACP_tdxIndex xIndex )
{
ACP_tdxIndex xDiv , xMod;
xDiv = xIndex >> 3;
xMod = ( xIndex & 0x00000007 );
p_cTab[ xDiv ] |= ( 1 << xMod );
}
INLINE
void MGT_M_vUnSetBit( char *p_cTab , ACP_tdxIndex xIndex )
{
ACP_tdxIndex xDiv , xMod;
char cValue;
xDiv = xIndex >> 3;
xMod = ( xIndex & 0x00000007 );
cValue = ~((char)( 1 << xMod ));
p_cTab[ xDiv ] &= cValue;
}
*/
/*
===================================================================================================
* The main loop in Game Engine to deal with magnet morph.
*
* QZY 1997.11.18
===================================================================================================
*/
void MGT_fn_vTreatMagnets(void)
{
ACP_tdxIndex xMagnetIndex , xObjectIndex;
HIE_tdxHandleToSuperObject *p_h_SOMagnet;
MS_tdxHandleToMSMagnet h_Magnet;
MTH3D_tdstVector *p_stPreviousPosition , stCurrentPosition , stMove;
MTH_tdxReal xDistance;
MGT_tdxHandleToModifiedObject *p_h_ModifiedObject;
MGT_tdxHandleToMagnetModification *p_h_MagnetModif;
ACP_tdxBool bObjectChanged ;
unsigned char ucStatus;
/* update list of influenced points*/
if( MGT_g_xMaxIndexOfModifiedObject )
{
MGT_fn_vInitTreatement();
}
for ( xMagnetIndex = 0 , p_h_SOMagnet = MGT_g_aDEF_hActivatedMagnets ;
xMagnetIndex < MGT_g_xMaxIndexOfActivatedMagnet ; xMagnetIndex++, p_h_SOMagnet++ )
{
h_Magnet = (*p_h_SOMagnet) ? M_GetMSHandle( (*p_h_SOMagnet), MSMagnet) : NULL ;
if( h_Magnet )
{
ucStatus = fn_lMSMagnetGetStatus( h_Magnet );
if( fn_bMSMagnetIsNearFarModified( h_Magnet ) )
{
POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( (*p_h_SOMagnet) ), & stCurrentPosition );
p_stPreviousPosition = fn_hMSMagnetGetPosition( h_Magnet );
MTH3D_M_vSubVector( & stMove , & stCurrentPosition , p_stPreviousPosition );
fn_vMSMagnetSetPosition( h_Magnet, & stCurrentPosition );
MGT_fn_vComputeInfluence( (*p_h_SOMagnet), h_Magnet, xMagnetIndex );
}
else
{
/* compute movement distance*/
switch( fn_lMSMagnetGetStatus( h_Magnet ) )
{
case MAGNETOFF:
case MAGNETRECOVERING:
fn_vMSMagnetSetPositionModification( h_Magnet, FALSE );
MGT_fn_vUpdateInfluence( h_Magnet , FALSE );
MGT_fn_vSetMagnetModificationUse( h_Magnet , TRUE );
break;
case MAGNETON:
case MAGNETGROWING:
POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( (*p_h_SOMagnet) ), & stCurrentPosition );
p_stPreviousPosition = fn_hMSMagnetGetPosition( h_Magnet );
MTH3D_M_vSubVector( & stMove , & stCurrentPosition , p_stPreviousPosition );
xDistance = MTH3D_M_xSqrVector( & stMove );
if( MTH_M_bGreater( xDistance , MGT_C_NoMoveDistanceSqr ) )
{
fn_vMSMagnetSetPosition( h_Magnet, & stCurrentPosition );
fn_vMSMagnetSetPositionModification( h_Magnet, TRUE );
MGT_fn_vComputeInfluence( (*p_h_SOMagnet), h_Magnet, xMagnetIndex );
}
else
{
fn_vMSMagnetSetPositionModification( h_Magnet, FALSE );
MGT_fn_vSetMagnetModificationUse( h_Magnet , TRUE );
}
break;
}
}
}
}
if( MGT_g_xMaxIndexOfModifiedObject )
{
MGT_fn_vEndTreatement();
}
/* compute influence*/
for( xObjectIndex = 0 , p_h_ModifiedObject = MGT_g_aDEF_hModifiedObjects ;
xObjectIndex < MGT_g_xMaxIndexOfModifiedObject ;
xObjectIndex++, p_h_ModifiedObject++ )
{
if( *p_h_ModifiedObject )
{
bObjectChanged = FALSE;
for( xMagnetIndex = 0 , p_h_MagnetModif = (*p_h_ModifiedObject) -> aDEF_hMagnet ;
xMagnetIndex < MGT_MAX_NUMBEROF_MAGNETS ;
xMagnetIndex++, p_h_MagnetModif++ )
{
if( *p_h_MagnetModif )
{
if( MGT_fn_bMorphMagnetModif( *p_h_MagnetModif ) )
bObjectChanged = TRUE;
}
}
if( bObjectChanged )
{
GEO_vEndModifyObject2( (*p_h_ModifiedObject) -> p_stMorphedObject );
}
}
}
if( MGT_g_xMaxIndexOfModifiedObject )
{
/* recompute bounding volume*/
MGT_fn_bUpdateBoundingVolume();
/* update ModifiedObjects List*/
MGT_fn_vUpdateModifiedObjectsList();
}
/**/
if( MGT_g_xMaxIndexOfActivatedMagnet )
{
/* update MSMagnet List*/
MGT_fn_vUpdateActivatedMagnetsList();
}
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vInitTreatement( void )
{
ACP_tdxIndex xIndex , xIndexMagnet;
MGT_tdxHandleToModifiedObject *p_h_ModifiedObject;
MGT_tdxHandleToMagnetModification *p_h_MagnetModif;
for( xIndex = 0 , p_h_ModifiedObject = MGT_g_aDEF_hModifiedObjects ;
xIndex < MGT_g_xMaxIndexOfModifiedObject ;
xIndex++, p_h_ModifiedObject++ )
{
if( *p_h_ModifiedObject )
{
MGT_fn_vClearAlreadyInfluencedPointsOfModifiedObject( *p_h_ModifiedObject );
for ( xIndexMagnet = 0 , p_h_MagnetModif = (*p_h_ModifiedObject) -> aDEF_hMagnet ;
xIndexMagnet < MGT_MAX_NUMBEROF_MAGNETS ; xIndexMagnet++, p_h_MagnetModif++ )
{
if( (*p_h_MagnetModif) )
(*p_h_MagnetModif) -> bUsed = FALSE;
}
}
}
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vEndTreatement( void )
{
ACP_tdxIndex xIndex , xIndexMagnet;
MGT_tdxHandleToModifiedObject *p_h_ModifiedObject;
MGT_tdxHandleToMagnetModification *p_h_MagnetModif;
for( xIndex = 0 , p_h_ModifiedObject = MGT_g_aDEF_hModifiedObjects ;
xIndex < MGT_g_xMaxIndexOfModifiedObject ;
xIndex++, p_h_ModifiedObject++ )
{
if( *p_h_ModifiedObject )
{
MGT_fn_vClearAlreadyInfluencedPointsOfModifiedObject( *p_h_ModifiedObject );
for ( xIndexMagnet = 0 , p_h_MagnetModif = (*p_h_ModifiedObject) -> aDEF_hMagnet ;
xIndexMagnet < MGT_MAX_NUMBEROF_MAGNETS ; xIndexMagnet++, p_h_MagnetModif++ )
{
if( (*p_h_MagnetModif) )
{
if( (*p_h_MagnetModif) -> bUsed )
break;
else
MGT_fn_vDeleteMagnetModification( *p_h_MagnetModif );
}
}
if( xIndexMagnet == MGT_MAX_NUMBEROF_MAGNETS )
MGT_fn_vDeleteModifiedObjectIfNeeded( xIndex );
}
}
}
/*=======================================================================================
* Description compute the influence of magnet in all static objects
*
* Creation date 01/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vComputeInfluence( HIE_tdxHandleToSuperObject h_SO , MS_tdxHandleToMSMagnet h_Magnet , ACP_tdxIndex x_Magnet )
{
/* init influence*/
ACP_tdxIndex xIndex;
MTH_tdxReal xFar, xFarFar;
MS_tdxHandleToSectInfo hSectInfo;
HIE_tdxHandleToSuperObject h_SOSector;
SECT_tdxHandleOfElementLstCollisionInteraction hCollisionList;
MGT_fn_vUpdateInfluence( h_Magnet , TRUE );
MGT_fn_vSetMagnetModificationUse( h_Magnet , FALSE );
xFar = fn_xMSMagnetGetFar( h_Magnet );
xFarFar = MTH_M_xSqr( xFar );
MGT_fn_vClearMagnetModificationFlagInHierarchy( SECT_hFatherSector );
hSectInfo = M_GetMSHandle( h_SO , SectInfo );
h_SOSector = fn_h_SectInfoGetCurrentSector( hSectInfo );
/* call recurse influence on Current sector*/
MGT_fn_bComputeInfluenceOnSuperObject( h_Magnet, x_Magnet, xFarFar, h_SOSector );
/* call recurse influence on collisionable sectors*/
SECT_M_ForEachCollisionNodeInCollisionInteractionList( h_SOSector, hCollisionList, xIndex )
{
h_SOSector = SECT_GetSectorInCollisionList( hCollisionList );
MGT_fn_bComputeInfluenceOnSuperObject( h_Magnet, x_Magnet, xFarFar, h_SOSector );
}
/* update MSMagnet*/
for( xIndex = 0 ; xIndex < MGT_MAX_NUMBEROF_MODIFIEDOBJECTS ; xIndex++ )
{
if( fn_hMSMagnetGetMagnetModification( h_Magnet, xIndex ) )
{
break;
}
}
if( ( xIndex == MGT_MAX_NUMBEROF_MODIFIEDOBJECTS ) && (fn_lMSMagnetGetStatus( h_Magnet ) == MAGNETRECOVERING) )
{
fn_vMSMagnetSetStatus( h_Magnet, MAGNETOFF);
/* delete the magnet from the active magnet list.*/
MGT_fn_vDeleteMagnetFromMagnetList( x_Magnet );
}
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
ACP_tdxIndex MGT_fn_bComputeInfluenceOnSuperObject( MS_tdxHandleToMSMagnet h_Magnet , ACP_tdxIndex x_Magnet , MTH_tdxReal xFarFar, HIE_tdxHandleToSuperObject h_SuperObject )
{
GEO_tdstGeometricObject *p_stObject;
HIE_tdxHandleToSuperObject h_Child;
ACP_tdxIndex xIndex;
POS_tdxHandleToPosition hMatrix;
POS_tdstCompletePosition stMatrix;
MTH3D_tdstVector stMagnetLocalPosition, *p_stPosition;
MTH_tdxReal xRadius;
ACP_tdxIndex x_ModifiedObject;
ACP_tdxBool bObjectModified , bIntersectBdV, bBoxVolume;
GEO_tdxHandleToParallelBox hBoxVolume;
GEO_tdxHandleToBoundingSphere hSphereVolume;
MTH3D_tdstVector stMaxBoxPoint , stMinBoxPoint , stCenter;
/* compute influence on the SO*/
bIntersectBdV = TRUE;
bObjectModified = FALSE;
p_stObject = HIE_fn_p_stGetGeometricObjectFromSuperObject( h_SuperObject );
if( p_stObject )
{
bBoxVolume = HIE_fn_SO_bHasABoxBoundingVolume( h_SuperObject );
x_ModifiedObject = MGT_fn_xFindModifiedObject( p_stObject );
bObjectModified = FALSE;
hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( h_SuperObject );
p_stPosition = fn_hMSMagnetGetPosition( h_Magnet );
/**/
/* take account Bounding Box of SO*/
if( bBoxVolume )
{
hBoxVolume = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume( h_SuperObject );
if( hBoxVolume )
{
MTH3D_M_vAddVector( & stMaxBoxPoint, & hMatrix -> stTranslationVector, GEO_fn_pGetMaxPointOfParallelBox( hBoxVolume ) );
MTH3D_M_vAddVector( & stMinBoxPoint, & hMatrix -> stTranslationVector, GEO_fn_pGetMinPointOfParallelBox( hBoxVolume ) );
bIntersectBdV = INT_fn_bIntersectSphereWithBox( p_stPosition, fn_xMSMagnetGetFar( h_Magnet ), & stMinBoxPoint, & stMaxBoxPoint );
}
if( bIntersectBdV )
{
POS_fn_vInvertMatrix( & stMatrix , hMatrix );
POS_fn_vMulMatrixVertex( & stMagnetLocalPosition , & stMatrix , p_stPosition );
}
}
else
{
hSphereVolume = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume( h_SuperObject );
POS_fn_vInvertMatrix( & stMatrix , hMatrix );
POS_fn_vMulMatrixVertex( & stMagnetLocalPosition , & stMatrix , p_stPosition );
if( hSphereVolume )
{
MTH3D_M_vCopyVector(&stCenter, GEO_fn_pGetCenterPointOfBoundingSphere(hSphereVolume));
xRadius = GEO_fn_xGetRadiusOfBoundingSphere(hSphereVolume);
bIntersectBdV = INT_fn_bIntersectSphereWithSphere( & stMagnetLocalPosition, fn_xMSMagnetGetFar( h_Magnet ), & stCenter , xRadius );
}
}
if( bIntersectBdV )
{
bObjectModified = MGT_fn_bComputeInfluenceOnObject( x_Magnet, xFarFar, p_stObject , &x_ModifiedObject, & stMagnetLocalPosition , h_SuperObject );
if( bObjectModified )
{
HIE_fn_vSetMagnetModification( h_SuperObject, TRUE );
}
}
if( (x_ModifiedObject != MGT_C_xIndexError) && ! bObjectModified && ( fn_lMSMagnetGetStatus( h_Magnet ) == MAGNETRECOVERING ) )
{
MGT_fn_hDeleteIfExistsMagnetModification( x_ModifiedObject, x_Magnet );
}
}
if( bIntersectBdV )
{
/* node examination*/
HIE_M_ForEachChildOf(h_SuperObject, h_Child, xIndex)
{
/* recurence*/
bObjectModified |= MGT_fn_bComputeInfluenceOnSuperObject( h_Magnet , x_Magnet , xFarFar, h_Child );
}
}
HIE_fn_vSetMagnetModification( h_SuperObject, bObjectModified );
return bObjectModified;
}
/*=======================================================================================
* Description
*
* Creation date 01/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vClearMagnetModificationFlagInHierarchy( HIE_tdxHandleToSuperObject h_SuperObject )
{
HIE_tdxHandleToSuperObject h_Child;
ACP_tdxIndex xIndex;
HIE_fn_vSetMagnetModification( h_SuperObject, FALSE );
HIE_M_ForEachChildOf(h_SuperObject, h_Child, xIndex)
{
/* recurence*/
MGT_fn_vClearMagnetModificationFlagInHierarchy( h_Child);
}
}
/*=======================================================================================
* Description
*
* Creation date 01/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_bUpdateBoundingVolume( void )
{
HIE_tdxHandleToSuperObject h_Child;
ACP_tdxIndex xIndex;
HIE_M_ForEachChildOf(SECT_hFatherSector, h_Child, xIndex)
{
if( HIE_fn_bGetMagnetModification( h_Child ) )
MGT_fn_vRecurUpdateBoundingVolumeInHierarchy( h_Child );
}
}
/*=======================================================================================
* Description
*
* Creation date 01/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vRecurUpdateBoundingVolumeInHierarchy( HIE_tdxHandleToSuperObject h_SuperObject )
{
HIE_tdxHandleToSuperObject h_Child;
ACP_tdxIndex xIndex;
GEO_tdstGeometricObject * hGeometricObject;
GEO_tdxHandleToParallelBox hBdVBoxFather;
GEO_tdxHandleToBoundingSphere hBdVSphereFather;
MTH3D_tdstVector * p_stGlobalMaxBoxPointFather, *p_stGlobalMinBoxPointFather , stSphereCenterFather;
ACP_tdxBool bBdVIsABox;
MTH_tdxReal xRadiusFather;
GEO_tdxHandleToMatrix hGlobalMatrix;
if( ! HIE_fn_bGetMagnetModification( h_SuperObject ) )
return;
/* current*/
/**/
hGeometricObject = HIE_fn_p_stGetGeometricObjectFromSuperObject( h_SuperObject );
hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( h_SuperObject );
bBdVIsABox = HIE_fn_SO_bHasABoxBoundingVolume( h_SuperObject );
/* add local bounding volume*/
/* compute local bounding volume*/
if( bBdVIsABox )
{
hBdVBoxFather = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume( h_SuperObject );
hBdVSphereFather = NULL;
if( hBdVBoxFather )
{
p_stGlobalMaxBoxPointFather = GEO_fn_pGetMaxPointOfParallelBox( hBdVBoxFather );
p_stGlobalMinBoxPointFather = GEO_fn_pGetMinPointOfParallelBox( hBdVBoxFather );
if( hGeometricObject )
{
MTH3D_tdstVector stLocalMaxBoxPoint, stLocalMinBoxPoint;
MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, hGeometricObject->d_stListOfPoints);
MTH3D_M_vCopyVector(&stLocalMinBoxPoint, hGeometricObject->d_stListOfPoints);
MTH3D_M_vMulMatrixVector( p_stGlobalMaxBoxPointFather, &hGlobalMatrix->stTransformMatrix, &stLocalMaxBoxPoint);
MTH3D_M_vMulMatrixVector( p_stGlobalMinBoxPointFather, &hGlobalMatrix->stTransformMatrix, &stLocalMinBoxPoint);
GEO_fn_vAddObjectToBox(hGeometricObject, hGlobalMatrix, p_stGlobalMaxBoxPointFather, p_stGlobalMinBoxPointFather);
}
else
{
/* init bdv*/
MTH3D_M_vNullVector( p_stGlobalMaxBoxPointFather );
MTH3D_M_vNullVector( p_stGlobalMinBoxPointFather );
}
}
}
else
{
hBdVSphereFather = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume( h_SuperObject );
hBdVBoxFather = NULL;
if( hBdVSphereFather )
{
MTH3D_M_vCopyVector(&stSphereCenterFather, GEO_fn_pGetCenterPointOfBoundingSphere(hBdVSphereFather));
xRadiusFather = GEO_fn_xGetRadiusOfBoundingSphere(hBdVSphereFather);
if( hGeometricObject )
{
GEO_fn_vAddObjectToSphere(hGeometricObject, &stSphereCenterFather , & xRadiusFather );
}
else
{
/* init bdv*/
MTH3D_M_vNullVector( & stSphereCenterFather );
xRadiusFather = MTH_C_ZERO;
}
}
}
HIE_M_ForEachChildOf(h_SuperObject, h_Child, xIndex)
{
/* compute bounding volume of child chil*/
MGT_fn_vRecurUpdateBoundingVolumeInHierarchy( h_Child );
/*
Now, the bounding volume of a SuperObject doesn't take account the bounding volume of children
// recompute Bounding volume with children
if( hBdVBoxFather || hBdVSphereFather )
{
// take account this bouding volume
hLocalMatrix = HIE_fn_hGetSuperObjectMatrix( h_Child );
POS_fn_vGetTranslationVector( hLocalMatrix, &stTranslation );
if( HIE_fn_SO_bHasABoxBoundingVolume( h_Child ) )
{
// Child has a Box as Bounding Volume
GEO_tdxHandleToParallelBox hBdVBox;
MTH3D_tdstVector *p_stGlobalMaxBoxPoint, *p_stGlobalMinBoxPoint;
MTH3D_tdstVector stLocalMaxBoxPoint, stLocalMinBoxPoint;
hBdVBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoxBoundingVolume( h_Child );
if( hBdVBox )
{
p_stGlobalMaxBoxPoint = GEO_fn_pGetMaxPointOfParallelBox( hBdVBox );
p_stGlobalMinBoxPoint = GEO_fn_pGetMinPointOfParallelBox( hBdVBox );
// translate points to father axis
MTH3D_M_vAddVector( &stLocalMaxBoxPoint, p_stGlobalMaxBoxPoint, &stTranslation );
MTH3D_M_vAddVector( &stLocalMinBoxPoint, p_stGlobalMinBoxPoint, &stTranslation );
if( bBdVIsABox )
{
// Father has a Box as Bounding Volume
// Box = Box + Box
GEO_fn_vComputeParallelBoxOfTwoBoxes( p_stGlobalMaxBoxPointFather, p_stGlobalMinBoxPointFather,
& stLocalMaxBoxPoint, & stLocalMinBoxPoint,
p_stGlobalMaxBoxPointFather, p_stGlobalMinBoxPointFather );
}
else
{
// Father has a Sphere as Bounding Volume
// Sphere = Sphere + Box
MTH3D_tdstVector stSphereCenter;
MTH_tdxReal xRadius;
GEO_fn_vGetSphereFromParallelBox( & stSphereCenter , &xRadius, & stLocalMaxBoxPoint, & stLocalMinBoxPoint );
GEO_fn_vComputeBoundingSphereOfTwoSpheres( & stSphereCenterFather , & xRadiusFather,
& stSphereCenterFather , xRadiusFather,
& stSphereCenter , xRadius );
}
}
}
else
{
// Child has a Sphere as Bounding Volume
ACP_tdxHandleOfObject hBdVSphere;
MTH3D_tdstVector stSphereCenter;
MTH_tdxReal xRadius;
hBdVSphere = HIE_fn_hGetSuperObjectBoundingVolume( h_Child );
if( hBdVSphere )
{
GEO_fn_vGetSphereFromBoundingVolume( & stSphereCenter , &xRadius , hBdVSphere );
// translate sphere to father axis
MTH3D_M_vAddVector( & stSphereCenter, & stSphereCenter, & stTranslation );
if( bBdVIsABox )
{
// Father has a Box as Bounding Volume
// Box = Box + Sphere
COL_fn_vComputeBoundingBoxOfSphereAndBox ( p_stGlobalMinBoxPointFather, p_stGlobalMaxBoxPointFather,
& stSphereCenter , xRadius ,
p_stGlobalMinBoxPointFather, p_stGlobalMaxBoxPointFather );
}
else
{
// Father has a Sphere as Bounding Volume
// Sphere = Sphere + Sphere
GEO_fn_vComputeBoundingSphereOfTwoSpheres( & stSphereCenterFather , & xRadiusFather,
& stSphereCenterFather , xRadiusFather,
& stSphereCenter , xRadius );
}
}
}
if( ! bBdVIsABox )
{
GEO_fn_vSetSphereToBoundingVolume( & stSphereCenterFather, xRadiusFather, hBdVSphereFather);
}
}
*/
}
}
/*=======================================================================================
* Description
*
* Creation date 01/03/98
* Author Marc Trabucato
*=====================================================================================*/
ACP_tdxBool MGT_fn_bComputeInfluenceOnObject( ACP_tdxIndex x_Magnet, MTH_tdxReal xFarFar, GEO_tdstGeometricObject *p_stObject ,
ACP_tdxIndex *p_x_ModifiedObject ,
MTH3D_tdstVector *p_stMagnetPosition , HIE_tdxHandleToSuperObject h_SuperObject )
{
ACP_tdxIndex xIndexPoint;
MTH3D_tdstVector *p_stCurrentPoint, stVect;
MTH_tdxReal xDX , xTemp;
MGT_tdxHandleToMagnetModification h_MagnetModif;
ACP_tdxBool bObjectModified;
bObjectModified = FALSE;
h_MagnetModif = NULL;
for ( xIndexPoint = 0 , p_stCurrentPoint = p_stObject -> d_stListOfPoints ; xIndexPoint < p_stObject -> xNbPoints ; xIndexPoint++, p_stCurrentPoint++ )
{
MTH3D_M_vSubVector( &stVect , p_stMagnetPosition, p_stCurrentPoint );
xDX = MTH_M_xSqr( stVect . xX );
if (MTH_M_bLess( xDX, xFarFar ))
{
xTemp = MTH_M_xSqr( stVect . xY );
xDX = MTH_M_xAdd( xDX, xTemp );
if (MTH_M_bLess( xDX, xFarFar ))
{
xTemp = MTH_M_xSqr( stVect . xZ );
xDX = MTH_M_xAdd( xDX, xTemp );
if (MTH_M_bLess( xDX, xFarFar ))
{
/* the point is modified*/
if( h_MagnetModif == NULL )
{
/* new object modified*/
if( *p_x_ModifiedObject == MGT_C_xIndexError )
*p_x_ModifiedObject = MGT_fn_xCreateModifiedObject( p_stObject );
h_MagnetModif = MGT_fn_hFindOrAddMagnetModification( x_Magnet , *p_x_ModifiedObject , p_stObject );
if( h_MagnetModif )
{
h_MagnetModif -> h_SuperObject = h_SuperObject;
h_MagnetModif -> bUsed = TRUE;
bObjectModified = TRUE;
}
}
if( h_MagnetModif )
{
MGT_M_vSetBit( h_MagnetModif -> d_cFieldBitsModifiedPoints , xIndexPoint );
MGT_M_vSetBit( h_MagnetModif -> d_cFieldBitsInfluencedPoints , xIndexPoint );
}
}
}
}
}
return bObjectModified;
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vUpdateInfluence( MS_tdxHandleToMSMagnet h_Magnet, ACP_tdxBool bRecompute )
{
ACP_tdxIndex xIndex;
MGT_tdxHandleToMagnetModification h_MagnetModif;
for ( xIndex = 0 ; xIndex < MGT_MAX_NUMBEROF_MODIFIEDOBJECTS ; xIndex++ )
{
h_MagnetModif = fn_hMSMagnetGetMagnetModification( h_Magnet ,xIndex );
if( h_MagnetModif )
{
MGT_fn_vClearInfluencedPointsOfMagnetModification( h_MagnetModif );
}
}
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vSetMagnetModificationUse( MS_tdxHandleToMSMagnet h_Magnet, ACP_tdxBool bUse )
{
ACP_tdxIndex xIndex;
MGT_tdxHandleToMagnetModification h_MagnetModif;
for ( xIndex = 0 ; xIndex < MGT_MAX_NUMBEROF_MODIFIEDOBJECTS ; xIndex++ )
{
h_MagnetModif = fn_hMSMagnetGetMagnetModification( h_Magnet ,xIndex );
if( h_MagnetModif )
{
h_MagnetModif -> bUsed = bUse;
}
}
}
/*=======================================================================================
* Description compute the influence of magnet in all static objects
*
* Creation date 01/03/98
* Author Marc Trabucato
*=====================================================================================*/
ACP_tdxBool MGT_fn_bMorphMagnetModif( MGT_tdxHandleToMagnetModification h_MagnetModif )
{
ACP_tdxIndex xIndexPoint;
GEO_tdstGeometricObject *h_Object;
POS_tdxHandleToPosition hMatrix;
POS_tdstCompletePosition stMatrix;
MTH3D_tdstVector stMagnetLocalPosition, *p_stPosition;
MS_tdxHandleToMSMagnet h_Magnet;
MTH_tdxReal xNear , xFar , xStrength , xInvFarMinusNear , xInvFrames;
ACP_tdxBool bChanged , bUnsetPoint , bMagnetModified , bGrowing;
unsigned long ulFrameDuration , *p_ulCurrentDuration;
MTH3D_tdstVector *p_stOriginalPosition , *p_stCurrentPosition;
MGT_tdxHandleToModifiedObject h_ModifiedObject;
char *p_cFieldBitsOfAlreadyInfluencedPoints;
/**/
if( ( h_MagnetModif == NULL ) || ! MGT_fn_bIsExistModifiedPointsOnMagnetModification( h_MagnetModif ) )
return FALSE;
/**/
h_ModifiedObject = MGT_g_aDEF_hModifiedObjects[ h_MagnetModif -> xIndexOfModifiedObject ];
p_cFieldBitsOfAlreadyInfluencedPoints = h_ModifiedObject -> d_cFieldBitsAlreadyInfluencedPoints;
ulFrameDuration = g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime;
h_Object = h_ModifiedObject -> p_stMorphedObject;
if( MGT_g_aDEF_hActivatedMagnets[ h_MagnetModif -> xIndexOfActivatedMagnet ] == NULL )
{
for ( xIndexPoint = 0 , p_ulCurrentDuration = h_MagnetModif -> d_ulCurrentDuration , p_stOriginalPosition = h_ModifiedObject -> d_stOriginalPosition , p_stCurrentPosition = h_Object -> d_stListOfPoints ;
xIndexPoint < h_Object -> xNbPoints ;
xIndexPoint++, p_ulCurrentDuration++, p_stOriginalPosition++, p_stCurrentPosition++ )
{
if( MGT_M_bIsSetBit( h_MagnetModif -> d_cFieldBitsModifiedPoints , xIndexPoint ) /* the point is modified, recompute influence*/
&& ! MGT_M_bIsSetBit( h_MagnetModif -> d_cFieldBitsInfluencedPoints , xIndexPoint ) /* the point is currently not influenced by the magnet*/
&& ((*p_ulCurrentDuration) > 0)
)
{
(*p_ulCurrentDuration) -= ( (*p_ulCurrentDuration) >= ulFrameDuration ) ? ulFrameDuration : (*p_ulCurrentDuration);
MGT_fn_vComputePreviousPosition( h_MagnetModif, xIndexPoint, p_cFieldBitsOfAlreadyInfluencedPoints,
(*p_ulCurrentDuration) , ulFrameDuration ,
p_stOriginalPosition , p_stCurrentPosition );
bChanged = TRUE;
if( (*p_ulCurrentDuration) == 0 )
{
MGT_M_vUnSetBit( h_MagnetModif -> d_cFieldBitsModifiedPoints , xIndexPoint );
bUnsetPoint = TRUE;
}
}
}
}
else if( h_Magnet = M_GetMSHandle( MGT_g_aDEF_hActivatedMagnets[ h_MagnetModif -> xIndexOfActivatedMagnet ], MSMagnet)) /* volontary assignment*/
{
bGrowing = FALSE;
xFar = fn_xMSMagnetGetFar(h_Magnet);
xNear = fn_xMSMagnetGetNear(h_Magnet);
xStrength = fn_xMSMagnetGetStrength(h_Magnet);
xInvFarMinusNear = MTH_M_xSub( xFar , xNear );
bMagnetModified = fn_bMSMagnetIsNearFarModified (h_Magnet) ||
fn_bMSMagnetIsStrengthModified(h_Magnet) ||
fn_bMSMagnetIsPositionModified(h_Magnet);
if( MTH_M_bDifferentZero( xInvFarMinusNear ) )
xInvFarMinusNear = MTH_M_xInv( xInvFarMinusNear );
else
xInvFarMinusNear = MTH_C_ONE;
xInvFrames = MTH_M_xInv( (float)(h_Magnet -> ulDuration) );
hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( h_MagnetModif -> h_SuperObject );
POS_fn_vInvertMatrix( & stMatrix , hMatrix );
p_stPosition = fn_hMSMagnetGetPosition( h_Magnet );
POS_fn_vMulMatrixVertex( & stMagnetLocalPosition , & stMatrix , p_stPosition );
h_Object = h_ModifiedObject -> p_stMorphedObject;
bChanged = FALSE;
bUnsetPoint = FALSE;
for ( xIndexPoint = 0 , p_ulCurrentDuration = h_MagnetModif -> d_ulCurrentDuration , p_stOriginalPosition = h_ModifiedObject -> d_stOriginalPosition , p_stCurrentPosition = h_Object -> d_stListOfPoints ;
xIndexPoint < h_Object -> xNbPoints ;
xIndexPoint++, p_ulCurrentDuration++, p_stOriginalPosition++, p_stCurrentPosition++ )
{
if( MGT_M_bIsSetBit( h_MagnetModif -> d_cFieldBitsModifiedPoints , xIndexPoint ) )
{
/* the point is modified, recompute influence*/
if( MGT_M_bIsSetBit( h_MagnetModif -> d_cFieldBitsInfluencedPoints , xIndexPoint ) )
{
/* the point is currently influenced by the magnet*/
if( ((*p_ulCurrentDuration) < h_Magnet -> ulDuration) || bMagnetModified )
{
(*p_ulCurrentDuration) += ulFrameDuration;
if( (*p_ulCurrentDuration) > h_Magnet -> ulDuration )
{
(*p_ulCurrentDuration) = h_Magnet -> ulDuration;
}
MGT_fn_vComputeNewPosition( h_MagnetModif, xIndexPoint, p_cFieldBitsOfAlreadyInfluencedPoints, (*p_ulCurrentDuration) ,
p_stOriginalPosition , p_stCurrentPosition , p_stPosition ,
xNear , xStrength , xInvFarMinusNear , xInvFrames);
bChanged = TRUE;
}
}
else
{
/* the point is currently not influenced by the magnet*/
if( (*p_ulCurrentDuration) > 0 )
{
(*p_ulCurrentDuration) -= ( (*p_ulCurrentDuration) >= ulFrameDuration ) ? ulFrameDuration : (*p_ulCurrentDuration);
MGT_fn_vComputePreviousPosition( h_MagnetModif, xIndexPoint, p_cFieldBitsOfAlreadyInfluencedPoints,
(*p_ulCurrentDuration) , ulFrameDuration ,
p_stOriginalPosition , p_stCurrentPosition );
bChanged = TRUE;
if( (*p_ulCurrentDuration) == 0 )
{
MGT_M_vUnSetBit( h_MagnetModif -> d_cFieldBitsModifiedPoints , xIndexPoint );
bUnsetPoint = TRUE;
}
}
}
}
}
}
else
return FALSE;
if( bUnsetPoint && ! MGT_fn_bIsExistModifiedPointsOnMagnetModification( h_MagnetModif ) )
{
MGT_fn_vDeleteMagnetModification( h_MagnetModif );
}
return bChanged;
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vComputeNewPosition( MGT_tdxHandleToMagnetModification h_MagnetModif , ACP_tdxIndex xIndexPoint, char *p_cFieldBitAlreadyInfluenced, unsigned long ulCurrentDuration ,
MTH3D_tdstVector *p_stInitialPosition , MTH3D_tdstVector *p_stCurrentPosition , MTH3D_tdstVector *p_stMagnetPosition ,
MTH_tdxReal xNear , MTH_tdxReal xStrength , MTH_tdxReal xInvFarMinusNear , MTH_tdxReal xInvFrames)
{
MTH_tdxReal xDistance , xFrameRatio, xRatio;
MTH3D_tdstVector stVect , stVectA , stVectB ;
xFrameRatio = MTH_M_xMul( (MTH_tdxReal)ulCurrentDuration , xInvFrames ) ;
MTH3D_M_vSubVector( & stVect , p_stMagnetPosition, p_stInitialPosition );
xDistance = MTH3D_M_xNormVector( & stVect );
MTH3D_M_vNormalizeVector( & stVectB, & stVect );
if( MTH_M_bLess( xDistance , xNear) )
{
if( MTH_M_bLess( xDistance , xStrength ) )
xRatio = MTH_M_xMul( xFrameRatio , xDistance );
else
xRatio = MTH_M_xMul( xFrameRatio , xStrength );
}
else
{
xRatio = MTH_M_xSub( xDistance, xNear );
xRatio = MTH_M_xMul( xRatio, xInvFarMinusNear );
xRatio = MTH_M_xSub( MTH_C_ONE, xRatio );
xRatio = MTH_M_xMul( xRatio, xStrength );
xRatio = MTH_M_xMul( xRatio, xFrameRatio );
}
MTH3D_M_vMulScalarVector( & stVectA, xRatio, & stVectB);
if( MGT_M_bIsSetBit( p_cFieldBitAlreadyInfluenced , xIndexPoint ) )
{
/* the point isn't already influenced by another magnet, uses the initial value*/
MTH3D_M_vAddVector ( & stVectB , p_stInitialPosition , & stVectA );
MTH3D_M_vMiddleVector( p_stCurrentPosition , p_stCurrentPosition, & stVectB );
}
else
{
/* the point is already influenced by another magnet, uses the modified value*/
MTH3D_M_vAddVector( p_stCurrentPosition , p_stInitialPosition , & stVectA );
MGT_M_vSetBit( p_cFieldBitAlreadyInfluenced , xIndexPoint );
}
}
/*=======================================================================================
* Description
*
* Creation date 02/03/98
* Author Marc Trabucato
*=====================================================================================*/
void MGT_fn_vComputePreviousPosition( MGT_tdxHandleToMagnetModification h_MagnetModif , ACP_tdxIndex xIndexPoint, char *p_cFieldBitAlreadyInfluenced,
unsigned long ulCurrentDuration , unsigned long ulDecreaseDuration ,
MTH3D_tdstVector *p_stInitialPosition , MTH3D_tdstVector *p_stCurrentPosition)
{
MTH_tdxReal xFrameRatio;
MTH3D_tdstVector stVect , stVectA , stVectB ;
/* compute previous deformation*/
MTH3D_M_vSubVector( & stVect, p_stCurrentPosition, p_stInitialPosition );
/* compute previous to current ratio*/
xFrameRatio = MTH_M_xFloatToReal( ((float)ulCurrentDuration) / ((float)(ulCurrentDuration+ulDecreaseDuration)) );
/* compute current deformation*/
MTH3D_M_vMulScalarVector( & stVectA, xFrameRatio, & stVect );
if( MGT_M_bIsSetBit( p_cFieldBitAlreadyInfluenced , xIndexPoint ) )
{
/* the point is already influenced by another magnet, uses the initial value*/
MTH3D_M_vAddVector ( & stVectB , p_stInitialPosition , & stVectA );
MTH3D_M_vMiddleVector( p_stCurrentPosition , p_stCurrentPosition, & stVectB );
}
else
{
/* the point isn't already influenced by another magnet, uses the modified value*/
MTH3D_M_vAddVector( p_stCurrentPosition , p_stInitialPosition , & stVectA );
MGT_M_vSetBit( p_cFieldBitAlreadyInfluenced , xIndexPoint );
}
}