CAMERA: Make the CAMERA_FRUSTUM structure values for nw, nh, fw and fh consistent.
The CAMERA_FRUSTUM structure values for nw, nh, fw and fh to always mean width and height for both perspective and orthographic views instead of half-width and half-height in perspective. The orthographic / perspective view toggle has been modified to keep the viewed plane at m_camera_pos_init * m_zoom the same dimensions in both projections.
This commit is contained in:
parent
47603fbc76
commit
5b9f56613e
|
@ -120,6 +120,14 @@ void CAMERA::Reset_T1()
|
||||||
m_rotate_aux_t1.z = static_cast<float>( 2.0f * M_PI );
|
m_rotate_aux_t1.z = static_cast<float>( 2.0f * M_PI );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAMERA::SetBoardLookAtPos( const SFVEC3F& aBoardPos )
|
||||||
|
{
|
||||||
|
if( m_board_lookat_pos_init != aBoardPos )
|
||||||
|
{
|
||||||
|
m_board_lookat_pos_init = aBoardPos;
|
||||||
|
SetLookAtPos( aBoardPos );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CAMERA::zoomChanged()
|
void CAMERA::zoomChanged()
|
||||||
{
|
{
|
||||||
|
@ -186,7 +194,6 @@ void CAMERA::rebuildProjection()
|
||||||
|
|
||||||
m_frustum.nearD = 0.10f;
|
m_frustum.nearD = 0.10f;
|
||||||
|
|
||||||
// Ratio width / height of the window display
|
|
||||||
m_frustum.angle = 45.0f;
|
m_frustum.angle = 45.0f;
|
||||||
|
|
||||||
m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ), m_frustum.ratio,
|
m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ), m_frustum.ratio,
|
||||||
|
@ -199,19 +206,22 @@ void CAMERA::rebuildProjection()
|
||||||
m_focalLen.x = ( (float)m_windowSize.y / (float)m_windowSize.x ) / m_frustum.tang;
|
m_focalLen.x = ( (float)m_windowSize.y / (float)m_windowSize.x ) / m_frustum.tang;
|
||||||
m_focalLen.y = 1.0f / m_frustum.tang;
|
m_focalLen.y = 1.0f / m_frustum.tang;
|
||||||
|
|
||||||
m_frustum.nh = m_frustum.nearD * m_frustum.tang;
|
m_frustum.nh = 2.0f * m_frustum.nearD * m_frustum.tang;
|
||||||
m_frustum.nw = m_frustum.nh * m_frustum.ratio;
|
m_frustum.nw = m_frustum.nh * m_frustum.ratio;
|
||||||
m_frustum.fh = m_frustum.farD * m_frustum.tang;
|
m_frustum.fh = 2.0f * m_frustum.farD * m_frustum.tang;
|
||||||
m_frustum.fw = m_frustum.fh * m_frustum.ratio;
|
m_frustum.fw = m_frustum.fh * m_frustum.ratio;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROJECTION_TYPE::ORTHO:
|
case PROJECTION_TYPE::ORTHO:
|
||||||
|
|
||||||
|
// Keep the viewed plane at (m_camera_pos_init * m_zoom) the same dimensions in both projections.
|
||||||
|
m_frustum.angle = 45.0f;
|
||||||
|
m_frustum.tang = glm::tan( glm::radians( m_frustum.angle ) * 0.5f );
|
||||||
|
|
||||||
m_frustum.nearD = -m_frustum.farD; // Use a symmetrical clip plane for ortho projection
|
m_frustum.nearD = -m_frustum.farD; // Use a symmetrical clip plane for ortho projection
|
||||||
|
|
||||||
// This formula was found by trial and error
|
const float orthoReductionFactor =
|
||||||
const float orthoReductionFactor = glm::length( m_camera_pos_init ) *
|
glm::length( m_camera_pos_init ) * m_zoom * m_frustum.tang;
|
||||||
m_zoom * m_zoom * 0.5f;
|
|
||||||
|
|
||||||
// Initialize Projection Matrix for Orthographic View
|
// Initialize Projection Matrix for Orthographic View
|
||||||
m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor,
|
m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor,
|
||||||
|
@ -283,21 +293,26 @@ void CAMERA::updateFrustum()
|
||||||
* http://www.lighthouse3d.com/tutorials/view-frustum-culling/
|
* http://www.lighthouse3d.com/tutorials/view-frustum-culling/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const SFVEC3F half_right_nw = m_right * m_frustum.nw * 0.5f;
|
||||||
|
const SFVEC3F half_right_fw = m_right * m_frustum.fw * 0.5f;
|
||||||
|
const SFVEC3F half_up_nh = m_up * m_frustum.nh * 0.5f;
|
||||||
|
const SFVEC3F half_up_fh = m_up * m_frustum.fh * 0.5f;
|
||||||
|
|
||||||
// compute the centers of the near and far planes
|
// compute the centers of the near and far planes
|
||||||
m_frustum.nc = m_pos - m_dir * m_frustum.nearD;
|
m_frustum.nc = m_pos - m_dir * m_frustum.nearD;
|
||||||
m_frustum.fc = m_pos - m_dir * m_frustum.farD;
|
m_frustum.fc = m_pos - m_dir * m_frustum.farD;
|
||||||
|
|
||||||
// compute the 4 corners of the frustum on the near plane
|
// compute the 4 corners of the frustum on the near plane
|
||||||
m_frustum.ntl = m_frustum.nc + m_up * m_frustum.nh - m_right * m_frustum.nw;
|
m_frustum.ntl = m_frustum.nc + half_up_nh - half_right_nw;
|
||||||
m_frustum.ntr = m_frustum.nc + m_up * m_frustum.nh + m_right * m_frustum.nw;
|
m_frustum.ntr = m_frustum.nc + half_up_nh + half_right_nw;
|
||||||
m_frustum.nbl = m_frustum.nc - m_up * m_frustum.nh - m_right * m_frustum.nw;
|
m_frustum.nbl = m_frustum.nc - half_up_nh - half_right_nw;
|
||||||
m_frustum.nbr = m_frustum.nc - m_up * m_frustum.nh + m_right * m_frustum.nw;
|
m_frustum.nbr = m_frustum.nc - half_up_nh + half_right_nw;
|
||||||
|
|
||||||
// compute the 4 corners of the frustum on the far plane
|
// compute the 4 corners of the frustum on the far plane
|
||||||
m_frustum.ftl = m_frustum.fc + m_up * m_frustum.fh - m_right * m_frustum.fw;
|
m_frustum.ftl = m_frustum.fc + half_up_fh - half_right_fw;
|
||||||
m_frustum.ftr = m_frustum.fc + m_up * m_frustum.fh + m_right * m_frustum.fw;
|
m_frustum.ftr = m_frustum.fc + half_up_fh + half_right_fw;
|
||||||
m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw;
|
m_frustum.fbl = m_frustum.fc - half_up_fh - half_right_fw;
|
||||||
m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw;
|
m_frustum.fbr = m_frustum.fc - half_up_fh + half_right_fw;
|
||||||
|
|
||||||
if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) )
|
if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) )
|
||||||
{
|
{
|
||||||
|
@ -306,16 +321,12 @@ void CAMERA::updateFrustum()
|
||||||
m_up_nY.resize( m_windowSize.y + 1 );
|
m_up_nY.resize( m_windowSize.y + 1 );
|
||||||
|
|
||||||
// Precalc X values for camera -> ray generation
|
// Precalc X values for camera -> ray generation
|
||||||
const SFVEC3F right_nw = m_right * m_frustum.nw;
|
|
||||||
|
|
||||||
for( unsigned int x = 0; x < ( (unsigned int) m_windowSize.x + 1 ); ++x )
|
for( unsigned int x = 0; x < ( (unsigned int) m_windowSize.x + 1 ); ++x )
|
||||||
m_right_nX[x] = right_nw * m_scr_nX[x];
|
m_right_nX[x] = half_right_nw * m_scr_nX[x];
|
||||||
|
|
||||||
// Precalc Y values for camera -> ray generation
|
// Precalc Y values for camera -> ray generation
|
||||||
const SFVEC3F up_nh = m_up * m_frustum.nh;
|
|
||||||
|
|
||||||
for( unsigned int y = 0; y < ( (unsigned int) m_windowSize.y + 1 ); ++y )
|
for( unsigned int y = 0; y < ( (unsigned int) m_windowSize.y + 1 ); ++y )
|
||||||
m_up_nY[y] = up_nh * m_scr_nY[y];
|
m_up_nY[y] = half_up_nh * m_scr_nY[y];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,18 +337,16 @@ void CAMERA::MakeRay( const SFVEC2I& aWindowPos, SFVEC3F& aOutOrigin,
|
||||||
wxASSERT( aWindowPos.x < m_windowSize.x );
|
wxASSERT( aWindowPos.x < m_windowSize.x );
|
||||||
wxASSERT( aWindowPos.y < m_windowSize.y );
|
wxASSERT( aWindowPos.y < m_windowSize.y );
|
||||||
|
|
||||||
const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
|
aOutOrigin = m_frustum.nc + m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
|
||||||
|
|
||||||
switch( m_projectionType )
|
switch( m_projectionType )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case PROJECTION_TYPE::PERSPECTIVE:
|
case PROJECTION_TYPE::PERSPECTIVE:
|
||||||
aOutOrigin = up_plus_right + m_frustum.nc;
|
|
||||||
aOutDirection = glm::normalize( aOutOrigin - m_pos );
|
aOutDirection = glm::normalize( aOutOrigin - m_pos );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROJECTION_TYPE::ORTHO:
|
case PROJECTION_TYPE::ORTHO:
|
||||||
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
|
|
||||||
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -360,16 +369,16 @@ void CAMERA::MakeRay( const SFVEC2F& aWindowPos, SFVEC3F& aOutOrigin,
|
||||||
m_right_nX[floorWinPos_i.x] * (1.0f - relativeWinPos.x) +
|
m_right_nX[floorWinPos_i.x] * (1.0f - relativeWinPos.x) +
|
||||||
m_right_nX[floorWinPos_i.x + 1] * relativeWinPos.x;
|
m_right_nX[floorWinPos_i.x + 1] * relativeWinPos.x;
|
||||||
|
|
||||||
|
aOutOrigin = up_plus_right + m_frustum.nc;
|
||||||
|
|
||||||
switch( m_projectionType )
|
switch( m_projectionType )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case PROJECTION_TYPE::PERSPECTIVE:
|
case PROJECTION_TYPE::PERSPECTIVE:
|
||||||
aOutOrigin = up_plus_right + m_frustum.nc;
|
|
||||||
aOutDirection = glm::normalize( aOutOrigin - m_pos );
|
aOutDirection = glm::normalize( aOutOrigin - m_pos );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROJECTION_TYPE::ORTHO:
|
case PROJECTION_TYPE::ORTHO:
|
||||||
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
|
|
||||||
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
aOutDirection = -m_dir + SFVEC3F( FLT_EPSILON );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,15 +109,7 @@ public:
|
||||||
float GetNear() const { return m_frustum.nearD; }
|
float GetNear() const { return m_frustum.nearD; }
|
||||||
float GetFar() const { return m_frustum.farD; }
|
float GetFar() const { return m_frustum.farD; }
|
||||||
|
|
||||||
void SetBoardLookAtPos( const SFVEC3F& aBoardPos )
|
void SetBoardLookAtPos( const SFVEC3F& aBoardPos );
|
||||||
{
|
|
||||||
if( m_board_lookat_pos_init != aBoardPos )
|
|
||||||
{
|
|
||||||
m_board_lookat_pos_init = aBoardPos;
|
|
||||||
SetLookAtPos( aBoardPos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void SetLookAtPos( const SFVEC3F& aLookAtPos ) = 0;
|
virtual void SetLookAtPos( const SFVEC3F& aLookAtPos ) = 0;
|
||||||
|
|
||||||
void SetLookAtPos_T1( const SFVEC3F& aLookAtPos )
|
void SetLookAtPos_T1( const SFVEC3F& aLookAtPos )
|
||||||
|
|
Loading…
Reference in New Issue