reman3/Rayman_X/cpa/tempgrp/PIC/Picking.c

348 lines
10 KiB
C

#include "MTH.h"
#include "Acp_base.h"
#include "Cpa_std.h"
#include "HDL.h"
#include "POS.h"
#include "GMT.h"
#include "GEO.h"
#include "COL.h"
#include "GLI.h"
#include "PIC.h"
/*#ifdef __cplusplus
extern "C"
{
#endif
M_LoadExternGlobalDeclaration();
#ifdef __cplusplus
} // extern "C"
#endif*/
#ifdef ACTIVE_EDITOR
static MTH2D_tdstVector g_stSouris2D;
static GLD_tdhDevice g_hDev = 0;
static GLD_tdhViewport g_hVp = 0;
#endif
/*
#ifdef PC
extern float gs_xConstantFor3dfxBugFloat;
#endif
*/
/*************************************************************************************/
/* Calcul de la position 3d de la souris. Le point 3d calcule appartient a l'ecran. */
/*************************************************************************************/
#ifdef ACTIVE_EDITOR
// active editor only
void PIC_vMouse3DScreen ( GLD_tdhDevice hDev,
GLD_tdhViewport hVp,
GLI_tdst2DVertex *p_stInput ,
MTH3D_tdstVector *p_stOutput )
{
GLI_tdstSpecificAttributesFor3D *p_stSpecAttrib3D;
GLD_tdstViewportAttributes stViewAttrib;
GLD_tdstDeviceAttributes stDevAttrib;
MTH3D_tdstVector stTemp ;
POS_tdstCompletePosition stMatrix, stInvMatrix ;
GLI_tdstCamera *p_stCam;
GLI_tdst2DVertex stTrans;
MTH_tdxReal xScreen;
if ( !GLD_bGetViewportAttributes( hDev, hVp, &stViewAttrib ) ) return;
if ( !GLD_bGetDeviceAttributes( hDev, &stDevAttrib ) ) return;
p_stSpecAttrib3D = (GLI_tdstSpecificAttributesFor3D *)stViewAttrib.p_vSpecificToXD;
p_stCam = p_stSpecAttrib3D->p_stCam;
switch(p_stCam->lCameraMode)
{
case GLI_C_lIsoCamWithDistorsion :
case GLI_C_lIsoCamWithoutDistorsion :
xScreen = MTH_M_xFloatToReal(0.1f);
break;
case GLI_C_lPersCamWithDistorsion :
case GLI_C_lPersCamWithoutDistorsion :
xScreen = p_stCam->xScreen;
break ;
default:
p_stOutput->xX = p_stOutput->xY = p_stOutput->xZ = MTH_M_xFloatToReal(0.0f);
return;
}
/* on se ramene en unite du monde */
/*
if(GLI_lWhatIsGLI() == GLI_C_VersionGlide)
{
#ifdef PC
stTrans.xX = p_stCam->stTrans.xX - gs_xConstantFor3dfxBugFloat;
stTrans.xY = p_stCam->stTrans.xY - gs_xConstantFor3dfxBugFloat;
#endif
}
else
{
stTrans.xX = p_stCam->stTrans.xX;
stTrans.xY = p_stCam->stTrans.xY;
}
*/
stTrans.xX = p_stCam->stTrans.xX;
stTrans.xY = p_stCam->stTrans.xY;
stTemp.xX = MTH_M_xDiv( MTH_M_xSub( MTH_M_xLongToReal(p_stInput->xX), MTH_M_xLongToReal(stTrans.xX)),
MTH_M_xFloatToReal(p_stCam->stScale.xX));
stTemp.xY = MTH_M_xDiv( MTH_M_xSub( MTH_M_xLongToReal(p_stInput->xY), MTH_M_xLongToReal(stTrans.xY) ),
MTH_M_xFloatToReal(p_stCam->stScale.xY) ) ;
stTemp.xZ = xScreen;
/* Convertion dans le repere du monde */
GLI_xGetCameraMatrix ( p_stCam , &stMatrix );
POS_fn_vInvertMatrix( &stInvMatrix , &stMatrix );
POS_fn_vMulMatrixVertex( p_stOutput , &stInvMatrix , &stTemp );
}
#endif
#ifdef ACTIVE_EDITOR
// active editor only
void PIC_vGetPosCamAndMouse(GLD_tdhDevice hDev,
GLD_tdhViewport hVp,
GLI_tdst2DVertex *p_stSouris2D,
MTH3D_tdstVector *p_stSouris3D,
MTH3D_tdstVector *p_stCamera)
{
GLD_tdstViewportAttributes stViewAttrib;
GLI_tdstSpecificAttributesFor3D *p_stSpecAttrib3D;
GLI_tdstCamera *p_stCam;
POS_tdstCompletePosition stMatrix, stInvMatrix;
MTH3D_tdstVector stAxe, stAxeZ;
MTH3D_tdstVector stSouris3D, stTmp;
MTH3D_tdstVector stTrans;
// recuperation de la camera
if(!GLD_bGetViewportAttributes(hDev, hVp, &stViewAttrib)) return;
p_stSpecAttrib3D = (GLI_tdstSpecificAttributesFor3D *)stViewAttrib.p_vSpecificToXD;
p_stCam = p_stSpecAttrib3D->p_stCam;
PIC_vMouse3DScreen ( hDev, hVp, p_stSouris2D , &stSouris3D );
// get camera position
if( p_stCam->lCameraMode == GLI_C_lPersCamWithDistorsion
|| p_stCam->lCameraMode == GLI_C_lPersCamWithoutDistorsion )
{
GLI_xGetCameraMatrix ( p_stCam, &stMatrix );
POS_fn_vInvertMatrix( &stInvMatrix , &stMatrix );
POS_fn_vGetTranslationVector( &stInvMatrix , p_stCamera );
}
else if( p_stCam->lCameraMode == GLI_C_lIsoCamWithDistorsion
|| p_stCam->lCameraMode == GLI_C_lIsoCamWithoutDistorsion )
{
// calcul de l'axe Z de la camera
GLI_xGetCameraMatrix ( p_stCam, &stMatrix );
POS_fn_vInvertMatrix( &stInvMatrix , &stMatrix );
stAxe.xX = MTH_M_xFloatToReal(0.0);
stAxe.xY = MTH_M_xFloatToReal(0.0);
stAxe.xZ = MTH_M_xFloatToReal(1.0);
POS_fn_vMulMatrixVertex(&stTmp, &stInvMatrix, &stAxe);
POS_fn_vGetTranslationVector( &stInvMatrix,&stTrans);
MTH3D_M_vSubVector(&stAxeZ, &stTmp, &stTrans);
MTH3D_M_vSubVector(p_stCamera, &stSouris3D, &stAxeZ);
}
if(p_stSouris3D != NULL)
{
*p_stSouris3D = stSouris3D;
}
g_stSouris2D.xX = p_stSouris2D->xX;
g_stSouris2D.xY = p_stSouris2D->xY;
g_hDev = hDev;
g_hVp = hVp;
}
#endif
#ifdef ACTIVE_EDITOR
// active editor only
BOOL PIC_xIntersectSemiAxeWithSphereBox(MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
GLI_tdstSphere *p_stSphere )
{
return TRUE;
}
#endif
// used
BOOL PIC_bIntersectSegmentWithGeometricObject(MTH3D_tdstVector *p_stCameraPos,
MTH3D_tdstVector *p_stVertex12,
GEO_tdstGeometricObject *p_stObject ,
PIC_tdstPickedObject *p_stPickedObject)
{
// GLI_tdstSphere stSphere;
ACP_tdxIndex xNbElements;
BOOL bTest,bReturn = FALSE;
MTH3D_tdstVector stSouris3D;
MTH3D_M_vAddVector(&stSouris3D, p_stCameraPos, p_stVertex12);
bTest = INT_fn_bIntersectSegmentWithFaceOfGeometricObject(p_stCameraPos,
&stSouris3D,
p_stVertex12,
p_stObject,
PIC_C_DepthPickingElements,
&xNbElements,
p_stPickedObject->aDEF_stDataOfElement);
if( bTest )
{
MTH3D_tdstVector stTemp;
ACP_tdxIndex i;
POS_fn_vMulMatrixVertex(&stTemp, g_p_stCurrentMatrix, p_stCameraPos);
for(i=0; i<xNbElements; i++)
{
POS_fn_vMulMatrixVertex(&(p_stPickedObject->aDEF_stDataOfElement[i].stHit),
g_p_stCurrentMatrix,
&(p_stPickedObject->aDEF_stDataOfElement[i].stHit));
p_stPickedObject->aDEF_stDataOfElement[i].xDistance =
MTH3D_M_xVectorGap(&stTemp, &(p_stPickedObject->aDEF_stDataOfElement[i].stHit));
}
p_stPickedObject->xNbElements = xNbElements;
p_stPickedObject->xModePicking = PIC_C_ModePickingFace;
bReturn = TRUE;
}
return bReturn;
}
#if defined(ACTIVE_EDITOR)
// active editor only
BOOL PIC_bIntersectSemiAxeWithGeometricObject(PIC_tdeModePicking xModePicking,
MTH3D_tdstVector *p_stCameraPos,
MTH3D_tdstVector *p_stVertex12,
GEO_tdstGeometricObject *p_stObject ,
PIC_tdstPickedObject *p_stPickedObject)
{
GLI_tdstSphere stSphere;
ACP_tdxIndex xNbElements;
//XB980505
// BOOL bTest,bReturn = FALSE;
BOOL bTest=FALSE;
BOOL bReturn = FALSE;
//End XB
MTH3D_tdstVector stSouris3D;
GLI_tdst2DVertex stInput;
MTH3D_tdstVector stOutput;
POS_tdstCompletePosition stInvMatrix;
// stSphere = p_stObject->stAbsoluteSphereBox;
MTH3D_M_vAddVector(&stSouris3D, p_stCameraPos, p_stVertex12);
if(PIC_xIntersectSemiAxeWithSphereBox(p_stCameraPos, p_stVertex12, &stSphere) )
{
switch(xModePicking)
{
case PIC_C_ModePickingFace:
bTest = INT_fn_bIntersectSemiAxeWithFaceOfGeometricObject(p_stCameraPos,
&stSouris3D,
p_stVertex12,
p_stObject,
PIC_C_DepthPickingElements,
&xNbElements,
p_stPickedObject->aDEF_stDataOfElement);
if(GLD_bIsDeviceHandleValid(g_hDev) && GLD_bIsViewportHandleValid(g_hVp))
{
stInput.xX = g_stSouris2D.xX;
stInput.xY = g_stSouris2D.xY;
PIC_vMouse3DScreen(g_hDev, g_hVp, &stInput, &stOutput);
POS_fn_vInvertMatrix(&stInvMatrix , g_p_stCurrentMatrix);
POS_fn_vMulMatrixVertex(&stOutput, &stInvMatrix, &stOutput);
if( MTH3D_M_bEqualVector(&stOutput, &stSouris3D) )
{
GLD_tdstViewportAttributes stViewAttrib;
if ( !GLD_bGetViewportAttributes( g_hDev, g_hVp, &stViewAttrib ) ) return FALSE;
bTest += GLI_lPickSprites ( &stViewAttrib,
p_stObject,
&g_stSouris2D,
PIC_C_DepthPickingElements,
&xNbElements,
p_stPickedObject->aDEF_stDataOfElement,
p_stCameraPos,
FALSE);
}
}
break;
case PIC_C_ModePickingEdge:
bTest = INT_fn_bIntersectSemiAxeWithEdgeOfGeometricObject(p_stCameraPos,
p_stVertex12,
p_stObject,
PIC_C_DepthPickingElements,
&xNbElements,
p_stPickedObject->aDEF_stDataOfElement);
break;
case PIC_C_ModePickingPoint:
bTest = INT_fn_bIntersectSemiAxeWithPointOfGeometricObject(p_stCameraPos,
p_stVertex12,
p_stObject,
PIC_C_DepthPickingElements,
&xNbElements,
p_stPickedObject->aDEF_stDataOfElement);
break;
}
if( bTest ) // l'objet est sous la souris
{
MTH3D_tdstVector stTemp;
ACP_tdxIndex i;
POS_fn_vMulMatrixVertex(&stTemp, g_p_stCurrentMatrix, p_stCameraPos);
for(i=0; i<xNbElements; i++)
{
POS_fn_vMulMatrixVertex(&(p_stPickedObject->aDEF_stDataOfElement[i].stHit),
g_p_stCurrentMatrix,
&(p_stPickedObject->aDEF_stDataOfElement[i].stHit));
switch(xModePicking)
{
case PIC_C_ModePickingFace:
p_stPickedObject->aDEF_stDataOfElement[i].xDistance =
MTH3D_M_xVectorGap(&stTemp, &(p_stPickedObject->aDEF_stDataOfElement[i].stHit));
break;
case PIC_C_ModePickingEdge:
p_stPickedObject->aDEF_stDataOfElement[i].xDistance =
MTH3D_M_xVectorGap(&(p_stPickedObject->aDEF_stDataOfElement[i].stHit),
p_stObject->d_stListOfPoints + p_stPickedObject->aDEF_stDataOfElement[i].xIndexOfEdge);
break;
case PIC_C_ModePickingPoint:
p_stPickedObject->aDEF_stDataOfElement[i].xDistance =
MTH3D_M_xVectorGap(&(p_stPickedObject->aDEF_stDataOfElement[i].stHit),
p_stObject->d_stListOfPoints + p_stPickedObject->aDEF_stDataOfElement[i].xIndexOfPoint);
break;
}
}
p_stPickedObject->xNbElements = xNbElements;
p_stPickedObject->xModePicking = xModePicking;
bReturn = TRUE;
}
}
return bReturn;
}
#endif // ACTIVE_EDITOR