From c64a530be4e3d33dc163866c4b9f1341650c8e12 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 9 Feb 2014 16:24:38 -0800 Subject: [PATCH 1/5] first cut at lookAt --- interface/src/Camera.cpp | 16 +++++++++++++++- interface/src/Camera.h | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 87725967b9..6dd327a3c3 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -58,7 +58,9 @@ Camera::Camera() : _modeShift(1.0f), _linearModeShift(0.0f), _modeShiftRate(1.0f), - _scale(1.0f) + _scale(1.0f), + _lookingAt(0.0f, 0.0f, 0.0f), + _isKeepLookingAt(false) { } @@ -222,6 +224,18 @@ void Camera::setFrustumWasReshaped() { _frustumNeedsReshape = false; } +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 + setTargetRotation(rotation); +} + +void Camera::keepLookingAt(const glm::vec3& value) { + lookAt(value); + _isKeepLookingAt = true; +} CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : _camera(camera), _viewFrustum(viewFrustum) diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 075f1a7ed6..5f34dbfe6c 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -68,6 +69,17 @@ public: bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped void setFrustumWasReshaped(); // call this after reshaping the view frustum. + + // 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 stopKeepLookingAt() { _isKeepLookingAt = false; } private: @@ -99,6 +111,9 @@ private: float _linearModeShift; float _modeShiftRate; float _scale; + + glm::vec3 _lookingAt; + bool _isKeepLookingAt; void updateFollowMode(float deltaTime); }; @@ -119,6 +134,17 @@ public slots: void setOrientation(const glm::quat& value) { _camera->setTargetRotation(value); } glm::quat getOrientation() const { return _camera->getRotation(); } + // These only work on independent cameras + /// one time change to what the camera is looking at + void lookAt(const glm::vec3& value) { _camera->lookAt(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) { _camera->keepLookingAt(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 stopKeepLookingAt() { _camera->stopKeepLookingAt();} + PickRay computePickRay(float x, float y); private: From a457ccf933a0b84a7da5c0c5e66219c2a1caca97 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 9 Feb 2014 16:25:18 -0800 Subject: [PATCH 2/5] simple example of Camera.lookAt() --- examples/lookAtExample.js | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 examples/lookAtExample.js diff --git a/examples/lookAtExample.js b/examples/lookAtExample.js new file mode 100644 index 0000000000..bfc2525284 --- /dev/null +++ b/examples/lookAtExample.js @@ -0,0 +1,49 @@ +// +// lookAtExample.js +// hifi +// +// Created by Brad Hefta-Gaub on 2/6/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script that demonstrates use of the Camera class +// +// + +var oldMode = Camera.getMode(); +function mousePressEvent(event) { + print("mousePressEvent event.x,y=" + event.x + ", " + event.y); + var pickRay = Camera.computePickRay(event.x, event.y); + print("called Camera.computePickRay()"); + print("computePickRay origin=" + pickRay.origin.x + ", " + pickRay.origin.y + ", " + pickRay.origin.z); + print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z); + var pickRay = Camera.computePickRay(event.x, event.y); + var intersection = Voxels.findRayIntersection(pickRay); + if (intersection.intersects) { + print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", " + + intersection.voxel.green + ", " + intersection.voxel.blue); + print("intersection voxel.x/y/z/s=" + intersection.voxel.x + ", " + + intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s); + print("intersection face=" + intersection.face); + print("intersection distance=" + intersection.distance); + print("intersection intersection.x/y/z=" + intersection.intersection.x + ", " + + intersection.intersection.y + ", " + intersection.intersection.z); + + print("looking at intersection point"); + oldMode = Camera.getMode(); + Camera.setMode("independent"); + //Camera.lookAt({x:0, y:0, z:0} ); + Camera.lookAt(intersection.intersection); + } +} + +function mouseReleaseEvent(event) { + Camera.setMode(oldMode); +} + +Controller.mousePressEvent.connect(mousePressEvent); +Controller.mouseReleaseEvent.connect(mouseReleaseEvent); + +function scriptEnding() { +} +Script.scriptEnding.connect(scriptEnding); + From d5447452aeda6c8517e9180e7f440993b116aeac Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 9 Feb 2014 21:06:32 -0800 Subject: [PATCH 3/5] more work on lookAt behavior --- examples/lookAtExample.js | 127 ++++++++++++++++++++++++++++++-------- interface/src/Camera.cpp | 23 +++++-- interface/src/Camera.h | 2 +- 3 files changed, 120 insertions(+), 32 deletions(-) diff --git a/examples/lookAtExample.js b/examples/lookAtExample.js index bfc2525284..5d93cd2e80 100644 --- a/examples/lookAtExample.js +++ b/examples/lookAtExample.js @@ -5,45 +5,118 @@ // Created by Brad Hefta-Gaub on 2/6/14. // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // -// This is an example script that demonstrates use of the Camera class +// This is an example script that demonstrates use of the Camera class's lookAt(), keepLookingAt(), and stopLookingAt() +// features. +// +// To use the script, click on a voxel, and the camera will switch into independent mode and fix it's lookAt on the point +// on the face of the voxel that you clicked. Click again and it will stop looking at that point. While in this fixed mode +// you can use the arrow keys to change the position of the camera. // // +var lookingAtSomething = false; var oldMode = Camera.getMode(); -function mousePressEvent(event) { - print("mousePressEvent event.x,y=" + event.x + ", " + event.y); - var pickRay = Camera.computePickRay(event.x, event.y); - print("called Camera.computePickRay()"); - print("computePickRay origin=" + pickRay.origin.x + ", " + pickRay.origin.y + ", " + pickRay.origin.z); - print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z); - var pickRay = Camera.computePickRay(event.x, event.y); - var intersection = Voxels.findRayIntersection(pickRay); - if (intersection.intersects) { - print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", " - + intersection.voxel.green + ", " + intersection.voxel.blue); - print("intersection voxel.x/y/z/s=" + intersection.voxel.x + ", " - + intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s); - print("intersection face=" + intersection.face); - print("intersection distance=" + intersection.distance); - print("intersection intersection.x/y/z=" + intersection.intersection.x + ", " - + intersection.intersection.y + ", " + intersection.intersection.z); - - print("looking at intersection point"); - oldMode = Camera.getMode(); - Camera.setMode("independent"); - //Camera.lookAt({x:0, y:0, z:0} ); - Camera.lookAt(intersection.intersection); + +function cancelLookAt() { + if (lookingAtSomething) { + lookingAtSomething = false; + Camera.stopKeepLookingAt(); + Camera.setMode(oldMode); + releaseMovementKeys(); } } -function mouseReleaseEvent(event) { - Camera.setMode(oldMode); +function captureMovementKeys() { + Controller.captureKeyEvents({ text: "up" }); // Z- + Controller.captureKeyEvents({ text: "down" }); // Z+ + Controller.captureKeyEvents({ text: "UP" }); // Y+ + Controller.captureKeyEvents({ text: "DOWN" }); // Y- + Controller.captureKeyEvents({ text: "left" }); // X+ + Controller.captureKeyEvents({ text: "right" }); // X- } +function releaseMovementKeys() { + Controller.releaseKeyEvents({ text: "up" }); // Z- + Controller.releaseKeyEvents({ text: "down" }); // Z+ + Controller.releaseKeyEvents({ text: "UP" }); // Y+ + Controller.releaseKeyEvents({ text: "DOWN" }); // Y- + Controller.releaseKeyEvents({ text: "left" }); // X+ + Controller.releaseKeyEvents({ text: "right" }); // X- +} + +var cameraPosition = Camera.getPosition(); +function moveCamera() { + if (lookingAtSomething) { + Camera.setPosition(cameraPosition); + } +} + +Script.willSendVisualDataCallback.connect(moveCamera); + + +function mousePressEvent(event) { + if (lookingAtSomething) { + cancelLookAt(); + } else { + var pickRay = Camera.computePickRay(event.x, event.y); + var intersection = Voxels.findRayIntersection(pickRay); + if (intersection.intersects) { + + // remember the old mode we were in + oldMode = Camera.getMode(); + + print("looking at intersection point: " + intersection.intersection.x + ", " + + intersection.intersection.y + ", " + intersection.intersection.z); + + // switch to independent mode + Camera.setMode("independent"); + + // tell the camera to fix it's look at on the point we clicked + Camera.keepLookingAt(intersection.intersection); + + // keep track of the fact that we're in this looking at mode + lookingAtSomething = true; + + captureMovementKeys(); + cameraPosition = Camera.getPosition(); + } + } +} Controller.mousePressEvent.connect(mousePressEvent); -Controller.mouseReleaseEvent.connect(mouseReleaseEvent); + +function keyPressEvent(event) { + if (lookingAtSomething) { + + if (event.text == "ESC") { + cancelLookAt(); + } + + var MOVE_DELTA = 0.5; + + if (event.text == "UP" && !event.isShifted) { + cameraPosition.z -= MOVE_DELTA; + } + if (event.text == "DOWN" && !event.isShifted) { + cameraPosition.z += MOVE_DELTA; + } + if (event.text == "LEFT" && !event.isShifted) { + cameraPosition.x += MOVE_DELTA; + } + if (event.text == "RIGHT" && !event.isShifted) { + cameraPosition.x -= MOVE_DELTA; + } + if (event.text == "UP" && event.isShifted) { + cameraPosition.y += MOVE_DELTA; + } + if (event.text == "DOWN" && event.isShifted) { + cameraPosition.y -= MOVE_DELTA; + } + } +} +Controller.keyPressEvent.connect(keyPressEvent); function scriptEnding() { + cancelLookAt(); } Script.scriptEnding.connect(scriptEnding); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 6dd327a3c3..431aec5a83 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -96,8 +96,12 @@ void Camera::updateFollowMode(float deltaTime) { t = 1.0; } - // Update position and rotation, setting directly if tightness is 0.0 + // handle keepLookingAt + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } + // 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)); @@ -157,6 +161,15 @@ void Camera::setMode(CameraMode m) { } } +void Camera::setTargetPosition(const glm::vec3& t) { + _targetPosition = t; + + // handle keepLookingAt + if (_isKeepLookingAt) { + lookAt(_lookingAt); + } + +} void Camera::setTargetRotation( const glm::quat& targetRotation ) { _targetRotation = targetRotation; @@ -226,15 +239,17 @@ void Camera::setFrustumWasReshaped() { void Camera::lookAt(const glm::vec3& lookAt) { glm::vec3 up = IDENTITY_UP; - glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up); + glm::mat4 lookAtMatrix = glm::lookAt(_targetPosition, lookAt, up); glm::quat rotation = glm::quat_cast(lookAtMatrix); rotation.w = -rotation.w; // Rosedale approved setTargetRotation(rotation); } -void Camera::keepLookingAt(const glm::vec3& value) { - lookAt(value); +void Camera::keepLookingAt(const glm::vec3& point) { + qDebug() << "Camera::keepLookingAt()... point=" << point.x << ", "<< point.y << ", " << point.z; + lookAt(point); _isKeepLookingAt = true; + _lookingAt = point; } CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 5f34dbfe6c..3fd6edcccd 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -38,7 +38,7 @@ public: 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 setTargetPosition(const glm::vec3& t); void setTightness(float t) { _tightness = t; } void setTargetRotation(const glm::quat& rotation); From 221a5c75c79270e6bae2ac604981bea7789ceaa3 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 9 Feb 2014 23:22:10 -0800 Subject: [PATCH 4/5] remove debug --- interface/src/Camera.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 431aec5a83..694fd30f50 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -246,7 +246,6 @@ void Camera::lookAt(const glm::vec3& lookAt) { } void Camera::keepLookingAt(const glm::vec3& point) { - qDebug() << "Camera::keepLookingAt()... point=" << point.x << ", "<< point.y << ", " << point.z; lookAt(point); _isKeepLookingAt = true; _lookingAt = point; From bdf5c7a6b757ac2ed283fb406c6693fa85a26b85 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 9 Feb 2014 23:26:46 -0800 Subject: [PATCH 5/5] changed stopKeepLookingAt() to stopLooking() --- examples/lookAtExample.js | 2 +- interface/src/Camera.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/lookAtExample.js b/examples/lookAtExample.js index 5d93cd2e80..6340feda00 100644 --- a/examples/lookAtExample.js +++ b/examples/lookAtExample.js @@ -20,7 +20,7 @@ var oldMode = Camera.getMode(); function cancelLookAt() { if (lookingAtSomething) { lookingAtSomething = false; - Camera.stopKeepLookingAt(); + Camera.stopLooking(); Camera.setMode(oldMode); releaseMovementKeys(); } diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 3fd6edcccd..b4ba3dbe05 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -79,7 +79,7 @@ public: /// 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 stopKeepLookingAt() { _isKeepLookingAt = false; } + void stopLooking() { _isKeepLookingAt = false; } private: @@ -143,7 +143,7 @@ public slots: /// 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 stopKeepLookingAt() { _camera->stopKeepLookingAt();} + void stopLooking() { _camera->stopLooking();} PickRay computePickRay(float x, float y);