From 8d6b041758a469df13a282a0cf428699a299ed1e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:01:25 -0800 Subject: [PATCH 01/10] send a pick ray with HFActionEvent, not x,y --- interface/src/Application.cpp | 17 ++++++++++------- interface/src/Application.h | 3 +-- interface/src/Camera.h | 4 +++- .../scripting/JoystickScriptingInterface.cpp | 4 +--- libraries/script-engine/src/HFActionEvent.cpp | 7 +++---- libraries/script-engine/src/HFActionEvent.h | 9 ++++++--- libraries/shared/src/RegisteredMetaTypes.h | 3 ++- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b773231b0f..517c899f28 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -177,6 +177,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _packetsPerSecond(0), _bytesPerSecond(0), _nodeBoundsDisplay(this), + _cameraScriptableObject(&_myCamera, &_viewFrustum), _previousScriptLocation(), _applicationOverlay(), _runningScriptsWidget(NULL), @@ -1116,7 +1117,9 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Space: { if (!event->isAutoRepeat()) { // this starts an HFActionEvent - HFActionEvent startActionEvent(HFActionEvent::startType(), getViewportCenter()); + PickRay actionRay; + + HFActionEvent startActionEvent(HFActionEvent::startType(), actionRay); sendEvent(this, &startActionEvent); } @@ -1207,7 +1210,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { case Qt::Key_Space: { if (!event->isAutoRepeat()) { // this ends the HFActionEvent - HFActionEvent endActionEvent(HFActionEvent::endType(), getViewportCenter()); + HFActionEvent endActionEvent(HFActionEvent::endType(), Application::getInstance()->getCamera()->getPickRay()); sendEvent(this, &endActionEvent); } @@ -1301,7 +1304,8 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { } // nobody handled this - make it an action event on the _window object - HFActionEvent actionEvent(HFActionEvent::startType(), event->localPos()); + HFActionEvent actionEvent(HFActionEvent::startType(), + _cameraScriptableObject.computePickRay(event->x(), event->y())); sendEvent(this, &actionEvent); } else if (event->button() == Qt::RightButton) { @@ -1335,7 +1339,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { } // fire an action end event - HFActionEvent actionEvent(HFActionEvent::endType(), event->localPos()); + HFActionEvent actionEvent(HFActionEvent::endType(), + _cameraScriptableObject.computePickRay(event->x(), event->y())); sendEvent(this, &actionEvent); } } @@ -3846,9 +3851,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features scriptEngine->setAvatarHashMap(&_avatarManager, "AvatarList"); - CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera, &_viewFrustum); - scriptEngine->registerGlobalObject("Camera", cameraScriptable); - connect(scriptEngine, SIGNAL(finished(const QString&)), cameraScriptable, SLOT(deleteLater())); + scriptEngine->registerGlobalObject("Camera", &_cameraScriptableObject); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) scriptEngine->registerGlobalObject("SpeechRecognizer", Menu::getInstance()->getSpeechRecognizer()); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9fcf53cfa9..60d06929d2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -287,8 +287,6 @@ public: PointShader& getPointShader() { return _pointShader; } FileLogger* getLogger() { return _logger; } - QPointF getViewportCenter() const - { return QPointF(_glWidget->getDeviceWidth() / 2.0f, _glWidget->getDeviceHeight() / 2.0f); } glm::vec2 getViewportDimensions() const { return glm::vec2(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); } NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; } NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; } @@ -599,6 +597,7 @@ private: std::vector _voxelFades; QReadWriteLock _voxelFadesLock; ControllerScriptingInterface _controllerScriptingInterface; + CameraScriptableObject _cameraScriptableObject; QPointer _logDialog; QPointer _snapshotShareDialog; diff --git a/interface/src/Camera.h b/interface/src/Camera.h index e876f70e3a..3dd3f8a840 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -53,6 +53,8 @@ public: void setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; } void setScale(const float s) { _scale = s; } + PickRay getPickRay() const { return PickRay(getPosition(), getRotation() * IDENTITY_FRONT); } + glm::vec3 getPosition() const { return _position + _hmdPosition; } glm::quat getRotation() const { return _rotation * _hmdRotation; } const glm::vec3& getHmdPosition() const { return _hmdPosition; } @@ -66,7 +68,7 @@ public: const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; } const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } float getScale() const { return _scale; } - + signals: void modeUpdated(CameraMode newMode); diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/scripting/JoystickScriptingInterface.cpp index f2c7ef4579..7fc4e48843 100644 --- a/interface/src/scripting/JoystickScriptingInterface.cpp +++ b/interface/src/scripting/JoystickScriptingInterface.cpp @@ -129,9 +129,7 @@ void JoystickScriptingInterface::update() { : HFActionEvent::endType(); // global action events fire in the center of the screen - QPointF centerPoint = Application::getInstance()->getViewportCenter(); - HFActionEvent actionEvent(actionType, centerPoint); - + HFActionEvent actionEvent(actionType, Application::getInstance()->getCamera()->getPickRay()); qApp->sendEvent(qApp, &actionEvent); } diff --git a/libraries/script-engine/src/HFActionEvent.cpp b/libraries/script-engine/src/HFActionEvent.cpp index 8a966a3fb3..780788cfca 100644 --- a/libraries/script-engine/src/HFActionEvent.cpp +++ b/libraries/script-engine/src/HFActionEvent.cpp @@ -11,9 +11,9 @@ #include "HFActionEvent.h" -HFActionEvent::HFActionEvent(QEvent::Type type, const QPointF& localPosition) : +HFActionEvent::HFActionEvent(QEvent::Type type, const PickRay& actionRay) : HFMetaEvent(type), - localPosition(localPosition) + actionRay(actionRay) { } @@ -30,8 +30,7 @@ QEvent::Type HFActionEvent::endType() { QScriptValue HFActionEvent::toScriptValue(QScriptEngine* engine, const HFActionEvent& event) { QScriptValue obj = engine->newObject(); - obj.setProperty("x", event.localPosition.x()); - obj.setProperty("y", event.localPosition.y()); + obj.setProperty("actionRay", pickRayToScriptValue(engine, event.actionRay)); return obj; } diff --git a/libraries/script-engine/src/HFActionEvent.h b/libraries/script-engine/src/HFActionEvent.h index c094161053..c16b165ae3 100644 --- a/libraries/script-engine/src/HFActionEvent.h +++ b/libraries/script-engine/src/HFActionEvent.h @@ -12,14 +12,17 @@ #ifndef hifi_HFActionEvent_h #define hifi_HFActionEvent_h -#include "HFMetaEvent.h" #include +#include + +#include "HFMetaEvent.h" + class HFActionEvent : public HFMetaEvent { public: HFActionEvent() {}; - HFActionEvent(QEvent::Type type, const QPointF& localPosition); + HFActionEvent(QEvent::Type type, const PickRay& actionRay); static QEvent::Type startType(); static QEvent::Type endType(); @@ -27,7 +30,7 @@ public: static QScriptValue toScriptValue(QScriptEngine* engine, const HFActionEvent& event); static void fromScriptValue(const QScriptValue& object, HFActionEvent& event); - QPointF localPosition; + PickRay actionRay; }; Q_DECLARE_METATYPE(HFActionEvent) diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 7fe662740a..b8884be845 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -53,7 +53,8 @@ void qURLFromScriptValue(const QScriptValue& object, QUrl& url); class PickRay { public: - PickRay() : origin(0.0f), direction(0.0f) { } + PickRay() : origin(0.0f), direction(0.0f) { } + PickRay(const glm::vec3& origin, const glm::vec3 direction) : origin(origin), direction(direction) {} glm::vec3 origin; glm::vec3 direction; }; From 99219a17580bf77c6b7fea6ad644793e6d2c23af Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:17:00 -0800 Subject: [PATCH 02/10] use actionRay in lobby script --- examples/lobby.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index b5353131a5..f255af63ef 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -40,10 +40,8 @@ var ORB_SHIFT = { x: 0, y: -1.4, z: -0.8}; var HELMET_ATTACHMENT_URL = "https://hifi-public.s3.amazonaws.com/models/attachments/IronManMaskOnly.fbx" function reticlePosition() { - var screenSize = Controller.getViewportDimensions(); - var reticleRay = Camera.computePickRay(screenSize.x / 2, screenSize.y / 2); var RETICLE_DISTANCE = 1; - return Vec3.sum(reticleRay.origin, Vec3.multiply(reticleRay.direction, RETICLE_DISTANCE)); + return Vec3.sum(Camera.getPosition(), Vec3.multiply(Quat.getFront(Camera.getOrientation()), RETICLE_DISTANCE)); } function drawLobby() { @@ -132,10 +130,10 @@ function actionStartEvent(event) { if (panelWall) { // we've got an action event and our panel wall is up // check if we hit a panel and if we should jump there - var pickRay = Camera.computePickRay(event.x, event.y); - var result = Overlays.findRayIntersection(pickRay); + var result = Overlays.findRayIntersection(event.actionRay); if (result.intersects && result.overlayID == panelWall) { + var panelName = result.extraInfo; var panelStringIndex = panelName.indexOf("Panel"); if (panelStringIndex != -1) { From 957705998fba6c1b9c08a5f18fc757bbaf466649 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:19:56 -0800 Subject: [PATCH 03/10] fix an uninitialized action ray when hitting spacebar --- interface/src/Application.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 517c899f28..943e4283fe 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1117,9 +1117,8 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Space: { if (!event->isAutoRepeat()) { // this starts an HFActionEvent - PickRay actionRay; - - HFActionEvent startActionEvent(HFActionEvent::startType(), actionRay); + HFActionEvent startActionEvent(HFActionEvent::startType(), + Application::getInstance()->getCamera()->getPickRay()); sendEvent(this, &startActionEvent); } From 790aa848ae3e7121b34166ef1f66892f723124e8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:33:55 -0800 Subject: [PATCH 04/10] leverage Camera object for scripting, remove sep interface --- interface/src/Application.cpp | 7 ++-- interface/src/Application.h | 1 - interface/src/Camera.cpp | 72 +++++++++++++++-------------------- interface/src/Camera.h | 47 +++++++---------------- 4 files changed, 46 insertions(+), 81 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 943e4283fe..2438db18f8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -177,7 +177,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _packetsPerSecond(0), _bytesPerSecond(0), _nodeBoundsDisplay(this), - _cameraScriptableObject(&_myCamera, &_viewFrustum), _previousScriptLocation(), _applicationOverlay(), _runningScriptsWidget(NULL), @@ -1304,7 +1303,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { // nobody handled this - make it an action event on the _window object HFActionEvent actionEvent(HFActionEvent::startType(), - _cameraScriptableObject.computePickRay(event->x(), event->y())); + _myCamera.computePickRay(event->x(), event->y())); sendEvent(this, &actionEvent); } else if (event->button() == Qt::RightButton) { @@ -1339,7 +1338,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { // fire an action end event HFActionEvent actionEvent(HFActionEvent::endType(), - _cameraScriptableObject.computePickRay(event->x(), event->y())); + _myCamera.computePickRay(event->x(), event->y())); sendEvent(this, &actionEvent); } } @@ -3850,7 +3849,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features scriptEngine->setAvatarHashMap(&_avatarManager, "AvatarList"); - scriptEngine->registerGlobalObject("Camera", &_cameraScriptableObject); + scriptEngine->registerGlobalObject("Camera", &_myCamera); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) scriptEngine->registerGlobalObject("SpeechRecognizer", Menu::getInstance()->getSpeechRecognizer()); diff --git a/interface/src/Application.h b/interface/src/Application.h index 60d06929d2..d92333058f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -597,7 +597,6 @@ private: std::vector _voxelFades; QReadWriteLock _voxelFadesLock; ControllerScriptingInterface _controllerScriptingInterface; - CameraScriptableObject _cameraScriptableObject; QPointer _logDialog; QPointer _snapshotShareDialog; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index ceb4cb09a0..121833bd16 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -72,9 +72,9 @@ float Camera::getFarClip() const { : std::numeric_limits::max() - 1; } -void Camera::setMode(CameraMode m) { - _mode = m; - emit modeUpdated(m); +void Camera::setMode(CameraMode mode) { + _mode = mode; + emit modeUpdated(modeToString(mode)); } @@ -94,57 +94,45 @@ void Camera::setFarClip(float f) { _farClip = f; } -CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : - _camera(camera), _viewFrustum(viewFrustum) -{ - connect(_camera, &Camera::modeUpdated, this, &CameraScriptableObject::onModeUpdated); -} - -PickRay CameraScriptableObject::computePickRay(float x, float y) { +PickRay Camera::computePickRay(float x, float y) { float screenWidth = Application::getInstance()->getGLWidget()->width(); float screenHeight = Application::getInstance()->getGLWidget()->height(); PickRay result; if (OculusManager::isConnected()) { - result.origin = _camera->getPosition(); + result.origin = getPosition(); Application::getInstance()->getApplicationOverlay().computeOculusPickRay(x / screenWidth, y / screenHeight, result.direction); } else { - _viewFrustum->computePickRay(x / screenWidth, y / screenHeight, result.origin, result.direction); + Application::getInstance()->getViewFrustum()->computePickRay(x / screenWidth, y / screenHeight, + result.origin, result.direction); } return result; } -QString CameraScriptableObject::getMode() const { - return modeToString(_camera->getMode()); -} - -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); +void Camera::setModeString(const QString& mode) { + CameraMode targetMode = stringToMode(mode); + + switch (targetMode) { + case CAMERA_MODE_THIRD_PERSON: + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + break; + case CAMERA_MODE_MIRROR: + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + break; + case CAMERA_MODE_INDEPENDENT: + Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false); + break; + default: + break; } - if (currentMode != targetMode) { - _camera->setMode(targetMode); + + if (_mode != targetMode) { + setMode(targetMode); } } -void CameraScriptableObject::onModeUpdated(CameraMode m) { - emit modeUpdated(modeToString(m)); +QString Camera::getModeString() const { + return modeToString(_mode); } - - - diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 3dd3f8a840..769797c3f0 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -39,7 +39,6 @@ public: void update( float deltaTime ); - void setPosition(const glm::vec3& p) { _position = p; } void setRotation(const glm::quat& rotation) { _rotation = rotation; }; void setHmdPosition(const glm::vec3& hmdPosition) { _hmdPosition = hmdPosition; } void setHmdRotation(const glm::quat& hmdRotation) { _hmdRotation = hmdRotation; }; @@ -68,12 +67,20 @@ public: const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; } const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } float getScale() const { return _scale; } - -signals: - void modeUpdated(CameraMode newMode); - -private: +public slots: + QString getModeString() const; + void setModeString(const QString& mode); + void setPosition(const glm::vec3& position) { _position = position; } + + void setOrientation(const glm::quat& orientation) { setRotation(orientation); } + glm::quat getOrientation() const { return getRotation(); } + + PickRay computePickRay(float x, float y); +signals: + void modeUpdated(const QString& newMode); + +private: CameraMode _mode; glm::vec3 _position; float _fieldOfView; // degrees @@ -90,32 +97,4 @@ private: float _scale; }; - -class CameraScriptableObject : public QObject { - Q_OBJECT -public: - CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum); - -public slots: - QString getMode() const; - void setMode(const QString& mode); - void setPosition(const glm::vec3& value) { _camera->setPosition(value);} - - glm::vec3 getPosition() const { return _camera->getPosition(); } - - void setOrientation(const glm::quat& value) { _camera->setRotation(value); } - glm::quat getOrientation() const { return _camera->getRotation(); } - - PickRay computePickRay(float x, float y); - -signals: - void modeUpdated(const QString& newMode); - -private slots: - void onModeUpdated(CameraMode m); - -private: - Camera* _camera; - ViewFrustum* _viewFrustum; -}; #endif // hifi_Camera_h From 81ef722ef80ed3993c36a0d681cca072f362e53f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:35:41 -0800 Subject: [PATCH 05/10] update camera calls in JS to use new mode methods --- examples/cameraExample.js | 2 +- examples/concertCamera.js | 2 +- examples/concertCamera_kyrs.js | 8 ++++---- examples/headMove.js | 6 +++--- examples/inspect.js | 6 +++--- examples/lookAtExample.js | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/cameraExample.js b/examples/cameraExample.js index 332cc0fbca..bf91c46699 100644 --- a/examples/cameraExample.js +++ b/examples/cameraExample.js @@ -23,7 +23,7 @@ var THRUST_CONTROLLER = 0; var VIEW_CONTROLLER = 1; function checkCamera(deltaTime) { - if (Camera.getMode() == "independent") { + if (Camera.getModeString() == "independent") { var THRUST_MAG_UP = 800.0; var THRUST_MAG_DOWN = 300.0; var THRUST_MAG_FWD = 500.0; diff --git a/examples/concertCamera.js b/examples/concertCamera.js index 03908d0b57..1e6aa1e414 100644 --- a/examples/concertCamera.js +++ b/examples/concertCamera.js @@ -20,7 +20,7 @@ var cameraLocations = [ {x: 7971.9, y: 241.3, z: 7304.1}, {x: 7973.0, y: 241.3, var cameraLookAts = [ {x: 7971.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7971.3, y: 241.3, z: 7304.2} ]; function saveCameraState() { - oldMode = Camera.getMode(); + oldMode = Camera.getModeString(); avatarPosition = MyAvatar.position; Camera.setModeShiftPeriod(0.0); Camera.setMode("independent"); diff --git a/examples/concertCamera_kyrs.js b/examples/concertCamera_kyrs.js index 2b37a84f9e..8d3a07934e 100644 --- a/examples/concertCamera_kyrs.js +++ b/examples/concertCamera_kyrs.js @@ -20,15 +20,15 @@ var cameraLocations = [ {x: 2921.5, y: 251.3, z: 8254.8}, {x: 2921.5, y: 251.3, var cameraLookAts = [ {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.4 , y: 251.3, z: 8255.1} ]; function saveCameraState() { - oldMode = Camera.getMode(); + oldMode = Camera.getModeString(); avatarPosition = MyAvatar.position; Camera.setModeShiftPeriod(0.0); - Camera.setMode("independent"); + Camera.setModeString("independent"); } function restoreCameraState() { Camera.stopLooking(); - Camera.setMode(oldMode); + Camera.setModeString(oldMode); } function update(deltaTime) { @@ -52,7 +52,7 @@ function keyPressEvent(event) { saveCameraState(); freeCamera = true; } - Camera.setMode("independent"); + Camera.setModeString("independent"); Camera.setPosition(cameraLocations[choice - 1]); Camera.keepLookingAt(cameraLookAts[choice - 1]); } diff --git a/examples/headMove.js b/examples/headMove.js index 2c49847864..0ace39e853 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -53,12 +53,12 @@ var lastYawTurned = 0.0; var startPullbackPosition; function saveCameraState() { - oldMode = Camera.getMode(); - Camera.setMode("independent"); + oldMode = Camera.getModeString(); + Camera.setModeString("independent"); } function restoreCameraState() { - Camera.setMode(oldMode); + Camera.setModeString(oldMode); } function activateWarp() { diff --git a/examples/inspect.js b/examples/inspect.js index 81beea7ee9..5742f84765 100644 --- a/examples/inspect.js +++ b/examples/inspect.js @@ -118,14 +118,14 @@ function handlePanMode(dx, dy) { } function saveCameraState() { - oldMode = Camera.getMode(); + oldMode = Camera.getModeString(); var oldPosition = Camera.getPosition(); - Camera.setMode("independent"); + Camera.setModeString("independent"); Camera.setPosition(oldPosition); } function restoreCameraState() { - Camera.setMode(oldMode); + Camera.setModeString(oldMode); } function handleModes() { diff --git a/examples/lookAtExample.js b/examples/lookAtExample.js index 1cf8aabb96..281ba59066 100644 --- a/examples/lookAtExample.js +++ b/examples/lookAtExample.js @@ -17,13 +17,13 @@ // var lookingAtSomething = false; -var oldMode = Camera.getMode(); +var oldMode = Camera.getModeString(); function cancelLookAt() { if (lookingAtSomething) { lookingAtSomething = false; Camera.stopLooking(); - Camera.setMode(oldMode); + Camera.setModeString(oldMode); releaseMovementKeys(); } } @@ -65,13 +65,13 @@ function mousePressEvent(event) { if (intersection.intersects) { // remember the old mode we were in - oldMode = Camera.getMode(); + oldMode = Camera.getModeString(); print("looking at intersection point: " + intersection.intersection.x + ", " + intersection.intersection.y + ", " + intersection.intersection.z); // switch to independent mode - Camera.setMode("independent"); + Camera.setModeString("independent"); // tell the camera to fix it's look at on the point we clicked Camera.keepLookingAt(intersection.intersection); From fe0d593ac480bc8454dcd3a2684464e2fc7c2162 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:41:13 -0800 Subject: [PATCH 06/10] expose camera mode as property and leverage in scripts --- examples/concertCamera_kyrs.js | 8 ++++---- examples/headMove.js | 6 +++--- examples/inspect.js | 6 +++--- examples/lookAtExample.js | 8 ++++---- interface/src/Camera.h | 4 ++++ 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/examples/concertCamera_kyrs.js b/examples/concertCamera_kyrs.js index 8d3a07934e..4c7c893783 100644 --- a/examples/concertCamera_kyrs.js +++ b/examples/concertCamera_kyrs.js @@ -20,15 +20,15 @@ var cameraLocations = [ {x: 2921.5, y: 251.3, z: 8254.8}, {x: 2921.5, y: 251.3, var cameraLookAts = [ {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.4 , y: 251.3, z: 8255.1} ]; function saveCameraState() { - oldMode = Camera.getModeString(); + oldMode = Camera.mode; avatarPosition = MyAvatar.position; Camera.setModeShiftPeriod(0.0); - Camera.setModeString("independent"); + Camera.mode = "independent"; } function restoreCameraState() { Camera.stopLooking(); - Camera.setModeString(oldMode); + Camera.mode = oldMode; } function update(deltaTime) { @@ -52,7 +52,7 @@ function keyPressEvent(event) { saveCameraState(); freeCamera = true; } - Camera.setModeString("independent"); + Camera.mode = "independent"; Camera.setPosition(cameraLocations[choice - 1]); Camera.keepLookingAt(cameraLookAts[choice - 1]); } diff --git a/examples/headMove.js b/examples/headMove.js index 0ace39e853..b1f1c4ab7d 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -53,12 +53,12 @@ var lastYawTurned = 0.0; var startPullbackPosition; function saveCameraState() { - oldMode = Camera.getModeString(); - Camera.setModeString("independent"); + oldMode = Camera.mode; + Camera.mode = "independent"; } function restoreCameraState() { - Camera.setModeString(oldMode); + Camera.mode = oldMode; } function activateWarp() { diff --git a/examples/inspect.js b/examples/inspect.js index 5742f84765..49ebc86de1 100644 --- a/examples/inspect.js +++ b/examples/inspect.js @@ -118,14 +118,14 @@ function handlePanMode(dx, dy) { } function saveCameraState() { - oldMode = Camera.getModeString(); + oldMode = Camera.mode; var oldPosition = Camera.getPosition(); - Camera.setModeString("independent"); + Camera.mode = "independent"; Camera.setPosition(oldPosition); } function restoreCameraState() { - Camera.setModeString(oldMode); + Camera.mode = oldMode; } function handleModes() { diff --git a/examples/lookAtExample.js b/examples/lookAtExample.js index 281ba59066..729281fa03 100644 --- a/examples/lookAtExample.js +++ b/examples/lookAtExample.js @@ -17,13 +17,13 @@ // var lookingAtSomething = false; -var oldMode = Camera.getModeString(); +var oldMode = Camera.mode; function cancelLookAt() { if (lookingAtSomething) { lookingAtSomething = false; Camera.stopLooking(); - Camera.setModeString(oldMode); + Camera.mode = oldMode; releaseMovementKeys(); } } @@ -65,13 +65,13 @@ function mousePressEvent(event) { if (intersection.intersects) { // remember the old mode we were in - oldMode = Camera.getModeString(); + oldMode = Camera.mode; print("looking at intersection point: " + intersection.intersection.x + ", " + intersection.intersection.y + ", " + intersection.intersection.z); // switch to independent mode - Camera.setModeString("independent"); + Camera.mode = "independent"; // tell the camera to fix it's look at on the point we clicked Camera.keepLookingAt(intersection.intersection); diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 769797c3f0..e1f14a0a77 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -32,6 +32,10 @@ static int cameraModeId = qRegisterMetaType(); class Camera : public QObject { Q_OBJECT + + Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) + Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation) + Q_PROPERTY(QString mode READ getModeString WRITE setModeString) public: Camera(); From 303e8f6da95f83ef23a4371f8feabc4c8927951a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:41:36 -0800 Subject: [PATCH 07/10] more js changes for changes to camera interface --- examples/cameraExample.js | 10 +++++----- examples/concertCamera.js | 8 ++++---- examples/concertCamera_kims.js | 8 ++++---- examples/libraries/entityCameraTool.js | 12 ++++++------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/cameraExample.js b/examples/cameraExample.js index bf91c46699..4c02ce2f2e 100644 --- a/examples/cameraExample.js +++ b/examples/cameraExample.js @@ -23,7 +23,7 @@ var THRUST_CONTROLLER = 0; var VIEW_CONTROLLER = 1; function checkCamera(deltaTime) { - if (Camera.getModeString() == "independent") { + if (Camera.mode == "independent") { var THRUST_MAG_UP = 800.0; var THRUST_MAG_DOWN = 300.0; var THRUST_MAG_FWD = 500.0; @@ -102,19 +102,19 @@ function keyPressEvent(event) { } if (event.text == "1") { - Camera.setMode("first person"); + Camera.mode = "first person"; } if (event.text == "2") { - Camera.setMode("mirror"); + Camera.mode = "mirror"; } if (event.text == "3") { - Camera.setMode("third person"); + Camera.mode = "third person"; } if (event.text == "4") { - Camera.setMode("independent"); + Camera.mode = "independent"; joysticksCaptured = true; Controller.captureJoystick(THRUST_CONTROLLER); Controller.captureJoystick(VIEW_CONTROLLER); diff --git a/examples/concertCamera.js b/examples/concertCamera.js index 1e6aa1e414..7ab7785345 100644 --- a/examples/concertCamera.js +++ b/examples/concertCamera.js @@ -20,15 +20,15 @@ var cameraLocations = [ {x: 7971.9, y: 241.3, z: 7304.1}, {x: 7973.0, y: 241.3, var cameraLookAts = [ {x: 7971.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7971.3, y: 241.3, z: 7304.2} ]; function saveCameraState() { - oldMode = Camera.getModeString(); + oldMode = Camera.mode; avatarPosition = MyAvatar.position; Camera.setModeShiftPeriod(0.0); - Camera.setMode("independent"); + Camera.mode = "independent"; } function restoreCameraState() { Camera.stopLooking(); - Camera.setMode(oldMode); + Camera.mode = oldMode; } function update(deltaTime) { @@ -52,7 +52,7 @@ function keyPressEvent(event) { saveCameraState(); freeCamera = true; } - Camera.setMode("independent"); + Camera.mode = "independent"; Camera.setPosition(cameraLocations[choice - 1]); Camera.keepLookingAt(cameraLookAts[choice - 1]); } diff --git a/examples/concertCamera_kims.js b/examples/concertCamera_kims.js index 3017d3c008..ff4fb632de 100644 --- a/examples/concertCamera_kims.js +++ b/examples/concertCamera_kims.js @@ -20,15 +20,15 @@ var cameraLocations = [ {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5, var cameraLookAts = [ {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0} ]; function saveCameraState() { - oldMode = Camera.getMode(); + oldMode = Camera.mode; avatarPosition = MyAvatar.position; Camera.setModeShiftPeriod(0.0); - Camera.setMode("independent"); + Camera.mode = "independent"; } function restoreCameraState() { Camera.stopLooking(); - Camera.setMode(oldMode); + Camera.mode = oldMode; } function update(deltaTime) { @@ -52,7 +52,7 @@ function keyPressEvent(event) { saveCameraState(); freeCamera = true; } - Camera.setMode("independent"); + Camera.mode = "independent"; Camera.setPosition(cameraLocations[choice - 1]); Camera.keepLookingAt(cameraLookAts[choice - 1]); } diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 2f03cb28c8..8fed42eeee 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -88,8 +88,8 @@ CameraManager = function() { that.focalPoint = focalPoint; that.setFocalPoint(focalPoint); - that.previousCameraMode = Camera.getMode(); - Camera.setMode("independent"); + that.previousCameraMode = Camera.mode; + Camera.mode = "independent"; that.updateCamera(); @@ -102,7 +102,7 @@ CameraManager = function() { that.mode = MODE_INACTIVE; if (!ignoreCamera) { - Camera.setMode(that.previousCameraMode); + Camera.mode = that.previousCameraMode; } cameraTool.setVisible(false); } @@ -271,7 +271,7 @@ CameraManager = function() { } that.updateCamera = function() { - if (!that.enabled || Camera.getMode() != "independent") return; + if (!that.enabled || Camera.mode != "independent") return; var yRot = Quat.angleAxis(that.yaw, { x: 0, y: 1, z: 0 }); var xRot = Quat.angleAxis(that.pitch, { x: 1, y: 0, z: 0 }); @@ -300,7 +300,7 @@ CameraManager = function() { // Ease the position and orbit of the camera that.update = function(dt) { - if (Camera.getMode() != "independent") { + if (Camera.mode != "independent") { return; } @@ -350,7 +350,7 @@ CameraManager = function() { Controller.keyReleaseEvent.connect(function (event) { if (event.text == "ESC" && that.enabled) { - Camera.setMode(lastAvatarCameraMode); + Camera.mode = lastAvatarCameraMode; cameraManager.disable(true); } }); From 8452182b45f914a2a69f07fd103150097b00832b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:43:09 -0800 Subject: [PATCH 08/10] replace position and orientation calls in lobby --- examples/lobby.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index f255af63ef..474ee515e3 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -41,17 +41,17 @@ var HELMET_ATTACHMENT_URL = "https://hifi-public.s3.amazonaws.com/models/attachm function reticlePosition() { var RETICLE_DISTANCE = 1; - return Vec3.sum(Camera.getPosition(), Vec3.multiply(Quat.getFront(Camera.getOrientation()), RETICLE_DISTANCE)); + return Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), RETICLE_DISTANCE)); } function drawLobby() { if (!panelWall) { print("Adding overlays for the lobby panel wall and orb shell."); - var cameraEuler = Quat.safeEulerAngles(Camera.getOrientation()); + var cameraEuler = Quat.safeEulerAngles(Camera.orientation); var towardsMe = Quat.angleAxis(cameraEuler.y + 180, { x: 0, y: 1, z: 0}); - var orbPosition = Vec3.sum(Camera.getPosition(), Vec3.multiplyQbyV(towardsMe, ORB_SHIFT)); + var orbPosition = Vec3.sum(Camera.position, Vec3.multiplyQbyV(towardsMe, ORB_SHIFT)); var panelWallProps = { url: HIFI_PUBLIC_BUCKET + "models/sets/Lobby/LobbyPrototype/Lobby5_PanelsWithFrames.fbx", From f53455ee5563a9d001805660daf30fa8c6ad96c0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 11:40:47 -0800 Subject: [PATCH 09/10] use a ray from the near clip for action ray --- examples/lobby.js | 4 +++- interface/src/Application.cpp | 4 ++-- interface/src/Camera.h | 2 -- interface/src/scripting/JoystickScriptingInterface.cpp | 3 ++- libraries/octree/src/ViewFrustum.cpp | 7 +++++++ libraries/octree/src/ViewFrustum.h | 3 +++ 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 474ee515e3..7aa2039683 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -81,7 +81,8 @@ function drawLobby() { size: RETICLE_SPHERE_SIZE, color: { red: 0, green: 255, blue: 0 }, alpha: 1.0, - solid: true + solid: true, + ignoreRayIntersection: true }); // add an attachment on this avatar so other people see them in the lobby @@ -128,6 +129,7 @@ function cleanupLobby() { function actionStartEvent(event) { if (panelWall) { + // we've got an action event and our panel wall is up // check if we hit a panel and if we should jump there var result = Overlays.findRayIntersection(event.actionRay); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2438db18f8..1209774806 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1117,7 +1117,7 @@ void Application::keyPressEvent(QKeyEvent* event) { if (!event->isAutoRepeat()) { // this starts an HFActionEvent HFActionEvent startActionEvent(HFActionEvent::startType(), - Application::getInstance()->getCamera()->getPickRay()); + _viewFrustum.computePickRay(0.5f, 0.5f)); sendEvent(this, &startActionEvent); } @@ -1208,7 +1208,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { case Qt::Key_Space: { if (!event->isAutoRepeat()) { // this ends the HFActionEvent - HFActionEvent endActionEvent(HFActionEvent::endType(), Application::getInstance()->getCamera()->getPickRay()); + HFActionEvent endActionEvent(HFActionEvent::endType(), _viewFrustum.computePickRay(0.5f, 0.5f)); sendEvent(this, &endActionEvent); } diff --git a/interface/src/Camera.h b/interface/src/Camera.h index e1f14a0a77..bc7a3c5687 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -56,8 +56,6 @@ public: void setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; } void setScale(const float s) { _scale = s; } - PickRay getPickRay() const { return PickRay(getPosition(), getRotation() * IDENTITY_FRONT); } - glm::vec3 getPosition() const { return _position + _hmdPosition; } glm::quat getRotation() const { return _rotation * _hmdRotation; } const glm::vec3& getHmdPosition() const { return _hmdPosition; } diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/scripting/JoystickScriptingInterface.cpp index 7fc4e48843..68affeda5b 100644 --- a/interface/src/scripting/JoystickScriptingInterface.cpp +++ b/interface/src/scripting/JoystickScriptingInterface.cpp @@ -129,7 +129,8 @@ void JoystickScriptingInterface::update() { : HFActionEvent::endType(); // global action events fire in the center of the screen - HFActionEvent actionEvent(actionType, Application::getInstance()->getCamera()->getPickRay()); + HFActionEvent actionEvent(actionType, + Application::getInstance()->getViewFrustum()->computePickRay(0.5f, 0.5f)); qApp->sendEvent(qApp, &actionEvent); } diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index c1348e28c7..0549c60134 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -583,6 +583,13 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const return result; } +PickRay ViewFrustum::computePickRay(float x, float y) { + glm::vec3 pickRayOrigin; + glm::vec3 pickRayDirection; + computePickRay(x, y, pickRayOrigin, pickRayDirection); + return PickRay(pickRayOrigin, pickRayDirection); +} + 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)); diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index f1894c7cab..1fd306617b 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -17,6 +17,8 @@ #include #include +#include + #include "AABox.h" #include "AACube.h" #include "Plane.h" @@ -105,6 +107,7 @@ public: bool isVerySimilar(const ViewFrustum& compareTo, bool debug = false) const; bool isVerySimilar(const ViewFrustum* compareTo, bool debug = false) const { return isVerySimilar(*compareTo, debug); } + PickRay computePickRay(float x, float y); void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const; void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearValue, float& farValue, From b968f051230928ad95ddb0d3410d1d046ce262bb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 11:54:14 -0800 Subject: [PATCH 10/10] use a new cursor for selection in lobby --- examples/lobby.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 7aa2039683..63ea1654a9 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -74,15 +74,15 @@ function drawLobby() { orbShell = Overlays.addOverlay("model", orbShellProps); // for HMD wearers, create a reticle in center of screen - var RETICLE_SPHERE_SIZE = 0.025; + var CURSOR_SCALE = 0.025; - reticle = Overlays.addOverlay("sphere", { + reticle = Overlays.addOverlay("billboard", { + url: HIFI_PUBLIC_BUCKET + "images/cursor.svg", position: reticlePosition(), - size: RETICLE_SPHERE_SIZE, - color: { red: 0, green: 255, blue: 0 }, + ignoreRayIntersection: true, + isFacingAvatar: true, alpha: 1.0, - solid: true, - ignoreRayIntersection: true + scale: CURSOR_SCALE }); // add an attachment on this avatar so other people see them in the lobby