From 16f4cffbd3c2d9d187ccf2cfbad1b171a60c28a0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Oct 2014 12:19:26 -0700 Subject: [PATCH 01/34] Center HMD HUD and magnifiers on default eye position --- interface/src/ui/ApplicationOverlay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index d8d2213d8f..37bba98ecc 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -380,7 +380,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { glPushMatrix(); const glm::quat& orientation = myAvatar->getOrientation(); - const glm::vec3& position = myAvatar->getHead()->getEyePosition(); + const glm::vec3& position = myAvatar->getDefaultEyePosition(); glm::mat4 rotation = glm::toMat4(orientation); @@ -414,7 +414,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { renderTexturedHemisphere(); - renderPointersOculus(myAvatar->getHead()->getEyePosition()); + renderPointersOculus(myAvatar->getDefaultEyePosition()); glDepthMask(GL_TRUE); glBindTexture(GL_TEXTURE_2D, 0); @@ -1220,7 +1220,7 @@ void ApplicationOverlay::renderTexturedHemisphere() { Application* application = Application::getInstance(); MyAvatar* myAvatar = application->getAvatar(); const glm::quat& orientation = myAvatar->getOrientation(); - const glm::vec3& position = myAvatar->getHead()->getEyePosition(); + const glm::vec3& position = myAvatar->getDefaultEyePosition(); glm::mat4 rotation = glm::toMat4(orientation); From 170e328f5a496145afecba3ba0d0f0e50ac3c02a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Oct 2014 12:40:16 -0700 Subject: [PATCH 02/34] Fix similar problem for HMD third person view getUprightHeadPosition() changes with avatar lean. --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0752f9fa9e..1ec8078f53 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -620,8 +620,8 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { static const float THIRD_PERSON_CAMERA_DISTANCE = 1.5f; - _myCamera.setPosition(_myAvatar->getUprightHeadPosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale()); + _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale()); if (OculusManager::isConnected()) { _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } else { From 8e58e6e3b00321a59ce2ecd56830d63f1aff9e1d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Oct 2014 12:48:30 -0700 Subject: [PATCH 03/34] Remove unused methods --- interface/src/avatar/Avatar.cpp | 4 ---- interface/src/avatar/Avatar.h | 1 - interface/src/avatar/MyAvatar.cpp | 4 ---- interface/src/avatar/MyAvatar.h | 1 - 4 files changed, 10 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 59c8c90d1c..e29f68e585 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -1057,10 +1057,6 @@ float Avatar::getPelvisFloatingHeight() const { return -_skeletonModel.getBindExtents().minimum.y; } -float Avatar::getPelvisToHeadLength() const { - return glm::distance(_position, getHead()->getPosition()); -} - void Avatar::setShowDisplayName(bool showDisplayName) { if (!Menu::getInstance()->isOptionChecked(MenuOption::NamesAboveHeads)) { _displayNameAlpha = 0.0f; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 29fb4cf241..376e229d0c 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -230,7 +230,6 @@ protected: float getSkeletonHeight() const; float getHeadHeight() const; float getPelvisFloatingHeight() const; - float getPelvisToHeadLength() const; glm::vec3 getDisplayNamePosition(); void renderDisplayName(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 623631d5e5..2f7a123e4b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1004,10 +1004,6 @@ bool MyAvatar::isLookingAtLeftEye() { return _isLookingAtLeftEye; } -glm::vec3 MyAvatar::getUprightHeadPosition() const { - return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, getPelvisToHeadLength(), 0.0f); -} - glm::vec3 MyAvatar::getDefaultEyePosition() const { return _position + getWorldAlignedOrientation() * _skeletonModel.getDefaultEyeModelPosition(); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index aa3d569e2f..326e0e2665 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -66,7 +66,6 @@ public: const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } glm::vec3 getGravity() const { return _gravity; } - glm::vec3 getUprightHeadPosition() const; glm::vec3 getDefaultEyePosition() const; bool getShouldRenderLocally() const { return _shouldRender; } From 02f9bb489f47e54e15c8d76e63aaf553a2492b0c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Oct 2014 12:49:21 -0700 Subject: [PATCH 04/34] Fix some build warnings while in the vicinity --- interface/src/avatar/MyAvatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2f7a123e4b..79ab9eda81 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -416,7 +416,7 @@ void MyAvatar::renderDebugBodyPoints() { glPushMatrix(); glColor4f(0, 1, 0, .5f); glTranslatef(position.x, position.y, position.z); - Application::getInstance()->getGeometryCache()->renderSphere(0.2, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.2f, 10.0f, 10.0f); glPopMatrix(); // Head Sphere @@ -424,7 +424,7 @@ void MyAvatar::renderDebugBodyPoints() { glPushMatrix(); glColor4f(0, 1, 0, .5f); glTranslatef(position.x, position.y, position.z); - Application::getInstance()->getGeometryCache()->renderSphere(0.15, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.15f, 10.0f, 10.0f); glPopMatrix(); } From a9040c1a53170b580dccb6f3aedc84eb811a6582 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Oct 2014 15:15:44 -0700 Subject: [PATCH 05/34] Minor adjustment to Oculus pick ray calc --- interface/src/ui/ApplicationOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 37bba98ecc..4d2c710be7 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -183,7 +183,7 @@ void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& direc float dist = sqrt(x * x + y * y); float z = -sqrt(1.0f - dist * dist); - glm::vec3 relativePosition = myAvatar->getHead()->getEyePosition() + + glm::vec3 relativePosition = myAvatar->getDefaultEyePosition() + glm::normalize(myAvatar->getOrientation() * glm::vec3(x, y, z)); //Rotate the UI pick ray by the avatar orientation From af74fc09b946a8c449fcb1a53b9ba9884813d96b Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 1 Nov 2014 02:42:22 +0100 Subject: [PATCH 06/34] Adds AudioDevice mute functionality to ScriptEngine --- examples/audioMuteExample.js | 50 +++++++++++++++++++ interface/src/Application.cpp | 3 ++ .../AudioDeviceScriptingInterface.cpp | 8 +++ .../scripting/AudioDeviceScriptingInterface.h | 6 +++ 4 files changed, 67 insertions(+) create mode 100644 examples/audioMuteExample.js diff --git a/examples/audioMuteExample.js b/examples/audioMuteExample.js new file mode 100644 index 0000000000..efdd39e5aa --- /dev/null +++ b/examples/audioMuteExample.js @@ -0,0 +1,50 @@ +// +// audioMuteExample.js +// examples +// +// Created by Thijs Wenker on 10/31/14. +// Copyright 2014 High Fidelity, Inc. +// +// This example shows how to use the AudioDevice mute functions. +// Press the MUTE/UNMUTE button to see it function. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var toggleMuteButton = Overlays.addOverlay("text", { + x: 50, + y: 50, + width: 190, + height: 50, + backgroundColor: { red: 255, green: 255, blue: 255}, + color: { red: 255, green: 0, blue: 0}, + font: {size: 30}, + topMargin: 10 +}); + +function muteButtonText() { + print("Audio Muted: " + AudioDevice.getMuted()); +} + +function onMuteStateChanged() { + Overlays.editOverlay(toggleMuteButton, + AudioDevice.getMuted() ? {text: "UNMUTE", leftMargin: 10} : {text: "MUTE", leftMargin: 38}); + print("Audio Muted: " + AudioDevice.getMuted()); +} + +function mousePressEvent(event) { + if (Overlays.getOverlayAtPoint({x: event.x, y: event.y}) == toggleMuteButton) { + AudioDevice.toggleMute() + } +} + +function scriptEnding() { + Overlays.deleteOverlay(toggleMuteButton); +} + +onMuteStateChanged(); + +AudioDevice.muteToggled.connect(onMuteStateChanged); +Controller.mousePressEvent.connect(mousePressEvent); +Script.scriptEnding.connect(scriptEnding); \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0752f9fa9e..1a293628b7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1966,6 +1966,9 @@ void Application::init() { connect(getAudio(), &Audio::preProcessOriginalInboundAudio, &_audioReflector, &AudioReflector::preProcessOriginalInboundAudio,Qt::DirectConnection); + connect(getAudio(), &Audio::muteToggled, AudioDeviceScriptingInterface::getInstance(), + &AudioDeviceScriptingInterface::muteToggled, Qt::DirectConnection); + // save settings when avatar changes connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings); } diff --git a/interface/src/scripting/AudioDeviceScriptingInterface.cpp b/interface/src/scripting/AudioDeviceScriptingInterface.cpp index bcb5fc308d..e3826a24ea 100644 --- a/interface/src/scripting/AudioDeviceScriptingInterface.cpp +++ b/interface/src/scripting/AudioDeviceScriptingInterface.cpp @@ -78,3 +78,11 @@ void AudioDeviceScriptingInterface::setReverb(bool reverb) { void AudioDeviceScriptingInterface::setReverbOptions(const AudioEffectOptions* options) { Application::getInstance()->getAudio()->setReverbOptions(options); } + +void AudioDeviceScriptingInterface::toggleMute() { + Application::getInstance()->getAudio()->toggleMute(); +} + +bool AudioDeviceScriptingInterface::getMuted() { + return Application::getInstance()->getAudio()->getMuted(); +} diff --git a/interface/src/scripting/AudioDeviceScriptingInterface.h b/interface/src/scripting/AudioDeviceScriptingInterface.h index 45bdbc92e2..b7febaea07 100644 --- a/interface/src/scripting/AudioDeviceScriptingInterface.h +++ b/interface/src/scripting/AudioDeviceScriptingInterface.h @@ -41,6 +41,12 @@ public slots: void setInputVolume(float volume); void setReverb(bool reverb); void setReverbOptions(const AudioEffectOptions* options); + + bool getMuted(); + void toggleMute(); + +signals: + void muteToggled(); }; #endif // hifi_AudioDeviceScriptingInterface_h From 4475bb89d554cdaeced2d8534c50bf527aa625fa Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 3 Nov 2014 12:13:08 -0800 Subject: [PATCH 07/34] Fix for 3DTV mode with non-unity render scale. --- interface/src/devices/TV3DManager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index e8644c00d0..872f4ce7e6 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -91,8 +91,10 @@ void TV3DManager::display(Camera& whichCamera) { // left eye portal int portalX = 0; int portalY = 0; - int portalW = Application::getInstance()->getGLWidget()->getDeviceWidth() / 2; - int portalH = Application::getInstance()->getGLWidget()->getDeviceHeight(); + QSize deviceSize = Application::getInstance()->getGLWidget()->getDeviceSize() * + Application::getInstance()->getRenderResolutionScale(); + int portalW = deviceSize.width() / 2; + int portalH = deviceSize.height(); ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay(); @@ -135,7 +137,7 @@ void TV3DManager::display(Camera& whichCamera) { glDisable(GL_SCISSOR_TEST); // render right side view - portalX = Application::getInstance()->getGLWidget()->getDeviceWidth() / 2; + portalX = deviceSize.width() / 2; glEnable(GL_SCISSOR_TEST); // render left side view glViewport(portalX, portalY, portalW, portalH); @@ -165,8 +167,7 @@ void TV3DManager::display(Camera& whichCamera) { glDisable(GL_SCISSOR_TEST); // reset the viewport to how we started - glViewport(0, 0, Application::getInstance()->getGLWidget()->getDeviceWidth(), - Application::getInstance()->getGLWidget()->getDeviceHeight()); + glViewport(0, 0, deviceSize.width(), deviceSize.height()); Application::getInstance()->getGlowEffect()->render(); } From 96dd1eaf766c76cea4e85ac8734fbaa993b556c6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 3 Nov 2014 16:57:10 -0800 Subject: [PATCH 08/34] report restricted access state from domain-server in heartbeat --- domain-server/src/DomainServer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 131aa3fbe3..a2198370ce 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1109,6 +1109,14 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { domainObject[AUTOMATIC_NETWORKING_KEY] = _automaticNetworkingSetting; + // add a flag to indicate if this domain uses restricted access - for now that will exclude it from listings + const QString RESTRICTED_ACCESS_FLAG = "restricted"; + + const QVariant* allowedUsersVariant = valueForKeyPath(_settingsManager.getSettingsMap(), + ALLOWED_USERS_SETTINGS_KEYPATH); + QStringList allowedUsers = allowedUsersVariant ? allowedUsersVariant->toStringList() : QStringList(); + domainObject[RESTRICTED_ACCESS_FLAG] = (allowedUsers.size() > 0); + // add the number of currently connected agent users int numConnectedAuthedUsers = 0; foreach(const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { From e76a8c2234c886fc7a87ed3444c505493177ef1e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 3 Nov 2014 17:36:10 -0800 Subject: [PATCH 09/34] Fix for ambient occlusion in 3DTV mode. --- interface/resources/shaders/ambient_occlusion.frag | 12 ++++-------- interface/src/renderer/AmbientOcclusionEffect.cpp | 9 +-------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/interface/resources/shaders/ambient_occlusion.frag b/interface/resources/shaders/ambient_occlusion.frag index 621b123966..512922ca43 100644 --- a/interface/resources/shaders/ambient_occlusion.frag +++ b/interface/resources/shaders/ambient_occlusion.frag @@ -14,9 +14,6 @@ // the depth texture uniform sampler2D depthTexture; -// the normal texture -uniform sampler2D normalTexture; - // the random rotation texture uniform sampler2D rotationTexture; @@ -60,11 +57,10 @@ vec3 texCoordToViewSpace(vec2 texCoord) { } void main(void) { - vec3 rotationZ = texture2D(normalTexture, gl_TexCoord[0].st).xyz * 2.0 - vec3(1.0, 1.0, 1.0); - vec3 rotationY = normalize(cross(rotationZ, texture2D(rotationTexture, - gl_TexCoord[0].st * noiseScale).xyz - vec3(0.5, 0.5, 0.5))); - mat3 rotation = mat3(cross(rotationY, rotationZ), rotationY, rotationZ); - + vec3 rotationX = texture2D(rotationTexture, gl_TexCoord[0].st * noiseScale).rgb; + vec3 rotationY = normalize(cross(rotationX, vec3(0.0, 0.0, 1.0))); + mat3 rotation = mat3(rotationX, rotationY, cross(rotationX, rotationY)); + vec3 center = texCoordToViewSpace(gl_TexCoord[0].st); vec2 rdenominator = 1.0 / (rightTop - leftBottom); diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index 33a0b6e77d..f75ed7e8c3 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -51,8 +51,7 @@ void AmbientOcclusionEffect::init() { _occlusionProgram->bind(); _occlusionProgram->setUniformValue("depthTexture", 0); - _occlusionProgram->setUniformValue("normalTexture", 1); - _occlusionProgram->setUniformValue("rotationTexture", 2); + _occlusionProgram->setUniformValue("rotationTexture", 1); _occlusionProgram->setUniformValueArray("sampleKernel", sampleKernel, SAMPLE_KERNEL_SIZE); _occlusionProgram->setUniformValue("radius", 0.1f); _occlusionProgram->release(); @@ -102,9 +101,6 @@ void AmbientOcclusionEffect::render() { glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); - - glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, _rotationTextureID); // render with the occlusion shader to the secondary/tertiary buffer @@ -142,9 +138,6 @@ void AmbientOcclusionEffect::render() { glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); // now render secondary to primary with 4x4 blur From 3ba3299e35a398ddb3ea97640a78ee44374b8403 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 3 Nov 2014 21:13:01 -0800 Subject: [PATCH 10/34] Use glFrustum rather than Oculus's projection utility method, which seems to be returning weird results. --- interface/src/devices/OculusManager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 709080e354..b7884705e1 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -420,7 +420,7 @@ void OculusManager::endFrameTiming() { //Sets the camera FoV and aspect ratio void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) { #ifdef HAVE_LIBOVR - camera.setAspectRatio(_renderTargetSize.w / _renderTargetSize.h); + camera.setAspectRatio((float)_renderTargetSize.w / _renderTargetSize.h); camera.setFieldOfView(atan(_eyeFov[0].UpTan) * DEGREES_PER_RADIAN * 2.0f); #endif } @@ -511,12 +511,12 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p _camera->update(1.0f / Application::getInstance()->getFps()); - Matrix4f proj = ovrMatrix4f_Projection(_eyeRenderDesc[eye].Fov, whichCamera.getNearClip(), whichCamera.getFarClip(), true); - proj.Transpose(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glLoadMatrixf((GLfloat *)proj.M); - + const ovrFovPort& port = _eyeFov[_activeEyeIndex]; + float near = whichCamera.getNearClip(), far = whichCamera.getFarClip(); + glFrustum(-near * port.LeftTan, near * port.RightTan, -near * port.DownTan, near * port.UpTan, near, far); + glViewport(_eyeRenderViewport[eye].Pos.x, _eyeRenderViewport[eye].Pos.y, _eyeRenderViewport[eye].Size.w, _eyeRenderViewport[eye].Size.h); From 640c2c5fbfaf045d605c5205bd6deb5ccb981058 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 4 Nov 2014 08:30:10 -0800 Subject: [PATCH 11/34] Add optional orientation easing to entity camera --- examples/libraries/entityCameraTool.js | 56 +++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index d591d33b6d..48abffb01e 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -34,6 +34,13 @@ var EASING_MULTIPLIER = 8; var INITIAL_ZOOM_DISTANCE = 2; var INITIAL_ZOOM_DISTANCE_FIRST_PERSON = 3; +var easeOutCubic = function(t) { + t--; + return t * t * t + 1; +}; + +EASE_TIME = 0.5; + CameraManager = function() { var that = {}; @@ -51,6 +58,10 @@ CameraManager = function() { that.focalPoint = { x: 0, y: 0, z: 0 }; that.targetFocalPoint = { x: 0, y: 0, z: 0 }; + easing = false; + easingTime = 0; + startOrientation = Quat.fromPitchYawRollDegrees(0, 0, 0); + that.previousCameraMode = null; that.lastMousePosition = { x: 0, y: 0 }; @@ -100,13 +111,35 @@ CameraManager = function() { cameraTool.setVisible(false); } - that.focus = function() { - var dim = SelectionManager.worldDimensions; - var size = Math.max(dim.x, Math.max(dim.y, dim.z)); + that.focus = function(position, dimensions, easeOrientation) { + if (dimensions) { + var size = Math.max(dimensions.x, Math.max(dimensions.y, dimensions.z)); + that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM); + } else { + that.targetZoomDistance = Vec3.length(Vec3.subtract(Camera.getPosition(), position)); + } - that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM); + if (easeOrientation) { + // Do eased turning towards target + that.focalPoint = that.targetFocalPoint = position; - that.setFocalPoint(SelectionManager.worldPosition); + that.zoomDistance = that.targetZoomDistance = Vec3.length(Vec3.subtract(Camera.getPosition(), position)); + + var dPos = Vec3.subtract(that.focalPoint, Camera.getPosition()); + var xzDist = Math.sqrt(dPos.x * dPos.x + dPos.z * dPos.z); + + that.targetPitch = -Math.atan2(dPos.y, xzDist) * 180 / Math.PI; + that.targetYaw = Math.atan2(dPos.x, dPos.z) * 180 / Math.PI; + that.pitch = that.targetPitch; + that.yaw = that.targetYaw; + + startOrientation = Camera.getOrientation(); + + easing = true; + easingTime = 0; + } else { + that.setFocalPoint(position); + } that.updateCamera(); } @@ -255,6 +288,11 @@ CameraManager = function() { xRot = Quat.angleAxis(-that.pitch, { x: 1, y: 0, z: 0 }); q = Quat.multiply(yRot, xRot); + if (easing) { + var t = easeOutCubic(easingTime / EASE_TIME); + q = Quat.slerp(startOrientation, q, t); + } + Camera.setOrientation(q); } @@ -270,6 +308,10 @@ CameraManager = function() { return; } + if (easing) { + easingTime = Math.min(EASE_TIME, easingTime + dt); + } + var scale = Math.min(dt * EASING_MULTIPLIER, 1.0); var dYaw = that.targetYaw - that.yaw; @@ -292,6 +334,10 @@ CameraManager = function() { that.zoomDistance += scale * dZoom; that.updateCamera(); + + if (easingTime >= 1) { + easing = false; + } } // Last mode that was first or third person From 185b9ac5453a1d12b7cc7c6c7f95d5defb45d69a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 4 Nov 2014 08:32:21 -0800 Subject: [PATCH 12/34] Add Inspect tool to newEditEntities --- examples/libraries/entityCameraTool.js | 4 - examples/newEditEntities.js | 230 ++++++++++++++----------- 2 files changed, 127 insertions(+), 107 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 48abffb01e..2f03cb28c8 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -77,10 +77,6 @@ CameraManager = function() { var focalPoint = Vec3.sum(Camera.getPosition(), Vec3.multiply(that.zoomDistance, Quat.getFront(Camera.getOrientation()))); - if (Camera.getMode() == 'first person') { - that.targetZoomDistance = INITIAL_ZOOM_DISTANCE_FIRST_PERSON; - } - // Determine the correct yaw and pitch to keep the camera in the same location var dPos = Vec3.subtract(focalPoint, Camera.getPosition()); var xzDist = Math.sqrt(dPos.x * dPos.x + dPos.z * dPos.z); diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index d58f258e59..28d3eec660 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -51,6 +51,9 @@ var wantEntityGlow = false; var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; +var MENU_INSPECT_TOOL_ENABLED = 'Inspect Tool'; +var MENU_EASE_ON_FOCUS = 'Ease Orientation on Focus'; + var modelURLs = [ HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx", @@ -387,7 +390,6 @@ function isLocked(properties) { var selectedEntityID; -var mouseLastPosition; var orientation; var intersection; @@ -401,142 +403,154 @@ function rayPlaneIntersection(pickRay, point, normal) { return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, t)); } +function findClickedEntity(event) { + var pickRay = Camera.computePickRay(event.x, event.y); + + var foundIntersection = Entities.findRayIntersection(pickRay); + + if (!foundIntersection.accurate) { + return null; + } + var foundEntity = foundIntersection.entityID; + + if (!foundEntity.isKnownID) { + var identify = Entities.identifyEntity(foundEntity); + if (!identify.isKnownID) { + print("Unknown ID " + identify.id + " (update loop " + foundEntity.id + ")"); + selectionManager.clearSelections(); + return null; + } + foundEntity = identify; + } + + return { pickRay: pickRay, entityID: foundEntity }; +} + function mousePressEvent(event) { - mouseLastPosition = { x: event.x, y: event.y }; - var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); - - var entitySelected = false; - if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event) - || cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) { - // Event handled; do nothing. + if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event)) { return; - } else { - - // If we aren't active and didn't click on an overlay: quit - if (!isActive) { + } + if (isActive) { + var entitySelected = false; + if (cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) { + // Event handled; do nothing. return; - } - - var pickRay = Camera.computePickRay(event.x, event.y); - Vec3.print("[Mouse] Looking at: ", pickRay.origin); - var foundIntersection = Entities.findRayIntersection(pickRay); - - if(!foundIntersection.accurate) { - selectionManager.clearSelections(); - return; - } - var foundEntity = foundIntersection.entityID; - - if (!foundEntity.isKnownID) { - var identify = Entities.identifyEntity(foundEntity); - if (!identify.isKnownID) { - print("Unknown ID " + identify.id + " (update loop " + foundEntity.id + ")"); + } else { + var result = findClickedEntity(event); + if (result === null) { selectionManager.clearSelections(); return; } - foundEntity = identify; - } + var pickRay = result.pickRay; + var foundEntity = result.entityID; - var properties = Entities.getEntityProperties(foundEntity); - if (isLocked(properties)) { - print("Model locked " + properties.id); - } else { - var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; + var properties = Entities.getEntityProperties(foundEntity); + if (isLocked(properties)) { + print("Model locked " + properties.id); + } else { + var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; - print("Checking properties: " + properties.id + " " + properties.isKnownID + " - Half Diagonal:" + halfDiagonal); - // P P - Model - // /| A - Palm - // / | d B - unit vector toward tip - // / | X - base of the perpendicular line - // A---X----->B d - distance fom axis - // x x - distance from A - // - // |X-A| = (P-A).B - // X == A + ((P-A).B)B - // d = |P-X| + print("Checking properties: " + properties.id + " " + properties.isKnownID + " - Half Diagonal:" + halfDiagonal); + // P P - Model + // /| A - Palm + // / | d B - unit vector toward tip + // / | X - base of the perpendicular line + // A---X----->B d - distance fom axis + // x x - distance from A + // + // |X-A| = (P-A).B + // X == A + ((P-A).B)B + // d = |P-X| - var A = pickRay.origin; - var B = Vec3.normalize(pickRay.direction); - var P = properties.position; + var A = pickRay.origin; + var B = Vec3.normalize(pickRay.direction); + var P = properties.position; - var x = Vec3.dot(Vec3.subtract(P, A), B); - var X = Vec3.sum(A, Vec3.multiply(B, x)); - var d = Vec3.length(Vec3.subtract(P, X)); - var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; + var x = Vec3.dot(Vec3.subtract(P, A), B); + var X = Vec3.sum(A, Vec3.multiply(B, x)); + var d = Vec3.length(Vec3.subtract(P, X)); + var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; - var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14; + var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14; - var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) - && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); + var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) + && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); - if (0 < x && sizeOK) { - entitySelected = true; - selectedEntityID = foundEntity; - orientation = MyAvatar.orientation; - intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); + if (0 < x && sizeOK) { + entitySelected = true; + selectedEntityID = foundEntity; + orientation = MyAvatar.orientation; + intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); - if (!event.isShifted) { - selectionManager.clearSelections(); + if (!event.isShifted) { + selectionManager.clearSelections(); + } + selectionManager.addEntity(foundEntity); + + print("Model selected: " + foundEntity.id); } - selectionManager.addEntity(foundEntity); - - print("Model selected: " + foundEntity.id); } } - } - if (entitySelected) { - selectionDisplay.select(selectedEntityID, event); + if (entitySelected) { + selectionDisplay.select(selectedEntityID, event); + } + } else if (Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED)) { + var result = findClickedEntity(event); + if (result !== null && event.isRightButton) { + var currentProperties = Entities.getEntityProperties(result.entityID); + cameraManager.enable(); + cameraManager.focus(currentProperties.position, null, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + cameraManager.mousePressEvent(event); + } } } var highlightedEntityID = { isKnownID: false }; function mouseMoveEvent(event) { - if (!isActive) { - return; - } - - // allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing - if (selectionDisplay.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) { - return; - } - - var pickRay = Camera.computePickRay(event.x, event.y); - var entityIntersection = Entities.findRayIntersection(pickRay); - if (entityIntersection.accurate) { - if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) { - selectionDisplay.unhighlightSelectable(highlightedEntityID); - highlightedEntityID = { id: -1, isKnownID: false }; + if (isActive) { + // allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing + if (selectionDisplay.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) { + return; } - var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0; - - var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), - entityIntersection.properties.position)) * 180 / 3.14; - - var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) - && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); - - if (entityIntersection.entityID.isKnownID && sizeOK) { - if (wantEntityGlow) { - Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 }); + var pickRay = Camera.computePickRay(event.x, event.y); + var entityIntersection = Entities.findRayIntersection(pickRay); + if (entityIntersection.accurate) { + if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) { + selectionDisplay.unhighlightSelectable(highlightedEntityID); + highlightedEntityID = { id: -1, isKnownID: false }; } - highlightedEntityID = entityIntersection.entityID; - selectionDisplay.highlightSelectable(entityIntersection.entityID); - } + var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0; + + var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), + entityIntersection.properties.position)) * 180 / 3.14; + + var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) + && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); + + if (entityIntersection.entityID.isKnownID && sizeOK) { + if (wantEntityGlow) { + Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 }); + } + highlightedEntityID = entityIntersection.entityID; + selectionDisplay.highlightSelectable(entityIntersection.entityID); + } + + } + } else { + cameraManager.mouseMoveEvent(event); } } function mouseReleaseEvent(event) { - if (!isActive) { - return; - } - if (selectionManager.hasSelection()) { + if (isActive && selectionManager.hasSelection()) { tooltip.show(false); } + cameraManager.mouseReleaseEvent(event); } @@ -574,6 +588,9 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "File", menuItemName: "Export Models", shortcutKey: "CTRL+META+E", afterItem: "Models" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" }); Menu.addMenuItem({ menuName: "Developer", menuItemName: "Debug Ryans Rotation Problems", isCheckable: true }); + + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_INSPECT_TOOL_ENABLED, afterItem: "Edit Entities Help...", isCheckable: true }); + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED, isCheckable: true }); } setupModelMenus(); // do this when first running our script. @@ -594,6 +611,9 @@ function cleanupModelMenus() { Menu.removeMenuItem("File", "Export Models"); Menu.removeMenuItem("File", "Import Models"); Menu.removeMenuItem("Developer", "Debug Ryans Rotation Problems"); + + Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED); + Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS); } Script.scriptEnding.connect(function() { @@ -684,7 +704,11 @@ Controller.keyReleaseEvent.connect(function (event) { } else if (event.text == "TAB") { selectionDisplay.toggleSpaceMode(); } else if (event.text == "f") { - cameraManager.focus(); + if (isActive) { + cameraManager.focus(selectionManager.worldPosition, + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } } else if (event.text == '[') { if (isActive) { cameraManager.enable(); From af1b69d8a158ef89cb67e05251c833473702cce0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 4 Nov 2014 09:01:45 -0800 Subject: [PATCH 13/34] removed some dead code --- interface/src/entities/EntityTreeRenderer.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/interface/src/entities/EntityTreeRenderer.h b/interface/src/entities/EntityTreeRenderer.h index 0a725c8294..b8acb28c3b 100644 --- a/interface/src/entities/EntityTreeRenderer.h +++ b/interface/src/entities/EntityTreeRenderer.h @@ -64,12 +64,6 @@ public: /// clears the tree virtual void clear(); - //Q_INVOKABLE Model* getModel(const ModelEntityItem* modelEntityItem); - - // renderers for various types of entities - void renderEntityTypeBox(EntityItem* entity, RenderArgs* args); - void renderEntityTypeModel(EntityItem* entity, RenderArgs* args); - static QThread* getMainThread(); /// if a renderable entity item needs a model, we will allocate it for them From fc977e21e60ce872d8434cae1a20493dc8706b6a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 4 Nov 2014 09:14:14 -0800 Subject: [PATCH 14/34] Remove print statements --- examples/libraries/entityCameraTool.js | 1 - examples/newEditEntities.js | 1 - 2 files changed, 2 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 2f03cb28c8..c9757bde7d 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -339,7 +339,6 @@ CameraManager = function() { // Last mode that was first or third person var lastAvatarCameraMode = "first person"; Camera.modeUpdated.connect(function(newMode) { - print("Camera mode has been updated: " + newMode); if (newMode == "first person" || newMode == "third person") { lastAvatarCameraMode = newMode; that.disable(true); diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index ea1f69e15f..92c4b36a0b 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -820,7 +820,6 @@ function applyEntityProperties(data) { var properties = data.createEntities[i].properties; var newEntityID = Entities.addEntity(properties); DELETED_ENTITY_MAP[entityID.id] = newEntityID; - print(newEntityID.isKnownID); if (data.selectCreated) { selectedEntityIDs.push(newEntityID); } From fd8fb32190af8489b649678979b772f736d13bab Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 4 Nov 2014 09:33:39 -0800 Subject: [PATCH 15/34] Repopulate example models for "Upload URL" to better sized models --- examples/editModels.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 7f4c27814c..d26a6e14b0 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -50,14 +50,14 @@ var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; var modelURLs = [ - HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", - HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx", - HIFI_PUBLIC_BUCKET + "meshes/pug.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush6.fbx", HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo", - HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx", - HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX", - HIFI_PUBLIC_BUCKET + "meshes/orc.fbx", - HIFI_PUBLIC_BUCKET + "meshes/slimer.fbx" + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed2.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed4.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed7.fbx" ]; var jointList = MyAvatar.getJointNames(); From 4fdc00948f47fcd51da278dc5a44b8bd90c702a1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 4 Nov 2014 09:39:37 -0800 Subject: [PATCH 16/34] Repopulate example models in newEditEnties.js too --- examples/newEditEntities.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 64ccb556a9..22f4a6d71f 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -52,14 +52,14 @@ var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; var modelURLs = [ - HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", - HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx", - HIFI_PUBLIC_BUCKET + "meshes/pug.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush6.fbx", HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo", - HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx", - HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX", - HIFI_PUBLIC_BUCKET + "meshes/orc.fbx", - HIFI_PUBLIC_BUCKET + "meshes/slimer.fbx" + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed2.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed4.fbx", + HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed7.fbx" ]; var mode = 0; From 8d6b041758a469df13a282a0cf428699a299ed1e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:01:25 -0800 Subject: [PATCH 17/34] 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 573e6f119f13912b75d87fde5bd259d841024d7c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 4 Nov 2014 10:06:17 -0800 Subject: [PATCH 18/34] Add entity camera options to settings --- examples/newEditEntities.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 92c4b36a0b..fd956fc95a 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -51,8 +51,11 @@ var wantEntityGlow = false; var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; -var MENU_INSPECT_TOOL_ENABLED = 'Inspect Tool'; -var MENU_EASE_ON_FOCUS = 'Ease Orientation on Focus'; +var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool"; +var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; + +var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled"; +var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; var modelURLs = [ HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", @@ -590,8 +593,10 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" }); Menu.addMenuItem({ menuName: "Developer", menuItemName: "Debug Ryans Rotation Problems", isCheckable: true }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_INSPECT_TOOL_ENABLED, afterItem: "Edit Entities Help...", isCheckable: true }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED, isCheckable: true }); + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_INSPECT_TOOL_ENABLED, afterItem: "Edit Entities Help...", + isCheckable: true, isChecked: Settings.getValue(SETTING_INSPECT_TOOL_ENABLED) == "true" }); + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED, + isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" }); } setupModelMenus(); // do this when first running our script. @@ -619,6 +624,9 @@ function cleanupModelMenus() { } Script.scriptEnding.connect(function() { + Settings.setValue(SETTING_INSPECT_TOOL_ENABLED, Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED)); + Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + progressDialog.cleanup(); toolBar.cleanup(); cleanupModelMenus(); From 2e8e31fce93d15a93b1c6aa09f361f2b84787037 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 4 Nov 2014 10:06:45 -0800 Subject: [PATCH 19/34] Update inspect tool behavior to pan correctly --- examples/newEditEntities.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index fd956fc95a..575541e9f0 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -500,10 +500,14 @@ function mousePressEvent(event) { } } else if (Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED)) { var result = findClickedEntity(event); - if (result !== null && event.isRightButton) { - var currentProperties = Entities.getEntityProperties(result.entityID); - cameraManager.enable(); - cameraManager.focus(currentProperties.position, null, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + if (event.isRightButton) { + if (result !== null) { + var currentProperties = Entities.getEntityProperties(result.entityID); + cameraManager.enable(); + cameraManager.focus(currentProperties.position, null, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + cameraManager.mousePressEvent(event); + } + } else { cameraManager.mousePressEvent(event); } } From 99219a17580bf77c6b7fea6ad644793e6d2c23af Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 10:17:00 -0800 Subject: [PATCH 20/34] 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 21/34] 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 22/34] 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 23/34] 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 24/34] 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 25/34] 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 26/34] 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 a89287e4045f73f095570506b60bb9ba8a16e267 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 4 Nov 2014 11:01:37 -0800 Subject: [PATCH 27/34] reset the QElapsedTimer in usecTimestampNow() periodically to prevent error --- libraries/shared/src/SharedUtil.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 5801da339f..05d208c2f8 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -46,6 +46,26 @@ quint64 usecTimestampNow() { TIME_REFERENCE = QDateTime::currentMSecsSinceEpoch() * 1000; // ms to usec timestampTimer.start(); usecTimestampNowIsInitialized = true; + } else { + // We've seen the QElapsedTimer begin to introduce dramatic errors if it's been + // continuously running for a long time. So we will periodically reset it. + const quint64 SECS_TO_NSECS = 1000000000; + const quint64 RESET_AFTER_ELAPSED_SECS = 60 * 60; // 1 hour: 60 minutes * 60 seconds + const quint64 RESET_AFTER_ELAPSED_NSECS = RESET_AFTER_ELAPSED_SECS * SECS_TO_NSECS; + const quint64 nsecsElapsed = timestampTimer.nsecsElapsed(); + if (nsecsElapsed > RESET_AFTER_ELAPSED_NSECS) { + quint64 msecsElapsed = timestampTimer.restart(); + quint64 usecsElapsed = nsecsElapsed / 1000; // nsec to usec + TIME_REFERENCE += usecsElapsed; + const bool wantDebug = false; + if (wantDebug) { + qDebug() << "usecTimestampNow() - resetting QElapsedTimer. "; + qDebug() << " RESET_AFTER_ELAPSED_NSECS:" << RESET_AFTER_ELAPSED_NSECS; + qDebug() << " nsecsElapsed:" << nsecsElapsed; + qDebug() << " msecsElapsed:" << msecsElapsed; + qDebug() << " usecsElapsed:" << usecsElapsed; + } + } } // usec nsec to usec usec From f53455ee5563a9d001805660daf30fa8c6ad96c0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 11:40:47 -0800 Subject: [PATCH 28/34] 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 03ce8081a4815def879dec40914f4acc7ce8852a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 4 Nov 2014 11:44:47 -0800 Subject: [PATCH 29/34] Oh, when will I learn not to use "near" and "far" as variable names? --- interface/src/devices/OculusManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index b7884705e1..23cd52d946 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -514,8 +514,9 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p glMatrixMode(GL_PROJECTION); glLoadIdentity(); const ovrFovPort& port = _eyeFov[_activeEyeIndex]; - float near = whichCamera.getNearClip(), far = whichCamera.getFarClip(); - glFrustum(-near * port.LeftTan, near * port.RightTan, -near * port.DownTan, near * port.UpTan, near, far); + float nearClip = whichCamera.getNearClip(), farClip = whichCamera.getFarClip(); + glFrustum(-nearClip * port.LeftTan, nearClip * port.RightTan, -nearClip * port.DownTan, + nearClip * port.UpTan, nearClip, farClip); glViewport(_eyeRenderViewport[eye].Pos.x, _eyeRenderViewport[eye].Pos.y, _eyeRenderViewport[eye].Size.w, _eyeRenderViewport[eye].Size.h); From b968f051230928ad95ddb0d3410d1d046ce262bb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 11:54:14 -0800 Subject: [PATCH 30/34] 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 From 72f80d4a0fded278994bda3869ed795eecb043cf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 12:39:50 -0800 Subject: [PATCH 31/34] make camera getPosition() callable from js --- interface/src/Camera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Camera.h b/interface/src/Camera.h index bc7a3c5687..06db3dc3ef 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -56,7 +56,6 @@ public: void setEyeOffsetOrientation(const glm::quat& o) { _eyeOffsetOrientation = o; } void setScale(const float s) { _scale = s; } - glm::vec3 getPosition() const { return _position + _hmdPosition; } glm::quat getRotation() const { return _rotation * _hmdRotation; } const glm::vec3& getHmdPosition() const { return _hmdPosition; } const glm::quat& getHmdRotation() const { return _hmdRotation; } @@ -73,6 +72,7 @@ public slots: QString getModeString() const; void setModeString(const QString& mode); + glm::vec3 getPosition() const { return _position + _hmdPosition; } void setPosition(const glm::vec3& position) { _position = position; } void setOrientation(const glm::quat& orientation) { setRotation(orientation); } From d671dec61b5e868a8bbb764a70afe88c7075459e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 13:21:48 -0800 Subject: [PATCH 32/34] fix for ice server sock addr in domain-server --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a2198370ce..dbaaca43fa 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1148,7 +1148,7 @@ void DomainServer::performICEUpdates() { } void DomainServer::sendHeartbeatToIceServer() { - const HifiSockAddr ICE_SERVER_SOCK_ADDR = HifiSockAddr("ice.highfidelity.io", ICE_SERVER_DEFAULT_PORT); + static HifiSockAddr ICE_SERVER_SOCK_ADDR = HifiSockAddr("ice.highfidelity.io", ICE_SERVER_DEFAULT_PORT); LimitedNodeList::getInstance()->sendHeartbeatToIceServer(ICE_SERVER_SOCK_ADDR); } From d46f775f20597696c24cdcdfe0fd7713e0ef85b7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 13:23:53 -0800 Subject: [PATCH 33/34] async and sync nomenclature flip --- libraries/networking/src/HifiSockAddr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index 11674a948e..6eec22ab3e 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -44,12 +44,12 @@ HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort, bool if (_address.protocol() != QAbstractSocket::IPv4Protocol) { // lookup the IP by the hostname if (shouldBlockForLookup) { - qDebug() << "Asynchronously looking up IP address for hostname" << hostname; + qDebug() << "Synchronously looking up IP address for hostname" << hostname; QHostInfo result = QHostInfo::fromName(hostname); handleLookupResult(result); } else { int lookupID = QHostInfo::lookupHost(hostname, this, SLOT(handleLookupResult(QHostInfo))); - qDebug() << "Synchronously looking up IP address for hostname" << hostname << "- lookup ID is" << lookupID; + qDebug() << "Asynchronously looking up IP address for hostname" << hostname << "- lookup ID is" << lookupID; } } } From beb350d1e702368fc3fbbfa7b47f6b196f3ad2fe Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Nov 2014 13:53:56 -0800 Subject: [PATCH 34/34] fix for HifiSockAddr lookup for ice server from DomainHandler --- libraries/networking/src/DomainHandler.cpp | 6 +++++- libraries/networking/src/HifiSockAddr.cpp | 21 +++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 81d6a6d662..d64752dce0 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -14,6 +14,7 @@ #include #include "Assignment.h" +#include "HifiSockAddr.h" #include "NodeList.h" #include "PacketHeaders.h" #include "UserActivityLogger.h" @@ -144,7 +145,10 @@ void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, hardReset(); _iceDomainID = id; - _iceServerSockAddr = HifiSockAddr(iceServerHostname, ICE_SERVER_DEFAULT_PORT); + + HifiSockAddr* replaceableSockAddr = &_iceServerSockAddr; + replaceableSockAddr->~HifiSockAddr(); + replaceableSockAddr = new (replaceableSockAddr) HifiSockAddr(iceServerHostname, ICE_SERVER_DEFAULT_PORT); // refresh our ICE client UUID to something new _iceClientID = QUuid::createUuid(); diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index 6eec22ab3e..f2419f5124 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -31,9 +31,17 @@ HifiSockAddr::HifiSockAddr(const QHostAddress& address, quint16 port) : } -HifiSockAddr::HifiSockAddr(const HifiSockAddr& otherSockAddr) { - _address = otherSockAddr._address; - _port = otherSockAddr._port; +HifiSockAddr::HifiSockAddr(const HifiSockAddr& otherSockAddr) : + _address(otherSockAddr._address), + _port(otherSockAddr._port) +{ + +} + +HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { + HifiSockAddr temp(rhsSockAddr); + swap(temp); + return *this; } HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort, bool shouldBlockForLookup) : @@ -64,13 +72,6 @@ HifiSockAddr::HifiSockAddr(const sockaddr* sockaddr) { } } -HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { - _address = rhsSockAddr._address; - _port = rhsSockAddr._port; - - return *this; -} - void HifiSockAddr::swap(HifiSockAddr& otherSockAddr) { using std::swap;