diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d36d06ee3..3fbf489738 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -605,37 +605,37 @@ void Application::paintGL() { glEnable(GL_LINE_SMOOTH); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - _myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay if (!OculusManager::isConnected()) { - _myCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition()); - _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation()); + _myCamera.setPosition(_myAvatar->getHead()->getEyePosition()); + _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation()); } // OculusManager::display() updates camera position and rotation a bit further on. } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { //Note, the camera distance is set in Camera::setMode() so we dont have to do it here. - _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing - _myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition()); + float thirdPersonCameraDistance = MIRROR_FULLSCREEN_DISTANCE * _scaleMirror * 10.0f; + _myCamera.setPosition(_myAvatar->getUprightHeadPosition() + + _myAvatar->getOrientation() * glm::vec3(0,0,1) * thirdPersonCameraDistance); if (OculusManager::isConnected()) { - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation()); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } else { - _myCamera.setTargetRotation(_myAvatar->getHead()->getOrientation()); + _myCamera.setRotation(_myAvatar->getHead()->getOrientation()); } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - _myCamera.setTightness(0.0f); //Only behave like a true mirror when in the OR if (OculusManager::isConnected()) { - _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0)); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + + _myAvatar->getOrientation() * glm::vec3(0,0,-1) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } else { - _myCamera.setTightness(0.0f); glm::vec3 eyePosition = _myAvatar->getHead()->getEyePosition(); float headHeight = eyePosition.y - _myAvatar->getPosition().y; - _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - _myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0)); - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getPosition() + + glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0) + + _myAvatar->getOrientation() * glm::vec3(0,0,-1) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); } } @@ -659,11 +659,14 @@ void Application::paintGL() { ViewFrustumOffset viewFrustumOffset = Menu::getInstance()->getViewFrustumOffset(); // set the camera to third-person view but offset so we can see the frustum - _viewFrustumOffsetCamera.setTargetPosition(_myCamera.getTargetPosition()); - _viewFrustumOffsetCamera.setTargetRotation(_myCamera.getTargetRotation() * glm::quat(glm::radians(glm::vec3( + _viewFrustumOffsetCamera.setPosition(_myCamera.getPosition()); + _viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll)))); - _viewFrustumOffsetCamera.setUpShift(viewFrustumOffset.up); - _viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance); + // TODO: PHILIP + // Fix Frustum offset and up + //_viewFrustumOffsetCamera.setUpShift(viewFrustumOffset.up); + //_viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance); + _viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation _viewFrustumOffsetCamera.update(1.f/_fps); whichCamera = &_viewFrustumOffsetCamera; @@ -1779,10 +1782,8 @@ void Application::init() { // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager _avatarManager.init(); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftPeriod(1.0f); _mirrorCamera.setMode(CAMERA_MODE_MIRROR); - _mirrorCamera.setModeShiftPeriod(0.0f); OculusManager::connect(); if (OculusManager::isConnected()) { @@ -2122,17 +2123,14 @@ void Application::cameraMenuChanged() { if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { _myCamera.setMode(CAMERA_MODE_MIRROR); - _myCamera.setModeShiftPeriod(0.0f); } } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftPeriod(modeShiftPeriod); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftPeriod(modeShiftPeriod); } } } @@ -3101,30 +3099,30 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { bool eyeRelativeCamera = false; if (billboard) { _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees - _mirrorCamera.setDistance(BILLBOARD_DISTANCE * _myAvatar->getScale()); - _mirrorCamera.setTargetPosition(_myAvatar->getPosition()); + _mirrorCamera.setPosition(_myAvatar->getPosition() + + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); } else if (_rearMirrorTools->getZoomLevel() == BODY) { _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees - _mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); - _mirrorCamera.setTargetPosition(_myAvatar->getChestPosition()); + _mirrorCamera.setPosition(_myAvatar->getChestPosition() + + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); } else { // HEAD zoom level _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees - _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) { // as a hack until we have a better way of dealing with coordinate precision issues, reposition the // face/body so that the average eye position lies at the origin eyeRelativeCamera = true; - _mirrorCamera.setTargetPosition(glm::vec3()); + _mirrorCamera.setPosition(glm::vec3()); } else { - _mirrorCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition()); + _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + _myAvatar->getOrientation() * glm::vec3(0.f, 0.f, 1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); } } _mirrorCamera.setAspectRatio((float)region.width() / region.height()); - _mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); _mirrorCamera.update(1.0f/_fps); // set the bounds of rear mirror view diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 762fb1a3f6..79d66568bf 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -20,95 +20,21 @@ #include "Util.h" #include "devices/OculusManager.h" -const float CAMERA_FIRST_PERSON_MODE_UP_SHIFT = 0.0f; -const float CAMERA_FIRST_PERSON_MODE_DISTANCE = 0.0f; -const float CAMERA_FIRST_PERSON_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_INDEPENDENT_MODE_UP_SHIFT = 0.0f; -const float CAMERA_INDEPENDENT_MODE_DISTANCE = 0.0f; -const float CAMERA_INDEPENDENT_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; -const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 10.5f; -const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_MIRROR_MODE_UP_SHIFT = 0.0f; -const float CAMERA_MIRROR_MODE_DISTANCE = 0.17f; -const float CAMERA_MIRROR_MODE_TIGHTNESS = 100.0f; - Camera::Camera() : _needsToInitialize(true), _mode(CAMERA_MODE_THIRD_PERSON), - _prevMode(CAMERA_MODE_THIRD_PERSON), - _frustumNeedsReshape(true), _position(0.0f, 0.0f, 0.0f), - _idealPosition(0.0f, 0.0f, 0.0f), - _targetPosition(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 - _upShift(0.0f), - _distance(0.0f), - _tightness(10.0f), // default - _previousUpShift(0.0f), - _previousDistance(0.0f), - _previousTightness(0.0f), - _newUpShift(0.0f), - _newDistance(0.0f), - _newTightness(0.0f), - _modeShift(1.0f), - _linearModeShift(0.0f), - _modeShiftPeriod(1.0f), _scale(1.0f) { } -void Camera::update(float deltaTime) { - - if (_mode != CAMERA_MODE_NULL) { - // use iterative forces to push the camera towards the target position and angle - updateFollowMode(deltaTime); - } -} - -// use iterative forces to keep the camera at the desired position and angle -void Camera::updateFollowMode(float deltaTime) { - if (_linearModeShift < 1.0f) { - _linearModeShift += deltaTime / _modeShiftPeriod; - if (_needsToInitialize || _linearModeShift > 1.0f) { - _linearModeShift = 1.0f; - _modeShift = 1.0f; - _upShift = _newUpShift; - _distance = _newDistance; - _tightness = _newTightness; - } else { - _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PI ); - _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; - _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; - _tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift; - } - } - - // derive t from tightness - float t = _tightness * _modeShift * deltaTime; - if (t > 1.0f) { - t = 1.0f; - } - - // Update position and rotation, setting directly if tightness is 0.0 - if (_needsToInitialize || (_tightness == 0.0f)) { - _rotation = _targetRotation; - _idealPosition = _targetPosition + _scale * (_rotation * glm::vec3(0.0f, _upShift, _distance)); - _position = _idealPosition; - _needsToInitialize = false; - } else { - // pull rotation towards ideal - _rotation = safeMix(_rotation, _targetRotation, t); - _idealPosition = _targetPosition + _scale * (_rotation * glm::vec3(0.0f, _upShift, _distance)); - _position += (_idealPosition - _position) * t; - } +void Camera::update(float deltaTime) { + return; } float Camera::getFarClip() const { @@ -117,106 +43,46 @@ float Camera::getFarClip() const { : std::numeric_limits::max() - 1; } -void Camera::setModeShiftPeriod (float period) { - const float MIN_PERIOD = 0.001f; - const float MAX_PERIOD = 3.0f; - _modeShiftPeriod = glm::clamp(period, MIN_PERIOD, MAX_PERIOD); - - // if a zero period was requested, we clearly want to snap immediately to the target - if (period == 0.0f) { - update(MAX_PERIOD); - } -} - -void Camera::setMode(CameraMode m) { - - _prevMode = _mode; +void Camera::setMode(CameraMode m) { _mode = m; - _modeShift = 0.0; - _linearModeShift = 0.0; - - _previousUpShift = _upShift; - _previousDistance = _distance; - _previousTightness = _tightness; - - if (_mode == CAMERA_MODE_THIRD_PERSON) { - _newUpShift = CAMERA_THIRD_PERSON_MODE_UP_SHIFT; - _newDistance = CAMERA_THIRD_PERSON_MODE_DISTANCE; - _newTightness = CAMERA_THIRD_PERSON_MODE_TIGHTNESS; - } else if (_mode == CAMERA_MODE_FIRST_PERSON) { - _newUpShift = CAMERA_FIRST_PERSON_MODE_UP_SHIFT; - _newDistance = CAMERA_FIRST_PERSON_MODE_DISTANCE; - _newTightness = CAMERA_FIRST_PERSON_MODE_TIGHTNESS; - } else if (_mode == CAMERA_MODE_MIRROR) { - _newUpShift = CAMERA_MIRROR_MODE_UP_SHIFT; - _newDistance = CAMERA_MIRROR_MODE_DISTANCE; - _newTightness = CAMERA_MIRROR_MODE_TIGHTNESS; - } else if (_mode == CAMERA_MODE_INDEPENDENT) { - _newUpShift = CAMERA_INDEPENDENT_MODE_UP_SHIFT; - _newDistance = CAMERA_INDEPENDENT_MODE_DISTANCE; - _newTightness = CAMERA_INDEPENDENT_MODE_TIGHTNESS; - - } } -void Camera::setTargetPosition(const glm::vec3& t) { - _targetPosition = t; -} - -void Camera::setTargetRotation( const glm::quat& targetRotation ) { - _targetRotation = targetRotation; -} void Camera::setFieldOfView(float f) { _fieldOfView = f; - _frustumNeedsReshape = true; } void Camera::setAspectRatio(float a) { - _aspectRatio = a; - _frustumNeedsReshape = true; + _aspectRatio = a; } void Camera::setNearClip(float n) { - _nearClip = n; - _frustumNeedsReshape = true; + _nearClip = n; } void Camera::setFarClip(float f) { - _farClip = f; - _frustumNeedsReshape = true; + _farClip = f; } void Camera::setEyeOffsetPosition(const glm::vec3& p) { _eyeOffsetPosition = p; - _frustumNeedsReshape = true; } void Camera::setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; - _frustumNeedsReshape = true; + } void Camera::setScale(float s) { _scale = s; _needsToInitialize = true; - _frustumNeedsReshape = true; + } void Camera::initialize() { _needsToInitialize = true; - _modeShift = 0.0; } -// call to find out if the view frustum needs to be reshaped -bool Camera::getFrustumNeedsReshape() const { - return _frustumNeedsReshape; -} - -// call this after reshaping the view frustum -void Camera::setFrustumWasReshaped() { - _frustumNeedsReshape = false; -} CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : _camera(camera), _viewFrustum(viewFrustum) diff --git a/interface/src/Camera.h b/interface/src/Camera.h index ab229b7ef5..ee4930272d 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -35,14 +35,9 @@ public: void initialize(); // instantly put the camera at the ideal position and rotation. void update( float deltaTime ); - - void setUpShift(float u) { _upShift = u; } - void setDistance(float d) { _distance = d; } + void setPosition(const glm::vec3& p) { _position = p; } - void setTargetPosition(const glm::vec3& t); - void setTightness(float t) { _tightness = t; } - void setTargetRotation(const glm::quat& rotation); - void setModeShiftPeriod(float r); + void setRotation(const glm::quat& rotation) { _rotation = rotation; }; void setMode(CameraMode m); void setFieldOfView(float f); void setAspectRatio(float a); @@ -55,10 +50,6 @@ public: const glm::vec3& getPosition() const { return _position; } const glm::quat& getRotation() const { return _rotation; } CameraMode getMode() const { return _mode; } - float getModeShiftPeriod() const { return _modeShiftPeriod; } - float getDistance() const { return _distance; } - const glm::vec3& getTargetPosition() const { return _targetPosition; } - const glm::quat& getTargetRotation() const { return _targetRotation; } float getFieldOfView() const { return _fieldOfView; } float getAspectRatio() const { return _aspectRatio; } float getNearClip() const { return _scale * _nearClip; } @@ -67,18 +58,11 @@ public: const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } float getScale() const { return _scale; } - bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped - void setFrustumWasReshaped(); // call this after reshaping the view frustum. - private: bool _needsToInitialize; CameraMode _mode; - CameraMode _prevMode; - bool _frustumNeedsReshape; glm::vec3 _position; - glm::vec3 _idealPosition; - glm::vec3 _targetPosition; float _fieldOfView; // degrees float _aspectRatio; float _nearClip; @@ -86,22 +70,8 @@ private: glm::vec3 _eyeOffsetPosition; glm::quat _eyeOffsetOrientation; glm::quat _rotation; - glm::quat _targetRotation; - float _upShift; - float _distance; - float _tightness; - float _previousUpShift; - float _previousDistance; - float _previousTightness; - float _newUpShift; - float _newDistance; - float _newTightness; - float _modeShift; - float _linearModeShift; - float _modeShiftPeriod; + float _scale; - - void updateFollowMode(float deltaTime); }; @@ -113,12 +83,11 @@ public: public slots: QString getMode() const; void setMode(const QString& mode); - void setModeShiftPeriod(float r) {_camera->setModeShiftPeriod(r); } - void setPosition(const glm::vec3& value) { _camera->setTargetPosition(value);} + void setPosition(const glm::vec3& value) { _camera->setPosition(value);} glm::vec3 getPosition() const { return _camera->getPosition(); } - void setOrientation(const glm::quat& value) { _camera->setTargetRotation(value); } + void setOrientation(const glm::quat& value) { _camera->setRotation(value); } glm::quat getOrientation() const { return _camera->getRotation(); } PickRay computePickRay(float x, float y); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 087d670760..c0ce474d16 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1126,7 +1126,7 @@ void MyAvatar::renderBody(RenderMode renderMode, bool postLighting, float glowLe // Render head so long as the camera isn't inside it const Camera *camera = Application::getInstance()->getCamera(); - const glm::vec3 cameraPos = camera->getPosition() + (camera->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) * camera->getDistance(); + const glm::vec3 cameraPos = camera->getPosition(); if (shouldRenderHead(cameraPos, renderMode)) { getHead()->render(1.0f, modelRenderMode, postLighting); diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 65518b839c..eb48e3d463 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -311,10 +311,6 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p ovrPosef eyeRenderPose[ovrEye_Count]; - _camera->setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay - _camera->setDistance(0.0f); - _camera->setUpShift(0.0f); - glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -348,8 +344,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p orientation.z = eyeRenderPose[eye].Orientation.z; orientation.w = eyeRenderPose[eye].Orientation.w; - _camera->setTargetRotation(bodyOrientation * orientation); - _camera->setTargetPosition(position + trackerPosition); + _camera->setRotation(bodyOrientation * orientation); + _camera->setPosition(position + trackerPosition); // Store the latest left and right eye render locations for things that need to know glm::vec3 thisEyePosition = position + trackerPosition + @@ -413,8 +409,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p glBindTexture(GL_TEXTURE_2D, 0); // Update camera for use by rest of Interface. - whichCamera.setTargetPosition((_leftEyePosition + _rightEyePosition) / 2.f); - whichCamera.setTargetRotation(_camera->getTargetRotation()); + whichCamera.setPosition((_leftEyePosition + _rightEyePosition) / 2.f); + whichCamera.setRotation(_camera->getRotation()); #endif }