From d9c9622972148a425897fce0d0af762e3718c7f2 Mon Sep 17 00:00:00 2001 From: SaraP Date: Thu, 23 Jan 2025 10:07:48 +0100 Subject: [PATCH] =?UTF-8?q?EgtGraphics=202.7a2=20:=20-=20aggiunta=20vista?= =?UTF-8?q?=20prospettica=20con=20due=20modalit=C3=A0=20di=20zoom=20(=20st?= =?UTF-8?q?andard=20e=20dolly).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EgtGraphics.rc | Bin 11606 -> 11606 bytes Scene.h | 22 ++++- SceneBasic.cpp | 47 +++++++--- SceneCamera.cpp | 221 ++++++++++++++++++++++++++++++++++++++++----- SceneGlobFrame.cpp | 7 +- SceneSnap.cpp | 136 ++++++++++++++++------------ 6 files changed, 334 insertions(+), 99 deletions(-) diff --git a/EgtGraphics.rc b/EgtGraphics.rc index 6742815d18f54d415a0ab302bb4a7c78d9d9e39f..0780f2c070dabe289127d27e0f5836ae82cdaabe 100644 GIT binary patch delta 247 zcmcZ>buDVcI%aiGhCGIJh8%`ehGHOAV9;O)W+-7u1ma8}FBB-731Ux9)RLaOPc3V6 z9LpRgMx)IK`SvqS;?bF0pr{7qU6ib3+}y@(#SE6w1yL6zs~IbuDVcI%aKGhCGIJh8%`WhGK>c1_cHUhESkLCPN8BDnkm89}HwAf_cT06Sbr_ ze_&=~W;EQ~C?^P{CKn3pZa$#s$GEwL+X5oIpJ{TOWFB0~hjDX?uoW&TH)*I8l3^yK sy6NELJe_%ytJFkzL9X`%yEliS66D&+ADFW?tElTRqe^W~)cVQ<0C7e`aR2}S diff --git a/Scene.h b/Scene.h index f825be6..8d2da2e 100644 --- a/Scene.h +++ b/Scene.h @@ -112,6 +112,8 @@ class Scene : public IEGrScene bool ZoomOnPoint( const Point3d& ptWin, double dCoeff) override ; bool ZoomWin( const Point3d& ptWin1, const Point3d& ptWin2) override ; void GetOrthoCamParam( double* pdWidth, double* pdHeight, double* pdNear, double* pdFar) const override ; + bool SetCameraType( bool bOrthoOrPersp) override ; + bool SetZoomType( int nZoomMode) override ; // ShowMode bool SetShowMode( int nShowMode) override { if ( nShowMode != SM_WIREFRAME && @@ -248,6 +250,8 @@ class Scene : public IEGrScene bool VerifyCamera( bool bUseOrizzOffsCamera = false) ; bool CalcDirUp( bool bUseOrizzOffsCamera = false) ; bool CalcCameraFrame( Frame3d& frView) ; + double CalcMinCameraDistance() ; + bool CalcDistCamera() ; // Geometry bool DrawGroup( int nId, int nPass, const MdStMkCol& siParent) ; bool DrawGroup( const IGdbIterator& iIter, int nPass, const MdStMkCol& siParent) ; @@ -294,16 +298,19 @@ class Scene : public IEGrScene HDC m_hDC ; // Device Context HGLRC m_hRC ; // OpenGL Rendering Context int m_nOglVer ; // OpenGL Version - bool m_bNewWay ; // flag che indica nuova modalità (OpenGL 3.0 in poi) + bool m_bNewWay ; // flag che indica nuova modalità (OpenGL 3.0 in poi) // Camera - Point3d m_ptCenter ; // centro verso cui è rivolta la camera + Point3d m_ptCenter ; // centro verso cui è rivolta la camera Vector3d m_vtDirCamera ; // versore direzione dal centro alla camera int m_nOrizzOffsCamera ; // offset orizzontale viste camera in multipli di 90deg double m_dDistCamera ; // distanza dal centro alla camera + bool m_bDistOk ; // flag per stato aggiornamento di dDistCamera Vector3d m_vtUp ; // versore direzione Su della camera bool m_bUpOk ; // flag per stato aggiornamento di Up int m_nViewportW ; // larghezza della finestra int m_nViewportH ; // altezza della finestra + bool m_bOrthographic ; // flag che indica se camera ortografica o prospettica + int m_nPerspZoomType ; // flag che indica tipologia di zoom in vista prospettica ( standard, dolly) // Textures TextureMgr m_TextMgr ; // gestore di textures // Background @@ -313,7 +320,7 @@ class Scene : public IEGrScene int m_nShowMode ; // modo di visualizzazione (wireframe, hiddenline, shading) bool m_bShowCurveDirection ; // flag di visualizzazione direzione curve bool m_bShowTriaAdvanced ; // flag per abilitare la visualizzazione avanzata dei triangoli - int m_nShowZmap ; // modo visualizzazione Zmap (+1=surf, +2=spilloni, +4=normali, +8=più colori) + int m_nShowZmap ; // modo visualizzazione Zmap (+1=surf, +2=spilloni, +4=normali, +8=più colori) int m_nShowText ; // modo visualizzazione scritte (1=solo contorni, 2=con riempimento) // PointSize - LineWidth double m_dPointSize ; // dimensione punti @@ -338,9 +345,9 @@ class Scene : public IEGrScene SelRec m_nSelBuff[DIM_SEL_BUF] ; // buffer per selezione con OpenGL // Snap // lo snap a oggetti usa la select, quindi anche per esso valgono m_nObjFilterForSelect e m_Unsel - int m_nLastSnapId ; // Id dell'entità generatrice dell'ultimo punto snap + int m_nLastSnapId ; // Id dell'entità generatrice dell'ultimo punto snap Point3d m_ptLastSnapPnt ; // ultimo punto di snap - bool m_bLastSnapDirOk ; // flag validità direzione associata a ultimo punto snap + bool m_bLastSnapDirOk ; // flag validità direzione associata a ultimo punto snap Vector3d m_vtLastSnapDir ; // direzione associata a ultimo punto snap // Geometry IGeomDB* m_pGeomDB ; // puntatore al DB geometrico @@ -389,3 +396,8 @@ class Scene : public IEGrScene Point3d m_ptWinRectP1 ; // primo estremo del rettangolo diretto Point3d m_ptWinRectP2 ; // secondo estremo del rettangolo diretto } ; + + +//---------------------------------------------------------------------------- +static const double PERSPECTIVE_NEAR_PLANE = 10 ; +static const double PERSPECTIVE_STD_FOV = 45 ; diff --git a/SceneBasic.cpp b/SceneBasic.cpp index f6c364b..ec5af4b 100644 --- a/SceneBasic.cpp +++ b/SceneBasic.cpp @@ -57,12 +57,14 @@ Scene::Scene( void) SetCamera( 0, 0, 0) ; m_nViewportW = 0 ; m_nViewportH = 0 ; + m_bOrthographic = true ; + m_nPerspZoomType = ZT_STD ; // Textures m_TextMgr.SetScene( this) ; // Sfondo m_colBackTop.Set( 176, 176, 176) ; m_colBackBottom.Set( 176, 176, 176) ; - // Modalità di visualizzazione + // Modalità di visualizzazione m_nShowMode = SM_WIREFRAME ; m_bShowCurveDirection = false ; m_bShowTriaAdvanced = true ; @@ -138,7 +140,7 @@ Scene::Init( IGeomDB* pGeomDB) bool Scene::CreateContext( HDC hDC, int nDriver, bool b2Buff, int nColorBits, int nDepthBits) { - // verifico validità Device Context + // verifico validità Device Context if ( hDC == nullptr) return false ; m_hDC = hDC ; @@ -215,7 +217,7 @@ Scene::CreateContext( HDC hDC, int nDriver, bool b2Buff, int nColorBits, int nDe LOG_INFO( GetEGrLogger(), "WGL_ARB_create_context missing !") } - // verifico validità Rendering Context + // verifico validità Rendering Context if ( m_hRC == nullptr) return false ; @@ -226,7 +228,7 @@ Scene::CreateContext( HDC hDC, int nDriver, bool b2Buff, int nColorBits, int nDe if ( GlewInitResult != GLEW_OK) LOG_INFO( GetEGrLogger(), "GLEW is not initialized !") - // verifico se posso lavorare in modalità nuova + // verifico se posso lavorare in modalità nuova m_bNewWay = ( nDriver == OD_NEW && glewIsSupported( "GL_VERSION_3_0") == 1) ; if ( ! m_bNewWay) LOG_INFO( GetEGrLogger(), "OpenGL old way rendering !") @@ -288,11 +290,11 @@ Scene::ChooseGenPixelFormat( int nPfd, bool b2Buff, int nColorBits, int nDepthBi bool Scene::MakeCurrent( void) const { - // se RC della scena non è definito, errore + // se RC della scena non è definito, errore if ( m_hRC == nullptr) return false ; - // se RC della scena è quello corrente, ok + // se RC della scena è quello corrente, ok HGLRC hRC = wglGetCurrentContext() ; if ( m_hRC == hRC) return true ; @@ -419,7 +421,7 @@ Scene::SetExtension( const BBox3d& b3Ext) bool Scene::CalcExtView( void) { - // verifico se il calcolo è necessario + // verifico se il calcolo è necessario if ( m_bExtViewOk && m_bUpOk) return true ; // calcolo direzione camera Up @@ -515,8 +517,14 @@ Scene::CalcClippingPlanesFromExtView( void) // ricavo la posizione dei piani di clipping sull'asse Z di vista const double EXP_COEFF = 1.1 ; double dExtent = max( ( EXP_COEFF * vtExtent.z), MIN_ZCLIP_EXT) ; - m_dZNear = - ( ptCenter.z + dExtent) ; - m_dZFar = - ( ptCenter.z - dExtent) ; + if ( m_bOrthographic) { + m_dZNear = - ( ptCenter.z + dExtent) ; + m_dZFar = - ( ptCenter.z - dExtent) ; + } + else { + m_dZNear = PERSPECTIVE_NEAR_PLANE ; + m_dZFar = abs( ptCenter.z - dExtent) ; + } return true ; } @@ -673,6 +681,9 @@ Scene::Prepare( void) // eventuale ricalcolo parametri di vista CalcDirUp() ; + CalcDistCamera() ; + if ( ! m_bOrthographic) + m_bDistOk = false ; // resetto il flag per le prossime operazioni // imposto matrice di proiezione glMatrixMode( GL_PROJECTION) ; @@ -684,7 +695,17 @@ Scene::Prepare( void) // imposto area di pick gluPickMatrix( m_ptSelCent.x, ( Viewport[3] - m_ptSelCent.y), m_nSelW, m_nSelH, Viewport) ; } - glOrtho( - m_dHalfWidth, m_dHalfWidth, - m_dHalfHeight, m_dHalfHeight, m_dZNear, m_dZFar) ; + + if ( m_bOrthographic) + glOrtho( - m_dHalfWidth, m_dHalfWidth, - m_dHalfHeight, m_dHalfHeight, m_dZNear, m_dZFar) ; + else { + // calcolo del fov : se dolly è costante, se zoom standard deve adattarsi alla vista + double dFov = PERSPECTIVE_STD_FOV ; + if ( m_nPerspZoomType == ZT_STD) + dFov = 2 * atan2( m_dHalfHeight, m_dDistCamera) * RADTODEG ; + + gluPerspective( abs( dFov), m_dHalfWidth / m_dHalfHeight, m_dZNear, m_dZFar) ; + } // imposto matrice modello/vista glMatrixMode( GL_MODELVIEW) ; @@ -731,12 +752,12 @@ Scene::MyDraw( bool bSwapBF) if ( m_pGeomDB != nullptr) m_pGeomDB->GetDefaultMaterial( m_colDef) ; - // impostazioni dipendenti dalla modalità di visualizzazione + // impostazioni dipendenti dalla modalità di visualizzazione switch ( m_nShowMode) { case SM_WIREFRAME : // disabilito illuminazione glDisable( GL_LIGHTING) ; - // disegno griglia senza illuminazione (già impostato) + // disegno griglia senza illuminazione (già impostato) DrawGrid() ; // imposto dati standard per punti e linee glPointSize( (float) GetPointSize()) ; @@ -749,7 +770,7 @@ Scene::MyDraw( bool bSwapBF) case SM_HIDDENLINE : // disabilito illuminazione glDisable( GL_LIGHTING) ; - // disegno griglia senza illuminazione (già impostato) + // disegno griglia senza illuminazione (già impostato) DrawGrid() ; // imposto dati standard per punti e linee glPointSize( (float) GetPointSize()) ; diff --git a/SceneCamera.cpp b/SceneCamera.cpp index de14c00..b44646b 100644 --- a/SceneCamera.cpp +++ b/SceneCamera.cpp @@ -24,6 +24,75 @@ using namespace std ; static const double MIN_DIST_CAMERA = 10 ; static const double STD_DIST_CAMERA = 1000 ; +//---------------------------------------------------------------------------- +bool +Scene::SetCameraType( bool bOrthoOrPersp) +{ + m_bOrthographic = bOrthoOrPersp ; + // ricalcolo i parametri di vista + m_bDistOk = false ; + CalcDistCamera() ; + CalcClippingPlanesFromExtView() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Scene::SetZoomType( int nZoomMode) +{ + if ( nZoomMode != ZT_STD && nZoomMode != ZT_DOLLY) + return false ; + m_nPerspZoomType = nZoomMode ; + return true ; +} + +//---------------------------------------------------------------------------- +double +Scene::CalcMinCameraDistance() +{ + double dMinDist = MIN_DIST_CAMERA ; + + // nel caso di vista prospettica la distanza della camera deve garantire di non finire dentro gli oggetti + if ( ! m_bOrthographic) { + + // calcolo il box di tutti gli oggetti visibili nel frame della camera + Frame3d frCamera ; + CalcCameraFrame( frCamera) ; + BBox3d b3Tot ; + if ( m_pGeomDB != nullptr) + m_pGeomDB->GetGlobalBBox( GDB_ID_ROOT, b3Tot, BBF_ONLY_VISIBLE) ; + b3Tot.ToLoc( frCamera) ; + + // la distanza minima della camera è quella che garantisce di trovarsi ad una distanza pari almeno a PERSPECTIVE_NEAR_PLANE + // dalla faccia del box davanti alla camera + Point3d ptMax = b3Tot.GetMax() ; + ptMax.ToGlob( frCamera) ; + dMinDist = ( ptMax - m_ptCenter) * m_vtDirCamera + PERSPECTIVE_NEAR_PLANE + 10 * EPS_SMALL ; + } + + return dMinDist ; +} + +//---------------------------------------------------------------------------- +bool +Scene::CalcDistCamera() +{ + // verifico se il calcolo è necessario + if ( m_bDistOk) + return true ; + + if ( m_dDistCamera < EPS_SMALL) + m_dDistCamera = STD_DIST_CAMERA ; + else { + double dMinDist = CalcMinCameraDistance() ; + if ( m_dDistCamera < dMinDist) + m_dDistCamera = dMinDist ; + } + m_bDistOk = true ; + return true ; +} + //---------------------------------------------------------------------------- bool Scene::SetCenter( const Point3d& ptCenter) @@ -41,9 +110,10 @@ Scene::SetCenter( const Point3d& ptCenter) bool Scene::SetCamera( double dAngVertDeg, double dAngOrizzDeg, double dDist) { - // assegno la direzione e la distanza + // assegno la direzione ed eventuale distanza m_vtDirCamera = FromSpherical( 1, dAngVertDeg, dAngOrizzDeg) ; - m_dDistCamera = dDist ; + if ( dDist > EPS_SMALL) + m_dDistCamera = dDist ; if ( ! VerifyCamera()) return false ; // se vista da sopra, impongo vtUp da angolo orizzontale @@ -103,7 +173,11 @@ Scene::SetCamera( int nDir, double dDist) } if ( nDir != CT_CPLANE) m_vtDirCamera.Rotate( Z_AX, m_nOrizzOffsCamera * ANG_RIGHT) ; - m_dDistCamera = dDist ; + + // assegno eventuale distanza + if ( dDist > EPS_SMALL) + m_dDistCamera = dDist ; + return VerifyCamera( nDir != CT_CPLANE) ; } @@ -114,15 +188,16 @@ Scene::VerifyCamera( bool bUseOrizzOffsCamera) // verifico il versore if ( ! m_vtDirCamera.Normalize()) m_vtDirCamera.Set( 0, 0, 1) ; - // verifico la distanza - if ( m_dDistCamera < EPS_SMALL) - m_dDistCamera = STD_DIST_CAMERA ; - else - m_dDistCamera = max( m_dDistCamera, MIN_DIST_CAMERA) ; + // ricalcolo direzione Up m_bUpOk = false ; if ( ! CalcDirUp( bUseOrizzOffsCamera)) return false ; + + // verifico la distanza + m_bDistOk = false ; + CalcDistCamera() ; + // ricalcolo ExtView m_bExtViewOk = false ; if ( ! CalcExtView()) @@ -203,11 +278,11 @@ Scene::GetProjectedCenter( void) const bool Scene::CalcDirUp( bool bUseOrizzOffsCamera) { - // verifico se il calcolo è necessario + // verifico se il calcolo è necessario if ( m_bUpOk) return true ; // direzione perpendicolare giacente nel piano XY - // ( m_vtDirCamera è opposta alla direzione in cui si guarda) + // ( m_vtDirCamera è opposta alla direzione in cui si guarda) Vector3d vtPerpXY = m_vtDirCamera ^ Z_AX ; if ( ! vtPerpXY.Normalize()) { vtPerpXY = -X_AX ; @@ -256,7 +331,14 @@ Scene::PanCamera( const Point3d& ptWinOld, const Point3d& ptWinNew) // calcolo lo spostamento tra i due punti Vector3d vtMove = ptWorldNew - ptWorldOld ; // applico questo spostamento al centro di vista - return SetCenter( GetCenter() - vtMove) ; + SetCenter( GetCenter() - vtMove) ; + // se dolly aggiusto la distanza per non entrare negli oggetti + if ( ! m_bOrthographic && m_nPerspZoomType == ZT_DOLLY) + CalcDistCamera() ; + else + m_bDistOk = true ; + + return true ; } //---------------------------------------------------------------------------- @@ -302,6 +384,33 @@ Scene::ZoomAll( void) // calcolo nuovi dati di ingombro CalcDimViewFromExtView() ; + + if ( ! m_bOrthographic) { + if ( m_nPerspZoomType == ZT_DOLLY) { + // adatto la distanza della camera in modo che il fov resti al valore standard + m_dDistCamera = m_dHalfHeight / tan( PERSPECTIVE_STD_FOV * 0.5 * DEGTORAD) + ( m_b3ExtView.GetMax().z - m_b3ExtView.GetMin().z) * 0.5 ; + } + else { + // verifico di non finire dentro l'oggetto + double dDiam ; m_b3ExtView.GetDiameter( dDiam) ; + if ( m_dDistCamera < dDiam * 0.5) + m_dDistCamera = dDiam * 0.5 ; + + // il valore di m_dHalfHeight calcolato dal box non garantisce che l'oggetto sia interamente contenuto nel frustum + // perchè è il valore in corrispondenza della faccia del box davanti alla camera. Per il calcolo del fov m_dHalfHeight + // deve essere calcolato in corrispondenza di m_ptCenter + // distanza della camera dalla faccia davanti del box + double dDist = m_dDistCamera - ( m_b3ExtView.GetMax().z - m_b3ExtView.GetMin().z) * 0.5 ; + // aggiorno le dimensioni + double dAspect = m_dHalfWidth / m_dHalfHeight ; + m_dHalfHeight = m_dHalfHeight / dDist * m_dDistCamera ; + m_dHalfWidth = m_dHalfHeight * dAspect ; + + } + } + // la distanza della camera è calcolata correttamente + m_bDistOk = true ; + CalcClippingPlanesFromExtView() ; return true ; @@ -344,8 +453,32 @@ Scene::ZoomObject( int nId) double dHalfHeight = COEFF * ( b3Obj.GetMax().y - b3Obj.GetMin().y) / 2 ; // imposto il centro e le dimensioni di vista - m_ptCenter = ptCent ; - return AdjustDimView( dHalfWidth, dHalfHeight) ; + m_ptCenter = ptCent ; + if ( ! AdjustDimView( dHalfWidth, dHalfHeight)) + return false ; + + if ( ! m_bOrthographic) { + // cfr conti analoghi in ZoomAll + if ( m_nPerspZoomType == ZT_DOLLY) { + m_dDistCamera = m_dHalfHeight / tan( PERSPECTIVE_STD_FOV * 0.5 * DEGTORAD) + ( b3Obj.GetMax().z - b3Obj.GetMin().z) * 0.5 ; + } + else { + // verifico di non finire dentro l'oggetto + double dDiam ; b3Obj.GetDiameter( dDiam) ; + if ( m_dDistCamera < dDiam * 0.5) + m_dDistCamera = dDiam * 0.5 ; + // distanza della camera dalla faccia davanti del box + double dDist = m_dDistCamera - ( b3Obj.GetMax().z - b3Obj.GetMin().z) * 0.5 ; + // ricalcolo le dimensioni + double dAspect = m_dHalfWidth / m_dHalfHeight ; + m_dHalfHeight = m_dHalfHeight / dDist * m_dDistCamera ; + m_dHalfWidth = m_dHalfHeight * dAspect ; + } + } + // la distanza della camera è calcolata per non finire dentro gli oggetti + m_bDistOk = true ; + + return true ; } //---------------------------------------------------------------------------- @@ -353,7 +486,19 @@ bool Scene::ZoomRadius( double dRadius) { // adatto le dimensioni a quelle della vista - return AdjustDimView( dRadius, dRadius) ; + if ( ! AdjustDimView( dRadius, dRadius)) + return false ; + + // per il dolly va modificata la distanza dalla camera + if ( ! m_bOrthographic && m_nPerspZoomType == ZT_DOLLY) { + m_dDistCamera = m_dHalfHeight / tan( PERSPECTIVE_STD_FOV * 0.5 * DEGTORAD) ; + // verifico la distanza della camera + CalcDistCamera() ; + } + else + m_bDistOk = true ; + + return true ; } //---------------------------------------------------------------------------- @@ -363,14 +508,17 @@ Scene::ZoomChange( double dCoeff) const double MIN_COEFF = 0.5 ; const double MAX_COEFF = 2 ; - // controllo i limiti - if ( dCoeff < MIN_COEFF) - dCoeff = MIN_COEFF ; - else if ( dCoeff > MAX_COEFF) - dCoeff = MAX_COEFF ; // cambio le dimensioni di zoom - m_dHalfWidth *= dCoeff ; - m_dHalfHeight *= dCoeff ; + if ( ! m_bOrthographic && m_nPerspZoomType == ZT_DOLLY) { + // per il dolly va modificata la distanza della camera + m_dDistCamera *= dCoeff ; + } + else { + // controllo i limiti + dCoeff = clamp( dCoeff, MIN_COEFF, MAX_COEFF) ; + m_dHalfWidth *= dCoeff ; + m_dHalfHeight *= dCoeff ; + } return true ; } @@ -384,10 +532,24 @@ Scene::ZoomOnPoint( const Point3d& ptWin, double dCoeff) Point3d ptWorld ; if ( ! UnProject( ptView, ptWorld)) return false ; + // modifico opportunamente il centro di vista - Point3d ptNewCen = ptWorld + ( GetCenter() - ptWorld) * dCoeff ; + Point3d ptOldCen = m_ptCenter ; + Point3d ptNewCen = ptWorld + ( m_ptCenter - ptWorld) * dCoeff ; SetCenter( ptNewCen) ; - // eseguo lo zoom + + // nel caso di dolly verifico se il nuovo zoom fa entrare negli oggetti + if ( ! m_bOrthographic && m_nPerspZoomType == ZT_DOLLY) { + double dMinDist = CalcMinCameraDistance() ; + if ( m_dDistCamera * dCoeff < dMinDist) { + // adatto il coefficiente di zoom e ricalcolo il centro + dCoeff = dMinDist / m_dDistCamera ; + Point3d ptNewCenter = ptWorld + ( ptOldCen - ptWorld) * dCoeff ; + SetCenter( ptNewCenter) ; + } + } + m_bDistOk = true ; + return ZoomChange( dCoeff) ; } @@ -421,7 +583,18 @@ Scene::ZoomWin( const Point3d& ptWin1, const Point3d& ptWin2) double dHalfHeight = 0.5 * abs( ptView1.y - ptView2.y) ; // adatto le dimensioni a quelle della vista - return AdjustDimView( dHalfWidth, dHalfHeight) ; + if ( ! AdjustDimView( dHalfWidth, dHalfHeight)) + return false ; + + // per il dolly va modificata la distanza della camera + if ( ! m_bOrthographic && m_nPerspZoomType == ZT_DOLLY) { + m_dDistCamera = m_dHalfHeight / tan( PERSPECTIVE_STD_FOV * 0.5 * DEGTORAD) ; + CalcDistCamera() ; + } + else + m_bDistOk = true ; + + return true ; } //---------------------------------------------------------------------------- diff --git a/SceneGlobFrame.cpp b/SceneGlobFrame.cpp index 8bef1c6..0d13401 100644 --- a/SceneGlobFrame.cpp +++ b/SceneGlobFrame.cpp @@ -39,8 +39,13 @@ Scene::DrawGlobFrame( void) GLint Viewport[ 4] ; glGetIntegerv( GL_VIEWPORT, Viewport) ; - // imposto il riferimento + // imposto il riferimento sempre in vista ortografica + glMatrixMode( GL_PROJECTION) ; glPushMatrix() ; + if ( ! m_bOrthographic) { + glLoadIdentity() ; + glOrtho( - m_dHalfWidth, m_dHalfWidth, - m_dHalfHeight, m_dHalfHeight, m_dZNear, m_dZFar) ; + } // origine del riferimento globale const double DIST_BORDER = 30 ; diff --git a/SceneSnap.cpp b/SceneSnap.cpp index aa0ce97..bd2cadb 100644 --- a/SceneSnap.cpp +++ b/SceneSnap.cpp @@ -48,7 +48,7 @@ Scene::GetGraphicSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH, Poi // reset dati associati a ultimo punto snap m_nLastSnapId = GDB_ID_NULL ; m_bLastSnapDirOk = false ; - // verifico validità GDB + // verifico validità GDB if ( m_pGeomDB == nullptr) return false ; // se Snap Sketch o Grid, devo trovare il punto sulla griglia @@ -58,14 +58,14 @@ Scene::GetGraphicSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH, Poi return true ; } } - // se Snap Intersection, devo trovare l'intersezione tra due entità inquadrate + // se Snap Intersection, devo trovare l'intersezione tra due entità inquadrate else if ( nSnap == SP_INTERS) { if ( FindSelectedIntersectionPoint( ptWin, nW, nH)) { ptSel = m_ptLastSnapPnt ; return true ; } } - // altrimenti devo trovare il punto dall'entità inquadrata + // altrimenti devo trovare il punto dall'entità inquadrata else { if ( FindSelectedSnapPoint( nSnap, ptWin, nW, nH)) { ptSel = m_ptLastSnapPnt ; @@ -88,9 +88,17 @@ Scene::GetGridSnapPointZ( bool bSketch, const Point3d& ptWin, const Point3d& ptG if ( ! UnProject( ptWin, ptLine)) return false ; Vector3d vtLine = - m_vtDirCamera ; + if ( ! m_bOrthographic) { + // nella vista prospettica la direzione di mira è data dalla linea che coingiunge le proiezioni di ptWin sui piani near e far + Point3d ptLine2 ; + if ( ! UnProject( Point3d( ptWin.x, ptWin.y, 1), ptLine2)) + return false ; + vtLine = ptLine - ptLine2 ; + vtLine.Normalize() ; + } // piano di elevazione : - // per il punto di griglia, contenente la perp. alla griglia e più perp. possibile alla direzione di mira + // per il punto di griglia, contenente la perp. alla griglia e più perp. possibile alla direzione di mira Vector3d vtNorm = vtLine - ( vtLine * frGrid.VersZ()) * frGrid.VersZ() ; if ( ! vtNorm.Normalize()) return false ; @@ -123,6 +131,14 @@ Scene::FindGridSnapPoint( bool bSketch, const Point3d& ptWin) if ( ! UnProject( ptWin, ptLine)) return false ; Vector3d vtLine = - m_vtDirCamera ; + if ( ! m_bOrthographic) { + // nella vista prospettica la direzione di mira è data dalla linea che coingiunge le proiezioni di ptWin sui piani near e far + Point3d ptLine2 ; + if ( ! UnProject( Point3d( ptWin.x, ptWin.y, 1), ptLine2)) + return false ; + vtLine = ptLine - ptLine2 ; + vtLine.Normalize() ; + } // determino l'intersezione di questa linea con il piano della griglia double dDenom = vtLine * frGrid.VersZ() ; @@ -133,7 +149,7 @@ Scene::FindGridSnapPoint( bool bSketch, const Point3d& ptWin) // porto il punto sul piano di griglia m_ptLastSnapPnt.ToLoc( frGrid) ; - // se punto grid, devo arrotondare al nodo di griglia più vicino + // se punto grid, devo arrotondare al nodo di griglia più vicino if ( ! bSketch) { m_ptLastSnapPnt.x = floor( m_ptLastSnapPnt.x / m_dSnapStep + 0.5) * m_dSnapStep ; m_ptLastSnapPnt.y = floor( m_ptLastSnapPnt.y / m_dSnapStep + 0.5) * m_dSnapStep ; @@ -150,9 +166,9 @@ bool Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) { // --- l'intersezione viene calcolata nel piano della griglia --- - // salvo eventuale ultima entità precedentemente selezionata + // salvo eventuale ultima entità precedentemente selezionata int nPrevSel = GetFirstSelectedObj() ; - // verifico siano state selezionate delle entità + // verifico siano state selezionate delle entità int nSel ; Select( ptWin, nW, nH, nSel) ; if ( nSel <= 0) @@ -164,7 +180,7 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) double dWinZ = 0 ; int nCrvNum = 0 ; for ( int nObjId = GetFirstSelectedObj() ; nObjId != GDB_ID_NULL && nCrvNum < 2 ; nObjId = GetNextSelectedObj()) { - // se non è entità geometrica + // se non è entità geometrica const IGeoObj* pGObj ; if ( ( pGObj = m_pGeomDB->GetGeoObj( nObjId)) == nullptr) continue ; @@ -180,11 +196,11 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) // se nessuna curva, esco if ( nCrvNum == 0) return false ; - // se una sola curva, può essere auto intersezione + // se una sola curva, può essere auto intersezione if ( nCrvNum == 1) { // recupero il riferimento di griglia Frame3d frGrid = GetGridFrame() ; - // se il riferimento della curva è diverso da quello della griglia, devo trasformarla + // se il riferimento della curva è diverso da quello della griglia, devo trasformarla PtrOwner pcrvTrans0 ; if ( ! AreSameFrame( frEnt[0], frGrid)) { pcrvTrans0.Set( pCrv[0]->Clone()) ; @@ -199,7 +215,7 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) if ( ! UnProject( ptWinZ, ptNear)) ptNear = ORIG ; ptNear.ToLoc( frGrid) ; - // calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento + // calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento SelfIntersCurve sintC( *pCrv[0]) ; if ( ! sintC.GetIntersPointNearTo( ptNear, m_ptLastSnapPnt)) return false ; @@ -211,7 +227,7 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) // altrimenti due curve, procedo normalmente // recupero il riferimento di griglia Frame3d frGrid = GetGridFrame() ; - // se il riferimento della prima curva è diverso da quello della griglia, devo trasformarla + // se il riferimento della prima curva è diverso da quello della griglia, devo trasformarla PtrOwner pcrvTrans0 ; if ( ! AreSameFrame( frEnt[0], frGrid)) { pcrvTrans0.Set( pCrv[0]->Clone()) ; @@ -220,7 +236,7 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) pcrvTrans0->LocToLoc( frEnt[0], frGrid) ; pCrv[0] = pcrvTrans0 ; } - // se il riferimento della seconda curva è diverso da quello della griglia, devo trasformarla + // se il riferimento della seconda curva è diverso da quello della griglia, devo trasformarla PtrOwner pcrvTrans1 ; if ( ! AreSameFrame( frEnt[1], frGrid)) { pcrvTrans1.Set( pCrv[1]->Clone()) ; @@ -235,7 +251,7 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) if ( ! UnProject( ptWinZ, ptNear)) ptNear = ORIG ; ptNear.ToLoc( frGrid) ; - // calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento + // calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento IntersCurveCurve intCC( *pCrv[0], *pCrv[1], true) ; if ( ! intCC.GetIntersPointNearTo( ( nPrevSel == nIds[1] ? 1 : 0), ptNear, m_ptLastSnapPnt)) return false ; @@ -249,20 +265,20 @@ Scene::FindSelectedIntersectionPoint( const Point3d& ptWin, int nW, int nH) bool Scene::FindSelectedSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH) { - // seleziono e verifico siano state selezionate delle entità + // seleziono e verifico siano state selezionate delle entità int nSel ; Select( ptWin, nW, nH, nSel) ; if ( nSel <= 0) return false ; - // cerco il punto notevole più vicino alla selezione tra le entità selezionate + // cerco il punto notevole più vicino alla selezione tra le entità selezionate bool bFound = false ; double dMinSqDist = INFINITO * INFINITO ; for ( int nId = GetFirstSelectedObj() ; nId != GDB_ID_NULL ; nId = GetNextSelectedObj()) { - // se non è entità geometrica + // se non è entità geometrica const IGeoObj* pGObj ; if ( ( pGObj = m_pGeomDB->GetGeoObj( nId)) == nullptr) continue ; - // recupero riferimento dell'entità + // recupero riferimento dell'entità Frame3d frEnt ; if ( ! m_pGeomDB->GetGlobFrame( nId, frEnt)) continue ; @@ -478,7 +494,7 @@ Scene::FindCurveSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame UnProject( ptWinZ, ptRef) ; // lo porto nel frame della curva ptRef.ToLoc( frEnt) ; - // determino il punto più vicino della curva a questo + // determino il punto più vicino della curva a questo MinDistPCInfo mdInfo ; DistPointCurve dstPtCurve( ptRef, *pCrv) ; if ( dstPtCurve.GetMinDistInfo( 0, mdInfo)) { @@ -505,7 +521,7 @@ Scene::FindCurveSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame bool Scene::VerifySnapPoint( const Point3d& ptP, const Point3d& ptWin, double& dMinSqDist) const { - // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione + // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione Point3d ptWinZ( ptWin.x, ptWin.y, GetSelectedObjMinWinZ()) ; // punto di riferimento nello spazio geometrico 3d Point3d ptRef ; @@ -513,7 +529,7 @@ Scene::VerifySnapPoint( const Point3d& ptP, const Point3d& ptWin, double& dMinSq return false ; // recupero la direzione di mira Vector3d vtDir = - m_vtDirCamera ; - // il punto di confronto è quello sulla linea di mira a minima distanza dal punto dato + // il punto di confronto è quello sulla linea di mira a minima distanza dal punto dato Point3d ptCfr = ptRef + (( ptP - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptP, ptCfr) ; @@ -553,10 +569,10 @@ Scene::AdjustForCurveExtr( const Point3d& ptWin, const Frame3d& frEnt, const ICu double dExtrSqDist = INFINITO ; DistPointCurve dstPtECurve( ptRef - vtExtr, *pCrv) ; dstPtECurve.GetSqDist( dExtrSqDist) ; - // se più vicino a base non devo modificare il punto + // se più vicino a base non devo modificare il punto if ( dBaseSqDist <= dExtrSqDist) return false ; - // più vicino ad estrusione, quindi la aggiungo + // più vicino ad estrusione, quindi la aggiungo ptP += vtExtr ; return true ; } @@ -574,7 +590,7 @@ Scene::FindCurveCompoSnapPoint( int nSnap, const Point3d& ptWin, int nId, const return false ; // porto il punto nel riferimento della curva ptRef.ToLoc( frEnt) ; - // se richiesto il centro di gravità (baricentro, centroide) + // se richiesto il centro di gravità (baricentro, centroide) if ( nSnap == SP_CENTROID) { Point3d ptP ; bool bFound = false ; @@ -591,11 +607,11 @@ Scene::FindCurveCompoSnapPoint( int nSnap, const Point3d& ptWin, int nId, const return bFound ; } // altrimenti opero sulle curve componenti elementari - // determino la curva elementare più vicina al punto di riferimento + // determino la curva elementare più vicina al punto di riferimento int nCrv = - 1 ; double dPar ; int nFlag ; - // cerco il punto della curva più vicino, dal suo parametro deduco la curva elementare + // cerco il punto della curva più vicino, dal suo parametro deduco la curva elementare if ( DistPointCurve( ptRef, *pCrvCompo).GetParamAtMinDistPoint( 0, dPar, nFlag)) nCrv = static_cast( dPar) ; // lavoro sulla curva elementare @@ -625,7 +641,7 @@ bool Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame3d& frEnt, const ISurfTriMesh* pStm, double& dMinSqDist) { - // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione + // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione Point3d ptWinZ( ptWin.x, ptWin.y, GetSelectedObjMinWinZ()) ; // punto di riferimento nello spazio geometrico 3d Point3d ptRef ; @@ -651,12 +667,12 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram Color cCol ; bool bAlpha = ( m_pGeomDB->GetCalcMaterial( nId, cCol) && cCol.GetIntAlpha() <= ALPHA_LIM) ; - // se richiesto il centro di gravità (baricentro, centroide) + // se richiesto il centro di gravità (baricentro, centroide) if ( nSnap == SP_CENTROID) { Point3d ptP ; bool bFound = false ; if ( pStm->GetCentroid( ptP)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal vertice + // il punto di confronto è quello sulla linea di mira a minima distanza dal vertice Point3d ptCfr = ptRef + (( ptP - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptP, ptCfr) ; @@ -668,7 +684,7 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram m_bLastSnapDirOk = false ; } } - // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive + // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME)) dMinSqDist = 0 ; return bFound ; @@ -678,7 +694,7 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram ILSIVECTOR vInfo ; if ( ! IntersLineSurfTm( ptMir, vtDir, dLenMir, *pStm, vInfo)) return false ; - // se non trovato alcunchè, cerco le linee che partono dagli angoli e dai punti medi dei lati del rettangolo di mira + // se non trovato alcunchè, cerco le linee che partono dagli angoli e dai punti medi dei lati del rettangolo di mira VCT3DVECTOR vVtWind = { {0.51, 0.51, 0}, {0, 0.51, 0}, {-0.51, 0.51, 0}, {-0.51, 0, 0}, {-0.51, -0.51, 0}, {0, -0.51, 0}, {0.51, -0.51, 0}, {0.51, 0, 0}, {0.25, 0.51, 0}, {-0.25, 0.51, 0}, {-0.51, 0.25, 0}, {-0.51, -0.25, 0}, @@ -709,12 +725,12 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram for ( int i = 0 ; i < nTtot ; ++ i) { // punto di intersezione Point3d ptInt = vInfo[i].ptI ; - // punto finale più vicino + // punto finale più vicino int nF = pStm->GetFacetFromTria( vInfo[i].nT) ; Point3d ptEnd ; Vector3d vtN ; if ( pStm->GetFacetNearestEndPoint( nF, ptInt, ptEnd, vtN)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal vertice + // il punto di confronto è quello sulla linea di mira a minima distanza dal vertice Point3d ptCfr = ptRef + (( ptEnd - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptEnd, ptCfr) ; @@ -737,12 +753,12 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram for ( int i = 0 ; i < nTtot ; ++ i) { // punto di intersezione Point3d ptInt = vInfo[i].ptI ; - // punto medio più vicino + // punto medio più vicino int nF = pStm->GetFacetFromTria( vInfo[i].nT) ; Point3d ptMid ; Vector3d vtN ; if ( pStm->GetFacetNearestMidPoint( nF, ptInt, ptMid, vtN)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal punto medio + // il punto di confronto è quello sulla linea di mira a minima distanza dal punto medio Point3d ptCfr = ptRef + (( ptMid - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptMid, ptCfr) ; @@ -763,12 +779,12 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram // con wireframe devo provare tutti i triangoli intersecati, con shading e hiddenline solo il primo int nTtot = (( bAlpha || m_nShowMode == SM_WIREFRAME) ? int( vInfo.size()) : 1) ; for ( int i = 0 ; i < nTtot ; ++ i) { - // centro più vicino + // centro più vicino int nF = pStm->GetFacetFromTria( vInfo[i].nT) ; Point3d ptCen ; Vector3d vtN ; if ( pStm->GetFacetCenter( nF, ptCen, vtN)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal centro + // il punto di confronto è quello sulla linea di mira a minima distanza dal centro Point3d ptCfr = ptRef + (( ptCen - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptCen, ptCfr) ; @@ -789,7 +805,7 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram case SP_PERP : case SP_MINDIST : // considero solo il primo triangolo intersecato - // la distanza è nulla e la confronto con il minimo + // la distanza è nulla e la confronto con il minimo if ( 0 < dMinSqDist) { bFound = true ; dMinSqDist = 0 ; @@ -815,7 +831,7 @@ Scene::FindSurfTMSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram break ; } - // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive + // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME) && dMinSqDist < SRF_SMALL_SQDIST) dMinSqDist = 0 ; @@ -827,7 +843,7 @@ bool Scene::FindSurfFRSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame3d& frEnt, const ISurfFlatRegion* pSfr, double& dMinSqDist) { - // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione + // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione Point3d ptWinZ( ptWin.x, ptWin.y, GetSelectedObjMinWinZ()) ; // punto di riferimento nello spazio geometrico 3d Point3d ptRef ; @@ -844,11 +860,11 @@ Scene::FindSurfFRSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram // elaborazione a seconda del tipo di snap bool bFound = false ; - // se richiesto il centro di gravità (baricentro, centroide) + // se richiesto il centro di gravità (baricentro, centroide) if ( nSnap == SP_CENTROID) { Point3d ptP ; if ( pSfr->GetCentroid( ptP)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal centro + // il punto di confronto è quello sulla linea di mira a minima distanza dal centro Point3d ptCfr = ptRef + (( ptP - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptP, ptCfr) ; @@ -861,12 +877,12 @@ Scene::FindSurfFRSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram } } } - // se richiesto il centro (è il centroide del chunk più vicino) + // se richiesto il centro (è il centroide del chunk più vicino) else if ( nSnap == SP_CENTER) { Point3d ptP ; for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) { if ( pSfr->GetChunkCentroid( i, ptP)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal centro + // il punto di confronto è quello sulla linea di mira a minima distanza dal centro Point3d ptCfr = ptRef + (( ptP - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptP, ptCfr) ; @@ -917,7 +933,7 @@ Scene::FindSurfFRSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fram } } - // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive + // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME) && dMinSqDist < SRF_SMALL_SQDIST) dMinSqDist = 0 ; @@ -929,7 +945,7 @@ bool Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Frame3d& frEnt, const IVolZmap* pVzm, double& dMinSqDist) { - // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione + // il punto di riferimento deriva da XY su viewport e Z minima (più vicina a osservatore) da selezione Point3d ptWinZ( ptWin.x, ptWin.y, GetSelectedObjMinWinZ()) ; // punto di riferimento nello spazio geometrico 3d Point3d ptRef ; @@ -954,13 +970,13 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra Color cCol ; bool bAlpha = ( m_pGeomDB->GetCalcMaterial( nId, cCol) && cCol.GetIntAlpha() <= ALPHA_LIM) ; - // se richiesto il centro di gravità (baricentro, centroide) + // se richiesto il centro di gravità (baricentro, centroide) if ( nSnap == SP_CENTROID) { Point3d ptP ; bool bFound = false ; BBox3d b3Loc ; if ( pVzm->GetLocalBBox( b3Loc) && b3Loc.GetCenter( ptP)) { - // il punto di confronto è quello sulla linea di mira a minima distanza dal vertice + // il punto di confronto è quello sulla linea di mira a minima distanza dal vertice Point3d ptCfr = ptRef + (( ptP - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptP, ptCfr) ; @@ -972,7 +988,7 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra m_bLastSnapDirOk = false ; } } - // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive + // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME)) dMinSqDist = 0 ; return bFound ; @@ -982,7 +998,7 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra ILZIVECTOR vInfo ; if ( ! IntersLineVolZmap( ptMir, vtDir, *pVzm, vInfo)) return false ; - // se non trovato alcunchè, cerco le linee che partono dagli angoli del rettangolo di mira + // se non trovato alcunchè, cerco le linee che partono dagli angoli del rettangolo di mira Vector3d vtWinD( -1, -1, 0) ; for ( int i = 0 ; i < 4 && vInfo.size() == 0 ; ++ i) { // determino punto su vertice del rettangolo di selezione @@ -1011,7 +1027,7 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra for ( int i = 0 ; i < nTtot ; ++ i) { // triangolo Triangle3d& trTria = vInfo[i].trTria ; - // recupero il vertice del triangolo più vicino alla linea di mira + // recupero il vertice del triangolo più vicino alla linea di mira int nVert ; double dSqDist ; if ( GetTriaVertexNearestToLine( trTria, ptRef, vtDir, nVert, dSqDist) && dSqDist < dMinSqDist) { bFound = true ; @@ -1031,7 +1047,7 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra for ( int i = 0 ; i < nTtot ; ++ i) { // triangolo Triangle3d& trTria = vInfo[i].trTria ; - // recupero il punto medio del lato del triangolo più vicino alla linea di mira + // recupero il punto medio del lato del triangolo più vicino alla linea di mira Point3d ptMid ; double dSqDist ; if ( GetTriaMidEdgeNearestToLine( trTria, ptRef, vtDir, ptMid, dSqDist) && dSqDist < dMinSqDist) { bFound = true ; @@ -1051,9 +1067,9 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra for ( int i = 0 ; i < nTtot ; ++ i) { // triangolo Triangle3d& trTria = vInfo[i].trTria ; - // centro più vicino + // centro più vicino Point3d ptCen = trTria.GetCentroid() ; - // il punto di confronto è quello sulla linea di mira a minima distanza dal centro + // il punto di confronto è quello sulla linea di mira a minima distanza dal centro Point3d ptCfr = ptRef + (( ptCen - ptRef) * vtDir) * vtDir ; // determino la distanza e la confronto con il minimo double dSqDist = SqDist( ptCen, ptCfr) ; @@ -1073,7 +1089,7 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra case SP_PERP : case SP_MINDIST : // considero solo il primo triangolo intersecato - // la distanza è nulla e la confronto con il minimo + // la distanza è nulla e la confronto con il minimo if ( 0 < dMinSqDist) { bFound = true ; dMinSqDist = 0 ; @@ -1087,7 +1103,7 @@ Scene::FindVolZmapSnapPoint( int nSnap, const Point3d& ptWin, int nId, const Fra break ; } - // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive + // se trovato e modalità shading o hiddenline, la favorisco perchè davanti alle possibili successive if ( bFound && ! ( bAlpha || m_nShowMode == SM_WIREFRAME) && dMinSqDist < SRF_SMALL_SQDIST) dMinSqDist = 0 ; @@ -1275,6 +1291,14 @@ Scene::GetPlaneSnapPoint( const Point3d& ptWin, const Plane3d& plPlane, Point3d& if ( ! UnProject( ptWin, ptLine)) return false ; Vector3d vtLine = - m_vtDirCamera ; + if ( ! m_bOrthographic) { + // nella vista prospettica la direzione di mira è data dalla linea che coingiunge le proiezioni di ptWin sui piani near e far + Point3d ptLine2 ; + if ( ! UnProject( Point3d( ptWin.x, ptWin.y, 1), ptLine2)) + return false ; + vtLine = ptLine - ptLine2 ; + vtLine.Normalize() ; + } // determino l'intersezione di questa linea con il piano double dDenom = vtLine * plPlane.GetVersN() ;