From 666caf0d5981959c03734a2a27ab242903ec6bc9 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 12 May 2015 00:25:49 -0700 Subject: [PATCH 1/2] Working on fixing DK1 and santizing the transform stuff --- interface/src/Application.cpp | 78 ++---- interface/src/Camera.cpp | 28 +- interface/src/Camera.h | 29 +-- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/devices/OculusManager.cpp | 56 ++-- interface/src/devices/OculusManager.h | 2 +- interface/src/devices/TV3DManager.cpp | 12 +- libraries/octree/src/OctreeHeadlessViewer.cpp | 8 +- libraries/octree/src/ViewFrustum.cpp | 242 +++++------------- libraries/octree/src/ViewFrustum.h | 79 ++---- 10 files changed, 157 insertions(+), 379 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7334222b96..0c6d199f2b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -19,6 +19,7 @@ #include #include #include +#include // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" @@ -965,12 +966,11 @@ void Application::showEditEntitiesHelp() { void Application::resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size) { if (OculusManager::isConnected()) { - OculusManager::configureCamera(camera, size.x, size.y); + OculusManager::configureCamera(camera); } else if (TV3DManager::isConnected()) { TV3DManager::configureCamera(camera, size.x, size.y); } else { - camera.setAspectRatio((float)size.x / size.y); - camera.setFieldOfView(_fieldOfView.get()); + camera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), (float)size.x / size.y, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); } } @@ -984,7 +984,7 @@ void Application::resizeGL() { renderSize = _glWidget->getDeviceSize() * getRenderResolutionScale(); } if (_renderResolution == toGlm(renderSize)) { - return; + return; } _renderResolution = toGlm(renderSize); @@ -1011,25 +1011,15 @@ void Application::updateProjectionMatrix() { } void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + _projectionMatrix = camera.getProjection(); - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(glm::value_ptr(_projectionMatrix)); // Tell our viewFrustum about this change, using the application camera if (updateViewFrustum) { loadViewFrustum(camera, _viewFrustum); - _viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - } else { - ViewFrustum tempViewFrustum; - loadViewFrustum(camera, tempViewFrustum); - tempViewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - } - glFrustum(left, right, bottom, top, nearVal, farVal); - - // save matrix - glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&_projectionMatrix); + } glMatrixMode(GL_MODELVIEW); } @@ -1250,6 +1240,7 @@ void Application::keyPressEvent(QKeyEvent* event) { } break; +#if 0 case Qt::Key_I: if (isShifted) { _myCamera.setEyeOffsetOrientation(glm::normalize( @@ -1314,6 +1305,8 @@ void Application::keyPressEvent(QKeyEvent* event) { } updateProjectionMatrix(); break; +#endif + case Qt::Key_H: if (isShifted) { Menu::getInstance()->triggerOption(MenuOption::Mirror); @@ -2631,7 +2624,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node _octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); - _octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition()); + _octreeQuery.setCameraEyeOffsetPosition(glm::vec3()); auto lodManager = DependencyManager::get(); _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); @@ -2835,25 +2828,11 @@ QRect Application::getDesirableApplicationGeometry() { // void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { // We will use these below, from either the camera or head vectors calculated above - glm::vec3 position(camera.getPosition()); - float fov = camera.getFieldOfView(); // degrees - float nearClip = camera.getNearClip(); - float farClip = camera.getFarClip(); - float aspectRatio = camera.getAspectRatio(); - - glm::quat rotation = camera.getRotation(); + viewFrustum.setProjection(camera.getProjection()); // Set the viewFrustum up with the correct position and orientation of the camera - viewFrustum.setPosition(position); - viewFrustum.setOrientation(rotation); - - // Also make sure it's got the correct lens details from the camera - viewFrustum.setAspectRatio(aspectRatio); - viewFrustum.setFieldOfView(fov); // degrees - viewFrustum.setNearClip(nearClip); - viewFrustum.setFarClip(farClip); - viewFrustum.setEyeOffsetPosition(camera.getEyeOffsetPosition()); - viewFrustum.setEyeOffsetOrientation(camera.getEyeOffsetOrientation()); + viewFrustum.setPosition(camera.getPosition()); + viewFrustum.setOrientation(camera.getRotation()); // Ask the ViewFrustum class to calculate our corners viewFrustum.calculate(); @@ -2954,13 +2933,7 @@ void Application::updateShadowMap() { glm::vec3 shadowFrustumCenter = rotation * ((minima + maxima) * 0.5f); _shadowViewFrustum.setPosition(shadowFrustumCenter); _shadowViewFrustum.setOrientation(rotation); - _shadowViewFrustum.setOrthographic(true); - _shadowViewFrustum.setWidth(maxima.x - minima.x); - _shadowViewFrustum.setHeight(maxima.y - minima.y); - _shadowViewFrustum.setNearClip(minima.z); - _shadowViewFrustum.setFarClip(maxima.z); - _shadowViewFrustum.setEyeOffsetPosition(glm::vec3()); - _shadowViewFrustum.setEyeOffsetOrientation(glm::quat()); + _shadowViewFrustum.setProjection(glm::ortho(minima.x, maxima.x, minima.y, maxima.y, minima.z, maxima.z)); _shadowViewFrustum.calculate(); glMatrixMode(GL_PROJECTION); @@ -3147,12 +3120,6 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs glFrontFace(GL_CCW); } - glm::vec3 eyeOffsetPos = theCamera.getEyeOffsetPosition(); - glm::quat eyeOffsetOrient = theCamera.getEyeOffsetOrientation(); - glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient); - glRotatef(-glm::degrees(glm::angle(eyeOffsetOrient)), eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z); - glTranslatef(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z); - // transform view according to theCamera // could be myCamera (if in normal mode) // or could be viewFrustumOffsetCamera if in offset mode @@ -3170,8 +3137,6 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs Transform viewTransform; viewTransform.setTranslation(theCamera.getPosition()); viewTransform.setRotation(rotation); - viewTransform.postTranslate(eyeOffsetPos); - viewTransform.postRotate(eyeOffsetOrient); if (theCamera.getMode() == CAMERA_MODE_MIRROR) { viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f)); } @@ -3243,7 +3208,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs // finally render the starfield if (hasStars) { - _stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha); + _stars.render(_displayViewFrustum.getFieldOfView(), _displayViewFrustum.getAspectRatio(), _displayViewFrustum.getNearClip(), alpha); } // draw the sky dome @@ -3477,15 +3442,16 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { // Grab current viewport to reset it at the end int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); + float aspect = (float)region.width() / region.height(); + float fov = MIRROR_FIELD_OF_VIEW; // bool eyeRelativeCamera = false; if (billboard) { - _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees + fov = BILLBOARD_FIELD_OF_VIEW; // degees _mirrorCamera.setPosition(_myAvatar->getPosition() + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); } else if (RearMirrorTools::rearViewZoomLevel.get() == BODY) { - _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees _mirrorCamera.setPosition(_myAvatar->getChestPosition() + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); @@ -3506,12 +3472,10 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further // investigated in order to adapt the technique while fixing the head rendering issue, // but the complexity of the hack suggests that a better approach - _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); } - _mirrorCamera.setAspectRatio((float)region.width() / region.height()); - + _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); // set the bounds of rear mirror view diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 1016d60ccf..e501b91dea 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -48,10 +48,7 @@ QString modeToString(CameraMode mode) { Camera::Camera() : _mode(CAMERA_MODE_THIRD_PERSON), _position(0.0f, 0.0f, 0.0f), - _fieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES), - _aspectRatio(16.0f/9.0f), - _nearClip(DEFAULT_NEAR_CLIP), // default - _farClip(DEFAULT_FAR_CLIP), // default + _projection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), 16.0f/9.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)), _hmdPosition(), _hmdRotation(), _isKeepLookingAt(false), @@ -91,32 +88,13 @@ void Camera::setHmdRotation(const glm::quat& hmdRotation) { } } -float Camera::getFarClip() const { - return (_farClip < std::numeric_limits::max()) - ? _farClip - : std::numeric_limits::max() - 1; -} - void Camera::setMode(CameraMode mode) { _mode = mode; emit modeUpdated(modeToString(mode)); } - -void Camera::setFieldOfView(float f) { - _fieldOfView = f; -} - -void Camera::setAspectRatio(float a) { - _aspectRatio = a; -} - -void Camera::setNearClip(float n) { - _nearClip = n; -} - -void Camera::setFarClip(float f) { - _farClip = f; +void Camera::setProjection(const glm::mat4& projection) { + _projection = projection; } PickRay Camera::computePickRay(float x, float y) { diff --git a/interface/src/Camera.h b/interface/src/Camera.h index e06e12f7dc..b9518aa041 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -43,36 +43,24 @@ public: void update( float deltaTime ); + void setPosition(const glm::vec3& position); void setRotation(const glm::quat& rotation); + void setProjection(const glm::mat4 & projection); void setHmdPosition(const glm::vec3& hmdPosition); void setHmdRotation(const glm::quat& hmdRotation); - void setMode(CameraMode m); - void setFieldOfView(float f); - void setAspectRatio(float a); - void setNearClip(float n); - void setFarClip(float f); - void setEyeOffsetPosition(const glm::vec3& p) { _eyeOffsetPosition = p; } - void setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; } glm::quat getRotation() const { return _rotation * _hmdRotation; } + glm::vec3 getPosition() const { return _position + _hmdPosition; } + const glm::mat4& getProjection() const { return _projection; } const glm::vec3& getHmdPosition() const { return _hmdPosition; } const glm::quat& getHmdRotation() const { return _hmdRotation; } - CameraMode getMode() const { return _mode; } - float getFieldOfView() const { return _fieldOfView; } - float getAspectRatio() const { return _aspectRatio; } - float getNearClip() const { return _nearClip; } - float getFarClip() const; - const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; } - const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } + public slots: QString getModeString() const; void setModeString(const QString& mode); - glm::vec3 getPosition() const { return _position + _hmdPosition; } - void setPosition(const glm::vec3& position); - void setOrientation(const glm::quat& orientation) { setRotation(orientation); } glm::quat getOrientation() const { return getRotation(); } @@ -95,13 +83,8 @@ signals: private: CameraMode _mode; glm::vec3 _position; - float _fieldOfView; // degrees - float _aspectRatio; - float _nearClip; - float _farClip; - glm::vec3 _eyeOffsetPosition; - glm::quat _eyeOffsetOrientation; glm::quat _rotation; + glm::mat4 _projection; glm::vec3 _hmdPosition; glm::quat _hmdRotation; bool _isKeepLookingAt; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fe4485b5db..e573110157 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -862,7 +862,7 @@ void MyAvatar::updateLookAtTargetAvatar() { glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); - float smallestAngleTo = glm::radians(Application::getInstance()->getCamera()->getFieldOfView()) / 2.0f; + float smallestAngleTo = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES) / 2.0f; const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index f4693d3c08..75b6ca4e45 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -184,7 +184,7 @@ void OculusManager::connect() { if (!_camera) { _camera = new Camera; - configureCamera(*_camera, 0, 0); // no need to use screen dimensions; they're ignored + configureCamera(*_camera); // no need to use screen dimensions; they're ignored } #ifdef OVR_CLIENT_DISTORTION if (!_programInitialized) { @@ -449,9 +449,19 @@ void OculusManager::endFrameTiming() { } //Sets the camera FoV and aspect ratio -void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) { - camera.setAspectRatio(_renderTargetSize.w * 0.5f / _renderTargetSize.h); - camera.setFieldOfView(atan(_eyeFov[0].UpTan) * DEGREES_PER_RADIAN * 2.0f); +void OculusManager::configureCamera(Camera& camera) { + ovrFovPort fov; + if (_activeEye == ovrEye_Count) { + // When not rendering, provide a FOV encompasing both eyes + fov = _eyeFov[0]; + fov.RightTan = _eyeFov[1].RightTan; + } else { + // When rendering, provide the exact FOV + fov = _eyeFov[_activeEye]; + } + // Convert the FOV to the correct projection matrix + glm::mat4 projection = toGlm(ovrMatrix4f_Projection(fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded)); + camera.setProjection(projection); } //Displays everything for the oculus, frame timing must be active @@ -544,7 +554,8 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati glm::quat orientation; glm::vec3 trackerPosition; - + auto deviceSize = qApp->getDeviceSize(); + ovrTrackingState ts = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); ovrVector3f ovrHeadPosition = ts.HeadPose.ThePose.Position; @@ -582,9 +593,11 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati whichCamera.setHmdPosition(trackerPosition); whichCamera.setHmdRotation(orientation); + // Update our camera to what the application camera is doing _camera->setRotation(whichCamera.getRotation()); _camera->setPosition(whichCamera.getPosition()); + configureCamera(*_camera); // Store the latest left and right eye render locations for things that need to know glm::vec3 thisEyePosition = position + trackerPosition + @@ -595,25 +608,17 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati _camera->update(1.0f / Application::getInstance()->getFps()); glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - const ovrFovPort& port = _eyeFov[_activeEye]; - float nearClip = whichCamera.getNearClip(), farClip = whichCamera.getFarClip(); - glFrustum(-nearClip * port.LeftTan, nearClip * port.RightTan, -nearClip * port.DownTan, - nearClip * port.UpTan, nearClip, farClip); - - ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport; - vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale; - vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale; - - glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); + glLoadMatrixf(glm::value_ptr(_camera->getProjection())); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - // HACK: instead of passing the stereo eye offset directly in the matrix, pass it in the camera offset - //glTranslatef(_eyeRenderDesc[eye].ViewAdjust.x, _eyeRenderDesc[eye].ViewAdjust.y, _eyeRenderDesc[eye].ViewAdjust.z); + ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport; + vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale; + vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale; + + glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); - _camera->setEyeOffsetPosition(glm::vec3(-_eyeRenderDesc[eye].HmdToEyeViewOffset.x, -_eyeRenderDesc[eye].HmdToEyeViewOffset.y, -_eyeRenderDesc[eye].HmdToEyeViewOffset.z)); Application::getInstance()->displaySide(*_camera, false, RenderArgs::MONO); applicationOverlay.displayOverlayTextureHmd(*_camera); @@ -637,7 +642,6 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati glPopMatrix(); // restore our normal viewport - auto deviceSize = qApp->getDeviceSize(); glViewport(0, 0, deviceSize.width(), deviceSize.height()); #if 0 @@ -651,16 +655,22 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati //Wait till time-warp to reduce latency ovr_WaitTillTime(_hmdFrameTiming.TimewarpPointSeconds); +#ifdef DEBUG_RENDER_WITHOUT_DISTORTION + auto fboSize = finalFbo->getSize(); + glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); + glBlitFramebuffer( + 0, 0, fboSize.x, fboSize.y, + 0, 0, deviceSize.width(), deviceSize.height(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); +#else //Clear the color buffer to ensure that there isnt any residual color //Left over from when OR was not connected. glClear(GL_COLOR_BUFFER_BIT); - glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(finalFbo->getRenderBuffer(0))); - //Renders the distorted mesh onto the screen renderDistortionMesh(eyeRenderPose); - glBindTexture(GL_TEXTURE_2D, 0); +#endif glCanvas->swapBuffers(); #else diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index e41c6e8f9b..a6c3bbf4d5 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -60,7 +60,7 @@ public: static void beginFrameTiming(); static void endFrameTiming(); static bool allowSwap(); - static void configureCamera(Camera& camera, int screenWidth, int screenHeight); + static void configureCamera(Camera& camera); static void display(QGLWidget * glCanvas, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera); static void reset(); diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 5d60bf7e19..d90664131f 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -43,9 +43,9 @@ void TV3DManager::connect() { void TV3DManager::setFrustum(Camera& whichCamera) { const double DTR = 0.0174532925; // degree to radians const double IOD = 0.05; //intraocular distance - double fovy = whichCamera.getFieldOfView(); // field of view in y-axis - double nearZ = whichCamera.getNearClip(); // near clipping plane - double screenZ = Application::getInstance()->getViewFrustum()->getFocalLength(); // screen projection plane + double fovy = DEFAULT_FIELD_OF_VIEW_DEGREES; // field of view in y-axis + double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane + double screenZ = 0.25f; // screen projection plane double top = nearZ * tan(DTR * fovy / 2.0); //sets top of frustum based on fovy and near clipping plane double right = _aspect * top; // sets right of frustum based on aspect ratio @@ -81,8 +81,8 @@ void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int scre } void TV3DManager::display(Camera& whichCamera) { - double nearZ = whichCamera.getNearClip(); // near clipping plane - double farZ = whichCamera.getFarClip(); // far clipping plane + double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane + double farZ = DEFAULT_FAR_CLIP; // far clipping plane // left eye portal int portalX = 0; @@ -125,7 +125,6 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov); @@ -154,7 +153,6 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov); diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 0da694833a..90840854ad 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -20,10 +20,7 @@ OctreeHeadlessViewer::OctreeHeadlessViewer() : _boundaryLevelAdjust(0), _maxPacketsPerSecond(DEFAULT_MAX_OCTREE_PPS) { - _viewFrustum.setFieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES); - _viewFrustum.setAspectRatio(DEFAULT_ASPECT_RATIO); - _viewFrustum.setNearClip(DEFAULT_NEAR_CLIP); - _viewFrustum.setFarClip(DEFAULT_FAR_CLIP); + _viewFrustum.setProjection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), DEFAULT_ASPECT_RATIO, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); } OctreeHeadlessViewer::~OctreeHeadlessViewer() { @@ -67,7 +64,8 @@ void OctreeHeadlessViewer::queryOctree() { _octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio()); _octreeQuery.setCameraNearClip(_viewFrustum.getNearClip()); _octreeQuery.setCameraFarClip(_viewFrustum.getFarClip()); - _octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition()); + _octreeQuery.setCameraEyeOffsetPosition(glm::vec3()); + _octreeQuery.setOctreeSizeScale(getVoxelSizeScale()); _octreeQuery.setBoundaryLevelAdjust(getBoundaryLevelAdjust()); diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index 11ed24799d..2694314b57 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -14,7 +14,7 @@ #include #include #include - +#include #include #include @@ -37,6 +37,36 @@ void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) { _direction = glm::vec3(orientationAsQuaternion * glm::vec4(IDENTITY_FRONT, 0.0f)); } +// Order cooresponds to the order defined in the BoxVertex enum. +static const glm::vec4 NDC_VALUES[8] = { + glm::vec4(-1, -1, -1, 1), + glm::vec4(1, -1, -1, 1), + glm::vec4(1, 1, -1, 1), + glm::vec4(-1, 1, -1, 1), + glm::vec4(-1, -1, 1, 1), + glm::vec4(1, -1, 1, 1), + glm::vec4(1, 1, 1, 1), + glm::vec4(-1, 1, 1, 1), +}; + +void ViewFrustum::setProjection(const glm::mat4& projection) { + _projection = projection; + _inverseProjection = glm::inverse(projection); + + // compute our dimensions the usual way + for (int i = 0; i < 8; ++i) { + _corners[i] = _inverseProjection * NDC_VALUES[i]; + _corners[i] /= _corners[i].w; + } + _nearClip = -_corners[BOTTOM_LEFT_NEAR].z; + _farClip = -_corners[BOTTOM_LEFT_FAR].z; + _aspectRatio = (_corners[TOP_RIGHT_NEAR].x - _corners[BOTTOM_LEFT_NEAR].x) / + (_corners[TOP_RIGHT_NEAR].y - _corners[BOTTOM_LEFT_NEAR].y); + glm::vec3 right = glm::normalize(glm::vec3(_corners[TOP_RIGHT_NEAR])); + glm::vec3 left = glm::normalize(glm::vec3(_corners[TOP_LEFT_NEAR])); + _fieldOfView = abs(glm::degrees(glm::angle(right, left))); +} + // ViewFrustum::calculateViewFrustum() // // Description: this will calculate the view frustum bounds for a given position and direction @@ -45,48 +75,16 @@ void ViewFrustum::setOrientation(const glm::quat& orientationAsQuaternion) { // http://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/ // void ViewFrustum::calculate() { - if (_orthographic) { - calculateOrthographic(); - return; - } - - // compute the off-axis frustum parameters as we would for glFrustum - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - - // start with the corners of the near frustum window - glm::vec3 topLeft(left, top, -nearVal); - glm::vec3 topRight(right, top, -nearVal); - glm::vec3 bottomLeft(left, bottom, -nearVal); - glm::vec3 bottomRight(right, bottom, -nearVal); // find the intersections of the rays through the corners with the clip planes in view space, // then transform them to world space - glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, -_direction)) * - glm::translate(_eyeOffsetPosition) * glm::mat4_cast(_eyeOffsetOrientation); - _farTopLeft = glm::vec3(worldMatrix * glm::vec4(topLeft * - (-farClipPlane.w / glm::dot(topLeft, glm::vec3(farClipPlane))), 1.0f)); - _farTopRight = glm::vec3(worldMatrix * glm::vec4(topRight * - (-farClipPlane.w / glm::dot(topRight, glm::vec3(farClipPlane))), 1.0f)); - _farBottomLeft = glm::vec3(worldMatrix * glm::vec4(bottomLeft * - (-farClipPlane.w / glm::dot(bottomLeft, glm::vec3(farClipPlane))), 1.0f)); - _farBottomRight = glm::vec3(worldMatrix * glm::vec4(bottomRight * - (-farClipPlane.w / glm::dot(bottomRight, glm::vec3(farClipPlane))), 1.0f)); - _nearTopLeft = glm::vec3(worldMatrix * glm::vec4(topLeft * - (-nearClipPlane.w / glm::dot(topLeft, glm::vec3(nearClipPlane))), 1.0f)); - _nearTopRight = glm::vec3(worldMatrix * glm::vec4(topRight * - (-nearClipPlane.w / glm::dot(topRight, glm::vec3(nearClipPlane))), 1.0f)); - _nearBottomLeft = glm::vec3(worldMatrix * glm::vec4(bottomLeft * - (-nearClipPlane.w / glm::dot(bottomLeft, glm::vec3(nearClipPlane))), 1.0f)); - _nearBottomRight = glm::vec3(worldMatrix * glm::vec4(bottomRight * - (-nearClipPlane.w / glm::dot(bottomRight, glm::vec3(nearClipPlane))), 1.0f)); - - // compute the offset position and axes in world space - _offsetPosition = glm::vec3(worldMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - _offsetDirection = glm::vec3(worldMatrix * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)); - _offsetUp = glm::vec3(worldMatrix * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)); - _offsetRight = glm::vec3(worldMatrix * glm::vec4(1.0f, 0.0f, 0.0f, 0.0f)); + glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, -_direction)); + glm::vec4 v; + for (int i = 0; i < 8; ++i) { + v = worldMatrix * _corners[i]; + v /= v.w; + _cornersWorld[i] = glm::vec3(v); + } // compute the six planes // The planes are defined such that the normal points towards the inside of the view frustum. @@ -99,73 +97,26 @@ void ViewFrustum::calculate() { // the function set3Points assumes that the points are given in counter clockwise order, assume you // are inside the frustum, facing the plane. Start with any point, and go counter clockwise for // three consecutive points - - _planes[TOP_PLANE ].set3Points(_nearTopRight,_nearTopLeft,_farTopLeft); - _planes[BOTTOM_PLANE].set3Points(_nearBottomLeft,_nearBottomRight,_farBottomRight); - _planes[LEFT_PLANE ].set3Points(_nearBottomLeft,_farBottomLeft,_farTopLeft); - _planes[RIGHT_PLANE ].set3Points(_farBottomRight,_nearBottomRight,_nearTopRight); - _planes[NEAR_PLANE ].set3Points(_nearBottomRight,_nearBottomLeft,_nearTopLeft); - _planes[FAR_PLANE ].set3Points(_farBottomLeft,_farBottomRight,_farTopRight); + _planes[TOP_PLANE].set3Points(_cornersWorld[TOP_RIGHT_NEAR], _cornersWorld[TOP_LEFT_NEAR], _cornersWorld[TOP_LEFT_FAR]); + _planes[BOTTOM_PLANE].set3Points(_cornersWorld[BOTTOM_LEFT_NEAR], _cornersWorld[BOTTOM_RIGHT_NEAR], _cornersWorld[BOTTOM_RIGHT_FAR]); + _planes[LEFT_PLANE].set3Points(_cornersWorld[BOTTOM_LEFT_NEAR], _cornersWorld[BOTTOM_LEFT_FAR], _cornersWorld[TOP_LEFT_FAR]); + _planes[RIGHT_PLANE].set3Points(_cornersWorld[BOTTOM_RIGHT_FAR], _cornersWorld[BOTTOM_RIGHT_NEAR], _cornersWorld[TOP_RIGHT_FAR]); + _planes[NEAR_PLANE].set3Points(_cornersWorld[BOTTOM_RIGHT_NEAR], _cornersWorld[BOTTOM_LEFT_NEAR], _cornersWorld[TOP_LEFT_NEAR]); + _planes[FAR_PLANE].set3Points(_cornersWorld[BOTTOM_LEFT_FAR], _cornersWorld[BOTTOM_RIGHT_FAR], _cornersWorld[TOP_RIGHT_FAR]); // Also calculate our projection matrix in case people want to project points... // Projection matrix : Field of View, ratio, display range : near to far - const float CLIP_NUDGE = 1.0f; - float farClip = (_farClip != _nearClip) ? _farClip : _nearClip + CLIP_NUDGE; // don't allow near and far to be equal - glm::mat4 projection = glm::perspective(_fieldOfView, _aspectRatio, _nearClip, farClip); glm::vec3 lookAt = _position + _direction; glm::mat4 view = glm::lookAt(_position, lookAt, _up); // Our ModelViewProjection : multiplication of our 3 matrices (note: model is identity, so we can drop it) - _ourModelViewProjectionMatrix = projection * view; // Remember, matrix multiplication is the other way around + _ourModelViewProjectionMatrix = _projection * view; // Remember, matrix multiplication is the other way around // Set up our keyhole bounding box... glm::vec3 corner = _position - _keyholeRadius; _keyholeBoundingCube = AACube(corner,(_keyholeRadius * 2.0f)); } -void ViewFrustum::calculateOrthographic() { - float halfWidth = _width * 0.5f; - float halfHeight = _height * 0.5f; - - // find the corners of the view box in world space - glm::mat4 worldMatrix = glm::translate(_position) * glm::mat4(glm::mat3(_right, _up, -_direction)) * - glm::translate(_eyeOffsetPosition) * glm::mat4_cast(_eyeOffsetOrientation); - _farTopLeft = glm::vec3(worldMatrix * glm::vec4(-halfWidth, halfHeight, -_farClip, 1.0f)); - _farTopRight = glm::vec3(worldMatrix * glm::vec4(halfWidth, halfHeight, -_farClip, 1.0f)); - _farBottomLeft = glm::vec3(worldMatrix * glm::vec4(-halfWidth, -halfHeight, -_farClip, 1.0f)); - _farBottomRight = glm::vec3(worldMatrix * glm::vec4(halfWidth, -halfHeight, -_farClip, 1.0f)); - _nearTopLeft = glm::vec3(worldMatrix * glm::vec4(-halfWidth, halfHeight, -_nearClip, 1.0f)); - _nearTopRight = glm::vec3(worldMatrix * glm::vec4(halfWidth, halfHeight, -_nearClip, 1.0f)); - _nearBottomLeft = glm::vec3(worldMatrix * glm::vec4(-halfWidth, -halfHeight, -_nearClip, 1.0f)); - _nearBottomRight = glm::vec3(worldMatrix * glm::vec4(halfWidth, -halfHeight, -_nearClip, 1.0f)); - - // compute the offset position and axes in world space - _offsetPosition = glm::vec3(worldMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - _offsetDirection = glm::vec3(worldMatrix * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)); - _offsetUp = glm::vec3(worldMatrix * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)); - _offsetRight = glm::vec3(worldMatrix * glm::vec4(1.0f, 0.0f, 0.0f, 0.0f)); - - _planes[TOP_PLANE].set3Points(_nearTopRight, _nearTopLeft, _farTopLeft); - _planes[BOTTOM_PLANE].set3Points(_nearBottomLeft, _nearBottomRight, _farBottomRight); - _planes[LEFT_PLANE].set3Points(_nearBottomLeft, _farBottomLeft, _farTopLeft); - _planes[RIGHT_PLANE].set3Points(_farBottomRight, _nearBottomRight, _nearTopRight); - _planes[NEAR_PLANE].set3Points(_nearBottomRight, _nearBottomLeft, _nearTopLeft); - _planes[FAR_PLANE].set3Points(_farBottomLeft, _farBottomRight, _farTopRight); - - // Also calculate our projection matrix in case people want to project points... - // Projection matrix : Field of View, ratio, display range : near to far - glm::mat4 projection = glm::ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, _nearClip, _farClip); - glm::vec3 lookAt = _position + _direction; - glm::mat4 view = glm::lookAt(_position, lookAt, _up); - - // Our ModelViewProjection : multiplication of our 3 matrices (note: model is identity, so we can drop it) - _ourModelViewProjectionMatrix = projection * view; // Remember, matrix multiplication is the other way around - - // Set up our keyhole bounding box... - glm::vec3 corner = _position - _keyholeRadius; - _keyholeBoundingCube = AACube(corner, (_keyholeRadius * 2.0f)); -} - //enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; const char* ViewFrustum::debugPlaneName (int plane) const { switch (plane) { @@ -305,7 +256,6 @@ ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point) const return keyholeResult; // escape early will be the value from checking the keyhole } } - return regularResult; } @@ -429,9 +379,7 @@ bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const { testMatches(compareTo._aspectRatio, _aspectRatio) && testMatches(compareTo._nearClip, _nearClip) && testMatches(compareTo._farClip, _farClip) && - testMatches(compareTo._focalLength, _focalLength) && - testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition) && - testMatches(compareTo._eyeOffsetOrientation, _eyeOffsetOrientation); + testMatches(compareTo._focalLength, _focalLength); if (!result && debug) { qCDebug(octree, "ViewFrustum::matches()... result=%s", debug::valueOf(result)); @@ -466,15 +414,6 @@ bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const { qCDebug(octree, "%s -- compareTo._focalLength=%f _focalLength=%f", (testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"), compareTo._focalLength, _focalLength); - qCDebug(octree, "%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f", - (testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition) ? "MATCHES " : "NO MATCH"), - compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z, - _eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z); - qCDebug(octree, "%s -- compareTo._eyeOffsetOrientation=%f,%f,%f,%f _eyeOffsetOrientation=%f,%f,%f,%f", - (testMatches(compareTo._eyeOffsetOrientation, _eyeOffsetOrientation) ? "MATCHES " : "NO MATCH"), - compareTo._eyeOffsetOrientation.x, compareTo._eyeOffsetOrientation.y, - compareTo._eyeOffsetOrientation.z, compareTo._eyeOffsetOrientation.w, - _eyeOffsetOrientation.x, _eyeOffsetOrientation.y, _eyeOffsetOrientation.z, _eyeOffsetOrientation.w); } return result; } @@ -485,9 +424,6 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const const float POSITION_SIMILAR_ENOUGH = 5.0f; // 5 meters float positionDistance = glm::distance(_position, compareTo._position); - const float EYEOFFSET_POSITION_SIMILAR_ENOUGH = 0.15f; // 0.15 meters - float eyeOffsetpositionDistance = glm::distance(_eyeOffsetPosition, compareTo._eyeOffsetPosition); - // Compute the angular distance between the two orientations const float ORIENTATION_SIMILAR_ENOUGH = 10.0f; // 10 degrees in any direction glm::quat dQOrientation = _orientation * glm::inverse(compareTo._orientation); @@ -496,23 +432,14 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const angleOrientation = 0.0f; } - glm::quat dQEyeOffsetOrientation = _eyeOffsetOrientation * glm::inverse(compareTo._eyeOffsetOrientation); - float angleEyeOffsetOrientation = compareTo._eyeOffsetOrientation == _eyeOffsetOrientation - ? 0.0f : glm::degrees(glm::angle(dQEyeOffsetOrientation)); - if (isNaN(angleEyeOffsetOrientation)) { - angleEyeOffsetOrientation = 0.0f; - } - bool result = - testMatches(0, positionDistance, POSITION_SIMILAR_ENOUGH) && - testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) && + testMatches(0, positionDistance, POSITION_SIMILAR_ENOUGH) && + testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) && testMatches(compareTo._fieldOfView, _fieldOfView) && testMatches(compareTo._aspectRatio, _aspectRatio) && testMatches(compareTo._nearClip, _nearClip) && testMatches(compareTo._farClip, _farClip) && - testMatches(compareTo._focalLength, _focalLength) && - testMatches(0, eyeOffsetpositionDistance, EYEOFFSET_POSITION_SIMILAR_ENOUGH) && - testMatches(0, angleEyeOffsetOrientation, ORIENTATION_SIMILAR_ENOUGH); + testMatches(compareTo._focalLength, _focalLength); if (!result && debug) { @@ -529,7 +456,7 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const qCDebug(octree, "%s -- angleOrientation=%f", (testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"), angleOrientation); - + qCDebug(octree, "%s -- compareTo._fieldOfView=%f _fieldOfView=%f", (testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"), compareTo._fieldOfView, _fieldOfView); @@ -545,19 +472,6 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const qCDebug(octree, "%s -- compareTo._focalLength=%f _focalLength=%f", (testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"), compareTo._focalLength, _focalLength); - - qCDebug(octree, "%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f", - (testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"), - compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z, - _eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z); - - qCDebug(octree, "%s -- eyeOffsetpositionDistance=%f", - (testMatches(0,eyeOffsetpositionDistance, EYEOFFSET_POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"), - eyeOffsetpositionDistance); - - qCDebug(octree, "%s -- angleEyeOffsetOrientation=%f", - (testMatches(0, angleEyeOffsetOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"), - angleEyeOffsetOrientation); } return result; } @@ -570,39 +484,19 @@ PickRay ViewFrustum::computePickRay(float x, float y) { } void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const { - origin = _nearTopLeft + x * (_nearTopRight - _nearTopLeft) + y * (_nearBottomLeft - _nearTopLeft); - direction = glm::normalize(origin - (_position + _orientation * _eyeOffsetPosition)); + origin = _cornersWorld[TOP_LEFT_NEAR] + x * (_cornersWorld[TOP_RIGHT_NEAR] - _cornersWorld[TOP_LEFT_NEAR]) + + y * (_cornersWorld[BOTTOM_LEFT_NEAR] - _cornersWorld[TOP_LEFT_NEAR]); + direction = glm::normalize(origin - _position); } void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearValue, float& farValue, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { - // compute our dimensions the usual way - float hheight = _nearClip * tanf(_fieldOfView * 0.5f * RADIANS_PER_DEGREE); - float hwidth = _aspectRatio * hheight; - if (isOrthographic()) { - hheight = getHeight(); - hwidth = getWidth(); - } - - // get our frustum corners in view space - glm::mat4 eyeMatrix = glm::mat4_cast(glm::inverse(_eyeOffsetOrientation)) * glm::translate(-_eyeOffsetPosition); - glm::vec4 corners[8]; - float farScale = _farClip / _nearClip; - corners[0] = eyeMatrix * glm::vec4(-hwidth, -hheight, -_nearClip, 1.0f); - corners[1] = eyeMatrix * glm::vec4(hwidth, -hheight, -_nearClip, 1.0f); - corners[2] = eyeMatrix * glm::vec4(hwidth, hheight, -_nearClip, 1.0f); - corners[3] = eyeMatrix * glm::vec4(-hwidth, hheight, -_nearClip, 1.0f); - corners[4] = eyeMatrix * glm::vec4(-hwidth * farScale, -hheight * farScale, -_farClip, 1.0f); - corners[5] = eyeMatrix * glm::vec4(hwidth * farScale, -hheight * farScale, -_farClip, 1.0f); - corners[6] = eyeMatrix * glm::vec4(hwidth * farScale, hheight * farScale, -_farClip, 1.0f); - corners[7] = eyeMatrix * glm::vec4(-hwidth * farScale, hheight * farScale, -_farClip, 1.0f); - // find the minimum and maximum z values, which will be our near and far clip distances nearValue = FLT_MAX; farValue = -FLT_MAX; for (int i = 0; i < 8; i++) { - nearValue = min(nearValue, -corners[i].z); - farValue = max(farValue, -corners[i].z); + nearValue = min(nearValue, -_corners[i].z); + farValue = max(farValue, -_corners[i].z); } // make sure the near clip isn't too small to be valid @@ -610,9 +504,9 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom nearValue = max(MIN_NEAR, nearValue); // get the near/far normal and use it to find the clip planes - glm::vec4 normal = eyeMatrix * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); - nearClipPlane = glm::vec4(-normal.x, -normal.y, -normal.z, glm::dot(normal, corners[0])); - farClipPlane = glm::vec4(normal.x, normal.y, normal.z, -glm::dot(normal, corners[4])); + glm::vec4 normal = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); + nearClipPlane = glm::vec4(-normal.x, -normal.y, -normal.z, glm::dot(normal, _corners[0])); + farClipPlane = glm::vec4(normal.x, normal.y, normal.z, -glm::dot(normal, _corners[4])); // compute the focal proportion (zero is near clip, one is far clip) float focalProportion = (_focalLength - _nearClip) / (_farClip - _nearClip); @@ -623,7 +517,7 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom bottom = FLT_MAX; top = -FLT_MAX; for (int i = 0; i < 4; i++) { - glm::vec4 corner = glm::mix(corners[i], corners[i + 4], focalProportion); + glm::vec4 corner = glm::mix(_corners[i], _corners[i + 4], focalProportion); glm::vec4 intersection = corner * (-nearValue / corner.z); left = min(left, intersection.x); right = max(right, intersection.x); @@ -644,9 +538,6 @@ void ViewFrustum::printDebugDetails() const { qCDebug(octree, "_nearClip=%f", _nearClip); qCDebug(octree, "_farClip=%f", _farClip); qCDebug(octree, "_focalLength=%f", _focalLength); - qCDebug(octree, "_eyeOffsetPosition=%f,%f,%f", _eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z ); - qCDebug(octree, "_eyeOffsetOrientation=%f,%f,%f,%f", _eyeOffsetOrientation.x, _eyeOffsetOrientation.y, _eyeOffsetOrientation.z, - _eyeOffsetOrientation.w ); } glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const { @@ -846,20 +737,7 @@ float ViewFrustum::distanceToCamera(const glm::vec3& point) const { } void ViewFrustum::evalProjectionMatrix(glm::mat4& proj) const { - if (isOrthographic()) { - glm::vec3 frustumCenter = glm::inverse( _orientation) * _position; - - proj = glm::ortho(frustumCenter.x -0.5f * getWidth(), - frustumCenter.x +0.5f * getWidth(), - frustumCenter.y -0.5f * getHeight(), - frustumCenter.y +0.5f * getHeight(), - -getFarClip(), -getNearClip()); - } else { - float left, right, bottom, top, near, far; - glm::vec4 clip0, clip1; - computeOffAxisFrustum(left, right, bottom, top, near, far, clip0, clip1); - proj = glm::perspective(glm::radians(getFieldOfView()), getAspectRatio(), getNearClip(), getFarClip()); - } + proj = _projection; } void ViewFrustum::evalViewTransform(Transform& view) const { diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index 5b20126293..0422120e51 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -50,19 +50,11 @@ public: const glm::vec3& getRight() const { return _right; } // setters for lens attributes - void setOrthographic(bool orthographic) { _orthographic = orthographic; } - void setWidth(float width) { _width = width; } - void setHeight(float height) { _height = height; } - void setFieldOfView(float f) { _fieldOfView = f; } - void setAspectRatio(float a) { _aspectRatio = a; } - void setNearClip(float n) { _nearClip = n; } - void setFarClip(float f) { _farClip = f; } - void setFocalLength(float length) { _focalLength = length; } - void setEyeOffsetPosition(const glm::vec3& p) { _eyeOffsetPosition = p; } - void setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; } + void setProjection(const glm::mat4 & projection); + void getFocalLength(float focalLength) { _focalLength = focalLength; } // getters for lens attributes - bool isOrthographic() const { return _orthographic; } + const glm::mat4 getProjection() const { return _projection; }; float getWidth() const { return _width; } float getHeight() const { return _height; } float getFieldOfView() const { return _fieldOfView; } @@ -70,23 +62,16 @@ public: float getNearClip() const { return _nearClip; } float getFarClip() const { return _farClip; } float getFocalLength() const { return _focalLength; } - const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; } - const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } - const glm::vec3& getOffsetPosition() const { return _offsetPosition; } - const glm::vec3& getOffsetDirection() const { return _offsetDirection; } - const glm::vec3& getOffsetUp() const { return _offsetUp; } - const glm::vec3& getOffsetRight() const { return _offsetRight; } + const glm::vec3& getFarTopLeft() const { return _cornersWorld[TOP_LEFT_FAR]; } + const glm::vec3& getFarTopRight() const { return _cornersWorld[TOP_RIGHT_FAR]; } + const glm::vec3& getFarBottomLeft() const { return _cornersWorld[BOTTOM_LEFT_FAR]; } + const glm::vec3& getFarBottomRight() const { return _cornersWorld[BOTTOM_RIGHT_FAR]; } - const glm::vec3& getFarTopLeft() const { return _farTopLeft; } - const glm::vec3& getFarTopRight() const { return _farTopRight; } - const glm::vec3& getFarBottomLeft() const { return _farBottomLeft; } - const glm::vec3& getFarBottomRight() const { return _farBottomRight; } - - const glm::vec3& getNearTopLeft() const { return _nearTopLeft; } - const glm::vec3& getNearTopRight() const { return _nearTopRight; } - const glm::vec3& getNearBottomLeft() const { return _nearBottomLeft; } - const glm::vec3& getNearBottomRight() const { return _nearBottomRight; } + const glm::vec3& getNearTopLeft() const { return _cornersWorld[TOP_LEFT_NEAR]; } + const glm::vec3& getNearTopRight() const { return _cornersWorld[TOP_RIGHT_NEAR]; } + const glm::vec3& getNearBottomLeft() const { return _cornersWorld[BOTTOM_LEFT_NEAR]; } + const glm::vec3& getNearBottomRight() const { return _cornersWorld[BOTTOM_RIGHT_NEAR]; } // get/set for keyhole attribute void setKeyholeRadius(float keyholdRadius) { _keyholeRadius = keyholdRadius; } @@ -132,49 +117,33 @@ private: ViewFrustum::location cubeInKeyhole(const AACube& cube) const; ViewFrustum::location boxInKeyhole(const AABox& box) const; - void calculateOrthographic(); - // camera location/orientation attributes - glm::vec3 _position = glm::vec3(0.0f); // the position in world-frame - glm::quat _orientation = glm::quat(); + glm::vec3 _position; // the position in world-frame + glm::quat _orientation; + + // Lens attributes + glm::mat4 _projection; // calculated for orientation glm::vec3 _direction = IDENTITY_FRONT; glm::vec3 _up = IDENTITY_UP; glm::vec3 _right = IDENTITY_RIGHT; - // Lens attributes - bool _orthographic = false; + // keyhole attributes + float _keyholeRadius = DEFAULT_KEYHOLE_RADIUS; + AACube _keyholeBoundingCube; + + // Calculated values + glm::mat4 _inverseProjection; float _width = 1.0f; float _height = 1.0f; float _aspectRatio = 1.0f; float _nearClip = DEFAULT_NEAR_CLIP; float _farClip = DEFAULT_FAR_CLIP; float _focalLength = 0.25f; - glm::vec3 _eyeOffsetPosition = glm::vec3(0.0f); - glm::quat _eyeOffsetOrientation = glm::quat(); - - // in Degrees, doesn't apply to HMD like Oculus float _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES; - - // keyhole attributes - float _keyholeRadius = DEFAULT_KEYHOLE_RADIUS; - AACube _keyholeBoundingCube; - - - // Calculated values - glm::vec3 _offsetPosition = glm::vec3(0.0f); - glm::vec3 _offsetDirection = glm::vec3(0.0f); - glm::vec3 _offsetUp = glm::vec3(0.0f); - glm::vec3 _offsetRight = glm::vec3(0.0f); - glm::vec3 _farTopLeft = glm::vec3(0.0f); - glm::vec3 _farTopRight = glm::vec3(0.0f); - glm::vec3 _farBottomLeft = glm::vec3(0.0f); - glm::vec3 _farBottomRight = glm::vec3(0.0f); - glm::vec3 _nearTopLeft = glm::vec3(0.0f); - glm::vec3 _nearTopRight = glm::vec3(0.0f); - glm::vec3 _nearBottomLeft = glm::vec3(0.0f); - glm::vec3 _nearBottomRight = glm::vec3(0.0f); + glm::vec4 _corners[8]; + glm::vec3 _cornersWorld[8]; enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; ::Plane _planes[6]; // How will this be used? From 464925ecc75c04b2b001791f5aeced9ed5b55ef8 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 12 May 2015 01:15:30 -0700 Subject: [PATCH 2/2] Fixing the assignment client --- assignment-client/src/octree/OctreeQueryNode.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 30b9ef205b..856b6a1c00 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -258,11 +258,11 @@ bool OctreeQueryNode::updateCurrentViewFrustum() { float originalFOV = getCameraFov(); float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND; - newestViewFrustum.setFieldOfView(wideFOV); // hack - newestViewFrustum.setAspectRatio(getCameraAspectRatio()); - newestViewFrustum.setNearClip(getCameraNearClip()); - newestViewFrustum.setFarClip(getCameraFarClip()); - newestViewFrustum.setEyeOffsetPosition(getCameraEyeOffsetPosition()); + newestViewFrustum.setProjection(glm::perspective( + glm::radians(wideFOV), // hack + getCameraAspectRatio(), + getCameraNearClip(), + getCameraFarClip())); // if there has been a change, then recalculate if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {