2012-05-18 09:45:23 +02:00
//##################################################################################################
//
// Custom Visualization Core library
2013-09-20 15:22:29 +02:00
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
2012-05-18 09:45:23 +02:00
//
//##################################################################################################
# include "cafViewer.h"
2015-12-17 14:40:01 +01:00
# include "cafCadNavigation.h"
# include "cafFrameAnimationControl.h"
# include "cafNavigationPolicy.h"
2019-06-25 17:01:38 +02:00
# include "cafPointOfInterestVisualizer.h"
2015-12-17 14:40:01 +01:00
2012-05-18 09:45:23 +02:00
# include "cvfCamera.h"
2015-12-17 14:40:01 +01:00
# include "cvfDebugTimer.h"
# include "cvfDrawable.h"
# include "cvfDrawableGeo.h"
2016-08-16 10:58:07 +02:00
# include "cvfDynamicUniformSet.h"
2016-08-31 17:34:31 +02:00
# include "cvfFramebufferObject.h"
2015-12-17 14:40:01 +01:00
# include "cvfHitItemCollection.h"
# include "cvfManipulatorTrackball.h"
# include "cvfModel.h"
2016-08-31 17:34:31 +02:00
# include "cvfOpenGLCapabilities.h"
2012-05-18 09:45:23 +02:00
# include "cvfOpenGLResourceManager.h"
2015-12-17 14:40:01 +01:00
# include "cvfOverlayImage.h"
# include "cvfPart.h"
# include "cvfRay.h"
# include "cvfRayIntersectSpec.h"
2012-05-18 09:45:23 +02:00
# include "cvfRenderQueueSorter.h"
2015-12-17 14:40:01 +01:00
# include "cvfRenderSequence.h"
2016-08-31 17:34:31 +02:00
# include "cvfRenderbufferObject.h"
2015-12-17 14:40:01 +01:00
# include "cvfRendering.h"
2019-10-31 09:38:56 +01:00
# include "cvfRenderingScissor.h"
2012-05-18 09:45:23 +02:00
# include "cvfScene.h"
2016-08-31 17:34:31 +02:00
# include "cvfShaderSourceProvider.h"
# include "cvfSingleQuadRenderingGenerator.h"
2013-02-28 11:58:31 +01:00
# include "cvfTextureImage.h"
2012-05-18 09:45:23 +02:00
# include "cvfTransform.h"
2016-08-16 10:58:07 +02:00
# include "cvfUniform.h"
# include "cvfUniformSet.h"
2012-05-18 09:45:23 +02:00
2015-12-17 14:40:01 +01:00
# include "cvfqtOpenGLContext.h"
2012-05-18 09:45:23 +02:00
# include "cvfqtPerformanceInfoHud.h"
2012-06-26 16:10:41 +02:00
# include "cvfqtUtils.h"
2012-05-18 09:45:23 +02:00
2012-06-26 16:10:41 +02:00
# include <QDebug>
2015-12-17 14:40:01 +01:00
# include <QHBoxLayout>
# include <QInputEvent>
2019-10-31 09:38:56 +01:00
# include <cmath>
2012-05-18 09:45:23 +02:00
2016-08-16 10:58:07 +02:00
namespace caf
{
class GlobalViewerDynUniformSet : public cvf : : DynamicUniformSet
{
public :
GlobalViewerDynUniformSet ( )
{
m_headlightPosition = new cvf : : UniformFloat ( " u_ecLightPosition " , cvf : : Vec3f ( 0.5 , 5.0 , 7.0 ) ) ;
m_uniformSet = new cvf : : UniformSet ( ) ;
m_uniformSet - > setUniform ( m_headlightPosition . p ( ) ) ;
}
2019-01-10 22:13:19 +01:00
~ GlobalViewerDynUniformSet ( ) override { }
2016-08-16 10:58:07 +02:00
void setHeadLightPosition ( const cvf : : Vec3f posRelativeToCamera ) { m_headlightPosition - > set ( posRelativeToCamera ) ; }
2019-01-10 22:13:19 +01:00
cvf : : UniformSet * uniformSet ( ) override { return m_uniformSet . p ( ) ; }
void update ( cvf : : Rendering * rendering ) override { } ;
2016-08-16 10:58:07 +02:00
private :
cvf : : ref < cvf : : UniformSet > m_uniformSet ;
cvf : : ref < cvf : : UniformFloat > m_headlightPosition ;
} ;
2019-10-10 17:53:36 +02:00
2016-08-16 10:58:07 +02:00
}
2012-05-18 09:45:23 +02:00
std : : list < caf : : Viewer * > caf : : Viewer : : sm_viewers ;
cvf : : ref < cvf : : OpenGLContextGroup > caf : : Viewer : : sm_openGLContextGroup ;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf : : Viewer : : Viewer ( const QGLFormat & format , QWidget * parent )
2019-06-25 17:01:38 +02:00
# if QT_VERSION >= 0x050000
: caf : : OpenGLWidget ( contextGroup ( ) , format , nullptr , sharedWidget ( ) ) ,
# else
2012-05-18 09:45:23 +02:00
: caf : : OpenGLWidget ( contextGroup ( ) , format , new QWidget ( parent ) , sharedWidget ( ) ) ,
2019-06-25 17:01:38 +02:00
# endif
2018-02-18 18:17:50 +01:00
m_navigationPolicy ( nullptr ) ,
2018-02-23 19:57:09 +01:00
m_navigationPolicyEnabled ( true ) ,
2016-09-07 12:49:01 +02:00
m_defaultPerspectiveNearPlaneDistance ( 0.05 ) ,
m_maxClipPlaneDistance ( cvf : : UNDEFINED_DOUBLE ) ,
2015-12-05 00:56:14 +01:00
m_cameraFieldOfViewYDeg ( 40.0 ) ,
2012-06-26 16:10:41 +02:00
m_paintCounter ( 0 ) ,
2018-02-23 19:57:09 +01:00
m_releaseOGLResourcesEachFrame ( false ) ,
2016-10-28 19:16:27 +02:00
m_isOverlayPaintingEnabled ( true ) ,
m_offscreenViewportWidth ( 0 ) ,
2019-06-25 17:01:38 +02:00
m_offscreenViewportHeight ( 0 ) ,
2019-10-10 17:53:36 +02:00
m_parallelProjectionLightDirection ( 0 , 0 , - 1 ) , // Light directly from behind
m_comparisonViewOffset ( 0 , 0 , 0 ) ,
2019-10-22 13:39:18 +02:00
m_comparisonWindowNormalizedRect ( 0.5f , 0.0f , 0.5f , 1.0f ) ,
2019-11-06 13:07:31 +01:00
m_isComparisonFollowingAnimation ( true ) ,
m_isComparisonViewActiveFlag ( false )
2012-05-18 09:45:23 +02:00
{
2019-06-25 17:01:38 +02:00
# if QT_VERSION >= 0x050000
m_layoutWidget = new QWidget ( parent ) ;
# else
2012-05-18 09:45:23 +02:00
m_layoutWidget = parentWidget ( ) ;
2019-06-25 17:01:38 +02:00
# endif
2012-05-18 09:45:23 +02:00
QHBoxLayout * layout = new QHBoxLayout ( m_layoutWidget ) ;
layout - > addWidget ( this ) ;
2012-09-18 15:21:04 +02:00
layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
2012-05-18 09:45:23 +02:00
setAutoFillBackground ( false ) ;
setMouseTracking ( true ) ;
// Needed to get keystrokes
setFocusPolicy ( Qt : : ClickFocus ) ;
2016-08-16 10:58:07 +02:00
m_globalUniformSet = new GlobalViewerDynUniformSet ( ) ;
2012-05-18 09:45:23 +02:00
m_mainCamera = new cvf : : Camera ;
m_mainCamera - > setFromLookAt ( cvf : : Vec3d ( 0 , 0 , - 1 ) , cvf : : Vec3d ( 0 , 0 , 0 ) , cvf : : Vec3d ( 0 , 1 , 0 ) ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainCamera = new cvf : : Camera ;
m_comparisonMainCamera - > setFromLookAt ( cvf : : Vec3d ( 0 , 0 , - 1 ) , cvf : : Vec3d ( 0 , 0 , 0 ) , cvf : : Vec3d ( 0 , 1 , 0 ) ) ;
2012-05-18 09:45:23 +02:00
m_renderingSequence = new cvf : : RenderSequence ( ) ;
2016-08-15 14:27:46 +02:00
m_renderingSequence - > setDefaultFFLightPositional ( cvf : : Vec3f ( 0.5 , 5.0 , 7.0 ) ) ;
2019-10-10 17:53:36 +02:00
m_mainRendering = new cvf : : Rendering ( " Main Rendering " ) ;
m_comparisonMainRendering = new cvf : : Rendering ( " Comparison Rendering " ) ;
m_overlayItemsRendering = new cvf : : Rendering ( " Overlay Rendering " ) ;
m_overlayItemsRendering - > setClearMode ( cvf : : Viewport : : DO_NOT_CLEAR ) ;
m_comparisonRenderingScissor = new cvf : : RenderingScissor ;
m_comparisonMainRendering - > setRenderingScissor ( m_comparisonRenderingScissor . p ( ) ) ;
2012-05-18 09:45:23 +02:00
m_animationControl = new caf : : FrameAnimationControl ( this ) ;
connect ( m_animationControl , SIGNAL ( changeFrame ( int ) ) , SLOT ( slotSetCurrentFrame ( int ) ) ) ;
connect ( m_animationControl , SIGNAL ( endAnimation ( ) ) , SLOT ( slotEndAnimation ( ) ) ) ;
this - > setNavigationPolicy ( new caf : : CadNavigation ) ;
2013-02-28 11:58:31 +01:00
m_overlayTextureImage = new cvf : : TextureImage ;
m_overlayImage = new cvf : : OverlayImage ( m_overlayTextureImage . p ( ) ) ;
m_overlayImage - > setBlending ( cvf : : OverlayImage : : TEXTURE_ALPHA ) ;
2013-10-31 14:57:52 +01:00
m_overlayImage - > setLayoutFixedPosition ( cvf : : Vec2i ( 0 , 0 ) ) ;
2013-02-28 11:58:31 +01:00
2012-05-18 09:45:23 +02:00
setupMainRendering ( ) ;
setupRenderingSequence ( ) ;
m_showPerfInfoHud = false ;
sm_viewers . push_back ( this ) ;
}
2019-06-25 17:01:38 +02:00
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf : : Viewer : : ~ Viewer ( )
{
this - > cvfShutdownOpenGLContext ( ) ;
sm_viewers . remove ( this ) ;
// To delete the layout widget
if ( m_layoutWidget ) m_layoutWidget - > deleteLater ( ) ;
}
//--------------------------------------------------------------------------------------------------
2015-11-16 10:00:22 +01:00
///
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setupMainRendering ( )
{
m_mainRendering - > setCamera ( m_mainCamera . p ( ) ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainRendering - > setCamera ( m_comparisonMainCamera . p ( ) ) ;
m_overlayItemsRendering - > setCamera ( m_mainCamera . p ( ) ) ;
2012-05-18 09:45:23 +02:00
m_mainRendering - > setRenderQueueSorter ( new cvf : : RenderQueueSorterBasic ( cvf : : RenderQueueSorterBasic : : EFFECT_ONLY ) ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainRendering - > setRenderQueueSorter ( new cvf : : RenderQueueSorterBasic ( cvf : : RenderQueueSorterBasic : : EFFECT_ONLY ) ) ;
m_overlayItemsRendering - > setRenderQueueSorter ( new cvf : : RenderQueueSorterBasic ( cvf : : RenderQueueSorterBasic : : EFFECT_ONLY ) ) ;
2016-08-16 10:58:07 +02:00
m_mainRendering - > addGlobalDynamicUniformSet ( m_globalUniformSet . p ( ) ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainRendering - > addGlobalDynamicUniformSet ( m_globalUniformSet . p ( ) ) ;
2012-05-18 09:45:23 +02:00
2012-08-31 19:12:47 +02:00
// Set fixed function rendering if QGLFormat does not support directRendering
if ( ! this - > format ( ) . directRendering ( ) )
2012-05-18 09:45:23 +02:00
{
m_mainRendering - > renderEngine ( ) - > enableForcedImmediateMode ( true ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainRendering - > renderEngine ( ) - > enableForcedImmediateMode ( true ) ;
m_overlayItemsRendering - > renderEngine ( ) - > enableForcedImmediateMode ( true ) ;
2012-05-18 09:45:23 +02:00
}
2013-02-28 11:58:31 +01:00
2016-08-31 17:34:31 +02:00
if ( contextGroup ( ) - > capabilities ( ) & &
contextGroup ( ) - > capabilities ( ) - > hasCapability ( cvf : : OpenGLCapabilities : : FRAMEBUFFER_OBJECT ) )
{
m_offscreenFbo = new cvf : : FramebufferObject ;
2019-10-10 17:53:36 +02:00
2016-08-31 17:34:31 +02:00
m_mainRendering - > setTargetFramebuffer ( m_offscreenFbo . p ( ) ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainRendering - > setTargetFramebuffer ( m_offscreenFbo . p ( ) ) ;
m_overlayItemsRendering - > setTargetFramebuffer ( m_offscreenFbo . p ( ) ) ;
2016-08-31 17:34:31 +02:00
cvf : : ref < cvf : : RenderbufferObject > rbo = new cvf : : RenderbufferObject ( cvf : : RenderbufferObject : : DEPTH_COMPONENT24 , 1 , 1 ) ;
m_offscreenFbo - > attachDepthRenderbuffer ( rbo . p ( ) ) ;
m_offscreenTexture = new cvf : : Texture ( cvf : : Texture : : TEXTURE_2D , cvf : : Texture : : RGBA ) ;
m_offscreenTexture - > setSize ( 1 , 1 ) ;
m_offscreenFbo - > attachColorTexture2d ( 0 , m_offscreenTexture . p ( ) ) ;
}
2013-02-28 11:58:31 +01:00
updateOverlayImagePresence ( ) ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
2015-11-16 10:00:22 +01:00
///
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setupRenderingSequence ( )
{
2016-08-31 17:34:31 +02:00
m_renderingSequence - > addRendering ( m_mainRendering . p ( ) ) ;
2019-10-10 17:53:36 +02:00
m_renderingSequence - > addRendering ( m_comparisonMainRendering . p ( ) ) ;
m_renderingSequence - > addRendering ( m_overlayItemsRendering . p ( ) ) ;
2016-08-31 17:34:31 +02:00
if ( m_offscreenFbo . notNull ( ) )
{
// Setup second rendering drawing the texture on the screen
// -------------------------------------------------------------------------
cvf : : SingleQuadRenderingGenerator quadRenderGen ;
cvf : : ref < cvf : : Sampler > sampler = new cvf : : Sampler ;
sampler - > setWrapMode ( cvf : : Sampler : : CLAMP_TO_EDGE ) ;
sampler - > setMinFilter ( cvf : : Sampler : : NEAREST ) ;
sampler - > setMagFilter ( cvf : : Sampler : : NEAREST ) ;
quadRenderGen . addTexture ( m_offscreenTexture . p ( ) , sampler . p ( ) , " u_texture2D " ) ;
quadRenderGen . addFragmentShaderCode ( cvf : : ShaderSourceProvider : : instance ( ) - > getSourceFromRepository ( cvf : : ShaderSourceRepository : : fs_Unlit ) ) ;
quadRenderGen . addFragmentShaderCode ( cvf : : ShaderSourceProvider : : instance ( ) - > getSourceFromRepository ( cvf : : ShaderSourceRepository : : src_Texture ) ) ;
2016-09-05 13:43:10 +02:00
m_quadRendering = quadRenderGen . generate ( ) ;
m_renderingSequence - > addRendering ( m_quadRendering . p ( ) ) ;
2016-08-31 17:34:31 +02:00
}
2012-05-18 09:45:23 +02:00
updateCamera ( width ( ) , height ( ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf : : Viewer * caf : : Viewer : : sharedWidget ( )
{
if ( sm_viewers . size ( ) > 0 )
{
return * ( sm_viewers . begin ( ) ) ;
}
2018-02-18 18:17:50 +01:00
return nullptr ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : OpenGLContextGroup * caf : : Viewer : : contextGroup ( )
{
if ( sm_openGLContextGroup . isNull ( ) )
{
sm_openGLContextGroup = new cvf : : OpenGLContextGroup ( ) ;
}
return sm_openGLContextGroup . p ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : Camera * caf : : Viewer : : mainCamera ( )
{
return m_mainCamera . p ( ) ;
}
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
///
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
cvf : : Camera * caf : : Viewer : : comparisonMainCamera ( )
2012-05-18 09:45:23 +02:00
{
2019-10-10 17:53:36 +02:00
return m_comparisonMainCamera . p ( ) ;
}
2015-11-17 10:53:41 +01:00
2019-10-10 17:53:36 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setComparisonViewEyePointOffset ( const cvf : : Vec3d & offset )
{
m_comparisonViewOffset = offset ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
const cvf : : Vec3d caf : : Viewer : : comparisonViewEyePointOffset ( )
2012-05-18 09:45:23 +02:00
{
2019-10-10 17:53:36 +02:00
return m_comparisonViewOffset ;
}
//--------------------------------------------------------------------------------------------------
/// setNormalizedComparisonViewRect
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setComparisonViewVisibleNormalizedRect ( const cvf : : Rectf & visibleRect )
{
m_comparisonWindowNormalizedRect = visibleRect ;
updateCamera ( width ( ) , height ( ) ) ;
update ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : Rectf caf : : Viewer : : comparisonViewVisibleNormalizedRect ( ) const
{
return m_comparisonWindowNormalizedRect ;
}
2019-11-06 13:07:31 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : isComparisonViewActive ( ) const
{
return m_isComparisonViewActiveFlag ;
}
2019-10-10 17:53:36 +02:00
//--------------------------------------------------------------------------------------------------
/// Set the scene to be rendered when the animation is inactive (Stopped)
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setMainScene ( cvf : : Scene * scene , bool isForComparisonView )
{
appendAllStaticModelsToFrame ( scene , isForComparisonView ) ;
if ( ! isForComparisonView )
{
m_mainScene = scene ;
m_mainRendering - > setScene ( scene ) ;
}
else
{
m_comparisonMainScene = scene ;
m_comparisonMainRendering - > setScene ( scene ) ;
2019-11-06 13:07:31 +01:00
updateComparisonViewActiveFlag ( ) ;
2019-10-10 17:53:36 +02:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : Scene * caf : : Viewer : : mainScene ( bool isForComparisonView )
{
if ( ! isForComparisonView )
{
return m_mainScene . p ( ) ;
}
else
{
return m_comparisonMainScene . p ( ) ;
}
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Return the currently rendered scene
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
cvf : : Scene * caf : : Viewer : : currentScene ( bool isForComparisonView )
2012-05-18 09:45:23 +02:00
{
2019-10-10 17:53:36 +02:00
if ( ! isForComparisonView )
{
return m_mainRendering - > scene ( ) ;
}
else
{
return m_comparisonMainRendering - > scene ( ) ;
}
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : updateCamera ( int width , int height )
{
if ( width < 1 | | height < 1 ) return ;
m_mainCamera - > viewport ( ) - > set ( 0 , 0 , width , height ) ;
2019-10-10 17:53:36 +02:00
m_comparisonMainCamera - > viewport ( ) - > set ( 0 , 0 , width , height ) ;
m_comparisonRenderingScissor - > setScissorRectangle ( static_cast < int > ( width * m_comparisonWindowNormalizedRect . min ( ) . x ( ) ) ,
static_cast < int > ( height * m_comparisonWindowNormalizedRect . min ( ) . y ( ) ) ,
static_cast < int > ( width * m_comparisonWindowNormalizedRect . width ( ) ) ,
static_cast < int > ( height * m_comparisonWindowNormalizedRect . height ( ) ) ) ;
2012-05-18 09:45:23 +02:00
if ( m_mainCamera - > projection ( ) = = cvf : : Camera : : PERSPECTIVE )
{
2015-12-05 00:56:14 +01:00
m_mainCamera - > setProjectionAsPerspective ( m_cameraFieldOfViewYDeg , m_mainCamera - > nearPlane ( ) , m_mainCamera - > farPlane ( ) ) ;
2012-05-18 09:45:23 +02:00
}
else
{
2015-12-05 00:56:14 +01:00
m_mainCamera - > setProjectionAsOrtho ( m_mainCamera - > frontPlaneFrustumHeight ( ) , m_mainCamera - > nearPlane ( ) , m_mainCamera - > farPlane ( ) ) ;
2012-05-18 09:45:23 +02:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : canRender ( ) const
{
if ( m_renderingSequence - > renderingCount ( ) < 1 ) return false ;
if ( m_mainCamera . isNull ( ) ) return false ;
if ( m_mainCamera - > viewport ( ) - > width ( ) < 1 ) return false ;
if ( m_mainCamera - > viewport ( ) - > height ( ) < 1 ) return false ;
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : optimizeClippingPlanes ( )
{
2019-10-10 17:53:36 +02:00
double nearPlaneDist = HUGE_VAL ;
double farPlaneDist = HUGE_VAL ;
2012-05-18 09:45:23 +02:00
2019-10-10 17:53:36 +02:00
cvf : : Vec3d navPointOfinterest = m_navigationPolicy - > pointOfInterest ( ) ;
if ( calculateNearFarPlanes ( m_mainRendering . p ( ) , navPointOfinterest , & farPlaneDist , & nearPlaneDist ) )
{
if ( m_mainCamera - > projection ( ) = = cvf : : Camera : : PERSPECTIVE )
{
m_mainCamera - > setProjectionAsPerspective ( m_cameraFieldOfViewYDeg , nearPlaneDist , farPlaneDist ) ;
}
else
{
m_mainCamera - > setProjectionAsOrtho ( m_mainCamera - > frontPlaneFrustumHeight ( ) , nearPlaneDist , farPlaneDist ) ;
}
}
copyCameraView ( m_mainCamera . p ( ) , m_comparisonMainCamera . p ( ) ) ;
2019-11-04 10:01:40 +01:00
m_comparisonMainCamera - > viewport ( ) - > setClearColor ( m_mainCamera - > viewport ( ) - > clearColor ( ) ) ;
2019-10-10 17:53:36 +02:00
if ( m_comparisonMainRendering - > scene ( ) )
{
cvf : : Vec3d camUp ;
cvf : : Vec3d camEye ;
cvf : : Vec3d camViewRefPoint ;
m_comparisonMainCamera - > toLookAt ( & camEye , & camViewRefPoint , & camUp ) ;
camEye + = m_comparisonViewOffset ;
camViewRefPoint + = m_comparisonViewOffset ;
m_comparisonMainCamera - > setFromLookAt ( camEye , camViewRefPoint , camUp ) ;
2019-10-16 16:19:32 +02:00
navPointOfinterest + = m_comparisonViewOffset ;
2019-10-10 17:53:36 +02:00
if ( calculateNearFarPlanes ( m_comparisonMainRendering . p ( ) , navPointOfinterest , & farPlaneDist , & nearPlaneDist ) )
{
if ( m_comparisonMainCamera - > projection ( ) = = cvf : : Camera : : PERSPECTIVE )
{
m_comparisonMainCamera - > setProjectionAsPerspective ( m_cameraFieldOfViewYDeg , nearPlaneDist , farPlaneDist ) ;
}
else
{
m_comparisonMainCamera - > setProjectionAsOrtho ( m_comparisonMainCamera - > frontPlaneFrustumHeight ( ) , nearPlaneDist , farPlaneDist ) ;
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : calculateNearFarPlanes ( const cvf : : Rendering * rendering ,
const cvf : : Vec3d & navPointOfinterest ,
double * farPlaneDist ,
double * nearPlaneDist )
{
cvf : : BoundingBox bb = rendering - > boundingBox ( ) ;
if ( ! bb . isValid ( ) ) return false ;
cvf : : Vec3d eye = rendering - > camera ( ) - > position ( ) ;
cvf : : Vec3d viewdir = rendering - > camera ( ) - > direction ( ) ;
2015-12-13 20:55:37 +01:00
2016-08-15 16:11:38 +02:00
cvf : : Vec3d bboxCorners [ 8 ] ;
2015-12-13 20:55:37 +01:00
bb . cornerVertices ( bboxCorners ) ;
2012-05-18 09:45:23 +02:00
2016-08-15 16:11:38 +02:00
// Find the distance to the bbox corners most behind and most in front of camera
2015-12-13 20:55:37 +01:00
double maxDistEyeToCornerAlongViewDir = - HUGE_VAL ;
double minDistEyeToCornerAlongViewDir = HUGE_VAL ;
2019-10-10 17:53:36 +02:00
for ( int bcIdx = 0 ; bcIdx < 8 ; + + bcIdx )
2015-12-13 20:55:37 +01:00
{
double distEyeBoxCornerAlongViewDir = ( bboxCorners [ bcIdx ] - eye ) * viewdir ;
2016-08-15 16:11:38 +02:00
2019-10-10 17:53:36 +02:00
if ( distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir )
2016-08-15 16:11:38 +02:00
{
2015-12-13 20:55:37 +01:00
maxDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir ;
2016-08-15 16:11:38 +02:00
}
2019-10-10 17:53:36 +02:00
if ( distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir )
2016-08-15 16:11:38 +02:00
{
minDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir ; // Sometimes negative-> behind camera
}
2015-12-13 20:55:37 +01:00
}
2012-05-18 09:45:23 +02:00
2019-10-10 17:53:36 +02:00
( * farPlaneDist ) = CVF_MIN ( maxDistEyeToCornerAlongViewDir * 1.2 , m_maxClipPlaneDistance ) ;
2016-08-15 16:11:38 +02:00
// Near-plane:
2015-12-13 20:55:37 +01:00
bool isOrthoNearPlaneFollowingCamera = false ;
2016-08-15 16:11:38 +02:00
// If we have perspective projection, set the near plane just in front of camera, and not behind
2015-12-13 20:55:37 +01:00
2019-10-10 17:53:36 +02:00
if ( rendering - > camera ( ) - > projection ( ) = = cvf : : Camera : : PERSPECTIVE | | isOrthoNearPlaneFollowingCamera )
2015-12-13 20:55:37 +01:00
{
2016-09-07 12:49:01 +02:00
// Choose the one furthest from the camera of: 0.8*bbox distance, m_minPerspectiveNearPlaneDistance.
2019-10-10 17:53:36 +02:00
( * nearPlaneDist ) = CVF_MAX ( m_defaultPerspectiveNearPlaneDistance , 0.8 * minDistEyeToCornerAlongViewDir ) ;
2016-09-07 12:49:01 +02:00
// If we are zooming into a detail, allow the near-plane to move towards camera beyond the m_minPerspectiveNearPlaneDistance
2019-10-10 17:53:36 +02:00
if ( ( * nearPlaneDist ) = = m_defaultPerspectiveNearPlaneDistance // We are inside the bounding box
& & m_navigationPolicy . notNull ( ) & & m_navigationPolicyEnabled )
2015-12-13 20:55:37 +01:00
{
2019-10-10 17:53:36 +02:00
double pointOfInterestDist = ( eye - navPointOfinterest ) . length ( ) ;
( * nearPlaneDist ) = CVF_MIN ( ( * nearPlaneDist ) , pointOfInterestDist * 0.2 ) ;
2015-12-13 20:55:37 +01:00
}
2016-09-07 12:49:01 +02:00
// Guard against the zero nearplane possibility
2019-10-31 14:58:11 +01:00
if ( ( * nearPlaneDist ) < = 0 ) ( * nearPlaneDist ) = m_defaultPerspectiveNearPlaneDistance ;
2016-08-15 16:11:38 +02:00
}
else // Orthographic projection. Set to encapsulate the complete boundingbox, possibly setting a negative nearplane
{
2019-10-10 17:53:36 +02:00
if ( minDistEyeToCornerAlongViewDir > = 0 )
2016-08-15 16:11:38 +02:00
{
2019-10-10 17:53:36 +02:00
( * nearPlaneDist ) = CVF_MIN ( 0.8 * minDistEyeToCornerAlongViewDir , m_maxClipPlaneDistance ) ;
2016-08-15 16:11:38 +02:00
}
else
{
2019-10-10 17:53:36 +02:00
( * nearPlaneDist ) = CVF_MAX ( 1.2 * minDistEyeToCornerAlongViewDir , - m_maxClipPlaneDistance ) ;
2016-08-15 16:11:38 +02:00
}
2015-12-13 20:55:37 +01:00
}
2019-10-10 17:53:36 +02:00
if ( ( * farPlaneDist ) < = ( * nearPlaneDist ) ) ( * farPlaneDist ) = ( * nearPlaneDist ) + 1.0 ;
2012-05-18 09:45:23 +02:00
2019-10-10 17:53:36 +02:00
return true ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Forward all events classified as QInputEvent to the navigation policy
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : event ( QEvent * e )
{
2019-06-25 17:01:38 +02:00
# if QT_VERSION >= 0x050000
// The most reliable way we have found of detecting when an OpenGL context is about to be destroyed is
// hooking into the QEvent::PlatformSurface event and checking for the SurfaceAboutToBeDestroyed event type.
// From the Qt doc:
// The underlying native surface will be destroyed immediately after this event.
// The SurfaceAboutToBeDestroyed event type is useful as a means of stopping rendering to a platform window before it is destroyed.
if ( e - > type ( ) = = QEvent : : PlatformSurface )
{
QPlatformSurfaceEvent * platformSurfaceEvent = static_cast < QPlatformSurfaceEvent * > ( e ) ;
if ( platformSurfaceEvent - > surfaceEventType ( ) = = QPlatformSurfaceEvent : : SurfaceAboutToBeDestroyed )
{
cvfShutdownOpenGLContext ( ) ;
}
}
# endif
2012-06-26 16:10:41 +02:00
if ( e & & m_navigationPolicy . notNull ( ) & & m_navigationPolicyEnabled )
2012-05-18 09:45:23 +02:00
{
switch ( e - > type ( ) )
{
case QEvent : : ContextMenu :
case QEvent : : KeyPress :
case QEvent : : KeyRelease :
case QEvent : : ShortcutOverride :
case QEvent : : MouseButtonPress :
case QEvent : : MouseButtonRelease :
case QEvent : : MouseButtonDblClick :
case QEvent : : MouseMove :
2015-10-23 15:21:23 +02:00
case QEvent : : TabletMove :
case QEvent : : TabletPress :
2012-05-18 09:45:23 +02:00
case QEvent : : TabletRelease :
case QEvent : : TabletEnterProximity :
case QEvent : : TabletLeaveProximity :
case QEvent : : Wheel :
case QEvent : : TouchBegin :
2015-10-23 15:21:23 +02:00
case QEvent : : TouchUpdate :
2012-05-18 09:45:23 +02:00
case QEvent : : TouchEnd :
if ( m_navigationPolicy - > handleInputEvent ( static_cast < QInputEvent * > ( e ) ) )
return true ;
else return QGLWidget : : event ( e ) ;
break ;
default :
return QGLWidget : : event ( e ) ;
break ;
}
}
else return QGLWidget : : event ( e ) ;
}
//--------------------------------------------------------------------------------------------------
/// Set the pointer to the navigation policy to be used. Stored as a cvf::ref internally
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setNavigationPolicy ( caf : : NavigationPolicy * navigationPolicy )
{
m_navigationPolicy = navigationPolicy ;
if ( m_navigationPolicy . notNull ( ) ) m_navigationPolicy - > setViewer ( this ) ;
}
2017-04-26 15:17:58 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf : : NavigationPolicy * caf : : Viewer : : getNavigationPolicy ( ) const
{
return m_navigationPolicy . p ( ) ;
}
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-31 09:38:56 +01:00
cvf : : ref < cvf : : RayIntersectSpec > caf : : Viewer : : rayIntersectSpecFromWindowCoordinates ( int winPosX , int winPosY )
2012-05-18 09:45:23 +02:00
{
2019-10-31 09:38:56 +01:00
bool mousePosIsWithinComparisonView = isMousePosWithinComparisonView ( winPosX , winPosY ) ;
2012-05-18 09:45:23 +02:00
2019-11-06 13:07:31 +01:00
return this - > rayIntersectSpecFromWindowCoordinates ( winPosX , winPosY , mousePosIsWithinComparisonView ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : ref < cvf : : RayIntersectSpec > caf : : Viewer : : rayIntersectSpecFromWindowCoordinates ( int winPosX , int winPosY , bool isForComparisonView )
{
2013-01-21 16:01:46 +01:00
int translatedMousePosX = winPosX ;
int translatedMousePosY = height ( ) - winPosY ;
2012-05-18 09:45:23 +02:00
2019-11-06 13:07:31 +01:00
cvf : : Rendering * renderingToInvestigate = isForComparisonView ? m_comparisonMainRendering . p ( ) : m_mainRendering . p ( ) ;
2019-10-31 09:38:56 +01:00
return renderingToInvestigate - > rayIntersectSpecFromWindowCoordinates ( translatedMousePosX , translatedMousePosY ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : rayPick ( int winPosX , int winPosY , cvf : : HitItemCollection * pickedPoints , cvf : : Vec3d * globalRayOrigin /*=nullptr*/ )
{
CVF_ASSERT ( m_mainRendering . notNull ( ) ) ;
2019-10-16 12:56:06 +02:00
bool mousePosIsWithinComparisonView = isMousePosWithinComparisonView ( winPosX , winPosY ) ;
cvf : : Rendering * renderingToInvestigate = mousePosIsWithinComparisonView ? m_comparisonMainRendering . p ( ) : m_mainRendering . p ( ) ;
2019-10-31 09:38:56 +01:00
cvf : : ref < cvf : : RayIntersectSpec > ris = rayIntersectSpecFromWindowCoordinates ( winPosX , winPosY ) ;
2012-05-18 09:45:23 +02:00
if ( ris . notNull ( ) )
{
2019-10-16 12:56:06 +02:00
bool retVal = renderingToInvestigate - > rayIntersect ( * ris , pickedPoints ) ;
2019-01-31 15:49:12 +01:00
if ( retVal & & globalRayOrigin )
{
CVF_ASSERT ( ris - > ray ( ) ! = nullptr ) ;
* globalRayOrigin = ris - > ray ( ) - > origin ( ) ;
}
2012-05-18 09:45:23 +02:00
return retVal ;
}
else
{
return false ;
}
2019-10-16 12:56:06 +02:00
}
2012-05-18 09:45:23 +02:00
2019-10-16 12:56:06 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : isMousePosWithinComparisonView ( int winPosX , int winPosY )
{
bool mousePosIsWithinComparisonView = false ;
int translatedMousePosX = winPosX ;
int translatedMousePosY = height ( ) - winPosY ;
2012-05-18 09:45:23 +02:00
2019-10-16 12:56:06 +02:00
if ( m_comparisonMainRendering . notNull ( ) & & m_comparisonMainRendering - > scene ( ) )
{
if ( cvf : : RenderingScissor * sciss = m_comparisonMainRendering - > renderingScissor ( ) )
{
cvf : : Recti scissorRect ( sciss - > x ( ) , sciss - > y ( ) , sciss - > width ( ) , sciss - > height ( ) ) ;
if ( scissorRect . contains ( cvf : : Vec2i ( translatedMousePosX , translatedMousePosY ) ) )
{
mousePosIsWithinComparisonView = true ;
}
}
else // Whole screen is covered
{
mousePosIsWithinComparisonView = true ;
}
}
return mousePosIsWithinComparisonView ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : resizeGL ( int width , int height )
{
if ( width < 1 | | height < 1 ) return ;
2016-08-31 17:34:31 +02:00
if ( m_offscreenFbo . notNull ( ) )
{
m_offscreenFbo - > resizeAttachedBuffers ( width , height ) ;
2016-10-28 19:16:27 +02:00
m_offscreenViewportWidth = width ;
m_offscreenViewportHeight = height ;
2016-08-31 17:34:31 +02:00
}
2016-11-01 10:12:11 +01:00
if ( m_quadRendering . notNull ( ) )
{
m_quadRendering - > camera ( ) - > viewport ( ) - > set ( 0 , 0 , width , height ) ;
}
2012-05-18 09:45:23 +02:00
updateCamera ( width , height ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : enablePerfInfoHud ( bool enable )
{
m_showPerfInfoHud = enable ;
2013-02-28 11:58:31 +01:00
updateOverlayImagePresence ( ) ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : isPerfInfoHudEnabled ( )
{
return m_showPerfInfoHud ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : paintEvent ( QPaintEvent * event )
{
makeCurrent ( ) ;
cvf : : ref < cvf : : OpenGLContext > myOglContext = cvfOpenGLContext ( ) ;
CVF_CHECK_OGL ( myOglContext . p ( ) ) ;
2012-09-18 15:21:04 +02:00
CVF_ASSERT ( myOglContext - > isContextValid ( ) ) ;
2012-05-18 09:45:23 +02:00
QPainter painter ( this ) ;
if ( m_renderingSequence . isNull ( ) | | ! canRender ( ) )
{
QColor bgClr ( 128 , 128 , 128 ) ;
painter . fillRect ( rect ( ) , bgClr ) ;
return ;
}
2013-02-28 11:58:31 +01:00
// If Qt overlay painting is enabled, paint to an QImage, and set it to the cvf::OverlayImage
2015-11-23 13:29:11 +01:00
if ( m_isOverlayPaintingEnabled | | m_showPerfInfoHud )
2013-02-28 11:58:31 +01:00
{
// Set up image to draw to, and painter
if ( m_overlayPaintingQImage . size ( ) ! = this - > size ( ) )
{
m_overlayPaintingQImage = QImage ( this - > size ( ) , QImage : : Format_ARGB32 ) ;
}
m_overlayPaintingQImage . fill ( Qt : : transparent ) ;
2019-03-04 10:35:29 +01:00
QPainter overlayPainter ( & m_overlayPaintingQImage ) ;
2013-02-28 11:58:31 +01:00
// Call virtual method to allow subclasses to paint on the OpenGlCanvas
2015-11-23 13:29:11 +01:00
if ( m_isOverlayPaintingEnabled )
2013-02-28 11:58:31 +01:00
{
2019-03-04 10:35:29 +01:00
this - > paintOverlayItems ( & overlayPainter ) ;
2013-02-28 11:58:31 +01:00
}
// Draw performance overlay
if ( m_showPerfInfoHud )
{
cvfqt : : PerformanceInfoHud hud ;
hud . addStrings ( m_renderingSequence - > performanceInfo ( ) ) ;
hud . addStrings ( * m_mainCamera ) ;
hud . addString ( QString ( " PaintCount: %1 " ) . arg ( m_paintCounter + + ) ) ;
2019-03-04 10:35:29 +01:00
hud . draw ( & overlayPainter , width ( ) , height ( ) ) ;
2013-02-28 11:58:31 +01:00
}
// Convert the QImage into the cvf::TextureImage,
// handling vertical mirroring and (possible) byteswapping
2013-09-30 13:17:05 +02:00
if ( ( ( int ) m_overlayTextureImage - > height ( ) ) ! = this - > height ( ) | | ( ( int ) m_overlayTextureImage - > width ( ) ! = this - > width ( ) ) )
2013-02-28 11:58:31 +01:00
{
m_overlayTextureImage - > allocate ( this - > width ( ) , this - > height ( ) ) ;
}
2013-12-04 17:04:05 +01:00
cvfqt : : Utils : : toTextureImage ( m_overlayPaintingQImage , m_overlayTextureImage . p ( ) ) ;
2013-09-30 13:17:05 +02:00
2013-02-28 11:58:31 +01:00
m_overlayImage - > setImage ( m_overlayTextureImage . p ( ) ) ;
m_overlayImage - > setPixelSize ( cvf : : Vec2ui ( this - > width ( ) , this - > height ( ) ) ) ;
}
2012-05-18 09:45:23 +02:00
# if QT_VERSION >= 0x040600
// Qt 4.6
painter . beginNativePainting ( ) ;
# endif
if ( isShadersSupported ( ) )
{
cvfqt : : OpenGLContext : : saveOpenGLState ( myOglContext . p ( ) ) ;
}
optimizeClippingPlanes ( ) ;
2019-10-10 17:53:36 +02:00
m_renderingSequence - > removeRendering ( m_comparisonMainRendering . p ( ) ) ;
if ( m_comparisonMainRendering - > scene ( ) )
{
m_renderingSequence - > insertRendering ( m_overlayItemsRendering . p ( ) , m_comparisonMainRendering . p ( ) ) ;
}
2019-06-25 17:01:38 +02:00
if ( m_poiVisualizationManager . notNull ( ) )
{
2019-10-10 17:53:36 +02:00
m_poiVisualizationManager - > update ( m_navigationPolicy - > pointOfInterest ( ) ) ; // Todo: Must be inserted in comparison scene as well, using the display offset
2019-06-25 17:01:38 +02:00
m_mainRendering - > scene ( ) - > addModel ( m_poiVisualizationManager - > model ( ) ) ;
}
2012-05-18 09:45:23 +02:00
// Do normal drawing
m_renderingSequence - > render ( myOglContext . p ( ) ) ;
CVF_CHECK_OGL ( cvfOpenGLContext ( ) ) ;
2019-06-25 17:01:38 +02:00
if ( m_poiVisualizationManager . notNull ( ) )
{
m_mainRendering - > scene ( ) - > removeModel ( m_poiVisualizationManager - > model ( ) ) ;
}
2012-05-18 09:45:23 +02:00
if ( isShadersSupported ( ) )
{
cvfqt : : OpenGLContext : : restoreOpenGLState ( myOglContext . p ( ) ) ;
}
# if QT_VERSION >= 0x040600
// Qt 4.6
painter . endNativePainting ( ) ;
# endif
2013-02-28 11:58:31 +01:00
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-09-07 12:49:01 +02:00
void caf : : Viewer : : setDefaultPerspectiveNearPlaneDistance ( double dist )
2012-05-18 09:45:23 +02:00
{
2016-09-07 12:49:01 +02:00
m_defaultPerspectiveNearPlaneDistance = dist ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-09-07 12:49:01 +02:00
void caf : : Viewer : : setMaxClipPlaneDistance ( double dist )
2012-05-18 09:45:23 +02:00
{
2016-09-07 12:49:01 +02:00
m_maxClipPlaneDistance = dist ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setView ( const cvf : : Vec3d & alongDirection , const cvf : : Vec3d & upDirection )
{
2015-12-05 00:56:14 +01:00
if ( m_navigationPolicy . notNull ( ) & & m_navigationPolicyEnabled )
2012-05-18 09:45:23 +02:00
{
m_navigationPolicy - > setView ( alongDirection , upDirection ) ;
2015-09-03 13:01:39 +02:00
navigationPolicyUpdate ( ) ;
2012-05-18 09:45:23 +02:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : zoomAll ( )
{
2016-09-07 15:53:33 +02:00
cvf : : BoundingBox bb = m_mainRendering - > boundingBox ( ) ;
2012-05-18 09:45:23 +02:00
if ( ! bb . isValid ( ) )
{
return ;
}
cvf : : Vec3d eye , vrp , up ;
m_mainCamera - > toLookAt ( & eye , & vrp , & up ) ;
2016-08-15 08:52:55 +02:00
cvf : : Vec3d newEye = m_mainCamera - > computeFitViewEyePosition ( bb , vrp - eye , up , 0.9 , m_cameraFieldOfViewYDeg , m_mainCamera - > viewport ( ) - > aspectRatio ( ) ) ;
m_mainCamera - > setFromLookAt ( newEye , bb . center ( ) , up ) ;
2018-01-26 11:16:03 +01:00
2016-08-15 08:52:55 +02:00
updateParallelProjectionHeightFromMoveZoom ( bb . center ( ) ) ;
2015-09-03 13:01:39 +02:00
2018-01-26 11:16:03 +01:00
if ( m_navigationPolicy . notNull ( ) ) m_navigationPolicy - > setPointOfInterest ( bb . center ( ) ) ;
2015-09-03 13:01:39 +02:00
navigationPolicyUpdate ( ) ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
void caf : : Viewer : : addFrame ( cvf : : Scene * scene , bool isForComparisonView )
2012-05-18 09:45:23 +02:00
{
2019-10-10 17:53:36 +02:00
appendAllStaticModelsToFrame ( scene , isForComparisonView ) ;
if ( ! isForComparisonView )
{
m_frameScenes . push_back ( scene ) ;
}
else
{
m_comparisonFrameScenes . push_back ( scene ) ;
}
2015-11-17 10:53:41 +01:00
2019-10-10 17:53:36 +02:00
m_animationControl - > setNumFrames ( static_cast < int > ( frameCount ( ) ) ) ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
void caf : : Viewer : : removeAllFrames ( bool isForComparisonView )
2012-05-18 09:45:23 +02:00
{
2019-10-10 17:53:36 +02:00
if ( ! isForComparisonView )
{
m_frameScenes . clear ( ) ;
m_mainRendering - > setScene ( m_mainScene . p ( ) ) ;
}
else
{
m_comparisonFrameScenes . clear ( ) ;
m_comparisonMainRendering - > setScene ( m_comparisonMainScene . p ( ) ) ;
2019-11-06 13:07:31 +01:00
updateComparisonViewActiveFlag ( ) ;
2019-10-10 17:53:36 +02:00
}
m_animationControl - > setNumFrames ( static_cast < int > ( frameCount ( ) ) ) ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-11-08 10:38:45 +01:00
bool caf : : Viewer : : isAnimationActive ( bool isForComparisonView )
2012-05-18 09:45:23 +02:00
{
2019-11-08 10:38:45 +01:00
if ( ! isForComparisonView )
2012-05-18 09:45:23 +02:00
{
2019-11-08 10:38:45 +01:00
cvf : : Scene * currentScene = m_mainRendering - > scene ( ) ;
2012-05-18 09:45:23 +02:00
2019-11-08 10:38:45 +01:00
if ( ! currentScene )
{
return false ;
}
if ( m_mainScene . notNull ( ) & & m_mainScene . p ( ) = = currentScene )
{
return false ;
}
return true ;
2012-05-18 09:45:23 +02:00
}
2019-11-08 10:38:45 +01:00
else
{
cvf : : Scene * currentScene = m_comparisonMainRendering - > scene ( ) ;
2012-05-18 09:45:23 +02:00
2019-11-08 10:38:45 +01:00
if ( ! currentScene )
{
return false ;
}
if ( m_comparisonMainScene . notNull ( ) & & m_comparisonMainScene . p ( ) = = currentScene )
{
return false ;
}
return true ;
}
2012-05-18 09:45:23 +02:00
}
2019-11-06 13:07:31 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : updateComparisonViewActiveFlag ( )
{
m_isComparisonViewActiveFlag = m_comparisonMainRendering - > scene ( ) ! = nullptr ;
this - > setProperty ( " cafViewer_IsComparisonViewActive " , QVariant ( m_isComparisonViewActiveFlag ) ) ;
}
2019-10-22 13:39:18 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setCurrentComparisonFrame ( int frameIndex )
{
if ( m_frameScenes . size ( ) = = 0 ) return ;
2019-10-31 14:58:11 +01:00
unsigned clampedFrameIndex = static_cast < unsigned > ( clampFrameIndex ( frameIndex ) ) ;
2019-10-22 13:39:18 +02:00
if ( m_releaseOGLResourcesEachFrame )
{
releaseOGlResourcesForCurrentFrame ( ) ;
}
if ( m_comparisonFrameScenes . size ( ) > clampedFrameIndex & & m_comparisonFrameScenes . at ( clampedFrameIndex ) ! = nullptr )
{
m_comparisonMainRendering - > setScene ( m_comparisonFrameScenes . at ( clampedFrameIndex ) ) ;
2019-11-06 13:07:31 +01:00
updateComparisonViewActiveFlag ( ) ;
2019-10-22 13:39:18 +02:00
}
else
{
m_comparisonMainRendering - > setScene ( nullptr ) ;
2019-11-06 13:07:31 +01:00
updateComparisonViewActiveFlag ( ) ;
2019-10-22 13:39:18 +02:00
}
update ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setComparisonViewToFollowAnimation ( bool isToFollow )
{
m_isComparisonFollowingAnimation = isToFollow ;
}
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : slotSetCurrentFrame ( int frameIndex )
{
2015-09-01 09:20:15 +02:00
if ( m_frameScenes . size ( ) = = 0 ) return ;
2019-10-31 14:58:11 +01:00
unsigned clampedFrameIndex = static_cast < unsigned > ( clampFrameIndex ( frameIndex ) ) ;
2012-05-18 09:45:23 +02:00
2015-08-31 11:45:30 +02:00
if ( m_releaseOGLResourcesEachFrame )
{
releaseOGlResourcesForCurrentFrame ( ) ;
}
2012-08-31 19:12:47 +02:00
2019-10-10 17:53:36 +02:00
if ( m_frameScenes . size ( ) > clampedFrameIndex & & m_frameScenes . at ( clampedFrameIndex ) ! = nullptr )
{
m_mainRendering - > setScene ( m_frameScenes . at ( clampedFrameIndex ) ) ;
}
else
{
m_mainRendering - > setScene ( nullptr ) ;
}
2019-10-22 13:39:18 +02:00
if ( m_isComparisonFollowingAnimation )
2019-10-10 17:53:36 +02:00
{
2019-10-22 13:39:18 +02:00
if ( m_comparisonFrameScenes . size ( ) > clampedFrameIndex & & m_comparisonFrameScenes . at ( clampedFrameIndex ) ! = nullptr )
{
m_comparisonMainRendering - > setScene ( m_comparisonFrameScenes . at ( clampedFrameIndex ) ) ;
2019-11-06 13:07:31 +01:00
updateComparisonViewActiveFlag ( ) ;
2019-10-22 13:39:18 +02:00
}
else
{
m_comparisonMainRendering - > setScene ( nullptr ) ;
2019-11-06 13:07:31 +01:00
updateComparisonViewActiveFlag ( ) ;
2019-10-22 13:39:18 +02:00
}
2019-10-10 17:53:36 +02:00
}
2019-10-22 13:39:18 +02:00
2015-09-03 13:01:39 +02:00
update ( ) ;
2012-05-18 09:45:23 +02:00
}
2019-11-06 13:07:31 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2012-05-18 09:45:23 +02:00
void caf : : Viewer : : releaseOGlResourcesForCurrentFrame ( )
{
if ( isAnimationActive ( ) )
{
2016-09-07 15:53:33 +02:00
cvf : : Scene * currentScene = m_mainRendering - > scene ( ) ;
2012-05-18 09:45:23 +02:00
makeCurrent ( ) ;
2013-01-21 16:01:46 +01:00
cvf : : uint modelCount = currentScene - > modelCount ( ) ;
for ( cvf : : uint i = 0 ; i < modelCount ; + + i )
2012-05-18 09:45:23 +02:00
{
2012-08-31 19:12:47 +02:00
cvf : : Collection < cvf : : Part > partCollection ;
currentScene - > model ( i ) - > allParts ( & partCollection ) ;
for ( size_t pIdx = 0 ; pIdx < partCollection . size ( ) ; + + pIdx )
{
if ( partCollection [ pIdx ] . notNull ( ) & & partCollection [ pIdx ] - > drawable ( ) )
{
partCollection [ pIdx ] - > drawable ( ) - > releaseBufferObjectsGPU ( ) ;
}
}
2012-05-18 09:45:23 +02:00
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : slotEndAnimation ( )
{
if ( m_releaseOGLResourcesEachFrame )
{
releaseOGlResourcesForCurrentFrame ( ) ;
}
2016-09-07 15:53:33 +02:00
m_mainRendering - > setScene ( m_mainScene . p ( ) ) ;
2015-08-31 11:45:30 +02:00
2015-09-03 13:01:39 +02:00
update ( ) ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// This only updates the boundingboxes yet. Might want to do other things as well
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : updateCachedValuesInScene ( )
{
if ( m_mainScene . notNull ( ) )
{
cvf : : uint midx ;
for ( midx = 0 ; midx < m_mainScene - > modelCount ( ) ; + + midx )
{
m_mainScene - > model ( midx ) - > updateBoundingBoxesRecursive ( ) ;
}
}
size_t sIdx ;
for ( sIdx = 0 ; sIdx < m_frameScenes . size ( ) ; + + sIdx )
{
cvf : : uint midx ;
for ( midx = 0 ; midx < m_frameScenes [ sIdx ] - > modelCount ( ) ; + + midx )
{
m_frameScenes [ sIdx ] - > model ( midx ) - > updateBoundingBoxesRecursive ( ) ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool caf : : Viewer : : isShadersSupported ( )
{
QGLFormat : : OpenGLVersionFlags flags = QGLFormat : : openGLVersionFlags ( ) ;
bool hasOpenGL_2_0 = QGLFormat : : OpenGL_Version_2_0 & flags ;
if ( hasOpenGL_2_0 )
{
return true ;
}
return false ;
}
2016-08-31 17:34:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage caf : : Viewer : : snapshotImage ( )
{
2019-06-28 13:37:37 +02:00
// Qt5 : Call paintEvent() manually to make sure invisible widgets are rendered properly
// If this call is skipped, we get an assert in cvf::FramebufferObject::bind()
paintEvent ( nullptr ) ;
2016-11-01 10:12:11 +01:00
2016-08-31 17:34:31 +02:00
QImage image ;
2016-10-28 19:16:27 +02:00
if ( m_offscreenFbo . notNull ( ) & & m_offscreenViewportWidth > 0 & & m_offscreenViewportHeight > 0 )
2016-08-31 17:34:31 +02:00
{
2016-10-28 19:16:27 +02:00
cvf : : ref < cvf : : OpenGLContext > myOglContext = cvfOpenGLContext ( ) ;
2016-11-01 10:12:11 +01:00
m_offscreenFbo - > bind ( myOglContext . p ( ) ) ;
2016-10-28 19:16:27 +02:00
GLint iOldPackAlignment = 0 ;
glGetIntegerv ( GL_PACK_ALIGNMENT , & iOldPackAlignment ) ;
glPixelStorei ( GL_PACK_ALIGNMENT , 1 ) ;
CVF_CHECK_OGL ( myOglContext . p ( ) ) ;
cvf : : UByteArray arr ( 3 * m_offscreenViewportWidth * m_offscreenViewportHeight ) ;
glReadPixels ( 0 , 0 , static_cast < GLsizei > ( m_offscreenViewportWidth ) , static_cast < GLsizei > ( m_offscreenViewportHeight ) , GL_RGB , GL_UNSIGNED_BYTE , arr . ptr ( ) ) ;
CVF_CHECK_OGL ( myOglContext . p ( ) ) ;
glPixelStorei ( GL_PACK_ALIGNMENT , iOldPackAlignment ) ;
CVF_CHECK_OGL ( myOglContext . p ( ) ) ;
2016-11-01 10:12:11 +01:00
cvf : : FramebufferObject : : useDefaultWindowFramebuffer ( myOglContext . p ( ) ) ;
2016-10-28 19:16:27 +02:00
cvf : : TextureImage texImage ;
texImage . setFromRgb ( arr . ptr ( ) , m_offscreenViewportWidth , m_offscreenViewportHeight ) ;
image = cvfqt : : Utils : : toQImage ( texImage ) ;
2016-08-31 17:34:31 +02:00
}
else
{
// Code moved from RimView::snapshotWindowContent()
GLint currentReadBuffer ;
glGetIntegerv ( GL_READ_BUFFER , & currentReadBuffer ) ;
glReadBuffer ( GL_FRONT ) ;
image = this - > grabFrameBuffer ( ) ;
glReadBuffer ( currentReadBuffer ) ;
}
return image ;
}
2012-05-18 09:45:23 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
cvf : : Scene * caf : : Viewer : : frame ( size_t frameIndex , bool isForComparisonView )
2012-05-18 09:45:23 +02:00
{
2019-10-10 17:53:36 +02:00
if ( ! isForComparisonView )
{
if ( frameIndex < m_frameScenes . size ( ) )
return m_frameScenes [ frameIndex ] . p ( ) ;
else
return nullptr ;
}
2012-05-18 09:45:23 +02:00
else
2019-10-10 17:53:36 +02:00
{
if ( frameIndex < m_comparisonFrameScenes . size ( ) )
return m_comparisonFrameScenes [ frameIndex ] . p ( ) ;
else
return nullptr ;
}
2012-05-18 09:45:23 +02:00
}
2012-06-26 16:10:41 +02:00
//--------------------------------------------------------------------------------------------------
/// Helper function used to write out the name of all parts in a rendering sequence
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : debugShowRenderingSequencePartNames ( )
{
qDebug ( ) < < " \n \n " ;
size_t globalPartCount = 0 ;
cvf : : uint rIdx = m_renderingSequence - > renderingCount ( ) ;
for ( rIdx = 0 ; rIdx < m_renderingSequence - > renderingCount ( ) ; rIdx + + )
{
cvf : : Rendering * rendering = m_renderingSequence - > rendering ( rIdx ) ;
if ( rendering & & rendering - > scene ( ) )
{
cvf : : uint mIdx ;
for ( mIdx = 0 ; mIdx < rendering - > scene ( ) - > modelCount ( ) ; mIdx + + )
{
cvf : : Model * model = rendering - > scene ( ) - > model ( mIdx ) ;
if ( model )
{
cvf : : Collection < cvf : : Part > parts ;
model - > allParts ( & parts ) ;
size_t pIdx ;
for ( pIdx = 0 ; pIdx < parts . size ( ) ; pIdx + + )
{
cvf : : Part * part = parts . at ( pIdx ) ;
qDebug ( ) < < QString ( " %1 " ) . arg ( globalPartCount + + ) < < cvfqt : : Utils : : toQString ( part - > name ( ) ) ;
}
}
}
}
}
}
2012-09-18 15:21:04 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : enableNavigationPolicy ( bool enable )
{
m_navigationPolicyEnabled = enable ;
if ( enable & & m_navigationPolicy . notNull ( ) ) m_navigationPolicy - > init ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize caf : : Viewer : : sizeHint ( ) const
{
return QSize ( 500 , 400 ) ;
}
2015-11-16 10:00:22 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2012-08-31 19:12:47 +02:00
void caf : : Viewer : : enableForcedImmediateMode ( bool enable )
{
2015-11-16 10:00:22 +01:00
cvf : : uint rIdx = m_renderingSequence - > renderingCount ( ) ;
for ( rIdx = 0 ; rIdx < m_renderingSequence - > renderingCount ( ) ; rIdx + + )
{
cvf : : Rendering * rendering = m_renderingSequence - > rendering ( rIdx ) ;
if ( rendering & & rendering - > scene ( ) )
{
rendering - > renderEngine ( ) - > enableForcedImmediateMode ( enable ) ;
}
}
2012-08-31 19:12:47 +02:00
}
2012-09-11 09:22:36 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2015-12-17 14:40:01 +01:00
int caf : : Viewer : : currentFrameIndex ( ) const
2012-09-11 09:22:36 +02:00
{
2015-12-17 14:40:01 +01:00
if ( m_animationControl )
{
int clampedFrameIndex = clampFrameIndex ( m_animationControl - > currentFrame ( ) ) ;
return clampedFrameIndex ;
}
2012-09-11 09:22:36 +02:00
else return 0 ;
}
2013-02-28 11:58:31 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-03-04 10:35:29 +01:00
bool caf : : Viewer : : isOverlayPaintingEnabled ( ) const
2013-02-28 11:58:31 +01:00
{
2015-11-23 13:29:11 +01:00
return m_isOverlayPaintingEnabled ;
2013-02-28 11:58:31 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-03-04 10:35:29 +01:00
void caf : : Viewer : : enableOverlayPainting ( bool val )
2013-02-28 11:58:31 +01:00
{
2015-11-23 13:29:11 +01:00
m_isOverlayPaintingEnabled = val ;
2013-02-28 11:58:31 +01:00
updateOverlayImagePresence ( ) ;
}
2019-10-10 17:53:36 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : Rendering * caf : : Viewer : : overlayItemsRendering ( )
{
return m_overlayItemsRendering . p ( ) ;
}
2013-02-28 11:58:31 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : updateOverlayImagePresence ( )
{
2015-11-23 13:29:11 +01:00
if ( m_isOverlayPaintingEnabled | | m_showPerfInfoHud )
2013-02-28 11:58:31 +01:00
{
2019-10-10 17:53:36 +02:00
m_overlayItemsRendering - > addOverlayItem ( m_overlayImage . p ( ) ) ;
2013-02-28 11:58:31 +01:00
}
else
{
2019-10-10 17:53:36 +02:00
m_overlayItemsRendering - > removeOverlayItem ( m_overlayImage . p ( ) ) ;
2013-02-28 11:58:31 +01:00
}
}
2015-08-28 21:32:51 +02:00
//--------------------------------------------------------------------------------------------------
/// Create a virtual method so it is possible to override this function in derived classes
//--------------------------------------------------------------------------------------------------
2015-09-01 18:04:35 +02:00
void caf : : Viewer : : navigationPolicyUpdate ( )
2015-08-28 21:32:51 +02:00
{
2015-09-01 18:04:35 +02:00
update ( ) ;
2015-08-28 21:32:51 +02:00
}
2015-11-17 10:53:41 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
void caf : : Viewer : : addStaticModelOnce ( cvf : : Model * model , bool isForComparisonView )
2015-11-17 10:53:41 +01:00
{
2019-10-10 17:53:36 +02:00
if ( ! isForComparisonView )
{
if ( m_staticModels . contains ( model ) ) return ;
m_staticModels . push_back ( model ) ;
}
else
{
if ( m_comparisonStaticModels . contains ( model ) ) return ;
2015-11-17 10:53:41 +01:00
2019-10-10 17:53:36 +02:00
m_comparisonStaticModels . push_back ( model ) ;
}
2015-11-17 10:53:41 +01:00
2019-10-10 17:53:36 +02:00
appendModelToAllFrames ( model , isForComparisonView ) ;
2015-11-17 11:51:37 +01:00
updateCachedValuesInScene ( ) ;
2015-11-17 10:53:41 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : removeStaticModel ( cvf : : Model * model )
{
2019-11-04 17:06:21 +01:00
if ( m_staticModels . contains ( model ) | | m_comparisonStaticModels . contains ( model ) )
{
removeModelFromAllFrames ( model ) ;
2015-11-17 11:51:37 +01:00
2019-11-04 17:06:21 +01:00
m_staticModels . erase ( model ) ;
m_comparisonStaticModels . erase ( model ) ;
updateCachedValuesInScene ( ) ;
}
2015-11-17 10:53:41 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : removeAllStaticModels ( )
{
for ( size_t i = 0 ; i < m_staticModels . size ( ) ; i + + )
{
removeModelFromAllFrames ( m_staticModels . at ( i ) ) ;
}
2019-10-10 17:53:36 +02:00
for ( size_t i = 0 ; i < m_comparisonStaticModels . size ( ) ; i + + )
{
removeModelFromAllFrames ( m_comparisonStaticModels . at ( i ) ) ;
}
2015-11-17 10:53:41 +01:00
m_staticModels . clear ( ) ;
2019-10-10 17:53:36 +02:00
m_comparisonStaticModels . clear ( ) ;
2015-11-17 11:51:37 +01:00
updateCachedValuesInScene ( ) ;
2015-11-17 10:53:41 +01:00
}
2019-10-10 17:53:36 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setEnableMask ( unsigned int mask , bool isForComparisonView /*= false */ )
{
if ( ! isForComparisonView )
{
m_mainRendering - > setEnableMask ( mask ) ;
}
else
{
m_comparisonMainRendering - > setEnableMask ( mask ) ;
}
}
2015-11-17 10:53:41 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : removeModelFromAllFrames ( cvf : : Model * model )
{
for ( size_t i = 0 ; i < m_frameScenes . size ( ) ; i + + )
{
cvf : : Scene * scene = m_frameScenes . at ( i ) ;
scene - > removeModel ( model ) ;
}
2015-11-22 15:04:09 +01:00
if ( m_mainScene . notNull ( ) )
{
m_mainScene - > removeModel ( model ) ;
}
2019-10-10 17:53:36 +02:00
for ( size_t i = 0 ; i < m_comparisonFrameScenes . size ( ) ; i + + )
{
cvf : : Scene * scene = m_comparisonFrameScenes . at ( i ) ;
scene - > removeModel ( model ) ;
}
if ( m_comparisonMainScene . notNull ( ) )
{
m_comparisonMainScene - > removeModel ( model ) ;
}
2015-11-17 10:53:41 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
void caf : : Viewer : : appendModelToAllFrames ( cvf : : Model * model , bool isForComparisonView )
2015-11-17 10:53:41 +01:00
{
2019-10-10 17:53:36 +02:00
if ( ! isForComparisonView )
2015-11-17 10:53:41 +01:00
{
2019-10-10 17:53:36 +02:00
for ( size_t i = 0 ; i < m_frameScenes . size ( ) ; i + + )
{
cvf : : Scene * scene = m_frameScenes . at ( i ) ;
2015-11-17 10:53:41 +01:00
2019-10-10 17:53:36 +02:00
scene - > addModel ( model ) ;
}
2015-11-22 15:04:09 +01:00
2019-10-10 17:53:36 +02:00
if ( m_mainScene . notNull ( ) )
{
m_mainScene - > addModel ( model ) ;
}
}
else
2015-11-22 15:04:09 +01:00
{
2019-10-10 17:53:36 +02:00
for ( size_t i = 0 ; i < m_comparisonFrameScenes . size ( ) ; i + + )
{
cvf : : Scene * scene = m_comparisonFrameScenes . at ( i ) ;
scene - > addModel ( model ) ;
}
if ( m_comparisonMainScene . notNull ( ) )
{
m_comparisonMainScene - > addModel ( model ) ;
}
2015-11-22 15:04:09 +01:00
}
}
2015-11-17 10:53:41 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2019-10-10 17:53:36 +02:00
void caf : : Viewer : : appendAllStaticModelsToFrame ( cvf : : Scene * scene , bool isForComparisonView )
2015-11-17 10:53:41 +01:00
{
2019-10-10 17:53:36 +02:00
if ( ! scene ) return ;
if ( ! isForComparisonView )
2015-11-17 10:53:41 +01:00
{
2019-10-10 17:53:36 +02:00
for ( size_t i = 0 ; i < m_staticModels . size ( ) ; i + + )
{
scene - > addModel ( m_staticModels . at ( i ) ) ;
}
}
else
{
for ( size_t i = 0 ; i < m_comparisonStaticModels . size ( ) ; i + + )
{
scene - > addModel ( m_comparisonStaticModels . at ( i ) ) ;
}
2015-11-17 10:53:41 +01:00
}
}
2015-12-07 09:59:19 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : OverlayItem * caf : : Viewer : : overlayItem ( int winPosX , int winPosY )
{
2019-10-10 17:53:36 +02:00
if ( m_overlayItemsRendering . isNull ( ) ) return nullptr ;
2015-12-07 09:59:19 +01:00
int translatedMousePosX = winPosX ;
int translatedMousePosY = height ( ) - winPosY ;
2019-10-10 17:53:36 +02:00
return m_overlayItemsRendering - > overlayItemFromWindowCoordinates ( translatedMousePosX , translatedMousePosY ) ;
2015-12-07 09:59:19 +01:00
}
2015-12-05 00:56:14 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : enableParallelProjection ( bool enableOrtho )
{
if ( enableOrtho & & m_mainCamera - > projection ( ) = = cvf : : Camera : : PERSPECTIVE )
{
cvf : : Vec3d pointOfInterest ;
if ( m_navigationPolicy . isNull ( ) | | ! m_navigationPolicyEnabled )
{
using namespace cvf ;
Vec3d eye , vrp , up ;
m_mainCamera - > toLookAt ( & eye , & vrp , & up ) ;
Vec3d eyeToFocus = pointOfInterest - eye ;
Vec3d camDir = vrp - eye ;
camDir . normalize ( ) ;
double distToFocusPlane = 0.5 * ( m_mainCamera - > farPlane ( ) - m_mainCamera - > nearPlane ( ) ) ;
pointOfInterest = camDir * distToFocusPlane ;
}
else
{
pointOfInterest = m_navigationPolicy - > pointOfInterest ( ) ;
}
m_mainCamera - > setProjectionAsOrtho ( 1.0 , m_mainCamera - > nearPlane ( ) , m_mainCamera - > farPlane ( ) ) ;
2015-12-07 15:54:44 +01:00
this - > updateParallelProjectionHeightFromMoveZoom ( pointOfInterest ) ;
2016-08-16 10:58:07 +02:00
2019-06-25 17:01:38 +02:00
// Set a fake directional light by putting the point far away from the scene
2016-08-16 10:58:07 +02:00
float sceneDepth = m_mainCamera - > farPlane ( ) - m_mainCamera - > nearPlane ( ) ;
2019-06-25 17:01:38 +02:00
this - > m_renderingSequence - > setDefaultFFLightPositional ( - m_parallelProjectionLightDirection * 10 * sceneDepth ) ;
m_globalUniformSet - > setHeadLightPosition ( - m_parallelProjectionLightDirection * 10 * sceneDepth ) ;
2015-12-05 00:56:14 +01:00
this - > update ( ) ;
}
else if ( ! enableOrtho & & m_mainCamera - > projection ( ) = = cvf : : Camera : : ORTHO )
{
// We currently expect all the navigation policies to do walk-based navigation and not fiddle with the field of view
// so we do not need to update the camera position based on orthoHeight and fieldOfView.
// We assume the camera is in a sensible position.
2019-06-25 17:01:38 +02:00
// Set dummy near and far plane. These will be updated by the optimize clipping planes
2016-08-16 13:41:10 +02:00
m_mainCamera - > setProjectionAsPerspective ( m_cameraFieldOfViewYDeg , 0.1 , 1.0 ) ;
2016-08-15 14:27:46 +02:00
this - > m_renderingSequence - > setDefaultFFLightPositional ( cvf : : Vec3f ( 0.5 , 5.0 , 7.0 ) ) ;
2016-08-16 10:58:07 +02:00
m_globalUniformSet - > setHeadLightPosition ( cvf : : Vec3f ( 0.5 , 5.0 , 7.0 ) ) ;
2016-08-15 14:27:46 +02:00
2015-12-05 00:56:14 +01:00
this - > update ( ) ;
}
}
2019-06-25 17:01:38 +02:00
//--------------------------------------------------------------------------------------------------
/// Direction in camera coordinates default is (0, 0, -1) directly from behind
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setParallelProjectionHeadLightDirection ( const cvf : : Vec3f & direction )
{
m_parallelProjectionLightDirection = direction ;
float sceneDepth = m_mainCamera - > farPlane ( ) - m_mainCamera - > nearPlane ( ) ;
this - > m_renderingSequence - > setDefaultFFLightPositional ( - m_parallelProjectionLightDirection * 10 * sceneDepth ) ;
m_globalUniformSet - > setHeadLightPosition ( - m_parallelProjectionLightDirection * 10 * sceneDepth ) ;
this - > update ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : setPointOfInterestVisualizer ( PointOfInterestVisualizer * poiVisualizer )
{
m_poiVisualizationManager = poiVisualizer ;
}
2015-12-05 00:56:14 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double calculateOrthoHeight ( double perspectiveViewAngleYDeg , double focusPlaneDist )
{
return 2 * ( cvf : : Math : : tan ( cvf : : Math : : toRadians ( 0.5 * perspectiveViewAngleYDeg ) ) * focusPlaneDist ) ;
}
2015-12-07 15:54:44 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-08-16 13:41:10 +02:00
double calculateDistToPlaneOfOrthoHeight ( double perspectiveViewAngleYDeg , double orthoHeight )
2015-12-07 15:54:44 +01:00
{
return orthoHeight / ( 2 * ( cvf : : Math : : tan ( cvf : : Math : : toRadians ( 0.5 * perspectiveViewAngleYDeg ) ) ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double distToPlaneOfInterest ( const cvf : : Camera * camera , const cvf : : Vec3d & pointOfInterest )
{
using namespace cvf ;
CVF_ASSERT ( camera ) ;
Vec3d eye , vrp , up ;
camera - > toLookAt ( & eye , & vrp , & up ) ;
Vec3d camDir = vrp - eye ;
camDir . normalize ( ) ;
Vec3d eyeToFocus = pointOfInterest - eye ;
double distToFocusPlane = eyeToFocus * camDir ;
2016-08-16 13:41:10 +02:00
return distToFocusPlane ;
2015-12-07 15:54:44 +01:00
}
2015-12-05 00:56:14 +01:00
//--------------------------------------------------------------------------------------------------
/// Update the ortho projection view height from a walk based camera manipulation.
/// Using pointOfInterest, the perspective Y-field Of View along with the camera position
//--------------------------------------------------------------------------------------------------
2015-12-07 15:54:44 +01:00
void caf : : Viewer : : updateParallelProjectionHeightFromMoveZoom ( const cvf : : Vec3d & pointOfInterest )
2015-12-05 00:56:14 +01:00
{
using namespace cvf ;
cvf : : Camera * camera = m_mainCamera . p ( ) ;
if ( ! camera | | camera - > projection ( ) ! = Camera : : ORTHO ) return ;
2016-08-16 13:41:10 +02:00
// Negative distance can occur. If so, do not set a negative ortho.
2015-12-07 15:54:44 +01:00
2016-08-16 13:41:10 +02:00
double distToFocusPlane = cvf : : Math : : abs ( distToPlaneOfInterest ( camera , pointOfInterest ) ) ;
2015-12-07 15:54:44 +01:00
double orthoHeight = calculateOrthoHeight ( m_cameraFieldOfViewYDeg , distToFocusPlane ) ;
camera - > setProjectionAsOrtho ( orthoHeight , camera - > nearPlane ( ) , camera - > farPlane ( ) ) ;
}
//--------------------------------------------------------------------------------------------------
/// Update the camera eye position from point of interest, keeping the ortho height fixed and in sync
/// with distToPlaneOfInterest from a walk based camera manipulation in ortho projection.
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : updateParallelProjectionCameraPosFromPointOfInterestMove ( const cvf : : Vec3d & pointOfInterest )
{
using namespace cvf ;
cvf : : Camera * camera = m_mainCamera . p ( ) ;
if ( ! camera | | camera - > projection ( ) ! = Camera : : ORTHO ) return ;
double orthoHeight = camera - > frontPlaneFrustumHeight ( ) ;
2015-12-14 09:53:59 +01:00
//Trace::show(String::number(orthoHeight));
2015-12-07 15:54:44 +01:00
2016-08-16 13:41:10 +02:00
double neededDistToFocusPlane = calculateDistToPlaneOfOrthoHeight ( m_cameraFieldOfViewYDeg , orthoHeight ) ;
2015-12-07 15:54:44 +01:00
2015-12-05 00:56:14 +01:00
Vec3d eye , vrp , up ;
camera - > toLookAt ( & eye , & vrp , & up ) ;
Vec3d camDir = vrp - eye ;
camDir . normalize ( ) ;
2015-12-07 15:54:44 +01:00
double existingDistToFocusPlane = distToPlaneOfInterest ( camera , pointOfInterest ) ;
2015-12-05 00:56:14 +01:00
2015-12-07 15:54:44 +01:00
Vec3d newEye = eye + ( existingDistToFocusPlane - neededDistToFocusPlane ) * camDir ;
2015-12-14 09:53:59 +01:00
//Trace::show(String::number(newEye.x()) + ", " + String::number(newEye.y()) + ", " +String::number(newEye.z()));
2015-12-07 15:54:44 +01:00
camera - > setFromLookAt ( newEye , newEye + 10.0 * camDir , up ) ;
2015-12-05 00:56:14 +01:00
}
2015-12-07 15:54:44 +01:00
2015-12-17 14:40:01 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf : : Viewer : : clampFrameIndex ( int frameIndex ) const
{
2016-08-17 08:52:22 +02:00
int clampedFrameIndex = frameIndex ;
int frameCountInt = static_cast < int > ( frameCount ( ) ) ;
2015-12-17 14:40:01 +01:00
2016-08-17 08:52:22 +02:00
if ( clampedFrameIndex > = frameCountInt )
2015-12-17 14:40:01 +01:00
{
2016-08-17 08:52:22 +02:00
clampedFrameIndex = frameCountInt - 1 ;
2015-12-17 14:40:01 +01:00
}
else if ( clampedFrameIndex < 0 )
{
clampedFrameIndex = 0 ;
}
2016-08-17 08:52:22 +02:00
return clampedFrameIndex ;
2015-12-17 14:40:01 +01:00
}
2019-10-10 17:53:36 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf : : Viewer : : copyCameraView ( cvf : : Camera * srcCamera , cvf : : Camera * dstCamera )
{
if ( srcCamera - > projection ( ) = = cvf : : Camera : : PERSPECTIVE )
{
dstCamera - > setProjectionAsPerspective ( srcCamera - > fieldOfViewYDeg ( ) , srcCamera - > nearPlane ( ) , srcCamera - > farPlane ( ) ) ;
}
else
{
dstCamera - > setProjectionAsOrtho ( srcCamera - > frontPlaneFrustumHeight ( ) , srcCamera - > nearPlane ( ) , srcCamera - > farPlane ( ) ) ;
}
dstCamera - > setViewMatrix ( srcCamera - > viewMatrix ( ) ) ;
}