AppFwk: Add comparison view support to the Viewer.

Add a separate overlay rendering to make rendering of overlay items more flexible and to support the comparison view.
Add control of the Rendering Enable mask
This commit is contained in:
Jacob Støren 2019-10-10 17:53:36 +02:00
parent 6d2253ad26
commit 468cea28bc
2 changed files with 406 additions and 88 deletions

View File

@ -76,6 +76,7 @@
#include <QDebug>
#include <QHBoxLayout>
#include <QInputEvent>
#include "cvfRenderingScissor.h"
namespace caf
{
@ -103,6 +104,7 @@ private:
cvf::ref<cvf::UniformFloat> m_headlightPosition;
};
}
std::list<caf::Viewer*> caf::Viewer::sm_viewers;
@ -127,7 +129,9 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
m_isOverlayPaintingEnabled(true),
m_offscreenViewportWidth(0),
m_offscreenViewportHeight(0),
m_parallelProjectionLightDirection(0, 0, -1) // Light directly from behind
m_parallelProjectionLightDirection(0, 0, -1), // Light directly from behind
m_comparisonViewOffset(0, 0, 0),
m_comparisonWindowNormalizedRect(0.5f, 0.0f, 0.5f, 1.0f)
{
#if QT_VERSION >= 0x050000
m_layoutWidget = new QWidget(parent);
@ -150,10 +154,19 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
m_mainCamera = new cvf::Camera;
m_mainCamera->setFromLookAt(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,0,0), cvf::Vec3d(0,1,0));
m_comparisonMainCamera = new cvf::Camera;
m_comparisonMainCamera->setFromLookAt(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,0,0), cvf::Vec3d(0,1,0));
m_renderingSequence = new cvf::RenderSequence();
m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0.5, 5.0, 7.0));
m_mainRendering = new cvf::Rendering();
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());
m_animationControl = new caf::FrameAnimationControl(this);
connect(m_animationControl, SIGNAL(changeFrame(int)), SLOT(slotSetCurrentFrame(int)));
@ -193,20 +206,32 @@ caf::Viewer::~Viewer()
void caf::Viewer::setupMainRendering()
{
m_mainRendering->setCamera(m_mainCamera.p());
m_comparisonMainRendering->setCamera(m_comparisonMainCamera.p());
m_overlayItemsRendering->setCamera(m_mainCamera.p());
m_mainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_comparisonMainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_overlayItemsRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_mainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p());
m_comparisonMainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p());
// Set fixed function rendering if QGLFormat does not support directRendering
if (!this->format().directRendering())
{
m_mainRendering->renderEngine()->enableForcedImmediateMode(true);
m_comparisonMainRendering->renderEngine()->enableForcedImmediateMode(true);
m_overlayItemsRendering->renderEngine()->enableForcedImmediateMode(true);
}
if (contextGroup()->capabilities() &&
contextGroup()->capabilities()->hasCapability(cvf::OpenGLCapabilities::FRAMEBUFFER_OBJECT))
{
m_offscreenFbo = new cvf::FramebufferObject;
m_mainRendering->setTargetFramebuffer(m_offscreenFbo.p());
m_comparisonMainRendering->setTargetFramebuffer(m_offscreenFbo.p());
m_overlayItemsRendering->setTargetFramebuffer(m_offscreenFbo.p());
cvf::ref<cvf::RenderbufferObject> rbo = new cvf::RenderbufferObject(cvf::RenderbufferObject::DEPTH_COMPONENT24, 1, 1);
m_offscreenFbo->attachDepthRenderbuffer(rbo.p());
@ -225,6 +250,8 @@ void caf::Viewer::setupMainRendering()
void caf::Viewer::setupRenderingSequence()
{
m_renderingSequence->addRendering(m_mainRendering.p());
m_renderingSequence->addRendering(m_comparisonMainRendering.p());
m_renderingSequence->addRendering(m_overlayItemsRendering.p());
if (m_offscreenFbo.notNull())
{
@ -282,30 +309,94 @@ cvf::Camera* caf::Viewer::mainCamera()
}
//--------------------------------------------------------------------------------------------------
/// Set the scene to be rendered when the animation is inactive (Stopped)
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::setMainScene(cvf::Scene* scene)
cvf::Camera* caf::Viewer::comparisonMainCamera()
{
appendAllStaticModelsToFrame(scene);
m_mainScene = scene;
m_mainRendering->setScene(scene);
return m_comparisonMainCamera.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::mainScene()
void caf::Viewer::setComparisonViewEyePointOffset(const cvf::Vec3d& offset)
{
return m_mainScene.p();
m_comparisonViewOffset = offset;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::Vec3d caf::Viewer::comparisonViewEyePointOffset()
{
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;
}
//--------------------------------------------------------------------------------------------------
/// 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);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::mainScene( bool isForComparisonView)
{
if (!isForComparisonView)
{
return m_mainScene.p();
}
else
{
return m_comparisonMainScene.p();
}
}
//--------------------------------------------------------------------------------------------------
/// Return the currently rendered scene
//--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::currentScene()
cvf::Scene* caf::Viewer::currentScene(bool isForComparisonView)
{
return m_mainRendering->scene();
if (!isForComparisonView)
{
return m_mainRendering->scene();
}
else
{
return m_comparisonMainRendering->scene();
}
}
//--------------------------------------------------------------------------------------------------
@ -316,6 +407,11 @@ void caf::Viewer::updateCamera(int width, int height)
if (width < 1 || height < 1) return;
m_mainCamera->viewport()->set(0, 0, width, height);
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()));
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE)
{
@ -347,11 +443,66 @@ bool caf::Viewer::canRender() const
//--------------------------------------------------------------------------------------------------
void caf::Viewer::optimizeClippingPlanes()
{
cvf::BoundingBox bb = m_mainRendering->boundingBox();
if (!bb.isValid()) return;
double nearPlaneDist = HUGE_VAL;
double farPlaneDist = HUGE_VAL;
cvf::Vec3d eye = m_mainCamera->position();
cvf::Vec3d viewdir = m_mainCamera->direction();
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() );
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);
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();
cvf::Vec3d bboxCorners[8];
bb.cornerVertices(bboxCorners);
@ -360,68 +511,60 @@ void caf::Viewer::optimizeClippingPlanes()
double maxDistEyeToCornerAlongViewDir = -HUGE_VAL;
double minDistEyeToCornerAlongViewDir = HUGE_VAL;
for (int bcIdx = 0; bcIdx < 8; ++bcIdx )
for ( int bcIdx = 0; bcIdx < 8; ++bcIdx )
{
double distEyeBoxCornerAlongViewDir = (bboxCorners[bcIdx] - eye)*viewdir;
if (distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir)
if ( distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir )
{
maxDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir;
}
if (distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir)
if ( distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir )
{
minDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir; // Sometimes negative-> behind camera
}
}
double farPlaneDist = CVF_MIN(maxDistEyeToCornerAlongViewDir * 1.2, m_maxClipPlaneDistance);
(*farPlaneDist) = CVF_MIN(maxDistEyeToCornerAlongViewDir * 1.2, m_maxClipPlaneDistance);
// Near-plane:
bool isOrthoNearPlaneFollowingCamera = false;
double nearPlaneDist = HUGE_VAL;
// If we have perspective projection, set the near plane just in front of camera, and not behind
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE || isOrthoNearPlaneFollowingCamera)
if ( rendering->camera()->projection() == cvf::Camera::PERSPECTIVE || isOrthoNearPlaneFollowingCamera )
{
// Choose the one furthest from the camera of: 0.8*bbox distance, m_minPerspectiveNearPlaneDistance.
nearPlaneDist = CVF_MAX( m_defaultPerspectiveNearPlaneDistance, 0.8*minDistEyeToCornerAlongViewDir);
(*nearPlaneDist) = CVF_MAX(m_defaultPerspectiveNearPlaneDistance, 0.8*minDistEyeToCornerAlongViewDir);
// If we are zooming into a detail, allow the near-plane to move towards camera beyond the m_minPerspectiveNearPlaneDistance
if ( nearPlaneDist == m_defaultPerspectiveNearPlaneDistance // We are inside the bounding box
&& m_navigationPolicy.notNull() && m_navigationPolicyEnabled)
if ( (*nearPlaneDist) == m_defaultPerspectiveNearPlaneDistance // We are inside the bounding box
&& m_navigationPolicy.notNull() && m_navigationPolicyEnabled )
{
double pointOfInterestDist = (eye - m_navigationPolicy->pointOfInterest()).length();
nearPlaneDist = CVF_MIN(nearPlaneDist, pointOfInterestDist*0.2);
double pointOfInterestDist = (eye - navPointOfinterest).length();
(*nearPlaneDist) = CVF_MIN((*nearPlaneDist), pointOfInterestDist*0.2);
}
// Guard against the zero nearplane possibility
if (nearPlaneDist <= 0) nearPlaneDist = m_defaultPerspectiveNearPlaneDistance;
if ( nearPlaneDist <= 0 ) (*nearPlaneDist) = m_defaultPerspectiveNearPlaneDistance;
}
else // Orthographic projection. Set to encapsulate the complete boundingbox, possibly setting a negative nearplane
{
if(minDistEyeToCornerAlongViewDir >= 0)
if ( minDistEyeToCornerAlongViewDir >= 0 )
{
nearPlaneDist = CVF_MIN(0.8 * minDistEyeToCornerAlongViewDir, m_maxClipPlaneDistance);
(*nearPlaneDist) = CVF_MIN(0.8 * minDistEyeToCornerAlongViewDir, m_maxClipPlaneDistance);
}
else
{
nearPlaneDist = CVF_MAX(1.2 * minDistEyeToCornerAlongViewDir, -m_maxClipPlaneDistance);
(*nearPlaneDist) = CVF_MAX(1.2 * minDistEyeToCornerAlongViewDir, -m_maxClipPlaneDistance);
}
}
if (farPlaneDist <= nearPlaneDist) farPlaneDist = nearPlaneDist + 1.0;
if ( (*farPlaneDist) <= (*nearPlaneDist) ) (*farPlaneDist) = (*nearPlaneDist) + 1.0;
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE)
{
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, nearPlaneDist, farPlaneDist);
}
else
{
m_mainCamera->setProjectionAsOrtho(m_mainCamera->frontPlaneFrustumHeight(), nearPlaneDist, farPlaneDist);
}
return true;
}
//--------------------------------------------------------------------------------------------------
@ -644,9 +787,15 @@ void caf::Viewer::paintEvent(QPaintEvent* event)
optimizeClippingPlanes();
m_renderingSequence->removeRendering(m_comparisonMainRendering.p());
if ( m_comparisonMainRendering->scene() )
{
m_renderingSequence->insertRendering( m_overlayItemsRendering.p(), m_comparisonMainRendering.p());
}
if ( m_poiVisualizationManager.notNull() )
{
m_poiVisualizationManager->update(m_navigationPolicy->pointOfInterest());
m_poiVisualizationManager->update(m_navigationPolicy->pointOfInterest()); // Todo: Must be inserted in comparison scene as well, using the display offset
m_mainRendering->scene()->addModel(m_poiVisualizationManager->model());
}
@ -728,22 +877,39 @@ void caf::Viewer::zoomAll()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::addFrame(cvf::Scene* scene)
void caf::Viewer::addFrame(cvf::Scene* scene, bool isForComparisonView)
{
appendAllStaticModelsToFrame(scene);
appendAllStaticModelsToFrame(scene, isForComparisonView);
m_frameScenes.push_back(scene);
m_animationControl->setNumFrames(static_cast<int>(m_frameScenes.size()));
if ( !isForComparisonView )
{
m_frameScenes.push_back(scene);
}
else
{
m_comparisonFrameScenes.push_back(scene);
}
m_animationControl->setNumFrames( static_cast<int>( frameCount() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::removeAllFrames()
void caf::Viewer::removeAllFrames(bool isForComparisonView)
{
m_frameScenes.clear();
m_animationControl->setNumFrames(0);
m_mainRendering->setScene(m_mainScene.p());
if ( !isForComparisonView )
{
m_frameScenes.clear();
m_mainRendering->setScene(m_mainScene.p());
}
else
{
m_comparisonFrameScenes.clear();
m_comparisonMainRendering->setScene(m_comparisonMainScene.p());
}
m_animationControl->setNumFrames(static_cast<int>(frameCount()));
}
@ -776,15 +942,29 @@ void caf::Viewer::slotSetCurrentFrame(int frameIndex)
int clampedFrameIndex = clampFrameIndex(frameIndex);
if (m_frameScenes.at(clampedFrameIndex) == nullptr) return;
//if (m_frameScenes.at(clampedFrameIndex) == nullptr) return;
if (m_releaseOGLResourcesEachFrame)
{
releaseOGlResourcesForCurrentFrame();
}
m_mainRendering->setScene(m_frameScenes.at(clampedFrameIndex));
if (m_frameScenes.size() > clampedFrameIndex && m_frameScenes.at(clampedFrameIndex) != nullptr )
{
m_mainRendering->setScene(m_frameScenes.at(clampedFrameIndex));
}
else
{
m_mainRendering->setScene(nullptr);
}
if (m_comparisonFrameScenes.size() > clampedFrameIndex && m_comparisonFrameScenes.at(clampedFrameIndex) != nullptr )
{
m_comparisonMainRendering->setScene(m_comparisonFrameScenes.at(clampedFrameIndex));
}
else
{
m_comparisonMainRendering->setScene(nullptr);
}
update();
}
@ -881,10 +1061,6 @@ QImage caf::Viewer::snapshotImage()
m_offscreenFbo->bind(myOglContext.p());
// TODO: Consider refactor this code
// Creating a QImage from the bits in current frame buffer can be done by
// this->grabFrameBuffer()
GLint iOldPackAlignment = 0;
glGetIntegerv(GL_PACK_ALIGNMENT, &iOldPackAlignment);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
@ -924,12 +1100,22 @@ QImage caf::Viewer::snapshotImage()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Scene* caf::Viewer::frame(size_t frameIndex)
cvf::Scene* caf::Viewer::frame(size_t frameIndex, bool isForComparisonView)
{
if (frameIndex < m_frameScenes.size())
return m_frameScenes[frameIndex].p();
if ( !isForComparisonView )
{
if ( frameIndex < m_frameScenes.size() )
return m_frameScenes[frameIndex].p();
else
return nullptr;
}
else
return nullptr;
{
if ( frameIndex < m_comparisonFrameScenes.size() )
return m_comparisonFrameScenes[frameIndex].p();
else
return nullptr;
}
}
//--------------------------------------------------------------------------------------------------
@ -1031,6 +1217,14 @@ void caf::Viewer::enableOverlayPainting(bool val)
updateOverlayImagePresence();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Rendering* caf::Viewer::overlayItemsRendering()
{
return m_overlayItemsRendering.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1038,11 +1232,11 @@ void caf::Viewer::updateOverlayImagePresence()
{
if (m_isOverlayPaintingEnabled || m_showPerfInfoHud)
{
m_mainRendering->addOverlayItem(m_overlayImage.p());
m_overlayItemsRendering->addOverlayItem(m_overlayImage.p());
}
else
{
m_mainRendering->removeOverlayItem(m_overlayImage.p());
m_overlayItemsRendering->removeOverlayItem(m_overlayImage.p());
}
}
@ -1057,13 +1251,22 @@ void caf::Viewer::navigationPolicyUpdate()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::addStaticModelOnce(cvf::Model* model)
void caf::Viewer::addStaticModelOnce(cvf::Model* model, bool isForComparisonView)
{
if (m_staticModels.contains(model)) return;
if ( !isForComparisonView )
{
if ( m_staticModels.contains(model) ) return;
m_staticModels.push_back(model);
m_staticModels.push_back(model);
}
else
{
if ( m_comparisonStaticModels.contains(model) ) return;
appendModelToAllFrames(model);
m_comparisonStaticModels.push_back(model);
}
appendModelToAllFrames(model, isForComparisonView);
updateCachedValuesInScene();
}
@ -1076,6 +1279,7 @@ void caf::Viewer::removeStaticModel(cvf::Model* model)
removeModelFromAllFrames(model);
m_staticModels.erase(model);
m_comparisonStaticModels.erase(model);
updateCachedValuesInScene();
}
@ -1089,12 +1293,33 @@ void caf::Viewer::removeAllStaticModels()
{
removeModelFromAllFrames(m_staticModels.at(i));
}
for (size_t i = 0; i < m_comparisonStaticModels.size(); i++)
{
removeModelFromAllFrames(m_comparisonStaticModels.at(i));
}
m_staticModels.clear();
m_comparisonStaticModels.clear();
updateCachedValuesInScene();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::setEnableMask(unsigned int mask, bool isForComparisonView /*= false */)
{
if (!isForComparisonView)
{
m_mainRendering->setEnableMask(mask);
}
else
{
m_comparisonMainRendering->setEnableMask(mask);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1111,34 +1336,75 @@ void caf::Viewer::removeModelFromAllFrames(cvf::Model* model)
{
m_mainScene->removeModel(model);
}
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);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::appendModelToAllFrames(cvf::Model* model)
void caf::Viewer::appendModelToAllFrames(cvf::Model* model, bool isForComparisonView )
{
for (size_t i = 0; i < m_frameScenes.size(); i++)
if ( !isForComparisonView )
{
cvf::Scene* scene = m_frameScenes.at(i);
for ( size_t i = 0; i < m_frameScenes.size(); i++ )
{
cvf::Scene* scene = m_frameScenes.at(i);
scene->addModel(model);
scene->addModel(model);
}
if ( m_mainScene.notNull() )
{
m_mainScene->addModel(model);
}
}
if (m_mainScene.notNull())
else
{
m_mainScene->addModel(model);
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);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::appendAllStaticModelsToFrame(cvf::Scene* scene)
void caf::Viewer::appendAllStaticModelsToFrame(cvf::Scene* scene, bool isForComparisonView )
{
for (size_t i = 0; i < m_staticModels.size(); i++)
if (!scene) return;
if ( !isForComparisonView )
{
scene->addModel(m_staticModels.at(i));
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));
}
}
}
@ -1147,12 +1413,12 @@ void caf::Viewer::appendAllStaticModelsToFrame(cvf::Scene* scene)
//--------------------------------------------------------------------------------------------------
cvf::OverlayItem* caf::Viewer::overlayItem(int winPosX, int winPosY)
{
if (m_mainRendering.isNull()) return nullptr;
if (m_overlayItemsRendering.isNull()) return nullptr;
int translatedMousePosX = winPosX;
int translatedMousePosY = height() - winPosY;
return m_mainRendering->overlayItemFromWindowCoordinates(translatedMousePosX, translatedMousePosY);
return m_overlayItemsRendering->overlayItemFromWindowCoordinates(translatedMousePosX, translatedMousePosY);
}
@ -1341,3 +1607,19 @@ int caf::Viewer::clampFrameIndex(int frameIndex) const
return clampedFrameIndex;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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());
}

View File

@ -42,9 +42,11 @@
#include "cvfObject.h"
#include "cvfCollection.h"
#include "cvfVector3.h"
#include "cvfRect.h"
#include "cvfOpenGL.h"
#include "cafOpenGLWidget.h"
#include "cvfRenderingScissor.h"
namespace cvf {
@ -76,6 +78,7 @@ namespace caf
{
class GlobalViewerDynUniformSet;
class ScissorChanger;
class Viewer : public caf::OpenGLWidget
{
@ -86,24 +89,33 @@ public:
QWidget* layoutWidget() { return m_layoutWidget; } // Use this when putting it into something
cvf::Camera* mainCamera();
cvf::Camera* comparisonMainCamera();
void setComparisonViewEyePointOffset(const cvf::Vec3d& offset);
const cvf::Vec3d comparisonViewEyePointOffset();
void setComparisonViewVisibleNormalizedRect( const cvf::Rectf& visibleRect );
cvf::Rectf comparisonViewVisibleNormalizedRect() const;
// Set the main scene : the scene active when the animation is not active. (Stopped)
void setMainScene(cvf::Scene* scene);
cvf::Scene* mainScene();
cvf::Scene* currentScene(); // The scene currently rendered
void setMainScene(cvf::Scene* scene, bool isForComparisonView = false);
cvf::Scene* mainScene( bool isForComparisonView = false );
cvf::Scene* currentScene( bool isForComparisonView = false ); // The scene currently rendered
// Frame scenes for animation control
void addFrame(cvf::Scene* scene);
size_t frameCount() const { return m_frameScenes.size(); }
cvf::Scene* frame(size_t frameIndex);
void removeAllFrames();
void addFrame(cvf::Scene* scene, bool isForComparisonView = false);
size_t frameCount() const { return std::max( m_frameScenes.size(), m_comparisonFrameScenes.size() ) ; }
cvf::Scene* frame(size_t frameIndex, bool isForComparisonView = false);
void removeAllFrames(bool isForComparisonView = false);
int currentFrameIndex() const;
// Static models to be shown in all frames
void addStaticModelOnce(cvf::Model* model);
void addStaticModelOnce(cvf::Model* model, bool isForComparisonView = false);
void removeStaticModel(cvf::Model* model);
void removeAllStaticModels();
// Part enable/ disable mask
void setEnableMask( unsigned int mask, bool isForComparisonView = false );
// Recursively traverse all the scenes managed by the viewer and make sure all cached values are up-to-date
// Use when changing the contents inside the objects in the scene.
@ -145,6 +157,7 @@ public:
bool isOverlayPaintingEnabled() const;
void enableOverlayPainting(bool val);
cvf::Rendering* overlayItemsRendering();
// Performance information for debugging etc.
void enablePerfInfoHud(bool enable);
@ -157,6 +170,8 @@ public:
QImage snapshotImage();
static void copyCameraView(cvf::Camera* srcCamera, cvf::Camera* dstCamera);
public slots:
virtual void slotSetCurrentFrame(int frameIndex);
virtual void slotEndAnimation();
@ -171,6 +186,11 @@ protected:
// Overridable methods to setup the render system
virtual void optimizeClippingPlanes();
bool calculateNearFarPlanes(const cvf::Rendering* rendering,
const cvf::Vec3d& navPointOfinterest,
double *farPlaneDist,
double *nearPlaneDist);
// Standard overrides. Not for overriding
void resizeGL(int width, int height) override;
void paintEvent(QPaintEvent* event) override;
@ -195,8 +215,8 @@ private:
void setupMainRendering();
void setupRenderingSequence();
void appendAllStaticModelsToFrame(cvf::Scene* scene);
void appendModelToAllFrames(cvf::Model* model);
void appendAllStaticModelsToFrame(cvf::Scene* scene, bool isForComparisonView = false);
void appendModelToAllFrames(cvf::Model* model, bool isForComparisonView = false);
void removeModelFromAllFrames(cvf::Model* model);
void updateCamera(int width, int height);
@ -219,14 +239,27 @@ private:
// System to make sure we share OpenGL resources
static Viewer* sharedWidget();
static cvf::OpenGLContextGroup* contextGroup();
static std::list<Viewer*> sm_viewers;
static cvf::ref<cvf::OpenGLContextGroup>
sm_openGLContextGroup;
caf::FrameAnimationControl* m_animationControl;
cvf::Collection<cvf::Scene> m_frameScenes;
cvf::Collection<cvf::Model> m_staticModels;
cvf::ref<cvf::Rendering> m_comparisonMainRendering;
cvf::ref<cvf::Camera> m_comparisonMainCamera;
cvf::ref<cvf::Scene> m_comparisonMainScene;
cvf::Collection<cvf::Scene> m_comparisonFrameScenes;
cvf::Collection<cvf::Model> m_comparisonStaticModels;
cvf::Vec3d m_comparisonViewOffset;
cvf::ref<cvf::RenderingScissor> m_comparisonRenderingScissor;
cvf::Rectf m_comparisonWindowNormalizedRect;
// Poi visualization
cvf::ref<PointOfInterestVisualizer> m_poiVisualizationManager;
@ -241,6 +274,9 @@ private:
int m_offscreenViewportWidth;
int m_offscreenViewportHeight;
cvf::ref<cvf::Rendering> m_quadRendering;
cvf::ref<cvf::Rendering> m_overlayItemsRendering;
};
} // End namespace caf