reman3/Rayman_X/cpa/tempgrp/SPO/HiePick.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;
}
/*
*=================================================================================================
*=================================================================================================
*/