Merge branch 'master' of github.com:highfidelity/hifi into no-id-swap-redux

This commit is contained in:
Seth Alves 2015-05-20 18:24:40 -07:00
commit 38edc27cbb
13 changed files with 213 additions and 409 deletions

View file

@ -186,15 +186,15 @@ void OctreeQueryNode::resetOctreePacket() {
_currentPacketIsCompressed = getWantCompression();
OCTREE_PACKET_FLAGS flags = 0;
if (_currentPacketIsColor) {
setAtBit(flags,PACKET_IS_COLOR_BIT);
setAtBit(flags, PACKET_IS_COLOR_BIT);
}
if (_currentPacketIsCompressed) {
setAtBit(flags,PACKET_IS_COMPRESSED_BIT);
setAtBit(flags, PACKET_IS_COMPRESSED_BIT);
}
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
int numBytesPacketHeader = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(_octreePacket),
_myPacketType);
_myPacketType);
_octreePacketAt = _octreePacket + numBytesPacketHeader;
_octreePacketAvailableBytes -= numBytesPacketHeader;
@ -204,7 +204,7 @@ void OctreeQueryNode::resetOctreePacket() {
*flagsAt = flags;
_octreePacketAt += sizeof(OCTREE_PACKET_FLAGS);
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_FLAGS);
// pack in sequence number
OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt;
*sequenceAt = _sequenceNumber;
@ -258,11 +258,16 @@ 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());
if (0.0f != getCameraAspectRatio() &&
0.0f != getCameraNearClip() &&
0.0f != getCameraFarClip()) {
newestViewFrustum.setProjection(glm::perspective(
glm::radians(wideFOV), // hack
getCameraAspectRatio(),
getCameraNearClip(),
getCameraFarClip()));
}
// if there has been a change, then recalculate
if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {

View file

@ -65,6 +65,10 @@ td.buttons {
width: 30px;
}
td.buttons.reorder-buttons {
width: 40px;
}
td .glyphicon {
text-align: center;
font-size: 12px;

View file

@ -168,12 +168,20 @@ $(document).ready(function(){
if (sibling.hasClass(Settings.DATA_COL_CLASS)) {
// set focus to next input
sibling.find('input').focus()
} else if (sibling.hasClass(Settings.ADD_DEL_BUTTONS_CLASS)) {
sibling.find('.' + Settings.ADD_ROW_BUTTON_CLASS).click()
sibling.find('input').focus();
} else {
// set focus to the first input in the new row
$target.closest('table').find('tr.inputs input:first').focus()
// jump over the re-order row, if that's what we're on
if (sibling.hasClass(Settings.REORDER_BUTTONS_CLASS)) {
sibling = sibling.next();
}
if (sibling.hasClass(Settings.ADD_DEL_BUTTONS_CLASS)) {
sibling.find('.' + Settings.ADD_ROW_BUTTON_CLASS).click()
// set focus to the first input in the new row
$target.closest('table').find('tr.inputs input:first').focus()
}
}
} else if ($target.is('input')) {
@ -767,7 +775,8 @@ $('body').on('click', '.save-button', function(e){
});
function makeTable(setting, keypath, setting_value, isLocked) {
var isArray = !_.has(setting, 'key')
var isArray = !_.has(setting, 'key');
var isHash = !isArray;
if (!isArray && setting.can_order) {
setting.can_order = false;
@ -780,7 +789,8 @@ function makeTable(setting, keypath, setting_value, isLocked) {
}
html += "<table class='table table-bordered " + (isLocked ? "locked-table" : "") + "' data-short-name='" + setting.name
+ "' name='" + keypath + "' id='" + setting.html_id + "' data-setting-type='" + (isArray ? 'array' : 'hash') + "'>";
+ "' name='" + keypath + "' id='" + (typeof setting.html_id !== 'undefined' ? setting.html_id : keypath)
+ "' data-setting-type='" + (isArray ? 'array' : 'hash') + "'>";
// Column names
html += "<tr class='headers'>"
@ -799,8 +809,8 @@ function makeTable(setting, keypath, setting_value, isLocked) {
if (!isLocked && !setting.read_only) {
if (setting.can_order) {
html += "<td class=" + Settings.REORDER_BUTTONS_CLASSES +
"><a href='javascript:void(0);' class='glyphicon glyphicon-sort'></a></td>";
html += "<td class='" + Settings.REORDER_BUTTONS_CLASSES +
"'><a href='javascript:void(0);' class='glyphicon glyphicon-sort'></a></td>";
}
html += "<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES + "'></td></tr>"
}
@ -809,33 +819,38 @@ function makeTable(setting, keypath, setting_value, isLocked) {
var row_num = 1;
if (keypath.length > 0 && _.size(setting_value) > 0) {
_.each(setting_value, function(row, indexOrName) {
html += "<tr class='" + Settings.DATA_ROW_CLASS + "'" + (isArray ? "" : "name='" + keypath + "." + indexOrName + "'") + ">"
_.each(setting_value, function(row, rowIndexOrName) {
html += "<tr class='" + Settings.DATA_ROW_CLASS + "'" + (isArray ? "" : "name='" + keypath + "." + rowIndexOrName + "'") + ">"
if (setting.numbered === true) {
html += "<td class='numbered'>" + row_num + "</td>"
}
if (setting.key) {
html += "<td class='key'>" + indexOrName + "</td>"
html += "<td class='key'>" + rowIndexOrName + "</td>"
}
_.each(setting.columns, function(col) {
html += "<td class='" + Settings.DATA_COL_CLASS + "'>"
if (isArray) {
rowIsObject = setting.columns.length > 1
colValue = rowIsObject ? row[col.name] : row
html += colValue
// for arrays we add a hidden input to this td so that values can be posted appropriately
html += "<input type='hidden' name='" + keypath + "[" + indexOrName + "]"
+ (rowIsObject ? "." + col.name : "") + "' value='" + colValue + "'/>"
} else if (row.hasOwnProperty(col.name)) {
html += row[col.name]
rowIsObject = setting.columns.length > 1;
colValue = rowIsObject ? row[col.name] : row;
colName = keypath + "[" + rowIndexOrName + "]" + (rowIsObject ? "." + col.name : "");
} else {
colValue = row[col.name];
colName = keypath + "." + rowIndexOrName + "." + col.name;
}
html += "</td>"
// setup the td for this column
html += "<td class='" + Settings.DATA_COL_CLASS + "' name='" + colName + "'>";
// add the actual value to the td so it is displayed
html += colValue;
// for values to be posted properly we add a hidden input to this td
html += "<input type='hidden' name='" + colName + "' value='" + colValue + "'/>";
html += "</td>";
})
if (!isLocked && !setting.read_only) {

View file

@ -19,6 +19,7 @@
#include <glm/gtx/component_wise.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/vector_angle.hpp>
#include <glm/gtc/type_ptr.hpp>
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
@ -975,12 +976,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));
}
}
@ -994,7 +994,7 @@ void Application::resizeGL() {
renderSize = _glWidget->getDeviceSize() * getRenderResolutionScale();
}
if (_renderResolution == toGlm(renderSize)) {
return;
return;
}
_renderResolution = toGlm(renderSize);
@ -1021,25 +1021,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);
}
@ -1260,6 +1250,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
}
break;
#if 0
case Qt::Key_I:
if (isShifted) {
_myCamera.setEyeOffsetOrientation(glm::normalize(
@ -1324,6 +1315,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
}
updateProjectionMatrix();
break;
#endif
case Qt::Key_H:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::Mirror);
@ -2663,7 +2656,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<LODManager>();
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
@ -2867,25 +2860,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();
@ -2986,13 +2965,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);
@ -3190,12 +3163,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
@ -3213,8 +3180,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));
}
@ -3308,7 +3273,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
@ -3542,15 +3507,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());
@ -3571,12 +3537,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

View file

@ -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<int16_t>::max())
? _farClip
: std::numeric_limits<int16_t>::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) {

View file

@ -44,35 +44,24 @@ public:
void update( float deltaTime );
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; }
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 +84,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;

View file

@ -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;

View file

@ -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
@ -538,7 +548,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;
@ -576,9 +587,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 +
@ -589,25 +602,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));
qApp->displaySide(*_camera, false, RenderArgs::MONO);
qApp->getApplicationOverlay().displayOverlayTextureHmd(*_camera);
});
@ -630,7 +635,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
@ -644,16 +648,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

View file

@ -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();

View file

@ -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;
@ -95,7 +95,7 @@ void TV3DManager::display(Camera& whichCamera) {
DependencyManager::get<GlowEffect>()->prepare();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Camera eyeCamera;
eyeCamera.setRotation(whichCamera.getRotation());
eyeCamera.setPosition(whichCamera.getPosition());
@ -118,7 +118,6 @@ void TV3DManager::display(Camera& whichCamera) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0));
qApp->displaySide(eyeCamera, false, RenderArgs::MONO);
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
_activeEye = NULL;

View file

@ -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());

View file

@ -14,7 +14,7 @@
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/vector_angle.hpp>
#include <QtCore/QDebug>
#include <NumericalConstants.h>
@ -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 {

View file

@ -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?