diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f5d0e3b01a..0b3df7540f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -852,6 +852,11 @@ void Application::paintGL() { glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } + // Update camera position + if (!OculusManager::isConnected()) { + _myCamera.update(1.0f / _fps); + } + if (getShadowsEnabled()) { updateShadowMap(); } diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 7db598bdfc..1016d60ccf 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -53,24 +53,42 @@ Camera::Camera() : _nearClip(DEFAULT_NEAR_CLIP), // default _farClip(DEFAULT_FAR_CLIP), // default _hmdPosition(), - _hmdRotation() + _hmdRotation(), + _isKeepLookingAt(false), + _lookingAt(0.0f, 0.0f, 0.0f) { } +void Camera::update(float deltaTime) { + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } + return; +} + void Camera::setPosition(const glm::vec3& position) { _position = position; } void Camera::setRotation(const glm::quat& rotation) { _rotation = rotation; + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } } void Camera::setHmdPosition(const glm::vec3& hmdPosition) { _hmdPosition = hmdPosition; + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } } void Camera::setHmdRotation(const glm::quat& hmdRotation) { _hmdRotation = hmdRotation; + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } } float Camera::getFarClip() const { @@ -101,6 +119,10 @@ void Camera::setFarClip(float f) { _farClip = f; } +PickRay Camera::computePickRay(float x, float y) { + return qApp->computePickRay(x, y); +} + void Camera::setModeString(const QString& mode) { CameraMode targetMode = stringToMode(mode); @@ -129,3 +151,17 @@ void Camera::setModeString(const QString& mode) { QString Camera::getModeString() const { return modeToString(_mode); } + +void Camera::lookAt(const glm::vec3& lookAt) { + glm::vec3 up = IDENTITY_UP; + glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up); + glm::quat rotation = glm::quat_cast(lookAtMatrix); + rotation.w = -rotation.w; // Rosedale approved + _rotation = rotation; +} + +void Camera::keepLookingAt(const glm::vec3& point) { + lookAt(point); + _isKeepLookingAt = true; + _lookingAt = point; +} diff --git a/interface/src/Camera.h b/interface/src/Camera.h index b2eef3a8cb..e06e12f7dc 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -41,6 +41,8 @@ public: void initialize(); // instantly put the camera at the ideal position and rotation. + void update( float deltaTime ); + void setRotation(const glm::quat& rotation); void setHmdPosition(const glm::vec3& hmdPosition); void setHmdRotation(const glm::quat& hmdRotation); @@ -73,6 +75,19 @@ public slots: void setOrientation(const glm::quat& orientation) { setRotation(orientation); } glm::quat getOrientation() const { return getRotation(); } + + PickRay computePickRay(float x, float y); + + // These only work on independent cameras + /// one time change to what the camera is looking at + void lookAt(const glm::vec3& value); + + /// fix what the camera is looking at, and keep the camera looking at this even if position changes + void keepLookingAt(const glm::vec3& value); + + /// stops the keep looking at feature, doesn't change what's being looked at, but will stop camera from + /// continuing to update it's orientation to keep looking at the item + void stopLooking() { _isKeepLookingAt = false; } signals: void modeUpdated(const QString& newMode); @@ -89,6 +104,8 @@ private: glm::quat _rotation; glm::vec3 _hmdPosition; glm::quat _hmdRotation; + bool _isKeepLookingAt; + glm::vec3 _lookingAt; }; #endif // hifi_Camera_h diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 2d6141aac9..872cb62e4b 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -592,6 +592,7 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati glm::vec3(_eyeRenderDesc[eye].HmdToEyeViewOffset.x, _eyeRenderDesc[eye].HmdToEyeViewOffset.y, _eyeRenderDesc[eye].HmdToEyeViewOffset.z)); _eyePositions[eye] = thisEyePosition; + _camera->update(1.0f / Application::getInstance()->getFps()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index d74e210642..f1a762e64f 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -472,7 +472,6 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers) //Injecting mouse movements and clicks void SixenseManager::emulateMouse(PalmData* palm, int index) { MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); - auto glCanvas = Application::getInstance()->getGLWidget(); QPoint pos; Qt::MouseButton bumperButton; @@ -498,12 +497,12 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { // Get the angles, scaled between (-0.5,0.5) float xAngle = (atan2(direction.z, direction.x) + M_PI_2); float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2)); - + auto canvasSize = qApp->getCanvasSize(); // Get the pixel range over which the xAngle and yAngle are scaled - float cursorRange = glCanvas->width() * getCursorPixelRangeMult(); + float cursorRange = canvasSize.x * getCursorPixelRangeMult(); - pos.setX(glCanvas->width() / 2.0f + cursorRange * xAngle); - pos.setY(glCanvas->height() / 2.0f + cursorRange * yAngle); + pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle); + pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle); } diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 90030b2f84..9d5dd2faae 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -33,9 +33,8 @@ bool TV3DManager::isConnected() { } void TV3DManager::connect() { - Camera& camera = *Application::getInstance()->getCamera(); auto deviceSize = qApp->getDeviceSize(); - configureCamera(camera, deviceSize.width(), deviceSize.height()); + configureCamera(*(qApp->getCamera()), deviceSize.width(), deviceSize.height()); }