EgtGraphics 1.5b1 : primo commit.
This commit is contained in:
+295
@@ -0,0 +1,295 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SceneCamera.cpp Data : 10.02.14 Versione : 1.5b1
|
||||
// Contenuto : Implementazione della gestione camera della classe scena.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 10.02.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "Scene.h"
|
||||
#include "/EgtDev/Include/EgtILogger.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//--------------------------- Constants --------------------------------------
|
||||
static const double MIN_DIST_CAMERA = 10 ;
|
||||
static const double STD_DIST_CAMERA = 1000 ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::SetCenter( const Point3d& ptCenter)
|
||||
{
|
||||
// assegno il punto
|
||||
m_ptCenter = ptCenter ;
|
||||
// invalido ExtView
|
||||
m_bExtViewOk = false ;
|
||||
// calcolo nuovi dati di Z clipping
|
||||
CalcClippingPlanesFromExtView() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::SetCamera( double dAngVertDeg, double dAngOrizzDeg, double dDist)
|
||||
{
|
||||
// assegno la direzione e la distanza
|
||||
m_vtDirCamera.FromSpherical( 1, dAngVertDeg, dAngOrizzDeg) ;
|
||||
if ( dDist < EPS_SMALL)
|
||||
m_dDistCamera = STD_DIST_CAMERA ;
|
||||
else
|
||||
m_dDistCamera = __max( dDist, MIN_DIST_CAMERA) ;
|
||||
// invalido Up e ExtView
|
||||
m_bUpOk = false ;
|
||||
m_bExtViewOk = false ;
|
||||
// calcolo nuovi dati di Z clipping
|
||||
CalcClippingPlanesFromExtView() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::SetCamera( int nDir, double dDist)
|
||||
{
|
||||
const double ANG_VERT_ISOVIEW = 54.73561032 ;
|
||||
double dAngVertDeg ;
|
||||
double dAngOrizzDeg ;
|
||||
|
||||
|
||||
switch ( nDir) {
|
||||
case CT_TOP :
|
||||
dAngVertDeg = 0 ;
|
||||
dAngOrizzDeg = 0 ;
|
||||
break ;
|
||||
case CT_FRONT :
|
||||
dAngVertDeg = 90 ;
|
||||
dAngOrizzDeg = -90 ;
|
||||
break ;
|
||||
case CT_RIGHT :
|
||||
dAngVertDeg = 90 ;
|
||||
dAngOrizzDeg = 0 ;
|
||||
break ;
|
||||
case CT_BACK :
|
||||
dAngVertDeg = 90 ;
|
||||
dAngOrizzDeg = 90 ;
|
||||
break ;
|
||||
case CT_LEFT :
|
||||
dAngVertDeg = 90 ;
|
||||
dAngOrizzDeg = 180 ;
|
||||
break ;
|
||||
case CT_BOTTOM :
|
||||
dAngVertDeg = 180 ;
|
||||
dAngOrizzDeg = 0 ;
|
||||
break ;
|
||||
case CT_ISO_SW :
|
||||
dAngVertDeg = ANG_VERT_ISOVIEW ;
|
||||
dAngOrizzDeg = -135 ;
|
||||
break ;
|
||||
case CT_ISO_SE :
|
||||
dAngVertDeg = ANG_VERT_ISOVIEW ;
|
||||
dAngOrizzDeg = -45 ;
|
||||
break ;
|
||||
case CT_ISO_NE :
|
||||
dAngVertDeg = ANG_VERT_ISOVIEW ;
|
||||
dAngOrizzDeg = 45 ;
|
||||
break ;
|
||||
case CT_ISO_NW :
|
||||
dAngVertDeg = ANG_VERT_ISOVIEW ;
|
||||
dAngOrizzDeg = 135 ;
|
||||
break ;
|
||||
default :
|
||||
return false ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return SetCamera( dAngVertDeg, dAngOrizzDeg, dDist) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Scene::GetCamera( double* pdAngVertDeg, double* pdAngOrizzDeg, double* pdDist)
|
||||
{
|
||||
double dAngVertDeg ;
|
||||
double dAngOrizzDeg ;
|
||||
m_vtDirCamera.ToSpherical( nullptr, &dAngVertDeg, &dAngOrizzDeg) ;
|
||||
if ( fabs( dAngVertDeg) < EPS_ANG_SMALL)
|
||||
dAngOrizzDeg = -90 ;
|
||||
if ( pdAngVertDeg != nullptr)
|
||||
*pdAngVertDeg = dAngVertDeg ;
|
||||
if ( pdAngOrizzDeg != nullptr)
|
||||
*pdAngOrizzDeg = dAngOrizzDeg ;
|
||||
if ( pdDist != nullptr)
|
||||
*pdDist = m_dDistCamera ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
Scene::GetCameraDir( void)
|
||||
{
|
||||
if ( m_vtDirCamera.IsZplus())
|
||||
return CT_TOP ;
|
||||
else if ( m_vtDirCamera.IsYminus())
|
||||
return CT_FRONT ;
|
||||
else if ( m_vtDirCamera.IsXplus())
|
||||
return CT_RIGHT ;
|
||||
else if ( m_vtDirCamera.IsYplus())
|
||||
return CT_BACK ;
|
||||
else if ( m_vtDirCamera.IsXminus())
|
||||
return CT_LEFT ;
|
||||
else if ( m_vtDirCamera.IsZminus())
|
||||
return CT_BOTTOM ;
|
||||
else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, - SQRT1_3, - SQRT1_3)))
|
||||
return CT_ISO_SW ;
|
||||
else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, SQRT1_3, - SQRT1_3)))
|
||||
return CT_ISO_SE ;
|
||||
else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, SQRT1_3, SQRT1_3)))
|
||||
return CT_ISO_NE ;
|
||||
else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, - SQRT1_3, SQRT1_3)))
|
||||
return CT_ISO_NW ;
|
||||
else
|
||||
return CT_NONE ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Point3d
|
||||
Scene::GetProjectedCenter( void)
|
||||
{
|
||||
Point3d ptVCen ;
|
||||
if ( ! Project( m_ptCenter, ptVCen))
|
||||
ptVCen.Set( 0, 0, 0) ;
|
||||
|
||||
return ptVCen ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::CalcDirUp( void)
|
||||
{
|
||||
// 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)
|
||||
Vector3d vtPerpXY = m_vtDirCamera ^ Z_AX ;
|
||||
if ( ! vtPerpXY.Normalize()) {
|
||||
if ( m_vtDirCamera.z < 0)
|
||||
vtPerpXY = X_AX ;
|
||||
else
|
||||
vtPerpXY = - X_AX ;
|
||||
}
|
||||
// direzione Up
|
||||
m_vtUp = vtPerpXY ^ m_vtDirCamera ;
|
||||
m_bUpOk = m_vtUp.Normalize() ;
|
||||
// invalido ExtView
|
||||
m_bExtViewOk = false ;
|
||||
return m_bUpOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::PanCamera( const Point3d& ptWinOld, const Point3d& ptWinNew)
|
||||
{
|
||||
// porto i due punti in coordinate mondo
|
||||
double dZCenter = GetProjectedCenter().z ;
|
||||
Point3d ptViewOld( ptWinOld.x, ptWinOld.y, dZCenter) ;
|
||||
Point3d ptWorldOld ;
|
||||
if ( ! UnProject( ptViewOld, ptWorldOld))
|
||||
return false ;
|
||||
Point3d ptViewNew( ptWinNew.x, ptWinNew.y, dZCenter) ;
|
||||
Point3d ptWorldNew ;
|
||||
if ( ! UnProject( ptViewNew, ptWorldNew))
|
||||
return false ;
|
||||
// calcolo lo spostamento tra i due punti
|
||||
Vector3d vtMove = ptWorldNew - ptWorldOld ;
|
||||
// applico questo spostamento al centro di vista
|
||||
return SetCenter( GetCenter() - vtMove) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::RotateCamera( const Point3d& ptWinOld, const Point3d& ptWinNew)
|
||||
{
|
||||
const double MIN_ANG_VERT = 0.1 ;
|
||||
const double MAX_ANG_VERT = 179.9 ;
|
||||
|
||||
// angoli correnti della camera
|
||||
double dAngVertDeg ;
|
||||
double dAngOrizzDeg ;
|
||||
GetCamera( &dAngVertDeg, &dAngOrizzDeg) ;
|
||||
|
||||
// incrementi
|
||||
double dDeltaAngVertDeg = ( ptWinNew.y - ptWinOld.y) / m_nViewportH * 360 ;
|
||||
double dDeltaAngOrizzDeg = ( ptWinNew.x - ptWinOld.x) / m_nViewportW * 360 ;
|
||||
|
||||
// calcolo nuovi angoli e limitazione dell'angolo verticale
|
||||
dAngVertDeg -= dDeltaAngVertDeg ;
|
||||
if ( dAngVertDeg < MIN_ANG_VERT)
|
||||
dAngVertDeg = MIN_ANG_VERT ;
|
||||
else if ( dAngVertDeg > MAX_ANG_VERT)
|
||||
dAngVertDeg = MAX_ANG_VERT ;
|
||||
dAngOrizzDeg -= dDeltaAngOrizzDeg ;
|
||||
|
||||
// imposto nuova direzione camera
|
||||
return SetCamera( dAngVertDeg, dAngOrizzDeg, 0) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::ZoomAll( void)
|
||||
{
|
||||
// traslo il centro di vista nel centro del box
|
||||
Point3d ptExtCent ;
|
||||
if ( ! m_b3ExtWorld.GetCenter( ptExtCent))
|
||||
return false ;
|
||||
m_ptCenter = ptExtCent ;
|
||||
m_bExtViewOk = false ;
|
||||
|
||||
// calcolo nuovi dati di ingombro
|
||||
CalcDimViewFromExtView() ;
|
||||
CalcClippingPlanesFromExtView() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
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 ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Scene::ZoomOnPoint( const Point3d& ptWin, double dCoeff)
|
||||
{
|
||||
// porto il punto in coordinate mondo
|
||||
Point3d ptView( ptWin.x, ptWin.y, GetProjectedCenter().z) ;
|
||||
Point3d ptWorld ;
|
||||
if ( ! UnProject( ptView, ptWorld))
|
||||
return false ;
|
||||
// modifico opportunamente il centro di vista
|
||||
Point3d ptNewCen = ptWorld + ( GetCenter() - ptWorld) * dCoeff ;
|
||||
SetCenter( ptNewCen) ;
|
||||
// eseguo lo zoom
|
||||
return ZoomChange( dCoeff) ;
|
||||
}
|
||||
Reference in New Issue
Block a user