From 77e7f336d5a5b35730969364cdf11ec9702b2240 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 6 Feb 2014 20:03:57 -0800 Subject: [PATCH] scriptable camera --- interface/src/Application.cpp | 48 +++++++----- interface/src/Application.h | 1 + interface/src/Camera.cpp | 121 +++++++++++++++++++++-------- interface/src/Camera.h | 142 ++++++++++++++++++++-------------- interface/src/Menu.cpp | 10 ++- interface/src/Menu.h | 1 + 6 files changed, 208 insertions(+), 115 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 84ece357a7..73e58d79e2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -434,9 +434,9 @@ void Application::paintGL() { glEnable(GL_LINE_SMOOTH); if (OculusManager::isConnected()) { - _myCamera.setUpShift (0.0f); - _myCamera.setDistance (0.0f); - _myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing + _myCamera.setUpShift(0.0f); + _myCamera.setDistance(0.0f); + _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing _myCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition()); _myCamera.setTargetRotation(_myAvatar->getHead().getOrientation()); @@ -446,7 +446,7 @@ void Application::paintGL() { _myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - _myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing + _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing _myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition()); _myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation()); @@ -2220,28 +2220,30 @@ void Application::updateMetavoxels(float deltaTime) { } } +void Application::cameraMenuChanged() { + if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { + if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { + _myCamera.setMode(CAMERA_MODE_MIRROR); + _myCamera.setModeShiftRate(100.0f); + } + } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { + if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); + } + } else { + if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); + } + } +} + void Application::updateCamera(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateCamera()"); if (!OculusManager::isConnected() && !TV3DManager::isConnected()) { - if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { - if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { - _myCamera.setMode(CAMERA_MODE_MIRROR); - _myCamera.setModeShiftRate(100.0f); - } - } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { - if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftRate(1.0f); - } - } else { - if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftRate(1.0f); - } - } - if (Menu::getInstance()->isOptionChecked(MenuOption::OffAxisProjection)) { float xSign = _myCamera.getMode() == CAMERA_MODE_MIRROR ? 1.0f : -1.0f; if (_faceshift.isActive()) { @@ -4095,6 +4097,10 @@ void Application::loadScript(const QString& fileNameString) { // hook our avatar object into this script engine scriptEngine->setAvatarData( static_cast(_myAvatar), "MyAvatar"); + CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera); + scriptEngine->registerGlobalObject("Camera", cameraScriptable); + connect(scriptEngine, SIGNAL(finished(const QString&)), cameraScriptable, SLOT(deleteLater())); + QThread* workerThread = new QThread(this); // when the worker thread is started, call our engine's run.. diff --git a/interface/src/Application.h b/interface/src/Application.h index e82eaf1d6c..16173b809c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -238,6 +238,7 @@ private slots: void setFullscreen(bool fullscreen); void setEnable3DTVMode(bool enable3DTVMode); + void cameraMenuChanged(); void renderThrustAtVoxel(const glm::vec3& thrust); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 7ec4f90eef..4cd7059457 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -10,6 +10,7 @@ #include #include "Camera.h" +#include "Menu.h" #include "Util.h" const float CAMERA_MINIMUM_MODE_SHIFT_RATE = 0.5f; @@ -18,6 +19,10 @@ 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 = 1.5f; const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 8.0f; @@ -27,33 +32,33 @@ const float CAMERA_MIRROR_MODE_DISTANCE = 0.17f; const float CAMERA_MIRROR_MODE_TIGHTNESS = 100.0f; -Camera::Camera() { - - _needsToInitialize = true; - _frustumNeedsReshape = true; - - _modeShift = 1.0f; - _modeShiftRate = 1.0f; - _linearModeShift = 0.0f; - _mode = CAMERA_MODE_THIRD_PERSON; - _prevMode = CAMERA_MODE_THIRD_PERSON; - _tightness = 10.0f; // default - _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES; - _aspectRatio = 16.f/9.f; - _nearClip = 0.08f; // default - _farClip = 50.0f * TREE_SCALE; // default - _upShift = 0.0f; - _distance = 0.0f; - _previousUpShift = 0.0f; - _previousDistance = 0.0f; - _previousTightness = 0.0f; - _newUpShift = 0.0f; - _newDistance = 0.0f; - _newTightness = 0.0f; - _targetPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _position = glm::vec3(0.0f, 0.0f, 0.0f); - _idealPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _scale = 1.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.f/9.f), + _nearClip(0.08f), // default + _farClip(50.0f * TREE_SCALE), // 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), + _modeShiftRate(1.0f), + _scale(1.0f) + //,_wantsAutoFollow(true) +{ } void Camera::update(float deltaTime) { @@ -66,12 +71,9 @@ void Camera::update(float deltaTime) { // use iterative forces to keep the camera at the desired position and angle void Camera::updateFollowMode(float deltaTime) { - if (_linearModeShift < 1.0f) { _linearModeShift += _modeShiftRate * deltaTime; - _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE ); - _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; _tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift; @@ -98,7 +100,6 @@ void Camera::updateFollowMode(float deltaTime) { _idealPosition = _targetPosition + _scale * (_rotation * glm::vec3(0.0f, _upShift, _distance)); _position = _idealPosition; _needsToInitialize = false; - } else { // pull rotation towards ideal _rotation = safeMix(_rotation, _targetRotation, t); @@ -137,16 +138,19 @@ void Camera::setMode(CameraMode m) { _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; + } } @@ -218,4 +222,55 @@ void Camera::setFrustumWasReshaped() { } +QString CameraScriptableObject::getMode() const { + QString mode("unknown"); + switch(_camera->getMode()) { + case CAMERA_MODE_THIRD_PERSON: + mode = "third person"; + break; + case CAMERA_MODE_FIRST_PERSON: + mode = "first person"; + break; + case CAMERA_MODE_MIRROR: + mode = "mirror"; + break; + case CAMERA_MODE_INDEPENDENT: + mode = "independent"; + break; + default: + break; + } + return mode; +} + +void CameraScriptableObject::setMode(const QString& mode) { + CameraMode currentMode = _camera->getMode(); + CameraMode targetMode = currentMode; + if (mode == "third person") { + targetMode = CAMERA_MODE_THIRD_PERSON; + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + } else if (mode == "first person") { + targetMode = CAMERA_MODE_FIRST_PERSON; + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true); + } else if (mode == "mirror") { + targetMode = CAMERA_MODE_MIRROR; + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + } else if (mode == "independent") { + targetMode = CAMERA_MODE_INDEPENDENT; + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + } + if (currentMode != targetMode) { + _camera->setMode(targetMode); + _camera->setModeShiftRate(10.0f); + } +} + +void CameraScriptableObject::setPosition(const glm::vec3& p) { + _camera->setTargetPosition(p); +} + diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 7fc9b47634..65109492fd 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -11,7 +11,7 @@ #include #include -const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f; +const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f; enum CameraMode { @@ -19,11 +19,12 @@ enum CameraMode CAMERA_MODE_THIRD_PERSON, CAMERA_MODE_FIRST_PERSON, CAMERA_MODE_MIRROR, + CAMERA_MODE_INDEPENDENT, NUM_CAMERA_MODES }; -class Camera -{ +class Camera { + public: Camera(); @@ -31,73 +32,96 @@ public: void update( float deltaTime ); - void setUpShift ( float u ) { _upShift = u; } - void setDistance ( float d ) { _distance = d; } - void setTargetPosition( const glm::vec3& t ) { _targetPosition = t; } - void setPosition ( const glm::vec3& p ) { _position = p; } - void setTightness ( float t ) { _tightness = t; } - void setTargetRotation( const glm::quat& rotation ); + 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) { _targetPosition = t; } + void setTightness(float t) { _tightness = t; } + void setTargetRotation(const glm::quat& rotation); - void setMode ( CameraMode m ); - void setModeShiftRate ( float r ); - void setFieldOfView ( float f ); - void setAspectRatio ( float a ); - void setNearClip ( float n ); - void setFarClip ( float f ); - void setEyeOffsetPosition ( const glm::vec3& p ); - void setEyeOffsetOrientation( const glm::quat& o ); - void setScale ( const float s ); + void setMode(CameraMode m); + void setModeShiftRate(float r); + void setFieldOfView(float f); + void setAspectRatio(float a); + void setNearClip(float n); + void setFarClip(float f); + void setEyeOffsetPosition(const glm::vec3& p); + void setEyeOffsetOrientation(const glm::quat& o); + void setScale(const float s); - const glm::vec3& getTargetPosition () const { return _targetPosition; } - const glm::vec3& getPosition () const { return _position; } - const glm::quat& getTargetRotation () const { return _targetRotation; } - const glm::quat& getRotation () const { return _rotation; } - CameraMode getMode () const { return _mode; } - float getFieldOfView () const { return _fieldOfView; } - float getAspectRatio () const { return _aspectRatio; } - float getNearClip () const { return _scale * _nearClip; } - float getFarClip () const; - const glm::vec3& getEyeOffsetPosition () const { return _eyeOffsetPosition; } - const glm::quat& getEyeOffsetOrientation () const { return _eyeOffsetOrientation; } - float getScale () const { return _scale; } + const glm::vec3& getPosition() const { return _position; } + const glm::quat& getRotation() const { return _rotation; } + CameraMode getMode() const { return _mode; } + 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; } + float getFarClip() const; + const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; } + const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } + float getScale() const { return _scale; } CameraMode getInterpolatedMode() const; bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped void setFrustumWasReshaped(); // call this after reshaping the view frustum. + + bool getWantsAutoFollow() const { return _wantsAutoFollow; } + void setWantsAutoFollow(bool value) { _wantsAutoFollow = value; } private: - bool _needsToInitialize; - CameraMode _mode; - CameraMode _prevMode; - bool _frustumNeedsReshape; - glm::vec3 _position; - glm::vec3 _idealPosition; - glm::vec3 _targetPosition; - float _fieldOfView; - float _aspectRatio; - float _nearClip; - float _farClip; - 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 _modeShiftRate; - float _scale; + bool _needsToInitialize; + CameraMode _mode; + CameraMode _prevMode; + bool _frustumNeedsReshape; + glm::vec3 _position; + glm::vec3 _idealPosition; + glm::vec3 _targetPosition; + float _fieldOfView; + float _aspectRatio; + float _nearClip; + float _farClip; + 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 _modeShiftRate; + float _scale; + + bool _wantsAutoFollow; - void updateFollowMode( float deltaTime ); + void updateFollowMode(float deltaTime); }; + +class CameraScriptableObject : public QObject { + Q_OBJECT +public: + CameraScriptableObject(Camera* camera) { _camera = camera; } + +public slots: + QString getMode() const; + void setMode(const QString& mode); + void setPosition(const glm::vec3& p); + glm::vec3 getPosition() const { return _camera->getPosition(); } + + //bool getWantsAutoFollow() const { return _camera->getWantsAutoFollow(); } + //void setWantsAutoFollow(bool value) { _camera->setWantsAutoFollow(value); } + +private: + Camera* _camera; +}; #endif diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 709f848a2f..6ea1247049 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -232,9 +232,12 @@ Menu::Menu() : false, appInstance, SLOT(setFullscreen(bool))); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true, + appInstance,SLOT(cameraMenuChanged())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H,false, + appInstance,SLOT(cameraMenuChanged())); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false, appInstance, @@ -690,6 +693,9 @@ void Menu::removeAction(QMenu* menu, const QString& actionName) { menu->removeAction(_actionHash.value(actionName)); } +void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) { + return _actionHash.value(menuOption)->setChecked(isChecked); +} bool Menu::isOptionChecked(const QString& menuOption) { return _actionHash.value(menuOption)->isChecked(); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6f7986fcc3..fcd2d74940 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -48,6 +48,7 @@ public: ~Menu(); bool isOptionChecked(const QString& menuOption); + void setIsOptionChecked(const QString& menuOption, bool isChecked); void triggerOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption); bool isVoxelModeActionChecked();