#168 Merged in parallel projection

This commit is contained in:
Jacob Støren
2016-08-16 23:20:33 +02:00
26 changed files with 9904 additions and 26 deletions

View File

@@ -67,18 +67,18 @@ static const char light_AmbientDiffuse_inl[] =
" \n"
"varying vec3 v_ecPosition; \n"
"varying vec3 v_ecNormal; \n"
"uniform vec3 u_ecLightPosition; \n"
" \n"
"//-------------------------------------------------------------------------------------------------- \n"
"/// lightFragment() - Simple Headlight without Phong/specular component \n"
"/// lightFragment() - Simple Positional Headlight without Phong/specular component \n"
"/// \n"
"//-------------------------------------------------------------------------------------------------- \n"
"vec4 lightFragment(vec4 srcFragColor, float not_in_use_shadowFactor) \n"
"{ \n"
" const vec3 ecLightPosition = vec3(0.5, 5.0, 7.0); \n"
" const float ambientIntensity = 0.2; \n"
" \n"
" // Light vector (from point to light source) \n"
" vec3 L = normalize(ecLightPosition - v_ecPosition); \n"
" vec3 L = normalize(u_ecLightPosition - v_ecPosition); \n"
" \n"
" // Viewing vector (from point to eye) \n"
" // Since we are in eye space, the eye pos is at (0, 0, 0) \n"
@@ -101,7 +101,6 @@ cvf::String CommonShaderSources::light_AmbientDiffuse()
return cvf::String(light_AmbientDiffuse_inl);
}
//--------------------------------------------------------------------------------------------------
/// Static helper to configure polygon offset render state from enum
//--------------------------------------------------------------------------------------------------
@@ -283,11 +282,12 @@ void SurfaceEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
}
cvf::ref<cvf::ShaderProgram> shaderProg = gen.generate();
if (m_enableLighting) shaderProg->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0)));
cvf::ref<cvf::Effect> eff = effect;
eff->setShaderProgram(shaderProg.p());
eff->setUniform(new cvf::UniformFloat("u_color", m_color));
this->updateCommonEffect(effect);
}
@@ -443,6 +443,8 @@ void ScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::Effect* eff
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
eff->setShaderProgram(prog.p());
if(!m_disableLighting) prog->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5, 5.0, 7.0)));
// Result mapping texture
m_textureImage = new cvf::TextureImage();

View File

@@ -189,7 +189,10 @@ bool caf::CeetronPlusNavigation::handleInputEvent(QInputEvent* inputEvent)
initializeRotationCenter();
if (m_isRotCenterInitialized)
{
QWheelEvent* we = static_cast<QWheelEvent*> ( inputEvent);
#if 0
int translatedMousePosX = we->x();
int translatedMousePosY = m_viewer->height() - we->y();
int delta = we->delta();
@@ -199,8 +202,13 @@ bool caf::CeetronPlusNavigation::handleInputEvent(QInputEvent* inputEvent)
ray = m_viewer->mainCamera()->rayFromWindowCoordinates(translatedMousePosX, translatedMousePosY);
else
ray = m_viewer->mainCamera()->rayFromWindowCoordinates((int)(1.0*translatedMousePosX), (int)(1.0*translatedMousePosY));
#endif
zoomAlongRay(ray.p(), delta);
int cvfEvPosX, cvfEvPosY;
cvfEventPos(we->x(), we->y(), &cvfEvPosX, &cvfEvPosY);
cvf::ref<cvf::Ray> ray = createZoomRay(cvfEvPosX, cvfEvPosY);
zoomAlongRay(ray.p(), we->delta());
}
isEventHandled = true;

View File

@@ -159,6 +159,43 @@ void caf::TrackBallBasedNavigation::zoomAlongRay(cvf::Ray* ray, int delta)
m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up );
m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest);
m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest);
m_viewer->navigationPolicyUpdate();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::TrackBallBasedNavigation::cvfEventPos(int qtX, int qtY, int* cvfX, int* cvfY)
{
*cvfX = qtX;
*cvfY = m_viewer->height() - qtY;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Ray> caf::TrackBallBasedNavigation::createZoomRay(int cvfXPos, int cvfYPos)
{
cvf::ref<cvf::Ray> ray;
cvf::Camera* cam = m_viewer->mainCamera();
ray = cam->rayFromWindowCoordinates(cvfXPos, cvfYPos);
if (cam->projection() == cvf::Camera::ORTHO)
{
cvf::Vec3d camDir = cam->direction();
cvf::Plane focusPlane;
focusPlane.setFromPointAndNormal(m_pointOfInterest, -camDir);
cvf::Vec3d intersectionPoint;
ray->planeIntersect(focusPlane, &intersectionPoint);
cvf::ref<cvf::Ray> orthoZoomRay = new cvf::Ray();
orthoZoomRay->setOrigin(cam->position());
orthoZoomRay->setDirection((intersectionPoint - cam->position()).getNormalized());
ray = orthoZoomRay;
}
return ray;
}

View File

@@ -77,7 +77,10 @@ protected:
bool m_isNavigating;
bool m_hasMovedMouseDuringNavigation;
void cvfEventPos(int qtX, int qtY, int* x, int* y);
// Zooming towards cursor
cvf::ref<cvf::Ray> createZoomRay(int cvfXPos, int cvfYPos);
void zoomAlongRay( cvf::Ray* ray, int delta );
bool m_isZooming;
cvf::ref<cvf::Ray> m_zoomRay;

View File

@@ -45,6 +45,7 @@
#include "cvfDebugTimer.h"
#include "cvfDrawable.h"
#include "cvfDrawableGeo.h"
#include "cvfDynamicUniformSet.h"
#include "cvfHitItemCollection.h"
#include "cvfManipulatorTrackball.h"
#include "cvfModel.h"
@@ -59,6 +60,8 @@
#include "cvfScene.h"
#include "cvfTextureImage.h"
#include "cvfTransform.h"
#include "cvfUniform.h"
#include "cvfUniformSet.h"
#include "cvfqtOpenGLContext.h"
#include "cvfqtPerformanceInfoHud.h"
@@ -68,6 +71,34 @@
#include <QHBoxLayout>
#include <QInputEvent>
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());
}
virtual ~GlobalViewerDynUniformSet() {}
void setHeadLightPosition(const cvf::Vec3f posRelativeToCamera) { m_headlightPosition->set(posRelativeToCamera);}
virtual cvf::UniformSet* uniformSet() { return m_uniformSet.p(); }
virtual void update(cvf::Rendering* rendering){};
private:
cvf::ref<cvf::UniformSet> m_uniformSet;
cvf::ref<cvf::UniformFloat> m_headlightPosition;
};
}
std::list<caf::Viewer*> caf::Viewer::sm_viewers;
cvf::ref<cvf::OpenGLContextGroup> caf::Viewer::sm_openGLContextGroup;
@@ -98,9 +129,13 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
// Needed to get keystrokes
setFocusPolicy(Qt::ClickFocus);
m_globalUniformSet = new GlobalViewerDynUniformSet();
m_mainCamera = new cvf::Camera;
m_mainCamera->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_animationControl = new caf::FrameAnimationControl(this);
@@ -141,6 +176,7 @@ void caf::Viewer::setupMainRendering()
{
m_mainRendering->setCamera(m_mainCamera.p());
m_mainRendering->setRenderQueueSorter(new cvf::RenderQueueSorterBasic(cvf::RenderQueueSorterBasic::EFFECT_ONLY));
m_mainRendering->addGlobalDynamicUniformSet(m_globalUniformSet.p());
// Set fixed function rendering if QGLFormat does not support directRendering
if (!this->format().directRendering())
@@ -265,11 +301,62 @@ void caf::Viewer::optimizeClippingPlanes()
cvf::BoundingBox bb = m_renderingSequence->boundingBox();
if (!bb.isValid()) return;
cvf::Vec3d eye, vrp, up;
m_mainCamera->toLookAt(&eye, &vrp, &up);
cvf::Vec3d eye = m_mainCamera->position();
cvf::Vec3d viewdir = m_mainCamera->direction();
cvf::Vec3d viewdir = (vrp - eye).getNormalized();
cvf::Vec3d bboxCorners[8];
bb.cornerVertices(bboxCorners);
// Find the distance to the bbox corners most behind and most in front of camera
double maxDistEyeToCornerAlongViewDir = -HUGE_VAL;
double minDistEyeToCornerAlongViewDir = HUGE_VAL;
for (int bcIdx = 0; bcIdx < 8; ++bcIdx )
{
double distEyeBoxCornerAlongViewDir = (bboxCorners[bcIdx] - eye)*viewdir;
if (distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir)
{
maxDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir;
}
if (distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir)
{
minDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir; // Sometimes negative-> behind camera
}
}
double farPlaneDist = CVF_MIN(maxDistEyeToCornerAlongViewDir * 1.2, m_maxFarPlaneDistance);
// 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)
{
nearPlaneDist = CVF_MAX( m_minNearPlaneDistance, minDistEyeToCornerAlongViewDir);
if (m_navigationPolicy.notNull() && m_navigationPolicyEnabled)
{
double pointOfInterestDist = (eye - m_navigationPolicy->pointOfInterest()).length();
nearPlaneDist = CVF_MIN(nearPlaneDist, pointOfInterestDist*0.2);
}
}
else // Orthographic projection. Set to encapsulate the complete boundingbox, possibly setting a negative nearplane
{
if(minDistEyeToCornerAlongViewDir >= 0)
{
nearPlaneDist = CVF_MIN(0.8 * minDistEyeToCornerAlongViewDir, m_maxFarPlaneDistance);
}
else
{
nearPlaneDist = CVF_MAX(1.2 * minDistEyeToCornerAlongViewDir, -m_maxFarPlaneDistance);
}
}
#if 0
double distEyeBoxCenterAlongViewDir = (bb.center() - eye)*viewdir;
double farPlaneDist = distEyeBoxCenterAlongViewDir + bb.radius() * 1.2;
@@ -282,6 +369,7 @@ void caf::Viewer::optimizeClippingPlanes()
double pointOfInterestDist = (eye - m_navigationPolicy->pointOfInterest()).length();
nearPlaneDist = CVF_MIN(nearPlaneDist, pointOfInterestDist*0.2);
}
#endif
if (farPlaneDist <= nearPlaneDist) farPlaneDist = nearPlaneDist + 1.0;
@@ -536,7 +624,10 @@ void caf::Viewer::zoomAll()
cvf::Vec3d eye, vrp, up;
m_mainCamera->toLookAt(&eye, &vrp, &up);
m_mainCamera->fitView(bb, vrp-eye, up);
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);
updateParallelProjectionHeightFromMoveZoom(bb.center());
navigationPolicyUpdate();
}
@@ -946,6 +1037,11 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho)
m_mainCamera->setProjectionAsOrtho(1.0, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
this->updateParallelProjectionHeightFromMoveZoom(pointOfInterest);
// Set the light position behind us, far away from the scene
float sceneDepth = m_mainCamera->farPlane() - m_mainCamera->nearPlane();
this->m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0,0, 2 * sceneDepth));
m_globalUniformSet->setHeadLightPosition(cvf::Vec3f(0,0, 2 * sceneDepth));
this->update();
}
else if (!enableOrtho && m_mainCamera->projection() == cvf::Camera::ORTHO)
@@ -954,7 +1050,12 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho)
// so we do not need to update the camera position based on orthoHeight and fieldOfView.
// We assume the camera is in a sensible position.
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
// Set dummy near and far plane. These wll be updated by the optimize clipping planes
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, 0.1, 1.0);
this->m_renderingSequence->setDefaultFFLightPositional(cvf::Vec3f(0.5, 5.0, 7.0));
m_globalUniformSet->setHeadLightPosition(cvf::Vec3f(0.5, 5.0, 7.0));
this->update();
}
}
@@ -971,7 +1072,7 @@ double calculateOrthoHeight(double perspectiveViewAngleYDeg, double focusPlaneDi
///
//--------------------------------------------------------------------------------------------------
double calculateDistToPlaneOfInterest(double perspectiveViewAngleYDeg, double orthoHeight)
double calculateDistToPlaneOfOrthoHeight(double perspectiveViewAngleYDeg, double orthoHeight)
{
return orthoHeight / (2 * (cvf::Math::tan( cvf::Math::toRadians(0.5 * perspectiveViewAngleYDeg) )));
}
@@ -1009,8 +1110,9 @@ void caf::Viewer::updateParallelProjectionHeightFromMoveZoom(const cvf::Vec3d& p
if (!camera || camera->projection() != Camera::ORTHO) return;
// Negative distance can occur. If so, do not set a negative ortho.
double distToFocusPlane = distToPlaneOfInterest(camera, pointOfInterest);
double distToFocusPlane = cvf::Math::abs( distToPlaneOfInterest(camera, pointOfInterest));
double orthoHeight = calculateOrthoHeight(m_cameraFieldOfViewYDeg, distToFocusPlane);
@@ -1032,7 +1134,7 @@ void caf::Viewer::updateParallelProjectionCameraPosFromPointOfInterestMove(const
double orthoHeight = camera->frontPlaneFrustumHeight();
//Trace::show(String::number(orthoHeight));
double neededDistToFocusPlane = calculateDistToPlaneOfInterest(m_cameraFieldOfViewYDeg, orthoHeight);
double neededDistToFocusPlane = calculateDistToPlaneOfOrthoHeight(m_cameraFieldOfViewYDeg, orthoHeight);
Vec3d eye, vrp, up;
camera->toLookAt(&eye, &vrp, &up);

View File

@@ -73,6 +73,7 @@ class QInputEvent;
namespace caf
{
class GlobalViewerDynUniformSet;
class Viewer : public caf::OpenGLWidget
{
@@ -219,6 +220,10 @@ private:
caf::FrameAnimationControl* m_animationControl;
cvf::Collection<cvf::Scene> m_frameScenes;
cvf::Collection<cvf::Model> m_staticModels;
// Parallel projection light modification
cvf::ref<GlobalViewerDynUniformSet> m_globalUniformSet;
};
} // End namespace caf

View File

@@ -541,7 +541,7 @@ void WBTransparencySurfaceEffectGenerator::initStaticData()
m_depth->enableDepthWrite(false);
m_renderPassUniform = new UniformInt("isOpaquePass", 1);
m_cameraNearUniform = new UniformFloat("cameraNear", 0.01);
m_cameraNearUniform = new UniformFloat("cameraNear", 0.01f);
m_cameraFarUniform = new UniformFloat("cameraFar",1000);
}