//------------------------------------------------------------- // Gestion des deplacements en 3d a l'aide de la souris. // Olivier Didelot le 15 decembre 1995. // modification : Marc Villemain le 04/07/96 : adaptation ACP //------------------------------------------------------------- #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" typedef enum { ECRAN = 0 , MAP } tdeTContrainte ; #ifdef ACTIVE_EDITOR static tdeTContrainte sTypeContrainte = ECRAN; static GLI_tdst2DVertex stMouse2DPrec; static MTH3D_tdstVector stPointMobil; static GLI_tdstCamera *p_stCamPrec; static BOOL gOkPourDeplacement = FALSE ; static POS_tdstCompletePosition stMatrixPrec; static GLD_tdhDevice g_hDev; static GLD_tdhViewport g_hVp; #endif //*************************************************************************** // Definition of the plan as a non define plan. //*************************************************************************** #ifdef ACTIVE_EDITOR void PIC_vCreatePlan ( PIC_tdstEqPlan *p_stPlan ) { p_stPlan -> xA = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xB = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xC = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xD = GLI_M_FloatToValue ( 0.0 ) ; } #endif //*************************************************************************** // Return true if the plan is undefine. //*************************************************************************** #ifdef ACTIVE_EDITOR BOOL PIC_cIsPlanNull ( PIC_tdstEqPlan *p_stPlan ) { return ( (p_stPlan -> xA == GLI_M_FloatToValue ( 0.0 ) ) && (p_stPlan -> xB == GLI_M_FloatToValue ( 0.0 ) ) && (p_stPlan -> xC == GLI_M_FloatToValue ( 0.0 ) ) && (p_stPlan -> xD == GLI_M_FloatToValue ( 0.0 ) ) ) ; } #endif //*************************************************************************** // Definition of the plan thanks to his equation : // a.x+b.y+c.z+d=0 //*************************************************************************** #ifdef ACTIVE_EDITOR void PIC_vDefinePlanEquation ( PIC_tdstEqPlan *p_stPlan , GLI_tdxValue xA , GLI_tdxValue xB , GLI_tdxValue xC , GLI_tdxValue xD ) { p_stPlan -> xA = xA ; p_stPlan -> xB = xB ; p_stPlan -> xC = xC ; p_stPlan -> xD = xD ; } #endif //*************************************************************************** // Definition of the plan by a normal and a point. //*************************************************************************** #ifdef ACTIVE_EDITOR void PIC_vDefinePlanByNormale ( PIC_tdstEqPlan *p_stPlan , MTH3D_tdstVector *p_stNormal, MTH3D_tdstVector *p_stPoint ) { p_stPlan -> xA = p_stNormal -> xX ; p_stPlan -> xB = p_stNormal -> xY ; p_stPlan -> xC = p_stNormal -> xZ ; p_stPlan -> xD = GLI_M_Neg ( GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xA , p_stPoint -> xX ) , GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xB , p_stPoint -> xY ) , GLI_M_Mul ( p_stPlan -> xC , p_stPoint -> xZ ) ) ) ) ; } #endif //*************************************************************************** // Definition of the plan by 3 points. //*************************************************************************** #ifdef ACTIVE_EDITOR void PIC_vDefinePlanBy3Points ( PIC_tdstEqPlan *p_stPlan , MTH3D_tdstVector *p_stA, MTH3D_tdstVector *p_stB, MTH3D_tdstVector *p_stC ) { MTH3D_tdstVector stNormal ; GEO_xComputeNormalWeightedBySurf ( &stNormal , p_stA , p_stB , p_stC ) ; PIC_vDefinePlanByNormale ( p_stPlan , &stNormal, p_stA ) ; } #endif //*************************************************************************** // Definition of the plan as a perpendicular to the Z axe (horizontal plan), // and passing through the point (0, 0, Zo). //*************************************************************************** #ifdef ACTIVE_EDITOR void fn_vDefinePlanZConstant ( PIC_tdstEqPlan *p_stPlan , GLI_tdxValue stZConstant ) { p_stPlan -> xA = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xB = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xC = GLI_M_FloatToValue ( 1.0 ) ; p_stPlan -> xD = GLI_M_Neg ( stZConstant ) ; } #endif //*************************************************************************** // Definition of the plan as a perpendicular to the Y axe (vertical plan), // and passing through the point (0, Yo, 0). // Yo is a "long 1616". //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only void fn_vDefinePlanYConstant ( PIC_tdstEqPlan *p_stPlan , GLI_tdxValue stYConstant ) { p_stPlan -> xA = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xB = GLI_M_FloatToValue ( 1.0 ) ; p_stPlan -> xC = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xD = GLI_M_Neg ( stYConstant ) ; } #endif //*************************************************************************** // Definition of the plan as a perpendicular to the X axe (vertical plan), // and passing through the point (Xo, 0, 0). // Xo is a "long 1616". //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only void fn_vDefinePlanXConstant ( PIC_tdstEqPlan *p_stPlan , GLI_tdxValue stXConstant ) { p_stPlan -> xA = GLI_M_FloatToValue ( 1.0 ) ; p_stPlan -> xB = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xC = GLI_M_FloatToValue ( 0.0 ) ; p_stPlan -> xD = GLI_M_Neg ( stXConstant ) ; } #endif //*************************************************************************** // Modify equation of a plan : the plan become parallel to himself but he // passes through a particular point. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only void fn_vRecalePlanPoint ( PIC_tdstEqPlan *p_stPlan , MTH3D_tdstVector *p_stPoint ) { // On ne recalcul que le parametre xD. p_stPlan -> xD = GLI_M_Neg ( GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xA , p_stPoint -> xX ) , GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xB , p_stPoint -> xY ) , GLI_M_Mul ( p_stPlan -> xC , p_stPoint -> xZ ) ) ) ) ; } #endif //*************************************************************************** // Intersection between a plan and a line. // Input: // p_stA, p_stB --> The line. // Output: // p_stInter --> Intersection point. // Return TRUE if the Intersection exist, FALSE otherwise. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only BOOL PIC_bIntersectionPlanDroite ( PIC_tdstEqPlan *p_stPlan , MTH3D_tdstVector *p_stA , MTH3D_tdstVector *p_stB , MTH3D_tdstVector *p_stInter ) { GLI_tdxValue xReturnEqA , xReturnEqAB , xDivReturnEq ; MTH3D_tdstVector stAB ; MTH3D_M_vSubVector ( &stAB, p_stB, p_stA ) ; xReturnEqA = GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xA , p_stA -> xX ) , GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xB , p_stA -> xY ) , GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xC , p_stA -> xZ ) , p_stPlan -> xD ) ) ) ; xReturnEqAB = GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xA , stAB . xX ) , GLI_M_Add ( GLI_M_Mul ( p_stPlan -> xB , stAB . xY ) , GLI_M_Mul ( p_stPlan -> xC , stAB . xZ ) ) ) ; if ( xReturnEqAB == GLI_M_FloatToValue ( 0.0 ) ) /* le vecteur AB est dans le plan */ return FALSE ; xDivReturnEq = GLI_M_Neg ( GLI_M_Div ( xReturnEqA , xReturnEqAB ) ) ; p_stInter->xX = GLI_M_Add ( p_stA -> xX , GLI_M_Mul( xDivReturnEq , GLI_M_Sub ( p_stB -> xX , p_stA -> xX ) ) ) ; p_stInter->xY = GLI_M_Add ( p_stA -> xY , GLI_M_Mul( xDivReturnEq , GLI_M_Sub ( p_stB -> xY , p_stA -> xY ) ) ) ; p_stInter->xZ = GLI_M_Add ( p_stA -> xZ , GLI_M_Mul( xDivReturnEq , GLI_M_Sub ( p_stB -> xZ , p_stA -> xZ ) ) ) ; return TRUE ; } #endif // Defini le plan de contrainte comme etant perpendiculaire a l'axe Z de la camera, // et passant par le point P. #ifdef ACTIVE_EDITOR // active editor only void fn_vDefScreenConstraint ( PIC_tdstEqPlan *p_stPlan , MTH3D_tdstVector *p_stPoint ) { MTH3D_tdstVector stAxeCameraZ, stTemp; POS_tdstCompletePosition stMatrix, stInvMatrix; POS_fn_vSetIdentityMatrix(&stMatrix); POS_fn_vSetIdentityMatrix(&stInvMatrix); GLI_xGetCameraMatrix ( p_stCamPrec , &stMatrix ); POS_fn_vInvertIsoMatrix( &stInvMatrix , &stMatrix ); stTemp . xX = GLI_M_FloatToValue ( 0.0 ); stTemp . xY = GLI_M_FloatToValue ( 0.0 ); stTemp . xZ = GLI_M_FloatToValue ( 1.0 ); POS_fn_vMulMatrixVertex( &stAxeCameraZ , &stInvMatrix , &stTemp ); POS_fn_vGetTranslationVector( &stInvMatrix , &stTemp ); MTH3D_M_vSubVector( &stAxeCameraZ, &stAxeCameraZ, &stTemp); PIC_vDefinePlanByNormale ( p_stPlan , &stAxeCameraZ , p_stPoint ); } #endif //*************************************************************************** // Definition of the constraint plan, thanks to CONTRAINTE and point wich is // defined by the editor (p_stPoint). //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only void fn_vDefPlanConstraint ( PIC_tdstEqPlan *p_stPlan , MTH3D_tdstVector *p_stPoint ) { switch (sTypeContrainte) { case MAP : break; case ECRAN : fn_vDefScreenConstraint ( p_stPlan , p_stPoint ) ; break ; } } #endif //*************************************************************************** // Calculate the mouse 3d position. The calculated point is the intersection // between line [camera position; 3d Mouse (on screen)] and constraint plan. // Return 1 if the intersection exist, 0 otherwise. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only BOOL fn_bCalculateMouse3DConstraint ( PIC_tdstEqPlan *p_stPlan, GLI_tdst2DVertex *p_stPoint2D, MTH3D_tdstVector *p_stPoint3D ) { MTH3D_tdstVector stPosMouse, stPosCam; POS_tdstCompletePosition stMatrix, stInvMatrix; PIC_vMouse3DScreen ( g_hDev, g_hVp, p_stPoint2D , &stPosMouse); if( p_stCamPrec->lCameraMode == GLI_C_lPersCamWithDistorsion || p_stCamPrec->lCameraMode == GLI_C_lPersCamWithoutDistorsion ) { POS_fn_vSetIdentityMatrix(&stMatrix); //AR980624 A position MUST be initialised ! POS_fn_vSetIdentityMatrix(&stInvMatrix); GLI_xGetCameraMatrix ( p_stCamPrec, &stMatrix ) ; POS_fn_vInvertIsoMatrix( &stInvMatrix , &stMatrix ); POS_fn_vGetTranslationVector( &stInvMatrix , &stPosCam ) ; } else if( p_stCamPrec->lCameraMode == GLI_C_lIsoCamWithDistorsion || p_stCamPrec->lCameraMode == GLI_C_lIsoCamWithoutDistorsion ) { MTH3D_tdstVector stAxeCameraZ, stTemp; GLI_xGetCameraMatrix ( p_stCamPrec , &stMatrix ); POS_fn_vInvertIsoMatrix( &stInvMatrix , &stMatrix ); stTemp . xX = GLI_M_FloatToValue ( 0.0 ); stTemp . xY = GLI_M_FloatToValue ( 0.0 ); stTemp . xZ = GLI_M_FloatToValue ( 1.0 ); POS_fn_vMulMatrixVertex( &stAxeCameraZ , &stInvMatrix , &stTemp ); MTH3D_M_vSubVector( &stPosCam, &stPosMouse, &stAxeCameraZ); } return PIC_bIntersectionPlanDroite ( p_stPlan , &stPosCam , &stPosMouse , p_stPoint3D ) ; } #endif //*************************************************************************** // Calculate the mouse 3d position. The calculated point is on the map. // Return 1 if this position exist, 0 otherwise. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only BOOL fn_bCalculateMouse3DMap( GLI_tdst2DVertex *p_stPoint2D , MTH3D_tdstVector *p_stPoint3D ) { return FALSE ; } #endif //*************************************************************************** // Calculate the mouse 3d position. // Return 1 if this position exist, 0 otherwise. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only BOOL fn_bCalculateMouse3D ( PIC_tdstEqPlan *p_stPlan , GLI_tdst2DVertex *p_stPoint2D , MTH3D_tdstVector *p_stPoint3D ) { switch (sTypeContrainte) { case MAP : return fn_bCalculateMouse3DMap ( p_stPoint2D , p_stPoint3D ) ; case ECRAN : default : return fn_bCalculateMouse3DConstraint ( p_stPlan , p_stPoint2D , p_stPoint3D ) ; } } #endif //*************************************************************************** // Calculate the moving vector of 3d Mouse. This moving is constraint by the // plan PlanC in the constraint mode else the moving is in the screen plan. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only BOOL fn_bCalculateVectorMouse3D ( PIC_tdstEqPlan *p_stPlan , GLI_tdst2DVertex *p_stMouse2D , MTH3D_tdstVector *p_stVect ) { MTH3D_tdstVector stMouse3D , stMouse3DPrec ; BOOL bTest1, bTest2 ; bTest1 = fn_bCalculateMouse3D ( p_stPlan , &stMouse2DPrec , &stMouse3DPrec) ; bTest2 = fn_bCalculateMouse3D ( p_stPlan , p_stMouse2D , &stMouse3D ) ; if (bTest1 && bTest2) { MTH3D_M_vSubVector ( p_stVect ,&stMouse3D, &stMouse3DPrec ) ; return TRUE ; } else return FALSE ; } #endif //*************************************************************************** // Calculate the moving vector of 3d Mouse, if this is possible. // Input : // p_stMouse2D --> Mouse coordinates. // Output : // p_stVect --> Moving vector. // Return : // FALSE if no vecteur, else TRUE. //*************************************************************************** #ifdef ACTIVE_EDITOR // active editor only BOOL PIC_bGetVecteurDeplacement ( GLI_tdst2DVertex *p_stMouse2D , MTH3D_tdstVector *p_stVect ) { PIC_tdstEqPlan stPlan; MTH3D_tdstVector stVectCam; POS_tdstCompletePosition stMatrix, stChangeMatrix, stMatTemp; if( !gOkPourDeplacement ) return FALSE ; GLI_xGetCameraMatrix ( p_stCamPrec , &stMatTemp ); POS_fn_vInvertIsoMatrix( &stMatrix , &stMatTemp ); POS_fn_vMulMatrixMatrix( &stChangeMatrix, &stMatrix, &stMatrixPrec); POS_fn_vMulMatrixVertex( &stVectCam, &stChangeMatrix, &stPointMobil); MTH3D_M_vSubVector(&stVectCam, &stVectCam, &stPointMobil); // Calcul du deplacement de l'objet dû a la souris fn_vDefPlanConstraint( &stPlan , &stPointMobil ) ; if (! fn_bCalculateVectorMouse3D ( &stPlan , p_stMouse2D, p_stVect ) ) return FALSE ; // On tient compte du deplacement de la camera MTH3D_M_vAddVector(p_stVect, p_stVect, &stVectCam); // Pour le deplacement suivant stMatrixPrec = stMatTemp; stMouse2DPrec = *p_stMouse2D ; // mise a jour du point mobil MTH3D_M_vAddVector( &stPointMobil, &stPointMobil, p_stVect ) ; return TRUE ; } #endif #ifdef ACTIVE_EDITOR void PIC_vInitDeplacement ( GLD_tdhDevice hDev , GLD_tdhViewport hVp , GLI_tdst2DVertex *p_stMouse2D , MTH3D_tdstVector *p_stPointMobil) { GLI_tdstSpecificAttributesFor3D *p_stSpecAttrib3D; GLD_tdstViewportAttributes stViewAttrib; g_hDev = hDev; g_hVp = hVp; if ( !GLD_bGetViewportAttributes( hDev, hVp, &stViewAttrib ) ) return; p_stSpecAttrib3D = (GLI_tdstSpecificAttributesFor3D *)stViewAttrib.p_vSpecificToXD; p_stCamPrec = p_stSpecAttrib3D->p_stCam; stMouse2DPrec = *p_stMouse2D ; gOkPourDeplacement = TRUE ; stPointMobil = *p_stPointMobil; GLI_xGetCameraMatrix( p_stCamPrec , &stMatrixPrec ); } #endif #ifdef ACTIVE_EDITOR void PIC_vEndDeplacement ( void ) { gOkPourDeplacement = FALSE ; } #endif