969 lines
31 KiB
C
969 lines
31 KiB
C
/*ANNECY CB Attention, tout a été modifié dans ce fichier !!!*/
|
|
|
|
#include "ACP_base.h"
|
|
#include "GMT.h"
|
|
#include "GEO.h"
|
|
#include "GLI.h"
|
|
#include "PCS.h"
|
|
#include "COL.h"
|
|
#include "lst.h"
|
|
#include "PO.h"
|
|
|
|
#include "FIL.h"
|
|
#include "snd.h"
|
|
#include "gld.h"
|
|
#include "mec.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 "sct.h"
|
|
#ifndef D_THROW_PRT
|
|
#include "PRT.h"
|
|
#endif /* D_THROW_PRT */
|
|
#include "gam.h"
|
|
#include "tmr.h"
|
|
/*XB980821*/
|
|
#ifndef D_THROW_IPO
|
|
#include "IPO.h"
|
|
#endif /* D_THROW_IPO */
|
|
/*End XB*/
|
|
#undef extern
|
|
|
|
#include "SPO/HieConst.h"
|
|
#include "LST.h"
|
|
#include "SPO/HieSpObj.h"
|
|
#include "SPO/HieHand.h"
|
|
#include "SPO/HieDef.h"
|
|
#include "SPO/HieMacro.h"
|
|
#include "SPO/HieMtStk.h"
|
|
#include "SPO/HieExt.h"
|
|
#include "SPO/HiePick.h"
|
|
/*HP 180698*/
|
|
|
|
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
|
|
MTH_tdxReal VoidReal;
|
|
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
|
|
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
|
|
ACP_tdxHandleOfObject GeoHandle;
|
|
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
|
|
|
|
#ifndef D_THROW_VISUAL_SET
|
|
#define M_hGetFirstLodOfVisualSetFromPo(Po) (GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle)
|
|
#define M_hGetRepositionZoneFromPo(Po) (GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle)
|
|
#else
|
|
#define M_hGetFirstLodOfVisualSetFromPo(Po) PO_fn_hGetGeometricObject(Po)
|
|
#define M_hGetRepositionZoneFromPo(Po) PO_fn_hGetGeometricObject(Po)
|
|
#endif /* D_THROW_VISUAL_SET */
|
|
|
|
extern BOOL fn_bIsEditorsActive(void);
|
|
|
|
extern unsigned long fn_ulStandardGameGetCustomBitsSO (HIE_tdxHandleToSuperObject hSupObj);
|
|
|
|
extern ACP_tdxHandleOfObject fn_hMakeOneObjectFromManyZdx (unsigned char _ucZoneType, HIE_tdxHandleToSuperObject _hCharacter);
|
|
|
|
|
|
unsigned long g_ulSpoMask = 0;
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
#ifdef ACTIVE_EDITOR
|
|
/* active editor only*/
|
|
static ACP_tdxBool fn_bIsBoundingVolumeIntersect
|
|
(
|
|
GEO_tdxHandleToMatrix _p_stCurrentMatrix,
|
|
MTH3D_tdstVector * _p_stVertexA,
|
|
MTH3D_tdstVector * _p_stVectAB,
|
|
GEO_tdxHandleToBoundingSphere _hBoundingSphere
|
|
)
|
|
{
|
|
MTH3D_tdstVector stGlobalSphereCenter;
|
|
MTH_tdxReal xScaledRadius;
|
|
|
|
MTH3D_M_vMulMatrixVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stRotationMatrix, GEO_fn_pGetCenterPointOfBoundingSphere(_hBoundingSphere));
|
|
MTH3D_M_vAddVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stTranslationVector, &stGlobalSphereCenter);
|
|
|
|
xScaledRadius = GEO_fn_xGetRadiusOfBoundingSphere(_hBoundingSphere) * POS_fn_xGetMaxScale(_p_stCurrentMatrix);
|
|
|
|
return INT_fn_bDetectIntersectSemiAxeWithSphere (_p_stVertexA, _p_stVectAB, &stGlobalSphereCenter, xScaledRadius);
|
|
}
|
|
#endif
|
|
|
|
/* used*/
|
|
ACP_tdxBool fn_bDetectIntersectSegmentWithBoundingSphere
|
|
(
|
|
GEO_tdxHandleToMatrix _p_stCurrentMatrix,
|
|
MTH3D_tdstVector * _p_stVertexA,
|
|
MTH3D_tdstVector * _p_stVectAB,
|
|
GEO_tdxHandleToBoundingSphere _hBoundingSphere
|
|
)
|
|
{
|
|
|
|
MTH3D_tdstVector stGlobalSphereCenter;
|
|
MTH_tdxReal xScaledRadius;
|
|
|
|
MTH3D_M_vMulMatrixVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stRotationMatrix, GEO_fn_pGetCenterPointOfBoundingSphere(_hBoundingSphere));
|
|
MTH3D_M_vAddVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stTranslationVector, &stGlobalSphereCenter);
|
|
|
|
xScaledRadius = GEO_fn_xGetRadiusOfBoundingSphere(_hBoundingSphere) * POS_fn_xGetMaxScale(_p_stCurrentMatrix);
|
|
|
|
return INT_fn_bDetectIntersectSegmentWithSphere (_p_stVertexA, _p_stVectAB, &stGlobalSphereCenter, xScaledRadius);
|
|
}
|
|
|
|
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
|
|
#ifdef ACTIVE_EDITOR
|
|
/* active editor only*/
|
|
static ACP_tdxIndex fn_xIntersectSemiAxeWithRepositioningSuperObject
|
|
(
|
|
GLI_tdeModePicking xModePicking,
|
|
MTH3D_tdstVector *p_stVertexA,
|
|
MTH3D_tdstVector *p_stVertexB,
|
|
MTH3D_tdstVector *p_stVectAB,
|
|
HIE_tdxHandleToSuperObject _hSprObj,
|
|
HIE_tdstPickInfo *p_stPickInfo ,
|
|
ACP_tdxIndex *p_xNbPickInfo
|
|
)
|
|
{
|
|
static GEO_tdxHandleToBoundingSphere hBoundingSphere;
|
|
static GEO_tdxHandleToParallelBox hParallelBox;
|
|
static ACP_tdxHandleOfObject hSentObject;
|
|
static MTH3D_tdstVector stMinPoint;
|
|
static MTH3D_tdstVector stMaxPoint;
|
|
static ACP_tdxBool bBoxBoundingVolume,bIntersect;
|
|
ACP_tdxIndex i;
|
|
static long lType,lCustomBits;
|
|
HIE_tdxHandleToSuperObject hChild;
|
|
static MTH3D_tdstVector stVertexALocal, stVectAB;
|
|
static POS_tdstCompletePosition stInvMatrix;
|
|
static GLI_tdstPickedObject stPickedObject;
|
|
|
|
|
|
/* eliminate every object that must be ignored...*/
|
|
if (HIE_fn_SO_bIsNotPickable( _hSprObj ))
|
|
{
|
|
return *p_xNbPickInfo;
|
|
}
|
|
|
|
lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
|
|
|
|
/* we test if the character is rayman (has the custombit 32)*/
|
|
/* we also ignore the character if he can't be hit by ray tracing.*/
|
|
/* we also ignore inactive characters*/
|
|
if (lType==HIE_C_ulActor)
|
|
{
|
|
lCustomBits = fn_ulStandardGameGetCustomBitsSO(_hSprObj);
|
|
if ( !(lCustomBits & GAM_C_CustBitRayHit) || /* not hit by ray tracing*/
|
|
!(fn_bf1StandardGameGetIsActive(M_GetMSHandle(_hSprObj,StandardGame))) || /* inactive*/
|
|
(lCustomBits & (1<<31)) ) /* Rayman*/
|
|
{
|
|
return *p_xNbPickInfo;
|
|
}
|
|
}
|
|
|
|
/* ok, now we can pick*/
|
|
hBoundingSphere = NULL;
|
|
hParallelBox = NULL;
|
|
hSentObject = NULL;
|
|
|
|
HIE_fn_vPushMatrix (_hSprObj);
|
|
|
|
/* do we have a bounding sphere or a bounding box ??*/
|
|
bBoxBoundingVolume = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj);
|
|
|
|
if(bBoxBoundingVolume)
|
|
{
|
|
/* this is a BOX !! */
|
|
hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
|
|
if (hParallelBox)
|
|
{
|
|
/* the box realy exists, compute its 2 points in world coordinates*/
|
|
MTH3D_tdstVector *p_stMinPoint;
|
|
MTH3D_tdstVector *p_stMaxPoint;
|
|
MTH3D_tdstVector stTranslation;
|
|
|
|
p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
|
|
p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
|
|
stTranslation = (HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj))->stTranslationVector;
|
|
|
|
MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , &stTranslation);
|
|
MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , &stTranslation);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* this is a SPHERE, get it*/
|
|
hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
|
|
}
|
|
|
|
/* test intersection*/
|
|
if (!hBoundingSphere && !hParallelBox)
|
|
{
|
|
/* if there are no bounding volume at all (no box nor sphere) --> go further*/
|
|
bIntersect = TRUE;
|
|
}
|
|
else if (!bBoxBoundingVolume)
|
|
{
|
|
/* if there is a BV Sphere, seek an intersect between the sphere and the axe*/
|
|
bIntersect = fn_bIsBoundingVolumeIntersect(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), p_stVertexA, p_stVectAB, hBoundingSphere);
|
|
}
|
|
else
|
|
{
|
|
/*if there is a BV Box, seek an intersect between the box and the axe */
|
|
bIntersect = INT_fn_bDetectIntersectSemiAxeWithBox(p_stVertexA, p_stVertexB, p_stVectAB, &stMinPoint, &stMaxPoint);
|
|
}
|
|
|
|
if(bIntersect)
|
|
{
|
|
if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror))
|
|
{
|
|
hSentObject = (ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
|
|
}
|
|
else if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
|
|
{
|
|
PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet((PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj)); /*AR9809*/
|
|
hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL;
|
|
}
|
|
#ifndef D_THROW_IPO
|
|
else if( lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
|
|
{
|
|
PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet (IPO_fn_hGetPhysicalObject
|
|
((IPO_tdxHandleToInstanciatedPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj)));
|
|
hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL;
|
|
}
|
|
#endif
|
|
else if( lType == HIE_C_ulActor )
|
|
{
|
|
hSentObject=fn_hMakeOneObjectFromManyZdx(C_ucTypeZdr, _hSprObj);
|
|
}
|
|
|
|
/* intersection test*/
|
|
if (hSentObject)
|
|
{
|
|
/* convertion local coordinate system*/
|
|
POS_fn_vInvertMatrix(&stInvMatrix, g_p_stCurrentMatrix);
|
|
|
|
MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVectAB, &(stInvMatrix.stTransformMatrix), p_stVectAB);
|
|
MTH3D_M_vAddVector(&stVectAB, &(stInvMatrix.stTranslationVector), &stVectAB);
|
|
|
|
MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVertexALocal, &(stInvMatrix.stTransformMatrix), p_stVertexA);
|
|
MTH3D_M_vAddVector(&stVertexALocal, &(stInvMatrix.stTranslationVector), &stVertexALocal);
|
|
|
|
if (PIC_bIntersectSemiAxeWithGeometricObject (xModePicking,&stVertexALocal,&stVectAB,hSentObject,&stPickedObject))
|
|
{
|
|
ACP_tdxIndex i;
|
|
|
|
i=(*p_xNbPickInfo)-1;
|
|
while( (i >= 0) && (stPickedObject.aDEF_stDataOfElement[0].xDistance
|
|
< p_stPickInfo[i].stPickedObject.aDEF_stDataOfElement[0].xDistance) )
|
|
{
|
|
if ( i < (HIE_C_DepthPickingObjects-1) )
|
|
p_stPickInfo[i+1] = p_stPickInfo[i];
|
|
i--;
|
|
}
|
|
|
|
if ( i < (HIE_C_DepthPickingObjects-1) )
|
|
{
|
|
p_stPickInfo[i+1].stPickedObject = stPickedObject;
|
|
p_stPickInfo[i+1].hSprObject = _hSprObj;
|
|
p_stPickInfo[i+1].hGeoObject=hSentObject;
|
|
if ( (*p_xNbPickInfo) < HIE_C_DepthPickingObjects )
|
|
(*p_xNbPickInfo)++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bIntersect || HIE_fn_SO_bCheckChildren(_hSprObj))
|
|
{
|
|
/* node examination*/
|
|
HIE_M_ForEachChildOf(_hSprObj, hChild, i)
|
|
{
|
|
/* recurence*/
|
|
fn_xIntersectSemiAxeWithRepositioningSuperObject(xModePicking,
|
|
p_stVertexA,
|
|
p_stVertexB,
|
|
p_stVectAB,
|
|
hChild,
|
|
p_stPickInfo,
|
|
p_xNbPickInfo);
|
|
}
|
|
}
|
|
HIE_fn_vPopMatrix ();
|
|
return *p_xNbPickInfo;
|
|
}
|
|
#endif /* ACTIVE_EDITOR*/
|
|
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
#ifdef ACTIVE_EDITOR
|
|
/* active editor only*/
|
|
ACP_tdxIndex fn_xIntersectSemiAxeWithVisualSuperObject
|
|
(
|
|
GLI_tdeModePicking xModePicking,
|
|
MTH3D_tdstVector *p_stVertexA,
|
|
MTH3D_tdstVector *p_stVertexB,
|
|
MTH3D_tdstVector *p_stVectAB,
|
|
HIE_tdxHandleToSuperObject _hSprObj,
|
|
HIE_tdstPickInfo *p_stPickInfo ,
|
|
ACP_tdxIndex *p_xNbPickInfo
|
|
)
|
|
{
|
|
ACP_tdxHandleOfObject hSentObject = NULL;
|
|
ACP_tdxIndex i;
|
|
HIE_tdxHandleToSuperObject hChild;
|
|
long lType;
|
|
|
|
HIE_fn_vPushMatrix(_hSprObj);
|
|
|
|
lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
|
|
|
|
{
|
|
if (
|
|
HIE_fn_SO_bIsNotPickable( _hSprObj )
|
|
#ifdef ACTIVE_EDITOR
|
|
&& !fn_bIsEditorsActive()
|
|
#endif
|
|
)
|
|
{
|
|
HIE_fn_vPopMatrix ();
|
|
return *p_xNbPickInfo;
|
|
}
|
|
|
|
if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulPO | HIE_C_ulIPO | HIE_C_ulMirror| HIE_C_ulPO_Mirror | HIE_C_ulIPO_Mirror))
|
|
{
|
|
MTH3D_tdstVector stVertexALocal, stVertexBLocal, stVectAB;
|
|
POS_tdstCompletePosition stInvMatrix;
|
|
GLI_tdstPickedObject stPickedObject;
|
|
|
|
/* convertion loacal coordinate system*/
|
|
|
|
POS_fn_vInvertMatrix(&stInvMatrix, g_p_stCurrentMatrix);/*!!!*/
|
|
|
|
POS_fn_vMulMatrixVertex(&stVertexALocal, &stInvMatrix, p_stVertexA);
|
|
POS_fn_vMulMatrixVertex(&stVertexBLocal, &stInvMatrix, p_stVertexB);
|
|
MTH3D_M_vSubVector(&stVectAB, &stVertexBLocal, &stVertexALocal);
|
|
|
|
if(lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror))
|
|
hSentObject=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
|
|
|
|
if(lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
|
|
hSentObject=M_hGetFirstLodOfVisualSetFromPo((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj));
|
|
/*XB980821*/
|
|
#ifndef D_THROW_IPO
|
|
if(lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
|
|
hSentObject=M_hGetFirstLodOfVisualSetFromPo(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj)));
|
|
#endif /* D_THROW_IPO */
|
|
/*End XB*/
|
|
|
|
/* intersection test*/
|
|
if( PIC_bIntersectSemiAxeWithGeometricObject(xModePicking,
|
|
&stVertexALocal,
|
|
/* &stVertexBLocal,*/
|
|
&stVectAB,
|
|
hSentObject,
|
|
&stPickedObject) )
|
|
{ /* l'objet est sous la souris*/
|
|
ACP_tdxIndex i;
|
|
|
|
i=(*p_xNbPickInfo)-1;
|
|
while( (i >= 0) && (stPickedObject.aDEF_stDataOfElement[0].xDistance
|
|
< p_stPickInfo[i].stPickedObject.aDEF_stDataOfElement[0].xDistance) )
|
|
{
|
|
if ( i < (HIE_C_DepthPickingObjects-1) )
|
|
p_stPickInfo[i+1] = p_stPickInfo[i];
|
|
i--;
|
|
}
|
|
|
|
if ( i < (HIE_C_DepthPickingObjects-1) )
|
|
{
|
|
p_stPickInfo[i+1].stPickedObject = stPickedObject;
|
|
p_stPickInfo[i+1].hSprObject = _hSprObj;
|
|
p_stPickInfo[i+1].hGeoObject=hSentObject;
|
|
if ( (*p_xNbPickInfo) < HIE_C_DepthPickingObjects )
|
|
(*p_xNbPickInfo)++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* node examination*/
|
|
HIE_M_ForEachChildOf(_hSprObj, hChild, i)
|
|
{
|
|
/* recurence*/
|
|
fn_xIntersectSemiAxeWithVisualSuperObject(xModePicking,
|
|
p_stVertexA,
|
|
p_stVertexB,
|
|
p_stVectAB,
|
|
hChild,
|
|
p_stPickInfo,
|
|
p_xNbPickInfo);
|
|
}
|
|
}
|
|
HIE_fn_vPopMatrix ();
|
|
return *p_xNbPickInfo;
|
|
}
|
|
#endif /* ACTIVE_EDITOR*/
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
#ifdef ACTIVE_EDITOR
|
|
/* active editor only*/
|
|
ACP_tdxIndex HIE_xIsSuperObjectPick
|
|
(
|
|
GLI_tdeModePicking xModePicking,
|
|
GLD_tdhDevice hDev,
|
|
GLD_tdhViewport hVp,
|
|
GLI_tdst2DVertex *p_stSouris2D,
|
|
HIE_tdxHandleToSuperObject hSprObj,
|
|
HIE_tdstPickInfo *p_stPickInfo
|
|
)
|
|
{
|
|
MTH3D_tdstVector stSouris3D, stVertex12, stCameraPos;
|
|
ACP_tdxIndex xNbPickInfo=0;
|
|
|
|
/* calcul des positions 3d de la camera et de la souris dans le repere global*/
|
|
PIC_vGetPosCamAndMouse(hDev, hVp, p_stSouris2D, &stSouris3D, &stCameraPos);
|
|
MTH3D_M_vSubVector(&stVertex12, &stSouris3D, &stCameraPos);
|
|
|
|
return fn_xIntersectSemiAxeWithVisualSuperObject
|
|
(
|
|
xModePicking,
|
|
&stCameraPos,
|
|
&stSouris3D,
|
|
&stVertex12,
|
|
hSprObj,
|
|
p_stPickInfo,
|
|
&xNbPickInfo
|
|
);
|
|
}
|
|
#endif
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
#ifdef ACTIVE_EDITOR
|
|
/* active editor only*/
|
|
ACP_tdxIndex HIE_bIntersectSemiAxeWithSuperObject
|
|
(
|
|
GLI_tdeModePicking xModePicking,
|
|
MTH3D_tdstVector *p_stVertexA,
|
|
MTH3D_tdstVector *p_stVertexB,
|
|
MTH3D_tdstVector *p_stVectAB,
|
|
HIE_tdxHandleToSuperObject hSprObj,
|
|
HIE_tdstPickInfo *p_stPickInfo
|
|
)
|
|
{
|
|
ACP_tdxIndex xNbPickInfo = 0;
|
|
ACP_tdxIndex iRet;
|
|
|
|
HIE_fn_bLoadIdentity();
|
|
|
|
iRet = fn_xIntersectSemiAxeWithRepositioningSuperObject
|
|
(
|
|
xModePicking,
|
|
p_stVertexA,
|
|
p_stVertexB,
|
|
p_stVectAB,
|
|
hSprObj,
|
|
p_stPickInfo,
|
|
&xNbPickInfo
|
|
);
|
|
|
|
HIE_fn_vPopMatrix();
|
|
return iRet;
|
|
}
|
|
#endif
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
/* used*/
|
|
static ACP_tdxIndex fn_xIntersectSegmentWithRepositioningSuperObject
|
|
(
|
|
MTH3D_tdstVector *p_stVertexA,
|
|
MTH3D_tdstVector *p_stVectAB,
|
|
HIE_tdxHandleToSuperObject _hSprObj,
|
|
HIE_tdstPickInfo *p_stPickInfo ,
|
|
ACP_tdxIndex *p_xNbPickInfo
|
|
)
|
|
{
|
|
static GEO_tdxHandleToBoundingSphere hBoundingSphere;
|
|
static GEO_tdxHandleToParallelBox hParallelBox;
|
|
static ACP_tdxHandleOfObject hSentObject;
|
|
static MTH3D_tdstVector stMinPoint;
|
|
static MTH3D_tdstVector stMaxPoint;
|
|
static ACP_tdxBool bBoxBoundingVolume,bIntersect;
|
|
ACP_tdxIndex i;
|
|
/* XB 05/05/99 */
|
|
/* static long lType,lCustomBits; */
|
|
static long lType;
|
|
/* End XB 05/05/99 */
|
|
HIE_tdxHandleToSuperObject hChild;
|
|
static MTH3D_tdstVector stVertexALocal, stVectAB;
|
|
static POS_tdstCompletePosition stInvMatrix;
|
|
static GLI_tdstPickedObject stPickedObject;
|
|
register unsigned long ulSpoFlags;
|
|
|
|
ulSpoFlags = HIE_M_xGetSuperObjectMember(_hSprObj,ulFlags);
|
|
|
|
/* eliminate every object that has the No_Collision flag*/
|
|
if (ulSpoFlags & HIE_C_Flag_ulNotPickable)
|
|
{
|
|
return *p_xNbPickInfo;
|
|
}
|
|
|
|
lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
|
|
|
|
/* if object is not an actor, check the flags with the given mask...*/
|
|
/* else, check the custom bit */
|
|
if (lType != HIE_C_ulActor)
|
|
{
|
|
if (ulSpoFlags & g_ulSpoMask)
|
|
return *p_xNbPickInfo;
|
|
}
|
|
else
|
|
{
|
|
if (!fn_ulStandardGameGetCustomBitsSO(_hSprObj) & GAM_C_CustBitShadowOnMe)
|
|
{
|
|
return *p_xNbPickInfo;
|
|
}
|
|
}
|
|
|
|
hBoundingSphere = NULL;
|
|
hParallelBox = NULL;
|
|
hSentObject = NULL;
|
|
|
|
HIE_fn_vPushMatrix(_hSprObj);
|
|
|
|
/* do we have a bounding sphere or a bounding box ??*/
|
|
bBoxBoundingVolume = (unsigned char)(ulSpoFlags & HIE_C_Flag_ulTypeOfBoundingVolume);
|
|
|
|
if(bBoxBoundingVolume)
|
|
{
|
|
/* this is a BOX !! */
|
|
hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
|
|
if (hParallelBox)
|
|
{
|
|
/* the box realy exists, compute its 2 points in world coordinates*/
|
|
MTH3D_tdstVector *p_stMinPoint;
|
|
MTH3D_tdstVector *p_stMaxPoint;
|
|
MTH3D_tdstVector stTranslation;
|
|
|
|
p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
|
|
p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
|
|
stTranslation = (HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj))->stTranslationVector;
|
|
|
|
MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , &stTranslation);
|
|
MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , &stTranslation);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* this is a SPHERE, get it*/
|
|
hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
|
|
}
|
|
|
|
/* test intersection*/
|
|
if (!hBoundingSphere && !hParallelBox)
|
|
{
|
|
/* if there are no bounding volume at all (no box nor sphere) --> go further*/
|
|
bIntersect = TRUE;
|
|
}
|
|
else if (!bBoxBoundingVolume)
|
|
{
|
|
/* if there is a BV Sphere, seek an intersect between the sphere and the axe*/
|
|
bIntersect = fn_bDetectIntersectSegmentWithBoundingSphere(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), p_stVertexA, p_stVectAB, hBoundingSphere);
|
|
}
|
|
else
|
|
{
|
|
/*if there is a BV Box, seek an intersect between the box and the axe */
|
|
bIntersect = INT_fn_bDetectIntersectSegmentWithBox(p_stVertexA, p_stVectAB, &stMinPoint, &stMaxPoint,NULL);
|
|
}
|
|
|
|
|
|
if(bIntersect)
|
|
{
|
|
/* we found an intersection between the segment and the bounding volume --> let's see if we must get down to the faces*/
|
|
#ifndef U64 /* no editor objects on u64*/
|
|
if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror))
|
|
{
|
|
hSentObject = (ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
|
|
}
|
|
else
|
|
#endif
|
|
if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
|
|
{
|
|
PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet((PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj)); /*AR9809*/
|
|
hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL;
|
|
}
|
|
#ifndef D_THROW_IPO
|
|
else if( lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
|
|
{
|
|
PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet (IPO_fn_hGetPhysicalObject
|
|
((IPO_tdxHandleToInstanciatedPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj)));
|
|
hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL;
|
|
}
|
|
#endif
|
|
else if( lType == HIE_C_ulActor )
|
|
{
|
|
hSentObject=fn_hMakeOneObjectFromManyZdx(C_ucTypeZdr, _hSprObj);
|
|
}
|
|
|
|
if (hSentObject)
|
|
{
|
|
/* the detected objetc is relevant, let's see if there is a collision with its faces...*/
|
|
/*Convertion local coordinate system.*/
|
|
if (ulSpoFlags & HIE_C_Flag_ulNoTransformationMatrix)
|
|
{
|
|
/* Only translation, compute A i local*/
|
|
MTH3D_M_vSubVector (&stVertexALocal , p_stVertexA , &_hSprObj->hGlobalMatrix->stTranslationVector);
|
|
/* and nothing for the vector AB...*/
|
|
MTH3D_M_vCopyVector(&stVectAB,p_stVectAB);
|
|
}
|
|
else
|
|
{
|
|
POS_fn_vInvertMatrix(&stInvMatrix,_hSprObj->hGlobalMatrix);
|
|
/* MTH3D_M_vTranspMatrixWithoutBuffer(&stInvMatrix,&_hSprObj->hGlobalMatrix->stRotationMatrix);*/
|
|
|
|
/* here, stVectAB is used only as a temporary variable and has no meaning...*/
|
|
/* compute A in local coordinates*/
|
|
/* MTH3D_M_vSubVector (&stVectAB , p_stVertexA , &_hSprObj->hGlobalMatrix->stTranslationVector);*/
|
|
/* MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVertexALocal, &stInvMatrix, &stVectAB);*/
|
|
POS_fn_vMulMatrixVertex(&stVertexALocal,&stInvMatrix, p_stVertexA);
|
|
|
|
/* compute AB in local coordinates*/
|
|
POS_fn_vMulMatrixVector(&stVectAB, &stInvMatrix, p_stVectAB);
|
|
|
|
/* MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVectAB, &stInvMatrix, p_stVectAB);*/
|
|
}
|
|
|
|
if (PIC_bIntersectSegmentWithGeometricObject (&stVertexALocal,&stVectAB,hSentObject,&stPickedObject))
|
|
{
|
|
/* yes, we got an intersection !!*/
|
|
/* if it is the first one, then remember it*/
|
|
if (*p_xNbPickInfo == 0)
|
|
{
|
|
/* first one !*/
|
|
p_stPickInfo[0].stPickedObject = stPickedObject;
|
|
p_stPickInfo[0].hSprObject = _hSprObj;
|
|
p_stPickInfo[0].hGeoObject = hSentObject;
|
|
*p_xNbPickInfo = 1;
|
|
/* and reduce the lenght of the segment */
|
|
MTH3D_M_vSubVector(p_stVectAB, &(stPickedObject.aDEF_stDataOfElement[0].stHit),p_stVertexA);
|
|
}
|
|
else
|
|
{
|
|
/* there has already been a collision in this search, so check distance*/
|
|
/* compare this detection with the previous one*/
|
|
if (stPickedObject.aDEF_stDataOfElement[0].xDistance < p_stPickInfo[0].stPickedObject.aDEF_stDataOfElement[0].xDistance)
|
|
{
|
|
/* ok, the new one is nearer*/
|
|
/* lets remember the data*/
|
|
p_stPickInfo[0].stPickedObject = stPickedObject;
|
|
p_stPickInfo[0].hSprObject = _hSprObj;
|
|
p_stPickInfo[0].hGeoObject = hSentObject;
|
|
/* and reduce the lenght of the segment */
|
|
MTH3D_M_vSubVector(p_stVectAB, &(stPickedObject.aDEF_stDataOfElement[0].stHit),p_stVertexA);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* keep going on the sons of this SO */
|
|
if (bIntersect || HIE_fn_SO_bCheckChildren(_hSprObj))
|
|
{
|
|
HIE_M_ForEachChildOf(_hSprObj, hChild, i)
|
|
{
|
|
/* recurence*/
|
|
fn_xIntersectSegmentWithRepositioningSuperObject
|
|
(
|
|
p_stVertexA,
|
|
p_stVectAB,
|
|
hChild,
|
|
p_stPickInfo,
|
|
p_xNbPickInfo
|
|
);
|
|
}
|
|
}
|
|
HIE_fn_vPopMatrix ();
|
|
return *p_xNbPickInfo;
|
|
}
|
|
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
/* used*/
|
|
ACP_tdxIndex HIE_bIntersectSegmentWithSuperObject
|
|
(
|
|
MTH3D_tdstVector *p_stVertexA,
|
|
MTH3D_tdstVector *p_stVectAB,
|
|
HIE_tdxHandleToSuperObject hSprObj,
|
|
HIE_tdstPickInfo *p_stPickInfo
|
|
)
|
|
{
|
|
ACP_tdxIndex xNbPickInfo = 0, xReturnValue;
|
|
|
|
HIE_fn_bLoadIdentity();
|
|
xReturnValue = fn_xIntersectSegmentWithRepositioningSuperObject
|
|
(
|
|
p_stVertexA,
|
|
p_stVectAB,
|
|
hSprObj,
|
|
p_stPickInfo,
|
|
&xNbPickInfo
|
|
);
|
|
|
|
HIE_fn_bPopMatrix();
|
|
|
|
return xReturnValue;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|
|
/* used*/
|
|
/* compute the intersection between the segment [A, A+AB], and the hSprObj and its descendants*/
|
|
ACP_tdxBool HIE_bIntersectSegmentWithFirstSuperObject(MTH3D_tdstVector *_p_stVertexA,
|
|
MTH3D_tdstVector *_p_stVectAB,
|
|
HIE_tdxHandleToSuperObject hSprObj,
|
|
MTH3D_tdstVector *_p_stHit,
|
|
MTH3D_tdstVector *_p_stNormal,
|
|
HIE_tdxHandleToSuperObject *_p_hSprObjHit
|
|
)
|
|
{
|
|
HIE_aDEF_stTabOfPickInfo aDEF_stIntersInfo;
|
|
GEO_tdstGeometricObject *p_stGeomObj;
|
|
GLI_tdstDataOfElement *p_stDataOfElement;
|
|
MTH3D_tdstVector stNormal;
|
|
long lType;
|
|
|
|
|
|
if( HIE_bIntersectSegmentWithSuperObject(_p_stVertexA,_p_stVectAB,hSprObj,aDEF_stIntersInfo) > 0)
|
|
{
|
|
/* detection !!!*/
|
|
p_stGeomObj = aDEF_stIntersInfo[0].hGeoObject;
|
|
p_stDataOfElement = &(aDEF_stIntersInfo[0].stPickedObject.aDEF_stDataOfElement[0]);
|
|
|
|
lType = HIE_fn_ulGetSuperObjectType(aDEF_stIntersInfo[0].hSprObject);
|
|
|
|
if(lType & (HIE_C_ulEDT_Geometric | HIE_C_ulPO | HIE_C_ulMirror | HIE_C_ulPO_Mirror | HIE_C_ulActor | HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
|
|
{
|
|
*_p_hSprObjHit = aDEF_stIntersInfo[0].hSprObject;
|
|
}
|
|
else
|
|
{
|
|
*_p_hSprObjHit = NULL;
|
|
}
|
|
|
|
MTH3D_M_vCopyVector( _p_stHit, &(p_stDataOfElement->stHit));
|
|
|
|
if (_p_hSprObjHit && p_stGeomObj->d_xListOfElementsTypes[p_stDataOfElement->xElements] == GEO_C_xElementSpheres)
|
|
{
|
|
MTH3D_tdstVector stSphereCenter;
|
|
/* Get the sphere element*/
|
|
GEO_tdstElementSpheres * p_stElementSpheres = (GEO_tdstElementSpheres *) p_stGeomObj->d_stListOfElements[p_stDataOfElement->xElements];
|
|
/* The normal is the vector from the center of the sphere to the hit point (in the global axis)*/
|
|
POS_fn_vMulMatrixVertex (& stSphereCenter,
|
|
HIE_fn_hGetSuperObjectGlobalMatrix(* _p_hSprObjHit),
|
|
& p_stGeomObj->d_stListOfPoints[p_stElementSpheres->d_stListOfSpheres[p_stDataOfElement->xIndexOfFace].xCenterPoint]);
|
|
MTH3D_M_vSubVector (_p_stNormal, _p_stHit, & stSphereCenter);
|
|
MTH3D_M_vNormalizeVector (_p_stNormal, _p_stNormal);
|
|
}
|
|
else
|
|
{
|
|
GEO_vGetNormalOfGeometricObjectElement(p_stGeomObj,p_stDataOfElement->xElements,p_stDataOfElement->xIndexOfFace,&stNormal);
|
|
POS_fn_vMulMatrixVector(_p_stNormal, HIE_fn_hGetSuperObjectGlobalMatrix(* _p_hSprObjHit), &stNormal);
|
|
/* don't forget to normalize in case the target had scale... */
|
|
MTH3D_M_vNormalizeVector (_p_stNormal, _p_stNormal);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
******************************************************************************************************
|
|
******************************************************************************************************
|
|
******************************************************************************************************
|
|
******************************************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*=================================================================================================
|
|
* Picking function for camera.
|
|
*=================================================================================================
|
|
*/
|
|
/* used*/
|
|
ACP_tdxBool HIE_bDetectIntersectSegmentWithSuperObject
|
|
(
|
|
MTH3D_tdstVector *p_stVertexA,
|
|
MTH3D_tdstVector *p_stVectAB,
|
|
HIE_tdxHandleToSuperObject _hSprObj
|
|
)
|
|
{
|
|
static GEO_tdxHandleToBoundingSphere hBoundingSphere;
|
|
static GEO_tdxHandleToParallelBox hParallelBox;
|
|
static MTH3D_tdstVector stMinPoint;
|
|
static MTH3D_tdstVector stMaxPoint;
|
|
static MTH3D_tdstVector *p_stTranslation;
|
|
static ACP_tdxBool bBoxBoundingVolume,bIntersect;
|
|
static ACP_tdxHandleOfObject hSentObject;
|
|
ACP_tdxIndex i;
|
|
HIE_tdxHandleToSuperObject hChild;
|
|
static long lType;
|
|
/* XB 05/05/99 */
|
|
/* static MTH3D_tdstVector stVertexALocal, stVertexBLocal, stVectAB; */
|
|
static MTH3D_tdstVector stVertexALocal, stVectAB;
|
|
/* End XB 05/05/99 */
|
|
static POS_tdstCompletePosition stInvMatrix;
|
|
|
|
|
|
|
|
hBoundingSphere = NULL;
|
|
hParallelBox = NULL;
|
|
hSentObject = NULL;
|
|
|
|
p_stTranslation = &_hSprObj->hGlobalMatrix->stTranslationVector;
|
|
bBoxBoundingVolume = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj);
|
|
|
|
if(bBoxBoundingVolume)
|
|
{
|
|
hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
|
|
if (hParallelBox)
|
|
{
|
|
MTH3D_tdstVector *p_stMinPoint;
|
|
MTH3D_tdstVector *p_stMaxPoint;
|
|
|
|
/* get the min and max points in world coordinates*/
|
|
p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
|
|
p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
|
|
|
|
MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , p_stTranslation);
|
|
MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , p_stTranslation);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* get the bounding sphere*/
|
|
hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
|
|
}
|
|
|
|
/* test intersection*/
|
|
if (!hBoundingSphere && !hParallelBox)
|
|
{
|
|
/* if there are no bounding volume at all (no box nor sphere) --> go further*/
|
|
bIntersect = TRUE;
|
|
}
|
|
else if (!bBoxBoundingVolume)
|
|
{
|
|
/* if there is a BV Sphere, seek an intersect between the sphere and the axe*/
|
|
bIntersect = fn_bDetectIntersectSegmentWithBoundingSphere(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), p_stVertexA, p_stVectAB, hBoundingSphere);
|
|
}
|
|
else
|
|
{
|
|
/*if there is a BV Box, seek an intersect between the box and the axe */
|
|
bIntersect = INT_fn_bDetectIntersectSegmentWithBox(p_stVertexA, p_stVectAB, &stMinPoint, &stMaxPoint,NULL);
|
|
}
|
|
|
|
|
|
if(bIntersect)
|
|
{
|
|
lType = HIE_fn_ulGetSuperObjectType(_hSprObj);
|
|
|
|
#ifndef U64 /* no editor objects on u64*/
|
|
if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror ))
|
|
{
|
|
hSentObject = (ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
|
|
}
|
|
else
|
|
#endif
|
|
if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
|
|
{
|
|
hSentObject = M_hGetRepositionZoneFromPo((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj));
|
|
}
|
|
#ifndef D_THROW_IPO
|
|
else if( lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
|
|
{
|
|
hSentObject = M_hGetRepositionZoneFromPo(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj)));
|
|
}
|
|
#endif /* D_THROW_IPO */
|
|
else if (lType == HIE_C_ulActor)
|
|
{
|
|
hSentObject = fn_hMakeOneObjectFromManyZdx(C_ucTypeZdr,_hSprObj);
|
|
}
|
|
|
|
if (hSentObject)
|
|
{
|
|
/*Convertion local coordinate system.*/
|
|
if (HIE_fn_SO_bHasNoTransformationMatrix (_hSprObj))
|
|
{
|
|
/* Only translation, compute A i local*/
|
|
MTH3D_M_vSubVector (&stVertexALocal , p_stVertexA , p_stTranslation);
|
|
/* and nothing for the vector AB...*/
|
|
MTH3D_M_vCopyVector(&stVectAB,p_stVectAB);
|
|
}
|
|
else
|
|
{
|
|
POS_fn_vInvertMatrix(&stInvMatrix,_hSprObj->hGlobalMatrix);
|
|
/* compute A in local coordinates*/
|
|
POS_fn_vMulMatrixVertex(&stVertexALocal,&stInvMatrix, p_stVertexA);
|
|
/* compute AB in local coordinates*/
|
|
POS_fn_vMulMatrixVector(&stVectAB, &stInvMatrix, p_stVectAB);
|
|
}
|
|
|
|
/*
|
|
* Intersection test.
|
|
*/
|
|
if( INT_fn_bDetectIntersectSegmentWithFaceOfGeometricObject(&stVertexALocal, &stVectAB, hSentObject))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bIntersect || HIE_fn_SO_bCheckChildren(_hSprObj))
|
|
{
|
|
/* keep going on the sons of this SO, only if they are not actors */
|
|
HIE_M_ForEachChildOf(_hSprObj, hChild, i)
|
|
{
|
|
if( (HIE_fn_ulGetSuperObjectType(hChild) != HIE_C_ulActor) &&
|
|
(HIE_bDetectIntersectSegmentWithSuperObject(p_stVertexA,p_stVectAB,hChild))
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
*=================================================================================================
|
|
*=================================================================================================
|
|
*/
|