From 2e2d03c58b502d4731a8bb850b224d1033d05fe6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 26 Jun 2014 16:53:19 -0700 Subject: [PATCH 01/43] added ESC to restore to original camera in concertCamera.js --- examples/concertCamera.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/concertCamera.js b/examples/concertCamera.js index 7280958bc6..96218e697f 100644 --- a/examples/concertCamera.js +++ b/examples/concertCamera.js @@ -56,6 +56,11 @@ function keyPressEvent(event) { Camera.setPosition(cameraLocations[choice - 1]); Camera.keepLookingAt(cameraLookAts[choice - 1]); } + if (event.text == "ESC") { + cameraNumber = 0; + freeCamera = false; + restoreCameraState(); + } if (event.text == "0") { // Show camera location in log var cameraLocation = Camera.getPosition(); From f072c04b4cf6ca211b47d4c8e7906055aecd0471 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 27 Jun 2014 09:30:51 -0700 Subject: [PATCH 02/43] hair is a separate class --- interface/src/Hair.cpp | 35 +++++++++++++++++++++++++++++++ interface/src/Hair.h | 35 +++++++++++++++++++++++++++++++ interface/src/avatar/Avatar.cpp | 8 +++++++ interface/src/avatar/Avatar.h | 2 ++ interface/src/avatar/MyAvatar.cpp | 6 ++++++ 5 files changed, 86 insertions(+) create mode 100644 interface/src/Hair.cpp create mode 100644 interface/src/Hair.h diff --git a/interface/src/Hair.cpp b/interface/src/Hair.cpp new file mode 100644 index 0000000000..a23312eba1 --- /dev/null +++ b/interface/src/Hair.cpp @@ -0,0 +1,35 @@ +// +// Hair.cpp +// interface/src +// +// Created by Philip on June 26, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// Creates single flexible vertlet-integrated strands that can be used for hair/fur/grass + +#include "Hair.h" + +#include "Util.h" +#include "world.h" + + +Hair::Hair() { + qDebug() << "Creating Hair"; + } + +void Hair::simulate(float deltaTime) { +} + +void Hair::render() { + // + // Before calling this function, translate/rotate to the origin of the owning object + glPushMatrix(); + glColor3f(1.0f, 1.0f, 0.0f); + glutSolidSphere(1.0f, 15, 15); + glPopMatrix(); +} + + diff --git a/interface/src/Hair.h b/interface/src/Hair.h new file mode 100644 index 0000000000..e4dc3778c3 --- /dev/null +++ b/interface/src/Hair.h @@ -0,0 +1,35 @@ +// +// Hair.h +// interface/src +// +// Created by Philip on June 26, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_Hair_h +#define hifi_Hair_h + +#include + +#include +#include + +#include "GeometryUtil.h" +#include "InterfaceConfig.h" +#include "Util.h" + + +class Hair { +public: + Hair(); + void simulate(float deltaTime); + void render(); + +private: + + }; + +#endif // hifi_Hair_h diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5a294bb2a5..769d0398a2 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -143,6 +143,11 @@ void Avatar::simulate(float deltaTime) { if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { simulateHair(deltaTime); } + + foreach (Hair* hair, _hairs) { + hair->simulate(deltaTime); + } + } // update position by velocity, and subtract the change added earlier for gravity @@ -380,6 +385,9 @@ void Avatar::renderBody(RenderMode renderMode, float glowLevel) { getHead()->render(1.0f, modelRenderMode); if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { renderHair(); + foreach (Hair* hair, _hairs) { + hair->render(); + } } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index f20db1019d..369cd7e688 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -19,6 +19,7 @@ #include +#include "Hair.h" #include "Hand.h" #include "Head.h" #include "InterfaceConfig.h" @@ -159,6 +160,7 @@ signals: void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision); protected: + QVector _hairs; SkeletonModel _skeletonModel; QVector _attachmentModels; float _bodyYawDelta; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7367f64d73..cfdf7e057a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -199,6 +199,9 @@ void MyAvatar::simulate(float deltaTime) { PerformanceTimer perfTimer("MyAvatar::simulate/hair Simulate"); if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { simulateHair(deltaTime); + foreach (Hair* hair, _hairs) { + hair->simulate(deltaTime); + } } } @@ -860,6 +863,9 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) { getHead()->render(1.0f, modelRenderMode); if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { renderHair(); + foreach (Hair* hair, _hairs) { + hair->render(); + } } } getHand()->render(true, modelRenderMode); From 370540cc339423a176c2bc8597910641954b22d7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sat, 28 Jun 2014 13:00:51 -0700 Subject: [PATCH 03/43] squeezeHands uses different animation on clench/release --- examples/squeezeHands.js | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/examples/squeezeHands.js b/examples/squeezeHands.js index da720734e1..f920692a3b 100644 --- a/examples/squeezeHands.js +++ b/examples/squeezeHands.js @@ -18,13 +18,16 @@ var RIGHT = 1; var lastLeftFrame = 0; var lastRightFrame = 0; -var LAST_FRAME = 11.0; // What is the number of the last frame we want to use in the animation? -var SMOOTH_FACTOR = 0.80; +var leftDirection = true; +var rightDirection = true; +var LAST_FRAME = 15.0; // What is the number of the last frame we want to use in the animation? +var SMOOTH_FACTOR = 0.0; +var MAX_FRAMES = 30.0; Script.update.connect(function(deltaTime) { - var leftTriggerValue = Math.sqrt(Controller.getTriggerValue(LEFT)); - var rightTriggerValue = Math.sqrt(Controller.getTriggerValue(RIGHT)); + var leftTriggerValue = Controller.getTriggerValue(LEFT); + var rightTriggerValue = Controller.getTriggerValue(RIGHT); var leftFrame, rightFrame; @@ -32,10 +35,31 @@ Script.update.connect(function(deltaTime) { leftFrame = (leftTriggerValue * LAST_FRAME) * (1.0 - SMOOTH_FACTOR) + lastLeftFrame * SMOOTH_FACTOR; rightFrame = (rightTriggerValue * LAST_FRAME) * (1.0 - SMOOTH_FACTOR) + lastRightFrame * SMOOTH_FACTOR; - + if (!leftDirection) { + leftFrame = MAX_FRAMES - leftFrame; + } + if (!rightDirection) { + rightFrame = MAX_FRAMES - rightFrame; + } + + if ((leftTriggerValue == 1.0) && (leftDirection == true)) { + leftDirection = false; + lastLeftFrame = MAX_FRAMES - leftFrame; + } else if ((leftTriggerValue == 0.0) && (leftDirection == false)) { + leftDirection = true; + lastLeftFrame = leftFrame; + } + if ((rightTriggerValue == 1.0) && (rightDirection == true)) { + rightDirection = false; + lastRightFrame = MAX_FRAMES - rightFrame; + } else if ((rightTriggerValue == 0.0) && (rightDirection == false)) { + rightDirection = true; + lastRightFrame = rightFrame; + } + if ((leftFrame != lastLeftFrame) && leftHandAnimation.length){ MyAvatar.stopAnimation(leftHandAnimation); - MyAvatar.startAnimation(leftHandAnimation, 30.0, 1.0, false, true, leftFrame, leftFrame); + MyAvatar.startAnimation(leftHandAnimation, 30.0, 1.0, false, true, leftFrame, leftFrame); } if ((rightFrame != lastRightFrame) && rightHandAnimation.length) { MyAvatar.stopAnimation(rightHandAnimation); From 8b04a9c8b600d3c3eb8c81f21af4d7419b9bc391 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Jul 2014 16:19:05 -0700 Subject: [PATCH 04/43] Add toggle for user interface display - "/" toggles UI (incl. stats if displayed); menu View > User Interface - "%" = toggle status; menu View > Stats - Acts on normal, 3DTV, and Oculus display. --- interface/src/Application.cpp | 22 ++++++++++------------ interface/src/Menu.cpp | 6 ++---- interface/src/Menu.h | 2 +- interface/src/devices/OculusManager.cpp | 2 +- interface/src/devices/TV3DManager.cpp | 9 +++++++-- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9b2ed7b63d..0c469102cc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -683,16 +683,11 @@ void Application::paintGL() { _rearMirrorTools->render(true); } - { - PerformanceTimer perfTimer("paintGL/renderOverlay"); - //If alpha is 1, we can render directly to the screen. - if (_applicationOverlay.getAlpha() == 1.0f) { - _applicationOverlay.renderOverlay(); - } else { - //Render to to texture so we can fade it - _applicationOverlay.renderOverlay(true); - _applicationOverlay.displayOverlayTexture(); - } + PerformanceTimer perfTimer("paintGL/renderOverlay"); + // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() + _applicationOverlay.renderOverlay(true); + if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { + _applicationOverlay.displayOverlayTexture(); } } @@ -1012,6 +1007,9 @@ void Application::keyPressEvent(QKeyEvent* event) { Menu::getInstance()->triggerOption(MenuOption::FullscreenMirror); } break; + case Qt::Key_Slash: + Menu::getInstance()->triggerOption(MenuOption::UserInterface); + break; case Qt::Key_F: if (isShifted) { Menu::getInstance()->triggerOption(MenuOption::DisplayFrustum); @@ -1031,7 +1029,7 @@ void Application::keyPressEvent(QKeyEvent* event) { } break; break; - case Qt::Key_Slash: + case Qt::Key_Percent: Menu::getInstance()->triggerOption(MenuOption::Stats); break; case Qt::Key_Plus: @@ -2793,7 +2791,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { if (!selfAvatarOnly) { // Render the world box - if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { + if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) && Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { PerformanceTimer perfTimer("paintGL/displaySide/renderWorldBox"); renderWorldBox(); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index dba5feca9e..7b80b0b529 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -276,6 +276,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false, appInstance, SLOT(cameraMenuChanged())); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0, false, @@ -326,7 +327,7 @@ Menu::Menu() : addDisabledActionAndSeparator(viewMenu, "Stats"); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Percent); addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); @@ -407,9 +408,6 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false); - QMenu* oculusOptionsMenu = developerMenu->addMenu("Oculus Options"); - addCheckableActionToQMenuAndActionHash(oculusOptionsMenu, MenuOption::DisplayOculusOverlays, 0, true); - QMenu* sixenseOptionsMenu = developerMenu->addMenu("Sixense Options"); addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 06b5c5c9f4..2d13a81b1f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -349,7 +349,6 @@ namespace MenuOption { const QString DisplayModelBounds = "Display Model Bounds"; const QString DisplayModelElementProxy = "Display Model Element Bounds"; const QString DisplayModelElementChildProxies = "Display Model Element Children"; - const QString DisplayOculusOverlays = "Display Oculus Overlays"; const QString DisplayTimingDetails = "Display Timing Details"; const QString DontFadeOnVoxelServerChanges = "Don't Fade In/Out on Voxel Server Changes"; const QString EchoLocalAudio = "Echo Local Audio"; @@ -438,6 +437,7 @@ namespace MenuOption { const QString UploadAttachment = "Upload Attachment Model"; const QString UploadHead = "Upload Head Model"; const QString UploadSkeleton = "Upload Skeleton Model"; + const QString UserInterface = "UserInterface"; const QString Visage = "Visage"; const QString VoxelMode = "Cycle Voxel Mode"; const QString Voxels = "Voxels"; diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 199c313119..1260dc7036 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -269,7 +269,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p // We only need to render the overlays to a texture once, then we just render the texture on the hemisphere // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() applicationOverlay.renderOverlay(true); - const bool displayOverlays = Menu::getInstance()->isOptionChecked(MenuOption::DisplayOculusOverlays); + const bool displayOverlays = Menu::getInstance()->isOptionChecked(MenuOption::UserInterface); //Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) { diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 25d3ff892a..3b42c03f2d 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -100,6 +100,7 @@ void TV3DManager::display(Camera& whichCamera) { // We only need to render the overlays to a texture once, then we just render the texture as a quad // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() applicationOverlay.renderOverlay(true); + const bool displayOverlays = Menu::getInstance()->isOptionChecked(MenuOption::UserInterface); if (glowEnabled) { Application::getInstance()->getGlowEffect()->prepare(); @@ -128,7 +129,9 @@ void TV3DManager::display(Camera& whichCamera) { glLoadIdentity(); Application::getInstance()->displaySide(whichCamera); - applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); + if (displayOverlays) { + applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); + } } glPopMatrix(); glDisable(GL_SCISSOR_TEST); @@ -154,7 +157,9 @@ void TV3DManager::display(Camera& whichCamera) { glLoadIdentity(); Application::getInstance()->displaySide(whichCamera); - applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); + if (displayOverlays) { + applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); + } } glPopMatrix(); glDisable(GL_SCISSOR_TEST); From 97ca6d70fa73e87cfb6497012bf2496bee1f976e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Jul 2014 17:15:46 -0700 Subject: [PATCH 05/43] Fixed performance timer scope --- interface/src/Application.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0c469102cc..96fee69bda 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -683,11 +683,13 @@ void Application::paintGL() { _rearMirrorTools->render(true); } - PerformanceTimer perfTimer("paintGL/renderOverlay"); - // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() - _applicationOverlay.renderOverlay(true); - if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { - _applicationOverlay.displayOverlayTexture(); + { + PerformanceTimer perfTimer("paintGL/renderOverlay"); + // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() + _applicationOverlay.renderOverlay(true); + if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { + _applicationOverlay.displayOverlayTexture(); + } } } From 2ad2b6cd1ce6cd6b49d68d2c71275ab76c212718 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Jul 2014 18:23:37 -0700 Subject: [PATCH 06/43] Resize the overlay framebuffer when the application window is resized --- interface/src/Application.cpp | 1 + interface/src/ui/ApplicationOverlay.cpp | 6 ++++++ interface/src/ui/ApplicationOverlay.h | 1 + 3 files changed, 8 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 96fee69bda..ab31eb09cd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -712,6 +712,7 @@ void Application::resizeGL(int width, int height) { resetCamerasOnResizeGL(_myCamera, width, height); glViewport(0, 0, width, height); // shouldn't this account for the menu??? + _applicationOverlay.resize(); updateProjectionMatrix(); glLoadIdentity(); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 4c445958ec..879c7cda32 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -998,6 +998,12 @@ void ApplicationOverlay::renderTexturedHemisphere() { } +void ApplicationOverlay::resize() { + delete _framebufferObject; + _framebufferObject = NULL; + // _framebufferObject is recreated at the correct size the next time it is accessed via getFramebufferObject(). +} + QOpenGLFramebufferObject* ApplicationOverlay::getFramebufferObject() { if (!_framebufferObject) { _framebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size()); diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 7c1f87d575..5e8d06ab89 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -32,6 +32,7 @@ public: void displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov); void computeOculusPickRay(float x, float y, glm::vec3& direction) const; void getClickLocation(int &x, int &y) const; + void resize(); // Getters QOpenGLFramebufferObject* getFramebufferObject(); From d1cddb4f2854c844579f9031a2a800abc022a22d Mon Sep 17 00:00:00 2001 From: mpursley Date: Mon, 7 Jul 2014 01:02:04 -0700 Subject: [PATCH 07/43] adding "export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake" for qt5.2.1 --- BUILD.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILD.md b/BUILD.md index 674f0d24cc..e1935bd1c5 100644 --- a/BUILD.md +++ b/BUILD.md @@ -25,6 +25,8 @@ In order for CMake to find the Qt5 find modules, you will need to set an ENV var For example, a Qt5 5.2.0 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.0/clang_64/lib/cmake/ + ... or ... + export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake The path it needs to be set to will depend on where and how Qt5 was installed. From f13c7634ad8af64fc2369fd897fd24f76f61200a Mon Sep 17 00:00:00 2001 From: mpursley Date: Mon, 7 Jul 2014 01:08:11 -0700 Subject: [PATCH 08/43] adding "export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.2.1/lib/cmake" for qt5.2.1 --- BUILD.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BUILD.md b/BUILD.md index e1935bd1c5..93aafcc3e0 100644 --- a/BUILD.md +++ b/BUILD.md @@ -24,11 +24,12 @@ In order for CMake to find the Qt5 find modules, you will need to set an ENV var For example, a Qt5 5.2.0 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). +The path it needs to be set to will depend on where and how Qt5 was installed. e.g. + export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.0/clang_64/lib/cmake/ - ... or ... + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.2.1/lib/cmake export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake -The path it needs to be set to will depend on where and how Qt5 was installed. ####Generating build files Create a build directory in the root of your checkout and then run the CMake build from there. This will keep the rest of the directory clean. From 94e81da5575aa2aa9a3b3cb48053426404f8e5b7 Mon Sep 17 00:00:00 2001 From: TonyPeng Date: Tue, 8 Jul 2014 09:44:28 -0700 Subject: [PATCH 09/43] Added local lights to avatar. Added haze to voxel. --- interface/resources/shaders/model.frag | 19 ++- interface/resources/shaders/model.vert | 9 ++ .../resources/shaders/model_normal_map.frag | 7 +- interface/resources/shaders/skin_model.vert | 11 ++ interface/src/avatar/Avatar.cpp | 35 +++++- interface/src/avatar/Avatar.h | 14 ++- interface/src/renderer/Model.cpp | 1 + interface/src/voxels/VoxelSystem.cpp | 118 +++++++++++++++++- interface/src/voxels/VoxelSystem.h | 14 ++- 9 files changed, 218 insertions(+), 10 deletions(-) diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 488736abf9..86bc10179c 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +const int MAX_LOCAL_LIGHTS = 4; + // the diffuse texture uniform sampler2D diffuseMap; @@ -20,13 +22,27 @@ varying vec4 position; // the interpolated normal varying vec4 normal; +// static local light position +varying vec4 localLightPos[MAX_LOCAL_LIGHTS]; + void main(void) { // compute the base color based on OpenGL lighting model vec4 normalizedNormal = normalize(normal); float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse); + + // the local light that is always present + vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0); + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + float localDiffuse = dot(normalizedNormal, localLightPos[i]); + float localLight = step(0.0, localDiffuse); + float localLightVal = localDiffuse * localLight; + + totalLocalLight += (localLightVal * gl_LightSource[i+1].diffuse); + } + vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), @@ -35,4 +51,5 @@ void main(void) { // modulate texture by base color and add specular contribution gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); + } diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index da7e9640d9..06ad8a3300 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -11,12 +11,17 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +const int MAX_LOCAL_LIGHTS = 4; + // the interpolated position varying vec4 position; // the interpolated normal varying vec4 normal; +// local light position that is always present +varying vec4 localLightPos[MAX_LOCAL_LIGHTS]; + void main(void) { // transform and store the normal for interpolation @@ -36,4 +41,8 @@ void main(void) { // use standard pipeline transform gl_Position = ftransform(); + + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + localLightPos[i] = gl_ModelViewMatrixInverse * gl_LightSource[i+1].position; + } } diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 8444f2d6ea..ca0201f6ab 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -37,9 +37,14 @@ void main(void) { normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); float diffuse = dot(viewNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse); + float localDiffuse = dot(viewNormal, gl_LightSource[1].position); + float localLight = step(0.0, localDiffuse); vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + gl_FrontLightProduct[1].diffuse * (localDiffuse * localLight)); + + + // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal)); diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index d68347d33d..44f33da3e2 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -13,6 +13,7 @@ const int MAX_CLUSTERS = 128; const int INDICES_PER_VERTEX = 4; +const int MAX_LOCAL_LIGHTS = 4; uniform mat4 clusterMatrices[MAX_CLUSTERS]; @@ -25,6 +26,9 @@ varying vec4 position; // the interpolated normal varying vec4 normal; +// static local light position (inverse from eye space) +varying vec4 localLightPos[MAX_LOCAL_LIGHTS]; + void main(void) { position = vec4(0.0, 0.0, 0.0, 0.0); normal = vec4(0.0, 0.0, 0.0, 0.0); @@ -34,6 +38,7 @@ void main(void) { position += clusterMatrix * gl_Vertex * clusterWeight; normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; } + position = gl_ModelViewMatrix * position; normal = normalize(gl_ModelViewMatrix * normal); @@ -47,4 +52,10 @@ void main(void) { gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0); gl_Position = gl_ProjectionMatrix * position; + + // inverse view to make the light source position static + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + localLightPos[i] = gl_ModelViewMatrixInverse * gl_LightSource[i+1].position; + } + } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9b136980f4..38dbb02a14 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -81,6 +82,16 @@ void Avatar::init() { _initialized = true; _shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE); initializeHair(); + + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + _localLightColors[i] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + _localLightDirections[i] = glm::vec3(0.0f, 0.0f, 1.0f); + } + + // initialize first light + _localLightColors[0].r = 0.2f; _localLightColors[0].g = 0.2f, _localLightColors[0].b = 0.2f; + _localLightDirections[0].x = 1.0f; _localLightDirections[0].y = 0.0f; _localLightDirections[0].z = 0.0f; + } glm::vec3 Avatar::getChestPosition() const { @@ -219,7 +230,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { const float GLOW_DISTANCE = 20.0f; const float GLOW_MAX_LOUDNESS = 2500.0f; const float MAX_GLOW = 0.5f; - + float GLOW_FROM_AVERAGE_LOUDNESS = ((this == Application::getInstance()->getAvatar()) ? 0.0f : MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS); @@ -230,7 +241,17 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE ? 1.0f : GLOW_FROM_AVERAGE_LOUDNESS; - + + + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + glm::vec3 normalized = glm::normalize(_localLightDirections[i]); + glm::vec4 localLight = glm::vec4(normalized, 1.0f); + + // local light parameters + glLightfv(GL_LIGHT1 + i, GL_POSITION, glm::value_ptr(localLight)); + glLightfv(GL_LIGHT1 + i, GL_DIFFUSE, glm::value_ptr(_localLightColors[i])); + } + // render body if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { renderBody(renderMode, glowLevel); @@ -1107,3 +1128,13 @@ void Avatar::setShowDisplayName(bool showDisplayName) { } +void Avatar::setLocalLightDirection(const glm::vec3& direction, int lightIndex) { + _localLightDirections[lightIndex] = direction; + qDebug( "set light %d direction ( %f, %f, %f )\n", lightIndex, direction.x, direction.y, direction.z ); +} + +void Avatar::setLocalLightColor(const glm::vec4& color, int lightIndex) { + _localLightColors[lightIndex] = color; + qDebug( "set light %d color ( %f, %f, %f )\n", lightIndex, color.x, color.y, color.z ); +} + diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index f20db1019d..059264d43a 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -36,6 +36,8 @@ const int HAIR_STRANDS = 150; // Number of strands of hair const int HAIR_LINKS = 10; // Number of links in a hair strand const int HAIR_MAX_CONSTRAINTS = 2; // Hair verlet is connected to at most how many others +const int MAX_LOCAL_LIGHTS = 6; + enum DriveKeys { FWD = 0, BACK, @@ -154,7 +156,9 @@ public: public slots: void updateCollisionGroups(); - + void setLocalLightDirection(const glm::vec3& direction, int lightIndex); + void setLocalLightColor(const glm::vec4& color, int lightIndex); + signals: void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision); @@ -174,9 +178,13 @@ protected: glm::vec3 _mouseRayDirection; float _stringLength; bool _moving; ///< set when position is changing - + quint32 _collisionGroups; - + + // always-present local lighting for the avatar + glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; + glm::vec4 _localLightColors[MAX_LOCAL_LIGHTS]; + // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 723297f6b4..6fe57ea705 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1488,6 +1488,7 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re if (cascadedShadows) { program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances()); } + } else { glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]); program->bind(); diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index ca79967109..109d561306 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -21,6 +21,8 @@ #include #include +#include + #include "Application.h" #include "InterfaceConfig.h" #include "Menu.h" @@ -67,7 +69,13 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) _inOcclusions(false), _showCulledSharedFaces(false), _usePrimitiveRenderer(false), - _renderer(0) + _renderer(0), + _drawHaze(true), + _updateHaze(false), + _farHazeDistance(300.0f), + _hazeColor(0.24f, 0.27f, 0.34f), + _lastHazeCameraPosition(0.0f, 0.0f, 0.0f), + _lastYawAngle(0.0f) { _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; @@ -108,6 +116,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) _lastKnownVoxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE; _lastKnownBoundaryLevelAdjust = 0; + + _voxelColors = NULL; + _voxelPositions = NULL; } void VoxelSystem::elementDeleted(OctreeElement* element) { @@ -373,6 +384,9 @@ void VoxelSystem::cleanupVoxelMemory() { delete[] _readVoxelDirtyArray; _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; _readArraysLock.unlock(); + + delete[] _voxelColors; + delete[] _voxelPositions; } } @@ -521,11 +535,17 @@ void VoxelSystem::initVoxelMemory() { _shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances"); _cascadedShadowMapProgram.release(); } + } _renderer = new PrimitiveRenderer(_maxVoxels); _initialized = true; + _voxelColors = new xColor[_maxVoxels]; + memset(_voxelColors, 0, sizeof(xColor) *_maxVoxels); + + _voxelPositions = new glm::vec3[_maxVoxels]; + _writeArraysLock.unlock(); _readArraysLock.unlock(); } @@ -1114,6 +1134,7 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo node->setBufferIndex(nodeIndex); node->setVoxelSystem(this); } + // populate the array with points for the 8 vertices and RGB color for each added vertex updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); } @@ -1132,10 +1153,24 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex, float voxelScale, const nodeColor& color) { +// if (nodeIndex < 0 || nodeIndex > 1000) { +// return; +// } + if (_initialized && nodeIndex <= _maxVoxels) { _writeVoxelDirtyArray[nodeIndex] = true; - + + // cache the colors and position + _voxelColors[nodeIndex].red = color[0]; + _voxelColors[nodeIndex].green = color[1]; + _voxelColors[nodeIndex].blue = color[2]; + + // scaled voxel position + _voxelPositions[nodeIndex] = startVertex * (float)TREE_SCALE; + if (_useVoxelShader) { + // write in position, scale, and color for the voxel + if (_writeVoxelShaderData) { VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex]; writeVerticesAt->x = startVertex.x * TREE_SCALE; @@ -1157,9 +1192,85 @@ void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& } } } + + // want new color for haze + if (_drawHaze) { + _updateHaze = true; + } } } +void VoxelSystem::updateHazeColors() { + + // only update when player moves + if (_lastHazeCameraPosition != Application::getInstance()->getAvatar()->getPosition()) { + _updateHaze = true; + _lastHazeCameraPosition = Application::getInstance()->getAvatar()->getPosition(); + } + + // update when yaw angle changes + float avatarYaw = Application::getInstance()->getAvatar()->getBodyYaw(); + if (_lastYawAngle != avatarYaw) { + _updateHaze = true; + _lastYawAngle = avatarYaw; + } + + if (!_updateHaze) { + return; + } + + glm::vec3 cameraPosition = Application::getInstance()->getAvatar()->getPosition(); + float* hazeColor = glm::value_ptr(_hazeColor); + GLubyte* writeColorsAt = _writeColorsArray; + + // update voxel color + int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; + for (int i = 0; i < _voxelsInWriteArrays; i++) { + + float distanceToCamera = glm::length(_voxelPositions[i] - cameraPosition); + if(distanceToCamera > _farHazeDistance) { + distanceToCamera = _farHazeDistance; + } + + // how much haze there is at the distance + float hazeStrength = 1.0f - distanceToCamera / _farHazeDistance; + + // [0, 1] clamp + if (hazeStrength > 1.0f) { + hazeStrength = 1.0f; + } + else if (hazeStrength < 0.0f) { + hazeStrength = 0.0f; + } + + // color [0.0, 1.0] + float floatColor[] = {(float)_voxelColors[i].red / 255.0f, (float)_voxelColors[i].green / 255.0f, (float)_voxelColors[i].blue / 255.0f }; + assert(i >= 0 && i < _maxVoxels); + + // color * haze_strength + haze_color * (1.0 - haze_strength) + float oneMinusHazeStrength = 1.0f - hazeStrength; + nodeColor colorWithHaze = { + (unsigned char)((floatColor[0] * hazeStrength + hazeColor[0] * oneMinusHazeStrength) * 255.0f), + (unsigned char)((floatColor[1] * hazeStrength + hazeColor[1] * oneMinusHazeStrength) * 255.0f), + (unsigned char)((floatColor[2] * hazeStrength + hazeColor[2] * oneMinusHazeStrength) * 255.0f), + }; + + for (int j = 0; j < vertexPointsPerVoxel/3; j++ ) { + *(writeColorsAt + j*3) = colorWithHaze[0]; + *(writeColorsAt + j*3+1) = colorWithHaze[1]; + *(writeColorsAt + j*3+2) = colorWithHaze[2]; + } + + writeColorsAt += vertexPointsPerVoxel; + } + + copyWrittenDataToReadArraysFullVBOs(); + _voxelsDirty = true; + _readRenderFullVBO = true; + _updateHaze = false; + +} + glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const { const float* identityVertex = identityVertices + index * 3; return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale; @@ -1340,6 +1451,9 @@ void VoxelSystem::render() { return; } + if (!_useVoxelShader && _drawHaze) { + updateHazeColors(); + } updateVBOs(); // if not don't... then do... diff --git a/interface/src/voxels/VoxelSystem.h b/interface/src/voxels/VoxelSystem.h index ae8752605a..08f44a4d92 100644 --- a/interface/src/voxels/VoxelSystem.h +++ b/interface/src/voxels/VoxelSystem.h @@ -273,7 +273,19 @@ private: static unsigned short _sSwizzledOcclusionBits[64]; ///< Swizzle value of bit pairs of the value of index static unsigned char _sOctantIndexToBitMask[8]; ///< Map octant index to partition mask static unsigned char _sOctantIndexToSharedBitMask[8][8]; ///< Map octant indices to shared partition mask - + + // haze + xColor* _voxelColors; ///< Cached Voxel Colors + glm::vec3* _voxelPositions; ///< Cached Voxel Positions + bool _drawHaze; + bool _updateHaze; + float _farHazeDistance; + glm::vec3 _hazeColor; + glm::vec3 _lastHazeCameraPosition; + float _lastYawAngle; + + + void updateHazeColors(); }; #endif // hifi_VoxelSystem_h From db1a9fa09b40c36ef0e751323db066880211b2df Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 10:14:41 -0700 Subject: [PATCH 10/43] Fix for streaming error. --- libraries/metavoxels/src/MetavoxelClientManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index e69794917f..f16b6c2396 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -143,6 +143,9 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); _reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD(); + PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); + _remoteDataLOD = receiveRecord->getLOD(); + _remoteData = receiveRecord->getData(); } } else { Endpoint::handleMessage(message, in); From 1baa187a668e240b0ca8f33ea831c407f4a05ac5 Mon Sep 17 00:00:00 2001 From: TonyPeng Date: Tue, 8 Jul 2014 10:37:42 -0700 Subject: [PATCH 11/43] add javascript example for changing avatar's local lights. --- examples/avatarLocalLight.js | 125 +++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 examples/avatarLocalLight.js diff --git a/examples/avatarLocalLight.js b/examples/avatarLocalLight.js new file mode 100644 index 0000000000..600713a037 --- /dev/null +++ b/examples/avatarLocalLight.js @@ -0,0 +1,125 @@ +// +// avatarLocalLight.js +// +// Created by Tony Peng on July 2nd, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// Set the local light direction and color on the avatar +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var localLightDirections = [ {x: 1.0, y:0.0, z: 0.0}, {x: 0.0, y:1.0, z: 1.0}, {x: 0.0, y:0.0, z: 1.0}, {x: 1.0, y:1.0, z: 1.0} ]; +var localLightColors = [ {x: 0.0, y:0.0, z: 0.0, w: 1.0}, {x: 0.0, y:0.0, z: 0.0, w: 1.0}, {x: 0.0, y:0.0, z: 0.0, w: 1.0}, {x: 0.0, y:0.0, z: 0.0, w: 1.0} ]; + +var currentSelection = 0; +var currentNumLights = 1; + +function keyPressEvent(event) { + + var choice = parseInt(event.text); + + if (event.text == "1") { + currentSelection = 0; + print("selection = " + currentSelection); + } + else if (event.text == "2" ) { + currentSelection = 1; + print("selection = " + currentSelection); + } + else if (event.text == "3" ) { + currentSelection = 2; + print("selection = " + currentSelection); + } + else if (event.text == "4" ) { + currentSelection = 3; + print("selection = " + currentSelection); + } + else if (event.text == "5" ) { + localLightColors[currentSelection].x += 0.01; + if ( localLightColors[currentSelection].x > 1.0) { + localLightColors[currentSelection].x = 0.0; + } + + MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection); + } + else if (event.text == "6" ) { + localLightColors[currentSelection].y += 0.01; + if ( localLightColors[currentSelection].y > 1.0) { + localLightColors[currentSelection].y = 0.0; + } + + MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection); + } + else if (event.text == "7" ) { + localLightColors[currentSelection].z += 0.01; + if ( localLightColors[currentSelection].z > 1.0) { + localLightColors[currentSelection].z = 0.0; + } + + MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection); + } + else if (event.text == "8" ) { + localLightDirections[currentSelection].x += 0.01; + if (localLightDirections[currentSelection].x > 1.0) { + localLightDirections[currentSelection].x = -1.0; + } + + MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection); + } + else if (event.text == "9" ) { + localLightDirections[currentSelection].x -= 0.01; + if (localLightDirections[currentSelection].x < -1.0) { + localLightDirections[currentSelection].x = 1.0; + } + + MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection); + } + else if (event.text == "[" ) { + localLightDirections[currentSelection].y += 0.01; + if (localLightDirections[currentSelection].y > 1.0) { + localLightDirections[currentSelection].y = -1.0; + } + + MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection); + } + else if (event.text == "]" ) { + localLightDirections[currentSelection].y -= 0.01; + if (localLightDirections[currentSelection].y < -1.0) { + localLightDirections[currentSelection].y = 1.0; + } + + MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection); + } + else if (event.text == "+" ) { + if (currentNumLights + 1 < 4) { + + // default light + localLightColors[currentNumLights].x = 0.1; + localLightColors[currentNumLights].y = 0.1; + localLightColors[currentNumLights].z = 0.1; + + MyAvatar.setLocalLightColor(localLightColors[currentNumLights], currentNumLights); + MyAvatar.setLocalLightDirection(localLightDirections[currentNumLights], currentNumLights); + + ++currentNumLights; + } + } + else if (event.text == "-" ) { + if (currentNumLights - 1 >= 0 ) { + + // no light contribution + localLightColors[currentNumLights - 1].x = 0.0; + localLightColors[currentNumLights - 1].y = 0.0; + localLightColors[currentNumLights - 1].z = 0.0; + + MyAvatar.setLocalLightColor(localLightColors[currentNumLights - 1], currentNumLights - 1); + + --currentNumLights; + } + } + +} + +Controller.keyPressEvent.connect(keyPressEvent); From 0e117966f703e51e505eff1c25a27b6fc50d5030 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Jul 2014 11:43:06 -0700 Subject: [PATCH 12/43] better clapping --- examples/clap.js | 153 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 44 deletions(-) diff --git a/examples/clap.js b/examples/clap.js index 9da36ba094..7a2a77afc4 100644 --- a/examples/clap.js +++ b/examples/clap.js @@ -10,27 +10,34 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -function length(v) { - return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); -} +var clapAnimation = "https://s3-us-west-1.amazonaws.com/highfidelity-public/animations/ClapAnimations/ClapHands_Standing.fbx"; +var startEndFrames = []; +startEndFrames.push({ start: 0, end: 8}); +startEndFrames.push({ start: 10, end: 20}); +startEndFrames.push({ start: 20, end: 28}); +startEndFrames.push({ start: 30, end: 37}); +startEndFrames.push({ start: 41, end: 46}); +startEndFrames.push({ start: 53, end: 58}); +var lastClapFrame = 0; +var lastAnimFrame = 0; -function printVector(v) { - print(v.x + ", " + v.y + ", " + v.z + "\n"); -} +var claps = []; +claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap1Reverb.wav")); +claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap2Reverb.wav")); +claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap3Reverb.wav")); +claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap4Reverb.wav")); +claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap5Reverb.wav")); +claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap6Reverb.wav")); +var numberOfSounds = claps.length; -function vMinus(a, b) { - var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }; - return rval; -} +var clappingNow = false; +var collectedClicks = 0; -// First, load the clap sound from a URL -var clap1 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/clap1.raw"); -var clap2 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/clap2.raw"); -var clap3 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/clap3.raw"); -var clap4 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/clap4.raw"); -var clap5 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/clap5.raw"); -var clap6 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/clap6.raw"); +var clickClappingNow = false; +var CLAP_START_RATE = 15.0; +var clapRate = CLAP_START_RATE; +var startedTimer = false; var clapping = new Array(); clapping[0] = false; @@ -38,36 +45,94 @@ clapping[1] = false; function maybePlaySound(deltaTime) { // Set the location and other info for the sound to play - var palm1Position = Controller.getSpatialControlPosition(0); - var palm2Position = Controller.getSpatialControlPosition(2); - var distanceBetween = length(vMinus(palm1Position, palm2Position)); - for (var palm = 0; palm < 2; palm++) { - var palmVelocity = Controller.getSpatialControlVelocity(palm * 2 + 1); - var speed = length(palmVelocity); - - const CLAP_SPEED = 0.2; - const CLAP_DISTANCE = 0.2; + var animationDetails = MyAvatar.getAnimationDetails(clapAnimation); - if (!clapping[palm] && (distanceBetween < CLAP_DISTANCE) && (speed > CLAP_SPEED)) { - var options = new AudioInjectionOptions(); - options.position = palm1Position; - options.volume = speed / 2.0; - if (options.volume > 1.0) options.volume = 1.0; - which = Math.floor((Math.random() * 6) + 1); - if (which == 1) { Audio.playSound(clap1, options); } - else if (which == 2) { Audio.playSound(clap2, options); } - else if (which == 3) { Audio.playSound(clap3, options); } - else if (which == 4) { Audio.playSound(clap4, options); } - else if (which == 5) { Audio.playSound(clap5, options); } - else { Audio.playSound(clap6, options); } - Audio.playSound(clap, options); - clapping[palm] = true; - } else if (clapping[palm] && (speed < (CLAP_SPEED / 4.0))) { - clapping[palm] = false; - } + var frame = Math.floor(animationDetails.frameIndex); + + if (frame != lastAnimFrame) { + print("frame " + frame); + lastAnimFrame = frame; + } + for (var i = 0; i < startEndFrames.length; i++) { + if (frame == startEndFrames[i].start && (frame != lastClapFrame)) { + playClap(1.0, Camera.getPosition()); + lastClapFrame = frame; + } + } + + var palm1Position = MyAvatar.getLeftPalmPosition(); + var palm2Position = MyAvatar.getRightPalmPosition(); + var distanceBetween = Vec3.length(Vec3.subtract(palm1Position, palm2Position)); + + var palm1Velocity = Controller.getSpatialControlVelocity(1); + var palm2Velocity = Controller.getSpatialControlVelocity(3); + var closingVelocity = Vec3.length(Vec3.subtract(palm1Velocity, palm2Velocity)); + + const CLAP_SPEED = 0.7; + const CLAP_DISTANCE = 0.15; + + if ((closingVelocity > CLAP_SPEED) && (distanceBetween < CLAP_DISTANCE) && !clappingNow) { + var volume = closingVelocity / 2.0; + if (volume > 1.0) volume = 1.0; + playClap(volume, palm1Position); + clappingNow = true; + } else if (clappingNow && (distanceBetween > CLAP_DISTANCE * 1.2)) { + clappingNow = false; } } +function playClap(volume, position) { + var options = new AudioInjectionOptions(); + options.position = position; + options.volume = 1.0; + var clip = Math.floor(Math.random() * numberOfSounds); + Audio.playSound(claps[clip], options); +} + +function keepClapping() { + playClap(1.0, Camera.getPosition()); +} + +Controller.keyPressEvent.connect(function(event) { + if(event.text == "SHIFT") { + if (!clickClappingNow) { + playClap(1.0, Camera.getPosition()); + var whichClip = Math.floor(Math.random() * startEndFrames.length); + lastClapFrame = 0; + MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false); + clickClappingNow = true; + } else { + clapRate *= 1.25; + MyAvatar.stopAnimation(clapAnimation); + MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false); + collectedClicks = collectedClicks + 1; + } + } +}); + +var CLAP_END_WAIT_MSECS = 500; +Controller.keyReleaseEvent.connect(function(event) { + if (event.text == "SHIFT") { + if (!startedTimer) { + startedTimer = true; + collectedClicks = 0; + Script.setTimeout(stopClapping, CLAP_END_WAIT_MSECS); + } + } +}); + +function stopClapping() { + if (collectedClicks == 0) { + startedTimer = false; + MyAvatar.stopAnimation(clapAnimation); + clapRate = CLAP_START_RATE; + clickClappingNow = false; + } else { + startedTimer = false; + } +} + // Connect a call back that happens every frame -Script.update.connect(maybePlaySound); \ No newline at end of file +Script.update.connect(maybePlaySound); +//Controller.keyPressEvent.connect(keyPressEvent); \ No newline at end of file From 84aa4b9cda859f73751b3a3f8573bfb379d2cb60 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Jul 2014 11:59:10 -0700 Subject: [PATCH 13/43] use compiler default C++ Standard Library on OS X --- CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2451ab240a..b8566dd050 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,14 +32,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) -if (APPLE) - exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION) - string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) - if (DARWIN_VERSION GREATER 12) - set(CMAKE_CXX_FLAGS "-stdlib=libstdc++") - endif (DARWIN_VERSION GREATER 12) -endif (APPLE) - # targets not supported on windows if (NOT WIN32) add_subdirectory(animation-server) From d1afe127c3e47db8d754ce2afc92900391de702d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Jul 2014 12:06:43 -0700 Subject: [PATCH 14/43] updates to RtMidi find module to look for static or dynamic lib --- cmake/modules/FindRtMidi.cmake | 4 ++-- interface/CMakeLists.txt | 28 +++++++++++++--------------- interface/external/rtmidi/readme.txt | 4 +++- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cmake/modules/FindRtMidi.cmake b/cmake/modules/FindRtMidi.cmake index a54cc483e1..ad1167c5d6 100644 --- a/cmake/modules/FindRtMidi.cmake +++ b/cmake/modules/FindRtMidi.cmake @@ -26,8 +26,8 @@ else () set(RTMIDI_SEARCH_DIRS "${RTMIDI_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/rtmidi") find_path(RTMIDI_INCLUDE_DIR RtMidi.h PATH_SUFFIXES include HINTS ${RTMIDI_SEARCH_DIRS}) - find_file(RTMIDI_CPP NAMES RtMidi.cpp PATH_SUFFIXES src HINTS ${RTMIDI_SEARCH_DIRS}) + find_library(RTMIDI_LIBRARY NAMES rtmidi PATH_SUFFIXES lib HINTS ${RTMIDI_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(RTMIDI DEFAULT_MSG RTMIDI_INCLUDE_DIR RTMIDI_CPP) + find_package_handle_standard_args(RTMIDI DEFAULT_MSG RTMIDI_INCLUDE_DIR RTMIDI_LIBRARY) endif () \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 68ba2761aa..49a6da7438 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -111,16 +111,6 @@ if (APPLE) SET(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/interface.icns") endif() -# RtMidi for scripted MIDI control -find_package(RtMidi) - -if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI) - add_definitions(-DHAVE_RTMIDI) - include_directories(SYSTEM ${RTMIDI_INCLUDE_DIR}) - - set(INTERFACE_SRCS ${INTERFACE_SRCS} "${RTMIDI_CPP}") -endif () - # create the executable, make it a bundle on OS X add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM}) @@ -151,6 +141,7 @@ find_package(Sixense) find_package(Visage) find_package(ZLIB) find_package(Qxmpp) +find_package(RtMidi) # include the Sixense library for Razer Hydra if available if (SIXENSE_FOUND AND NOT DISABLE_SIXENSE) @@ -223,11 +214,18 @@ if (QXMPP_FOUND AND NOT DISABLE_QXMPP) target_link_libraries(${TARGET_NAME} "${QXMPP_LIBRARY}") endif (QXMPP_FOUND AND NOT DISABLE_QXMPP) -# link CoreMIDI if we're using RtMidi -if (RTMIDI_FOUND AND APPLE) - find_library(CoreMIDI CoreMIDI) - add_definitions(-D__MACOSX_CORE__) - target_link_libraries(${TARGET_NAME} ${CoreMIDI}) +# and with RtMidi for RtMidi control +if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI) + + add_definitions(-DHAVE_RTMIDI) + include_directories(SYSTEM ${RTMIDI_INCLUDE_DIR}) + target_link_libraries(${TARGET_NAME} "${RTMIDI_LIBRARY}") + + if (APPLE) + find_library(CoreMIDI CoreMIDI) + add_definitions(-D__MACOSX_CORE__) + target_link_libraries(${TARGET_NAME} ${CoreMIDI}) + endif() endif() # include headers for interface and InterfaceConfig. diff --git a/interface/external/rtmidi/readme.txt b/interface/external/rtmidi/readme.txt index d83d0c293e..d0480fce4a 100644 --- a/interface/external/rtmidi/readme.txt +++ b/interface/external/rtmidi/readme.txt @@ -7,7 +7,9 @@ Stephen Birarda, June 30, 2014 2. Copy RtMidi.h to externals/rtmidi/include. -3. Copy RtMidi.cpp to externals/rtmidi/src +3. Compile the RtMidi library. + +3. Copy either librtmidi.dylib (dynamic) or librtmidi.a (static) to externals/rtmidi/lib 4. Delete your build directory, run cmake and build, and you should be all set. From 4e04cecd8c9b3b7291aa63d0b41d49b68d7e69f5 Mon Sep 17 00:00:00 2001 From: TonyPeng Date: Tue, 8 Jul 2014 12:28:44 -0700 Subject: [PATCH 15/43] Use glFog for haze (better performance). --- interface/src/voxels/VoxelSystem.cpp | 122 ++++----------------------- interface/src/voxels/VoxelSystem.h | 8 -- 2 files changed, 16 insertions(+), 114 deletions(-) diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 109d561306..ee8b306ef3 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -70,12 +70,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) _showCulledSharedFaces(false), _usePrimitiveRenderer(false), _renderer(0), - _drawHaze(true), - _updateHaze(false), + _drawHaze(false), _farHazeDistance(300.0f), - _hazeColor(0.24f, 0.27f, 0.34f), - _lastHazeCameraPosition(0.0f, 0.0f, 0.0f), - _lastYawAngle(0.0f) + _hazeColor(0.24f, 0.27f, 0.34f) { _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; @@ -116,9 +113,6 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) _lastKnownVoxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE; _lastKnownBoundaryLevelAdjust = 0; - - _voxelColors = NULL; - _voxelPositions = NULL; } void VoxelSystem::elementDeleted(OctreeElement* element) { @@ -384,9 +378,7 @@ void VoxelSystem::cleanupVoxelMemory() { delete[] _readVoxelDirtyArray; _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; _readArraysLock.unlock(); - - delete[] _voxelColors; - delete[] _voxelPositions; + } } @@ -468,6 +460,7 @@ void VoxelSystem::initVoxelMemory() { _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); + } else { // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead @@ -540,14 +533,21 @@ void VoxelSystem::initVoxelMemory() { _renderer = new PrimitiveRenderer(_maxVoxels); _initialized = true; - - _voxelColors = new xColor[_maxVoxels]; - memset(_voxelColors, 0, sizeof(xColor) *_maxVoxels); - - _voxelPositions = new glm::vec3[_maxVoxels]; _writeArraysLock.unlock(); _readArraysLock.unlock(); + + // fog for haze + if(_drawHaze) { + GLfloat fogColor[] = {_hazeColor.x, _hazeColor.y, _hazeColor.z, 1.0f}; + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogfv(GL_FOG_COLOR, fogColor); + glFogf(GL_FOG_DENSITY, 0.25f); + glHint(GL_FOG_HINT, GL_DONT_CARE); + glFogf(GL_FOG_START, 20.0f); + glFogf(GL_FOG_END, _farHazeDistance); + glEnable(GL_FOG); + } } int VoxelSystem::parseData(const QByteArray& packet) { @@ -1152,22 +1152,10 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex, float voxelScale, const nodeColor& color) { - -// if (nodeIndex < 0 || nodeIndex > 1000) { -// return; -// } if (_initialized && nodeIndex <= _maxVoxels) { _writeVoxelDirtyArray[nodeIndex] = true; - // cache the colors and position - _voxelColors[nodeIndex].red = color[0]; - _voxelColors[nodeIndex].green = color[1]; - _voxelColors[nodeIndex].blue = color[2]; - - // scaled voxel position - _voxelPositions[nodeIndex] = startVertex * (float)TREE_SCALE; - if (_useVoxelShader) { // write in position, scale, and color for the voxel @@ -1193,84 +1181,9 @@ void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& } } - // want new color for haze - if (_drawHaze) { - _updateHaze = true; - } } } -void VoxelSystem::updateHazeColors() { - - // only update when player moves - if (_lastHazeCameraPosition != Application::getInstance()->getAvatar()->getPosition()) { - _updateHaze = true; - _lastHazeCameraPosition = Application::getInstance()->getAvatar()->getPosition(); - } - - // update when yaw angle changes - float avatarYaw = Application::getInstance()->getAvatar()->getBodyYaw(); - if (_lastYawAngle != avatarYaw) { - _updateHaze = true; - _lastYawAngle = avatarYaw; - } - - if (!_updateHaze) { - return; - } - - glm::vec3 cameraPosition = Application::getInstance()->getAvatar()->getPosition(); - float* hazeColor = glm::value_ptr(_hazeColor); - GLubyte* writeColorsAt = _writeColorsArray; - - // update voxel color - int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; - for (int i = 0; i < _voxelsInWriteArrays; i++) { - - float distanceToCamera = glm::length(_voxelPositions[i] - cameraPosition); - if(distanceToCamera > _farHazeDistance) { - distanceToCamera = _farHazeDistance; - } - - // how much haze there is at the distance - float hazeStrength = 1.0f - distanceToCamera / _farHazeDistance; - - // [0, 1] clamp - if (hazeStrength > 1.0f) { - hazeStrength = 1.0f; - } - else if (hazeStrength < 0.0f) { - hazeStrength = 0.0f; - } - - // color [0.0, 1.0] - float floatColor[] = {(float)_voxelColors[i].red / 255.0f, (float)_voxelColors[i].green / 255.0f, (float)_voxelColors[i].blue / 255.0f }; - assert(i >= 0 && i < _maxVoxels); - - // color * haze_strength + haze_color * (1.0 - haze_strength) - float oneMinusHazeStrength = 1.0f - hazeStrength; - nodeColor colorWithHaze = { - (unsigned char)((floatColor[0] * hazeStrength + hazeColor[0] * oneMinusHazeStrength) * 255.0f), - (unsigned char)((floatColor[1] * hazeStrength + hazeColor[1] * oneMinusHazeStrength) * 255.0f), - (unsigned char)((floatColor[2] * hazeStrength + hazeColor[2] * oneMinusHazeStrength) * 255.0f), - }; - - for (int j = 0; j < vertexPointsPerVoxel/3; j++ ) { - *(writeColorsAt + j*3) = colorWithHaze[0]; - *(writeColorsAt + j*3+1) = colorWithHaze[1]; - *(writeColorsAt + j*3+2) = colorWithHaze[2]; - } - - writeColorsAt += vertexPointsPerVoxel; - } - - copyWrittenDataToReadArraysFullVBOs(); - _voxelsDirty = true; - _readRenderFullVBO = true; - _updateHaze = false; - -} - glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const { const float* identityVertex = identityVertices + index * 3; return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale; @@ -1451,9 +1364,6 @@ void VoxelSystem::render() { return; } - if (!_useVoxelShader && _drawHaze) { - updateHazeColors(); - } updateVBOs(); // if not don't... then do... diff --git a/interface/src/voxels/VoxelSystem.h b/interface/src/voxels/VoxelSystem.h index 08f44a4d92..9f61e0579c 100644 --- a/interface/src/voxels/VoxelSystem.h +++ b/interface/src/voxels/VoxelSystem.h @@ -275,17 +275,9 @@ private: static unsigned char _sOctantIndexToSharedBitMask[8][8]; ///< Map octant indices to shared partition mask // haze - xColor* _voxelColors; ///< Cached Voxel Colors - glm::vec3* _voxelPositions; ///< Cached Voxel Positions bool _drawHaze; - bool _updateHaze; float _farHazeDistance; glm::vec3 _hazeColor; - glm::vec3 _lastHazeCameraPosition; - float _lastYawAngle; - - - void updateHazeColors(); }; #endif // hifi_VoxelSystem_h From e212f9f42eb56e7faf4722241f5eef8cd4090a94 Mon Sep 17 00:00:00 2001 From: TonyPeng Date: Tue, 8 Jul 2014 12:48:01 -0700 Subject: [PATCH 16/43] Change fog start to use default value. --- interface/src/voxels/VoxelSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index ee8b306ef3..e76a1cee7f 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -544,7 +544,7 @@ void VoxelSystem::initVoxelMemory() { glFogfv(GL_FOG_COLOR, fogColor); glFogf(GL_FOG_DENSITY, 0.25f); glHint(GL_FOG_HINT, GL_DONT_CARE); - glFogf(GL_FOG_START, 20.0f); + glFogf(GL_FOG_START, 0.0f); glFogf(GL_FOG_END, _farHazeDistance); glEnable(GL_FOG); } From 02cf1f006e14a4f2fde6db2e85ea159934778d8f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 13:41:42 -0700 Subject: [PATCH 17/43] Change tests to reflect transmission changes and fixed issue with reprocessing already-handled reliable delta. --- .../src/metavoxels/MetavoxelServer.cpp | 9 ++++--- .../src/metavoxels/MetavoxelServer.h | 1 + .../metavoxels/src/MetavoxelClientManager.cpp | 8 ++++-- .../metavoxels/src/MetavoxelClientManager.h | 1 + libraries/metavoxels/src/MetavoxelMessages.h | 4 +++ tests/metavoxels/src/MetavoxelTests.cpp | 27 +++++++++++++------ tests/metavoxels/src/MetavoxelTests.h | 3 +++ 7 files changed, 40 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index c601478f70..b0cf93fb3a 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -93,7 +93,8 @@ void MetavoxelServer::sendDeltas() { MetavoxelSession::MetavoxelSession(const SharedNodePointer& node, MetavoxelServer* server) : Endpoint(node, new PacketRecord(), NULL), _server(server), - _reliableDeltaChannel(NULL) { + _reliableDeltaChannel(NULL), + _reliableDeltaID(0) { connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleMessage(const QVariant&))); connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(checkReliableDeltaReceived())); @@ -109,7 +110,8 @@ void MetavoxelSession::update() { // if we're sending a reliable delta, wait until it's acknowledged if (_reliableDeltaChannel) { Bitstream& out = _sequencer.startPacket(); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); return; } @@ -134,7 +136,8 @@ void MetavoxelSession::update() { // go back to the beginning with the current packet and note that there's a delta pending _sequencer.getOutputStream().getUnderlying().device()->seek(start); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { ++_reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); } else { diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index f2769f26f2..0e8db55587 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -83,6 +83,7 @@ private: MetavoxelData _reliableDeltaData; MetavoxelLOD _reliableDeltaLOD; Bitstream::WriteMappings _reliableDeltaWriteMappings; + int _reliableDeltaID; }; #endif // hifi_MetavoxelServer_h diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index f16b6c2396..f3ea1ae8c5 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -87,7 +87,8 @@ void MetavoxelClientManager::updateClient(MetavoxelClient* client) { MetavoxelClient::MetavoxelClient(const SharedNodePointer& node, MetavoxelClientManager* manager) : Endpoint(node, new PacketRecord(), new PacketRecord()), _manager(manager), - _reliableDeltaChannel(NULL) { + _reliableDeltaChannel(NULL), + _reliableDeltaID(0) { connect(_sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX), SIGNAL(receivedMessage(const QVariant&, Bitstream&)), SLOT(handleMessage(const QVariant&, Bitstream&))); @@ -139,7 +140,10 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { } } } else if (userType == MetavoxelDeltaPendingMessage::Type) { - if (!_reliableDeltaChannel) { + // check the id to make sure this is not a delta we've already processed + int id = message.value().id; + if (id > _reliableDeltaID) { + _reliableDeltaID = id; _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); _reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD(); diff --git a/libraries/metavoxels/src/MetavoxelClientManager.h b/libraries/metavoxels/src/MetavoxelClientManager.h index 1f37b15c18..ad6c86c8fc 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.h +++ b/libraries/metavoxels/src/MetavoxelClientManager.h @@ -74,6 +74,7 @@ private: ReliableChannel* _reliableDeltaChannel; MetavoxelLOD _reliableDeltaLOD; + int _reliableDeltaID; }; #endif // hifi_MetavoxelClientManager_h diff --git a/libraries/metavoxels/src/MetavoxelMessages.h b/libraries/metavoxels/src/MetavoxelMessages.h index b822f1c561..91d73c08a9 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.h +++ b/libraries/metavoxels/src/MetavoxelMessages.h @@ -64,6 +64,10 @@ DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaMessage) /// A message indicating that metavoxel delta information is being sent on a reliable channel. class MetavoxelDeltaPendingMessage { STREAMABLE + +public: + + STREAM int id; }; DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaPendingMessage) diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 4132270620..49808fe080 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -647,7 +647,8 @@ TestEndpoint::TestEndpoint(Mode mode) : _mode(mode), _highPriorityMessagesToSend(0.0f), _reliableMessagesToSend(0.0f), - _reliableDeltaChannel(NULL) { + _reliableDeltaChannel(NULL), + _reliableDeltaID(0) { connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleHighPriorityMessage(const QVariant&))); @@ -908,7 +909,8 @@ bool TestEndpoint::simulate(int iterationNumber) { // if we're sending a reliable delta, wait until it's acknowledged if (_reliableDeltaChannel) { Bitstream& out = _sequencer.startPacket(); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); return false; } @@ -932,7 +934,8 @@ bool TestEndpoint::simulate(int iterationNumber) { _reliableDeltaLOD = _lod; _sequencer.getOutputStream().getUnderlying().device()->seek(start); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { ++_reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); } else { @@ -1081,15 +1084,22 @@ void TestEndpoint::handleMessage(const QVariant& message, Bitstream& in) { } else if (userType == MetavoxelDeltaMessage::Type) { PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); - _data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, - _dataLOD = getLastAcknowledgedSendRecord()->getLOD()); + _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, + _remoteDataLOD = getLastAcknowledgedSendRecord()->getLOD()); + in.reset(); + _data = _remoteData; compareMetavoxelData(); } else if (userType == MetavoxelDeltaPendingMessage::Type) { - if (!_reliableDeltaChannel) { + int id = message.value().id; + if (id > _reliableDeltaID) { + _reliableDeltaID = id; _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); _reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD(); + PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); + _remoteDataLOD = receiveRecord->getLOD(); + _remoteData = receiveRecord->getData(); } } else if (userType == QMetaType::QVariantList) { foreach (const QVariant& element, message.toList()) { @@ -1107,7 +1117,7 @@ PacketRecord* TestEndpoint::maybeCreateSendRecord() const { } PacketRecord* TestEndpoint::maybeCreateReceiveRecord() const { - return new TestReceiveRecord(_dataLOD, (_mode == METAVOXEL_SERVER_MODE) ? MetavoxelData() : _data, _remoteState); + return new TestReceiveRecord(_remoteDataLOD, _remoteData, _remoteState); } void TestEndpoint::handleHighPriorityMessage(const QVariant& message) { @@ -1127,9 +1137,10 @@ void TestEndpoint::handleHighPriorityMessage(const QVariant& message) { void TestEndpoint::handleReliableMessage(const QVariant& message, Bitstream& in) { if (message.userType() == MetavoxelDeltaMessage::Type) { PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); - _data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _dataLOD = _reliableDeltaLOD); + _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _remoteDataLOD = _reliableDeltaLOD); _sequencer.getInputStream().persistReadMappings(in.getAndResetReadMappings()); in.clearPersistentMappings(); + _data = _remoteData; compareMetavoxelData(); _reliableDeltaChannel = NULL; return; diff --git a/tests/metavoxels/src/MetavoxelTests.h b/tests/metavoxels/src/MetavoxelTests.h index 5d719ccfdf..ce357fbb90 100644 --- a/tests/metavoxels/src/MetavoxelTests.h +++ b/tests/metavoxels/src/MetavoxelTests.h @@ -79,6 +79,8 @@ private: MetavoxelData _data; MetavoxelLOD _dataLOD; + MetavoxelData _remoteData; + MetavoxelLOD _remoteDataLOD; MetavoxelLOD _lod; SharedObjectPointer _sphere; @@ -104,6 +106,7 @@ private: MetavoxelData _reliableDeltaData; MetavoxelLOD _reliableDeltaLOD; Bitstream::WriteMappings _reliableDeltaWriteMappings; + int _reliableDeltaID; }; /// A simple shared object. From 56361718369be6d464cbfd8bba02083675a4c67e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 14:41:16 -0700 Subject: [PATCH 18/43] Timing fix. --- assignment-client/src/metavoxels/MetavoxelServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index b0cf93fb3a..63776de7fa 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -87,7 +87,7 @@ void MetavoxelServer::sendDeltas() { int elapsed = now - _lastSend; _lastSend = now; - _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed)); + _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - qMax(elapsed, SEND_INTERVAL))); } MetavoxelSession::MetavoxelSession(const SharedNodePointer& node, MetavoxelServer* server) : From 40ad03dbf52ffcffb0498c73652d90a76e324e79 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Jul 2014 14:53:41 -0700 Subject: [PATCH 19/43] Another improvement to clapping to match animation pace with keystrokes --- examples/clap.js | 54 +++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/examples/clap.js b/examples/clap.js index 7a2a77afc4..35c344165f 100644 --- a/examples/clap.js +++ b/examples/clap.js @@ -1,23 +1,26 @@ // -// cameraExample.js +// clap.js // examples // // Copyright 2014 High Fidelity, Inc. // -// This sample script watches your hydra hands and makes clapping sound when they come close together fast +// This sample script watches your hydra hands and makes clapping sound when they come close together fast, +// and also watches for the 'shift' key and claps when that key is pressed. Clapping multiple times by pressing +// the shift key again makes the animation and sound match your pace of clapping. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // var clapAnimation = "https://s3-us-west-1.amazonaws.com/highfidelity-public/animations/ClapAnimations/ClapHands_Standing.fbx"; +var ANIMATION_FRAMES_PER_CLAP = 10.0; var startEndFrames = []; -startEndFrames.push({ start: 0, end: 8}); +startEndFrames.push({ start: 0, end: 10}); startEndFrames.push({ start: 10, end: 20}); -startEndFrames.push({ start: 20, end: 28}); -startEndFrames.push({ start: 30, end: 37}); -startEndFrames.push({ start: 41, end: 46}); -startEndFrames.push({ start: 53, end: 58}); +startEndFrames.push({ start: 20, end: 30}); +startEndFrames.push({ start: 30, end: 40}); +startEndFrames.push({ start: 41, end: 51}); +startEndFrames.push({ start: 53, end: 0}); var lastClapFrame = 0; var lastAnimFrame = 0; @@ -34,15 +37,12 @@ var numberOfSounds = claps.length; var clappingNow = false; var collectedClicks = 0; +var clickStartTime, clickEndTime; var clickClappingNow = false; var CLAP_START_RATE = 15.0; var clapRate = CLAP_START_RATE; var startedTimer = false; -var clapping = new Array(); -clapping[0] = false; -clapping[1] = false; - function maybePlaySound(deltaTime) { // Set the location and other info for the sound to play @@ -51,9 +51,9 @@ function maybePlaySound(deltaTime) { var frame = Math.floor(animationDetails.frameIndex); if (frame != lastAnimFrame) { - print("frame " + frame); lastAnimFrame = frame; } + for (var i = 0; i < startEndFrames.length; i++) { if (frame == startEndFrames[i].start && (frame != lastClapFrame)) { playClap(1.0, Camera.getPosition()); @@ -90,34 +90,41 @@ function playClap(volume, position) { Audio.playSound(claps[clip], options); } -function keepClapping() { - playClap(1.0, Camera.getPosition()); -} +var FASTEST_CLAP_INTERVAL = 100.0; +var SLOWEST_CLAP_INTERVAL = 2000.0; Controller.keyPressEvent.connect(function(event) { if(event.text == "SHIFT") { if (!clickClappingNow) { + clickClappingNow = true; + clickStartTime = new Date(); playClap(1.0, Camera.getPosition()); - var whichClip = Math.floor(Math.random() * startEndFrames.length); lastClapFrame = 0; MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false); - clickClappingNow = true; } else { - clapRate *= 1.25; - MyAvatar.stopAnimation(clapAnimation); - MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false); + // Adjust animation speed for measured clicking interval + clickEndTime = new Date(); + var milliseconds = clickEndTime - clickStartTime; + clickStartTime = new Date(); + if ((milliseconds < SLOWEST_CLAP_INTERVAL) && (milliseconds > FASTEST_CLAP_INTERVAL)) { + clapRate = ANIMATION_FRAMES_PER_CLAP * (1000.0 / milliseconds); + playClap(1.0, Camera.getPosition()); + MyAvatar.stopAnimation(clapAnimation); + MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false); + } collectedClicks = collectedClicks + 1; } } }); -var CLAP_END_WAIT_MSECS = 500; +var CLAP_END_WAIT_MSECS = 300; Controller.keyReleaseEvent.connect(function(event) { if (event.text == "SHIFT") { + collectedClicks = 0; if (!startedTimer) { - startedTimer = true; collectedClicks = 0; Script.setTimeout(stopClapping, CLAP_END_WAIT_MSECS); + startedTimer = true; } } }); @@ -134,5 +141,4 @@ function stopClapping() { } // Connect a call back that happens every frame -Script.update.connect(maybePlaySound); -//Controller.keyPressEvent.connect(keyPressEvent); \ No newline at end of file +Script.update.connect(maybePlaySound); \ No newline at end of file From b6570dc4ee83971e4cd8b480cf7eafaa5854a609 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 15:10:05 -0700 Subject: [PATCH 20/43] Use congestion control on server. --- .../src/metavoxels/MetavoxelServer.cpp | 22 +++++++++++++++---- .../src/metavoxels/MetavoxelServer.h | 2 ++ .../metavoxels/src/DatagramSequencer.cpp | 2 +- libraries/metavoxels/src/DatagramSequencer.h | 4 ++-- tests/metavoxels/src/MetavoxelTests.cpp | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 63776de7fa..14765e2ddc 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -109,10 +109,7 @@ void MetavoxelSession::update() { } // if we're sending a reliable delta, wait until it's acknowledged if (_reliableDeltaChannel) { - Bitstream& out = _sequencer.startPacket(); - MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; - out << QVariant::fromValue(msg); - _sequencer.endPacket(); + sendPacketGroup(); return; } Bitstream& out = _sequencer.startPacket(); @@ -143,6 +140,9 @@ void MetavoxelSession::update() { } else { _sequencer.endPacket(); } + + // perhaps send additional packets to fill out the group + sendPacketGroup(1); } void MetavoxelSession::handleMessage(const QVariant& message, Bitstream& in) { @@ -179,3 +179,17 @@ void MetavoxelSession::checkReliableDeltaReceived() { _reliableDeltaData = MetavoxelData(); _reliableDeltaChannel = NULL; } + +void MetavoxelSession::sendPacketGroup(int alreadySent) { + int additionalPackets = _sequencer.notePacketGroup() - alreadySent; + for (int i = 0; i < additionalPackets; i++) { + Bitstream& out = _sequencer.startPacket(); + if (_reliableDeltaChannel) { + MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; + out << QVariant::fromValue(msg); + } else { + out << QVariant(); + } + _sequencer.endPacket(); + } +} diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index 0e8db55587..6df769227c 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -74,6 +74,8 @@ private slots: private: + void sendPacketGroup(int alreadySent = 0); + MetavoxelServer* _server; MetavoxelLOD _lod; diff --git a/libraries/metavoxels/src/DatagramSequencer.cpp b/libraries/metavoxels/src/DatagramSequencer.cpp index 2c594fc1ca..536cfc9dfb 100644 --- a/libraries/metavoxels/src/DatagramSequencer.cpp +++ b/libraries/metavoxels/src/DatagramSequencer.cpp @@ -79,7 +79,7 @@ ReliableChannel* DatagramSequencer::getReliableInputChannel(int index) { return channel; } -int DatagramSequencer::startPacketGroup(int desiredPackets) { +int DatagramSequencer::notePacketGroup(int desiredPackets) { // figure out how much data we have enqueued and increase the number of packets desired int totalAvailable = 0; foreach (ReliableChannel* channel, _reliableOutputChannels) { diff --git a/libraries/metavoxels/src/DatagramSequencer.h b/libraries/metavoxels/src/DatagramSequencer.h index b85916b561..b6dce464f7 100644 --- a/libraries/metavoxels/src/DatagramSequencer.h +++ b/libraries/metavoxels/src/DatagramSequencer.h @@ -108,10 +108,10 @@ public: /// Returns the intput channel at the specified index, creating it if necessary. ReliableChannel* getReliableInputChannel(int index = 0); - /// Starts a packet group. + /// Notes that we're sending a group of packets. /// \param desiredPackets the number of packets we'd like to write in the group /// \return the number of packets to write in the group - int startPacketGroup(int desiredPackets = 1); + int notePacketGroup(int desiredPackets = 1); /// Starts a new packet for transmission. /// \return a reference to the Bitstream to use for writing to the packet diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 49808fe080..0a6a5de96d 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -859,7 +859,7 @@ bool TestEndpoint::simulate(int iterationNumber) { bytesReceived += datagram.size(); _remainingPipelineCapacity += datagram.size(); } - int packetCount = _sequencer.startPacketGroup(); + int packetCount = _sequencer.notePacketGroup(); groupsSent++; maxPacketsPerGroup = qMax(maxPacketsPerGroup, packetCount); for (int i = 0; i < packetCount; i++) { From 1b890a9e48ea88f27ff154db0851ee50c08d7754 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 15:37:59 -0700 Subject: [PATCH 21/43] Use congestion control for client sends, too. --- libraries/metavoxels/src/Endpoint.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/metavoxels/src/Endpoint.cpp b/libraries/metavoxels/src/Endpoint.cpp index 666ffe52d9..420a52ef95 100644 --- a/libraries/metavoxels/src/Endpoint.cpp +++ b/libraries/metavoxels/src/Endpoint.cpp @@ -39,9 +39,12 @@ Endpoint::~Endpoint() { } void Endpoint::update() { - Bitstream& out = _sequencer.startPacket(); - writeUpdateMessage(out); - _sequencer.endPacket(); + int packetsToSend = _sequencer.notePacketGroup(); + for (int i = 0; i < packetsToSend; i++) { + Bitstream& out = _sequencer.startPacket(); + writeUpdateMessage(out); + _sequencer.endPacket(); + } } int Endpoint::parseData(const QByteArray& packet) { From bc785115a938c36763e418e8707c88475270c1c7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 8 Jul 2014 16:33:31 -0700 Subject: [PATCH 22/43] Fix script errors not being reported Script.update event needs to be emitted after reporting any script errors. --- libraries/script-engine/src/ScriptEngine.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e93a7125b9..f5f15331ac 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -515,8 +515,6 @@ void ScriptEngine::run() { qint64 now = usecTimestampNow(); float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND; - emit update(deltaTime); - lastUpdate = now; if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); @@ -524,6 +522,9 @@ void ScriptEngine::run() { emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + _engine.uncaughtException().toString()); _engine.clearExceptions(); } + + emit update(deltaTime); + lastUpdate = now; } emit scriptEnding(); From b2912552f68e4acb394708ee2630442a9f090b59 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Jul 2014 21:00:02 -0700 Subject: [PATCH 23/43] switched to better sounds for clapping --- examples/clap.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/clap.js b/examples/clap.js index 35c344165f..28835c1f00 100644 --- a/examples/clap.js +++ b/examples/clap.js @@ -26,12 +26,16 @@ var lastClapFrame = 0; var lastAnimFrame = 0; var claps = []; -claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap1Reverb.wav")); -claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap2Reverb.wav")); -claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap3Reverb.wav")); -claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap4Reverb.wav")); -claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap5Reverb.wav")); -claps.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/claps/Clap6Reverb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap1Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap2Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap3Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap4Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap5Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap6Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap7Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap8Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap9Rvb.wav")); +claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap10Rvb.wav")); var numberOfSounds = claps.length; var clappingNow = false; From 1e7a18e62535e1f200158da3cb5360f4555535f3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 8 Jul 2014 21:02:32 -0700 Subject: [PATCH 24/43] Guard _framebufferObject deletion --- interface/src/ui/ApplicationOverlay.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 879c7cda32..302494852a 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -999,8 +999,10 @@ void ApplicationOverlay::renderTexturedHemisphere() { } void ApplicationOverlay::resize() { - delete _framebufferObject; - _framebufferObject = NULL; + if (_framebufferObject != NULL) { + delete _framebufferObject; + _framebufferObject = NULL; + } // _framebufferObject is recreated at the correct size the next time it is accessed via getFramebufferObject(). } From 51f7e8904d70325c11b2e4a144a9334e33fc2de5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 8 Jul 2014 21:04:30 -0700 Subject: [PATCH 25/43] Integrate UI toggling menu item and Hydra UI toggling They work together and both fade the UI in / out. --- interface/src/ui/ApplicationOverlay.cpp | 11 ++++++----- interface/src/ui/ApplicationOverlay.h | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 302494852a..b7e18df0b4 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -40,7 +40,6 @@ ApplicationOverlay::ApplicationOverlay() : _framebufferObject(NULL), _textureFov(DEFAULT_OCULUS_UI_ANGULAR_SIZE * RADIANS_PER_DEGREE), _alpha(1.0f), - _active(true), _crosshairTexture(0) { memset(_reticleActive, 0, sizeof(_reticleActive)); @@ -70,8 +69,8 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { QGLWidget* glWidget = application->getGLWidget(); MyAvatar* myAvatar = application->getAvatar(); - //Handle fadeing and deactivation/activation of UI - if (_active) { + //Handle fading and deactivation/activation of UI + if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { _alpha += FADE_SPEED; if (_alpha > 1.0f) { _alpha = 1.0f; @@ -485,7 +484,8 @@ void ApplicationOverlay::renderControllerPointers() { if (palmData->getTrigger() == 1.0f) { if (!triggerPressed[index]) { if (bumperPressed[index]) { - _active = !_active; + Menu::getInstance()->setIsOptionChecked(MenuOption::UserInterface, + !Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)); } triggerPressed[index] = true; } @@ -495,7 +495,8 @@ void ApplicationOverlay::renderControllerPointers() { if ((controllerButtons & BUTTON_FWD)) { if (!bumperPressed[index]) { if (triggerPressed[index]) { - _active = !_active; + Menu::getInstance()->setIsOptionChecked(MenuOption::UserInterface, + !Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)); } bumperPressed[index] = true; } diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 5e8d06ab89..e2ffb506d4 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -69,7 +69,6 @@ private: float _magSizeMult[NUMBER_OF_MAGNIFIERS]; float _alpha; - bool _active; GLuint _crosshairTexture; }; From 305623d8a7d3a2a45e592d48eac2e765be630c40 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 8 Jul 2014 21:37:08 -0700 Subject: [PATCH 26/43] Add option to hide focus indicators --- interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + interface/src/avatar/Avatar.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c0c25bb00d..019ce1df9e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -406,6 +406,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false); + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::HideFocusIndicators, 0, false); QMenu* oculusOptionsMenu = developerMenu->addMenu("Oculus Options"); addCheckableActionToQMenuAndActionHash(oculusOptionsMenu, MenuOption::DisplayOculusOverlays, 0, true); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e8146f8038..32458e1883 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -382,6 +382,7 @@ namespace MenuOption { const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity"; const QString HandsCollideWithSelf = "Collide With Self"; const QString HeadMouse = "Head Mouse"; + const QString HideFocusIndicators = "Hide Focus Indicators"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; const QString LoadScript = "Open and Run Script File..."; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9bb54efe20..e2e111c210 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -257,7 +257,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { } // If this is the avatar being looked at, render a little ball above their head - if (_isLookAtTarget) { + if (_isLookAtTarget && !Menu::getInstance()->isOptionChecked(MenuOption::HideFocusIndicators)) { const float LOOK_AT_INDICATOR_RADIUS = 0.03f; const float LOOK_AT_INDICATOR_OFFSET = 0.22f; const float LOOK_AT_INDICATOR_COLOR[] = { 0.8f, 0.0f, 0.0f, 0.75f }; From c50d9ae3e4333e6519ed9b16fddc259439c25480 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Jul 2014 22:22:27 -0700 Subject: [PATCH 27/43] Hand low velocity filter as a menu option --- interface/src/Application.cpp | 7 +++++++ interface/src/Application.h | 1 + interface/src/Menu.cpp | 7 +++++++ interface/src/Menu.h | 1 + interface/src/devices/SixenseManager.cpp | 19 ++++++++++++------- interface/src/devices/SixenseManager.h | 3 +++ 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ace265ad4f..f900ea18c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -354,6 +354,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // Set the sixense filtering _sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense)); + + // Set hand controller velocity filtering + _sixenseManager.setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter)); checkVersion(); @@ -1426,6 +1429,10 @@ void Application::setRenderVoxels(bool voxelRender) { } } +void Application::setLowVelocityFilter(bool lowVelocityFilter) { + getSixenseManager()->setLowVelocityFilter(lowVelocityFilter); +} + void Application::doKillLocalVoxels() { _wantToKillLocalVoxels = true; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 11f406abf0..321a43d548 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -317,6 +317,7 @@ public slots: void nudgeVoxelsByVector(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec); void setRenderVoxels(bool renderVoxels); + void setLowVelocityFilter(bool lowVelocityFilter); void doKillLocalVoxels(); void loadDialog(); void loadScriptURLDialog(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c0c25bb00d..b1f83c47cb 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -421,6 +421,13 @@ Menu::Menu() : true, appInstance->getSixenseManager(), SLOT(setFilter(bool))); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, + MenuOption::LowVelocityFilter, + 0, + true, + appInstance, + SLOT(setLowVelocityFilter(bool))); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandsCollideWithSelf, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e8146f8038..4fa02b802f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -368,6 +368,7 @@ namespace MenuOption { const QString Faceplus = "Faceplus"; const QString Faceshift = "Faceshift"; const QString FilterSixense = "Smooth Sixense Movement"; + const QString LowVelocityFilter = "Low Velocity Filter"; const QString FirstPerson = "First Person"; const QString FrameTimer = "Show Timer"; const QString FrustumRenderMode = "Render Mode"; diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index c50fc887d6..15d9da43b0 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -32,6 +32,7 @@ SixenseManager::SixenseManager() { #ifdef HAVE_SIXENSE _lastMovement = 0; _amountMoved = glm::vec3(0.0f); + _lowVelocityFilter = false; _calibrationState = CALIBRATION_STATE_IDLE; // By default we assume the _neckBase (in orb frame) is as high above the orb @@ -160,17 +161,21 @@ void SixenseManager::update(float deltaTime) { } palm->setRawVelocity(rawVelocity); // meters/sec - // Use a velocity sensitive filter to damp small motions and preserve large ones with - // no latency. - float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f); - palm->setRawPosition(palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter)); - // adjustment for hydra controllers fit into hands float sign = (i == 0) ? -1.0f : 1.0f; rotation *= glm::angleAxis(sign * PI/4.0f, glm::vec3(0.0f, 0.0f, 1.0f)); - palm->setRawRotation(safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter)); - + if (_lowVelocityFilter) { + // Use a velocity sensitive filter to damp small motions and preserve large ones with + // no latency. + float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f); + palm->setRawPosition(palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter)); + palm->setRawRotation(safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter)); + } else { + palm->setRawPosition(position); + palm->setRawRotation(rotation); + } + // use the velocity to determine whether there's any movement (if the hand isn't new) const float MOVEMENT_DISTANCE_THRESHOLD = 0.003f; _amountMoved += rawVelocity * deltaTime; diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 8ca27ef77c..bae9e1c6d6 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -47,6 +47,7 @@ public: public slots: void setFilter(bool filter); + void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; }; private: #ifdef HAVE_SIXENSE @@ -80,6 +81,8 @@ private: bool _bumperPressed[2]; int _oldX[2]; int _oldY[2]; + + bool _lowVelocityFilter; }; #endif // hifi_SixenseManager_h From f8185dec75035cb581f8128fc5464e41b86fe0a7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 8 Jul 2014 22:26:11 -0700 Subject: [PATCH 28/43] removed some debug logs --- interface/src/avatar/Avatar.cpp | 1 - interface/src/devices/SixenseManager.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9bb54efe20..758c903b5c 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -611,7 +611,6 @@ void Avatar::initializeHair() { } } - qDebug() << "Initialize Hair"; } bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const { diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 15d9da43b0..026c1d3eb4 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -61,10 +61,8 @@ SixenseManager::~SixenseManager() { void SixenseManager::setFilter(bool filter) { #ifdef HAVE_SIXENSE if (filter) { - qDebug("Sixense Filter ON"); sixenseSetFilterEnabled(1); } else { - qDebug("Sixense Filter OFF"); sixenseSetFilterEnabled(0); } #endif From 603ca02ef97f3018fb5e2e8d89ba74a66d17d0e5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 9 Jul 2014 11:21:16 -0700 Subject: [PATCH 29/43] Default UI to "on" --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 70faec4057..2c9f7b9c28 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -276,7 +276,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false, appInstance, SLOT(cameraMenuChanged())); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0, false, From 862f31130682519e478584bbb81af8e425cb584d Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Wed, 9 Jul 2014 11:29:33 -0700 Subject: [PATCH 30/43] Fixed full screen mirror mode for non oculus --- interface/src/Application.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7eb66bafd4..bf464f98aa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -604,9 +604,19 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness(0.0f); - _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0)); + //Only behave like a true mirror when in the OR + if (OculusManager::isConnected()) { + _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0)); + } else { + _myCamera.setTightness(0.0f); + glm::vec3 eyePosition = _myAvatar->getHead()->calculateAverageEyePosition(); + float headHeight = eyePosition.y - _myAvatar->getPosition().y; + _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + _myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0)); + _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + } } // Update camera position From 527f6b2a3f4d18f285a26aeff083174cb5ac2912 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 9 Jul 2014 11:32:38 -0700 Subject: [PATCH 31/43] Fix User Interface menu item string --- interface/src/Menu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 98c6af0be9..a2e1dd0c20 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -439,7 +439,7 @@ namespace MenuOption { const QString UploadAttachment = "Upload Attachment Model"; const QString UploadHead = "Upload Head Model"; const QString UploadSkeleton = "Upload Skeleton Model"; - const QString UserInterface = "UserInterface"; + const QString UserInterface = "User Interface"; const QString Visage = "Visage"; const QString VoxelMode = "Cycle Voxel Mode"; const QString Voxels = "Voxels"; From d214998d1aa67fb3fb296d6cc2e08d4f00c74376 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 11:53:09 -0700 Subject: [PATCH 32/43] enforce coding standard: explicit casts --- libraries/shared/src/SimpleMovingAverage.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/shared/src/SimpleMovingAverage.cpp b/libraries/shared/src/SimpleMovingAverage.cpp index 9f7e541c9a..64198d2a06 100644 --- a/libraries/shared/src/SimpleMovingAverage.cpp +++ b/libraries/shared/src/SimpleMovingAverage.cpp @@ -14,8 +14,8 @@ SimpleMovingAverage::SimpleMovingAverage(int numSamplesToAverage) : _numSamples(0), - _average(0), - _eventDeltaAverage(0), + _average(0.0f), + _eventDeltaAverage(0.0f), WEIGHTING(1.0f / numSamplesToAverage), ONE_MINUS_WEIGHTING(1 - WEIGHTING) { @@ -45,8 +45,8 @@ int SimpleMovingAverage::updateAverage(float sample) { void SimpleMovingAverage::reset() { _numSamples = 0; - _average = 0; - _eventDeltaAverage = 0; + _average = 0.0f; + _eventDeltaAverage = 0.0f; } float SimpleMovingAverage::getEventDeltaAverage() const { @@ -55,5 +55,5 @@ float SimpleMovingAverage::getEventDeltaAverage() const { } float SimpleMovingAverage::getAverageSampleValuePerSecond() const { - return _average * (1 / getEventDeltaAverage()); + return _average * (1.0f / getEventDeltaAverage()); } From d26585728b2cc5897120d1446cc278a54029ba93 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 11:53:53 -0700 Subject: [PATCH 33/43] Improved stat accumulation and context names --- interface/src/Application.cpp | 125 +++++++++++-------------- interface/src/avatar/Avatar.cpp | 33 ++++--- interface/src/avatar/AvatarManager.cpp | 4 + interface/src/avatar/MyAvatar.cpp | 44 +++------ interface/src/renderer/GlowEffect.cpp | 2 +- interface/src/ui/Stats.cpp | 2 + libraries/shared/src/PerfStat.cpp | 50 +++++++++- libraries/shared/src/PerfStat.h | 29 ++++-- 8 files changed, 163 insertions(+), 126 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ace265ad4f..b8368b96c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -682,7 +682,7 @@ void Application::paintGL() { } { - PerformanceTimer perfTimer("paintGL/renderOverlay"); + PerformanceTimer perfTimer("renderOverlay"); //If alpha is 1, we can render directly to the screen. if (_applicationOverlay.getAlpha() == 1.0f) { _applicationOverlay.renderOverlay(); @@ -1355,18 +1355,18 @@ void Application::idle() { if (timeSinceLastUpdate > IDLE_SIMULATE_MSECS) { _lastTimeUpdated.start(); { - PerformanceTimer perfTimer("idle/update"); + PerformanceTimer perfTimer("update"); PerformanceWarning warn(showWarnings, "Application::idle()... update()"); const float BIGGEST_DELTA_TIME_SECS = 0.25f; update(glm::clamp((float)timeSinceLastUpdate / 1000.f, 0.f, BIGGEST_DELTA_TIME_SECS)); } { - PerformanceTimer perfTimer("idle/updateGL"); + PerformanceTimer perfTimer("updateGL"); PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()"); _glWidget->updateGL(); } { - PerformanceTimer perfTimer("idle/rest"); + PerformanceTimer perfTimer("rest"); PerformanceWarning warn(showWarnings, "Application::idle()... rest of it"); _idleLoopStdev.addValue(timeSinceLastUpdate); @@ -1378,7 +1378,7 @@ void Application::idle() { } if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) { - PerformanceTimer perfTimer("idle/rest/_buckyBalls"); + PerformanceTimer perfTimer("buckyBalls"); _buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData()); } @@ -1792,7 +1792,7 @@ bool Application::isLookingAtMyAvatar(Avatar* avatar) { } void Application::updateLOD() { - PerformanceTimer perfTimer("idle/update/updateLOD"); + PerformanceTimer perfTimer("LOD"); // adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) { Menu::getInstance()->autoAdjustLOD(_fps); @@ -1802,7 +1802,7 @@ void Application::updateLOD() { } void Application::updateMouseRay() { - PerformanceTimer perfTimer("idle/update/updateMouseRay"); + PerformanceTimer perfTimer("mouseRay"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMouseRay()"); @@ -1835,7 +1835,7 @@ void Application::updateMouseRay() { } void Application::updateFaceshift() { - PerformanceTimer perfTimer("idle/update/updateFaceshift"); + PerformanceTimer perfTimer("faceshift"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateFaceshift()"); @@ -1850,7 +1850,7 @@ void Application::updateFaceshift() { } void Application::updateVisage() { - PerformanceTimer perfTimer("idle/update/updateVisage"); + PerformanceTimer perfTimer("visage"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateVisage()"); @@ -1860,11 +1860,11 @@ void Application::updateVisage() { } void Application::updateMyAvatarLookAtPosition() { - PerformanceTimer perfTimer("idle/update/updateMyAvatarLookAtPosition"); - + PerformanceTimer perfTimer("lookAt"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()"); + _myAvatar->updateLookAtTargetAvatar(); FaceTracker* tracker = getActiveFaceTracker(); bool isLookingAtSomeone = false; @@ -1927,7 +1927,7 @@ void Application::updateMyAvatarLookAtPosition() { } void Application::updateThreads(float deltaTime) { - PerformanceTimer perfTimer("idle/update/updateThreads"); + PerformanceTimer perfTimer("updateThreads"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateThreads()"); @@ -1942,7 +1942,7 @@ void Application::updateThreads(float deltaTime) { } void Application::updateMetavoxels(float deltaTime) { - PerformanceTimer perfTimer("idle/update/updateMetavoxels"); + PerformanceTimer perfTimer("updateMetavoxels"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMetavoxels()"); @@ -1972,7 +1972,7 @@ void Application::cameraMenuChanged() { } void Application::updateCamera(float deltaTime) { - PerformanceTimer perfTimer("idle/update/updateCamera"); + PerformanceTimer perfTimer("updateCamera"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateCamera()"); @@ -1990,7 +1990,7 @@ void Application::updateCamera(float deltaTime) { } void Application::updateDialogs(float deltaTime) { - PerformanceTimer perfTimer("idle/update/updateDialogs"); + PerformanceTimer perfTimer("updateDialogs"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateDialogs()"); @@ -2007,7 +2007,7 @@ void Application::updateDialogs(float deltaTime) { } void Application::updateCursor(float deltaTime) { - PerformanceTimer perfTimer("idle/update/updateCursor"); + PerformanceTimer perfTimer("updateCursor"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateCursor()"); @@ -2032,8 +2032,6 @@ void Application::updateCursor(float deltaTime) { } void Application::update(float deltaTime) { - //PerformanceTimer perfTimer("idle/update"); // NOTE: we track this above in Application::idle() - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::update()"); @@ -2043,72 +2041,61 @@ void Application::update(float deltaTime) { updateVisage(); { - PerformanceTimer perfTimer("idle/update/updateLookAtTargetAvatar"); - _myAvatar->updateLookAtTargetAvatar(); - } - updateMyAvatarLookAtPosition(); - { - PerformanceTimer perfTimer("idle/update/sixense,joystick,prioVR"); - _sixenseManager.update(deltaTime); - _joystickManager.update(); - _prioVR.update(deltaTime); - } - - { - PerformanceTimer perfTimer("idle/update/updateMyAvatar"); + PerformanceTimer perfTimer("myAvatar"); + updateMyAvatarLookAtPosition(); + { + PerformanceTimer perfTimer("devices"); + _sixenseManager.update(deltaTime); + _joystickManager.update(); + _prioVR.update(deltaTime); + } updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes } updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... - { - PerformanceTimer perfTimer("idle/update/_avatarManager"); - _avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them... - } + _avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them... + updateMetavoxels(deltaTime); // update metavoxels updateCamera(deltaTime); // handle various camera tweaks like off axis projection updateDialogs(deltaTime); // update various stats dialogs if present updateCursor(deltaTime); // Handle cursor updates { - PerformanceTimer perfTimer("idle/update/_particles"); + PerformanceTimer perfTimer("particles"); _particles.update(); // update the particles... - } - { - PerformanceTimer perfTimer("idle/update/_particleCollisionSystem"); - _particleCollisionSystem.update(); // collide the particles... + { + PerformanceTimer perfTimer("collisions"); + _particleCollisionSystem.update(); // collide the particles... + } } { - PerformanceTimer perfTimer("idle/update/_models"); + PerformanceTimer perfTimer("models"); _models.update(); // update the models... } { - PerformanceTimer perfTimer("idle/update/_overlays"); + PerformanceTimer perfTimer("overlays"); _overlays.update(deltaTime); } { - PerformanceTimer perfTimer("idle/update/emit simulating"); + PerformanceTimer perfTimer("emitSimulating"); // let external parties know we're updating emit simulating(deltaTime); } } void Application::updateMyAvatar(float deltaTime) { - PerformanceTimer perfTimer("updateMyAvatar"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMyAvatar()"); - { - PerformanceTimer perfTimer("updateMyAvatar/_myAvatar->update()"); - _myAvatar->update(deltaTime); - } + _myAvatar->update(deltaTime); { // send head/hand data to the avatar mixer and voxel server - PerformanceTimer perfTimer("updateMyAvatar/sendToAvatarMixer"); + PerformanceTimer perfTimer("send"); QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeAvatarData); packet.append(_myAvatar->toByteArray()); controlledBroadcastToNodes(packet, NodeSet() << NodeType::AvatarMixer); @@ -2121,13 +2108,13 @@ void Application::updateMyAvatar(float deltaTime) { // actually need to calculate the view frustum planes to send these details // to the server. { - PerformanceTimer perfTimer("updateMyAvatar/loadViewFrustum"); + PerformanceTimer perfTimer("loadViewFrustum"); loadViewFrustum(_myCamera, _viewFrustum); } // Update my voxel servers with my current voxel query... { - PerformanceTimer perfTimer("updateMyAvatar/queryOctree"); + PerformanceTimer perfTimer("queryOctree"); quint64 now = usecTimestampNow(); quint64 sinceLastQuery = now - _lastQueriedTime; const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND; @@ -2460,7 +2447,7 @@ glm::vec3 Application::getSunDirection() { } void Application::updateShadowMap() { - PerformanceTimer perfTimer("paintGL/updateShadowMap"); + PerformanceTimer perfTimer("shadowMap"); QOpenGLFramebufferObject* fbo = _textureCache.getShadowFramebufferObject(); fbo->bind(); glEnable(GL_DEPTH_TEST); @@ -2622,7 +2609,7 @@ QImage Application::renderAvatarBillboard() { } void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { - PerformanceTimer perfTimer("paintGL/displaySide"); + PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // transform by eye offset @@ -2656,7 +2643,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // Setup 3D lights (after the camera transform, so that they are positioned in world space) { - PerformanceTimer perfTimer("paintGL/displaySide/setupWorldLight"); + PerformanceTimer perfTimer("lights"); setupWorldLight(); } @@ -2675,7 +2662,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { - PerformanceTimer perfTimer("paintGL/displaySide/stars"); + PerformanceTimer perfTimer("stars"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... stars..."); if (!_stars.isStarsLoaded()) { @@ -2704,7 +2691,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // draw the sky dome if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - PerformanceTimer perfTimer("paintGL/displaySide/atmosphere"); + PerformanceTimer perfTimer("atmosphere"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... atmosphere..."); _environment.renderAtmospheres(whichCamera); @@ -2725,13 +2712,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // draw the audio reflector overlay { - PerformanceTimer perfTimer("paintGL/displaySide/audioReflector"); + PerformanceTimer perfTimer("audio"); _audioReflector.render(); } // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { - PerformanceTimer perfTimer("paintGL/displaySide/voxels"); + PerformanceTimer perfTimer("voxels"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxels..."); _voxels.render(); @@ -2739,14 +2726,14 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // also, metavoxels if (Menu::getInstance()->isOptionChecked(MenuOption::Metavoxels)) { - PerformanceTimer perfTimer("paintGL/displaySide/metavoxels"); + PerformanceTimer perfTimer("metavoxels"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... metavoxels..."); _metavoxels.render(); } if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) { - PerformanceTimer perfTimer("paintGL/displaySide/buckyBalls"); + PerformanceTimer perfTimer("buckyBalls"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... bucky balls..."); _buckyBalls.render(); @@ -2754,7 +2741,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // render particles... if (Menu::getInstance()->isOptionChecked(MenuOption::Particles)) { - PerformanceTimer perfTimer("paintGL/displaySide/particles"); + PerformanceTimer perfTimer("particles"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... particles..."); _particles.render(); @@ -2762,7 +2749,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // render models... if (Menu::getInstance()->isOptionChecked(MenuOption::Models)) { - PerformanceTimer perfTimer("paintGL/displaySide/models"); + PerformanceTimer perfTimer("models"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... models..."); _models.render(); @@ -2770,7 +2757,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // render the ambient occlusion effect if enabled if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { - PerformanceTimer perfTimer("paintGL/displaySide/AmbientOcclusion"); + PerformanceTimer perfTimer("ambientOcclusion"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... AmbientOcclusion..."); _ambientOcclusionEffect.render(); @@ -2785,20 +2772,20 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); { - PerformanceTimer perfTimer("paintGL/displaySide/renderAvatars"); + PerformanceTimer perfTimer("avatars"); _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly); } if (!selfAvatarOnly) { // Render the world box if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { - PerformanceTimer perfTimer("paintGL/displaySide/renderWorldBox"); + PerformanceTimer perfTimer("worldBox"); renderWorldBox(); } // view frustum for debugging if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum) && whichCamera.getMode() != CAMERA_MODE_MIRROR) { - PerformanceTimer perfTimer("paintGL/displaySide/ViewFrustum"); + PerformanceTimer perfTimer("viewFrustum"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... renderViewFrustum..."); renderViewFrustum(_viewFrustum); @@ -2806,7 +2793,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // render voxel fades if they exist if (_voxelFades.size() > 0) { - PerformanceTimer perfTimer("paintGL/displaySide/voxel fades"); + PerformanceTimer perfTimer("voxelFades"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxel fades..."); _voxelFadesLock.lockForWrite(); @@ -2823,13 +2810,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // give external parties a change to hook in { - PerformanceTimer perfTimer("paintGL/displaySide/inWorldInterface"); + PerformanceTimer perfTimer("inWorldInterface"); emit renderingInWorldInterface(); } // render JS/scriptable overlays { - PerformanceTimer perfTimer("paintGL/displaySide/3dOverlays"); + PerformanceTimer perfTimer("3dOverlays"); _overlays.render3D(); } } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9b136980f4..d8cfd58a5c 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -15,12 +15,12 @@ #include #include +#include #include #include +#include #include -#include - #include "Application.h" #include "Avatar.h" #include "Hand.h" @@ -118,29 +118,36 @@ void Avatar::simulate(float deltaTime) { bool inViewFrustum = Application::getInstance()->getViewFrustum()->sphereInFrustum(_position, boundingRadius) != ViewFrustum::OUTSIDE; - getHand()->simulate(deltaTime, false); + { + PerformanceTimer perfTimer("hand"); + getHand()->simulate(deltaTime, false); + } _skeletonModel.setLODDistance(getLODDistance()); if (!_shouldRenderBillboard && inViewFrustum) { if (_hasNewJointRotations) { + PerformanceTimer perfTimer("skeleton"); for (int i = 0; i < _jointData.size(); i++) { const JointData& data = _jointData.at(i); _skeletonModel.setJointState(i, data.valid, data.rotation); } _skeletonModel.simulate(deltaTime); } - _skeletonModel.simulate(deltaTime, _hasNewJointRotations); - simulateAttachments(deltaTime); - _hasNewJointRotations = false; + { + PerformanceTimer perfTimer("head"); + _skeletonModel.simulate(deltaTime, _hasNewJointRotations); + simulateAttachments(deltaTime); + _hasNewJointRotations = false; - glm::vec3 headPosition = _position; - _skeletonModel.getHeadPosition(headPosition); - Head* head = getHead(); - head->setPosition(headPosition); - head->setScale(_scale); - head->simulate(deltaTime, false, _shouldRenderBillboard); - + glm::vec3 headPosition = _position; + _skeletonModel.getHeadPosition(headPosition); + Head* head = getHead(); + head->setPosition(headPosition); + head->setScale(_scale); + head->simulate(deltaTime, false, _shouldRenderBillboard); + } if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { + PerformanceTimer perfTimer("hair"); simulateHair(deltaTime); } } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 59f31388f8..86ec7c2680 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -41,9 +41,13 @@ void AvatarManager::init() { } void AvatarManager::updateOtherAvatars(float deltaTime) { + if (_avatarHash.size() > 1) { + return; + } bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); + PerformanceTimer perfTimer("otherAvatars"); Application* applicationInstance = Application::getInstance(); glm::vec3 mouseOrigin = applicationInstance->getMouseRayOrigin(); glm::vec3 mouseDirection = applicationInstance->getMouseRayDirection(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6cb6ba6840..9154331cee 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -108,15 +108,10 @@ void MyAvatar::reset() { } void MyAvatar::update(float deltaTime) { - PerformanceTimer perfTimer("MyAvatar::update/"); Head* head = getHead(); head->relaxLean(deltaTime); - { - PerformanceTimer perfTimer("MyAvatar::update/updateFromTrackers"); - updateFromTrackers(deltaTime); - } + updateFromTrackers(deltaTime); if (Menu::getInstance()->isOptionChecked(MenuOption::MoveWithLean)) { - PerformanceTimer perfTimer("MyAvatar::update/moveWithLean"); // Faceshift drive is enabled, set the avatar drive based on the head position moveWithLean(); } @@ -127,18 +122,14 @@ void MyAvatar::update(float deltaTime) { head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness()); if (_motionBehaviors & AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY) { - PerformanceTimer perfTimer("MyAvatar::update/gravityWork"); setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition())); } - { - PerformanceTimer perfTimer("MyAvatar::update/simulate"); - simulate(deltaTime); - } + simulate(deltaTime); } void MyAvatar::simulate(float deltaTime) { - PerformanceTimer perfTimer("MyAvatar::simulate"); + PerformanceTimer perfTimer("simulate"); if (_scale != _targetScale) { float scale = (1.0f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale; @@ -150,31 +141,28 @@ void MyAvatar::simulate(float deltaTime) { _handState = HAND_STATE_NULL; { - PerformanceTimer perfTimer("MyAvatar::simulate/updateOrientation"); + PerformanceTimer perfTimer("transform"); updateOrientation(deltaTime); - } - { - PerformanceTimer perfTimer("MyAvatar::simulate/updatePosition"); updatePosition(deltaTime); } { - PerformanceTimer perfTimer("MyAvatar::simulate/hand Collision,simulate"); + PerformanceTimer perfTimer("hand"); // update avatar skeleton and simulate hand and head getHand()->simulate(deltaTime, true); } { - PerformanceTimer perfTimer("MyAvatar::simulate/_skeletonModel.simulate()"); + PerformanceTimer perfTimer("skeleton"); _skeletonModel.simulate(deltaTime); } { - PerformanceTimer perfTimer("MyAvatar::simulate/simulateAttachments"); + PerformanceTimer perfTimer("attachments"); simulateAttachments(deltaTime); } { - PerformanceTimer perfTimer("MyAvatar::simulate/copy joints"); + PerformanceTimer perfTimer("joints"); // copy out the skeleton joints from the model _jointData.resize(_skeletonModel.getJointStateCount()); for (int i = 0; i < _jointData.size(); i++) { @@ -184,7 +172,7 @@ void MyAvatar::simulate(float deltaTime) { } { - PerformanceTimer perfTimer("MyAvatar::simulate/head Simulate"); + PerformanceTimer perfTimer("head"); Head* head = getHead(); glm::vec3 headPosition; if (!_skeletonModel.getHeadPosition(headPosition)) { @@ -196,14 +184,14 @@ void MyAvatar::simulate(float deltaTime) { } { - PerformanceTimer perfTimer("MyAvatar::simulate/hair Simulate"); + PerformanceTimer perfTimer("hair"); if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { simulateHair(deltaTime); } } { - PerformanceTimer perfTimer("MyAvatar::simulate/ragdoll"); + PerformanceTimer perfTimer("ragdoll"); if (Menu::getInstance()->isOptionChecked(MenuOption::CollideAsRagdoll)) { const int minError = 0.01f; const float maxIterations = 10; @@ -216,7 +204,7 @@ void MyAvatar::simulate(float deltaTime) { // now that we're done stepping the avatar forward in time, compute new collisions if (_collisionGroups != 0) { - PerformanceTimer perfTimer("MyAvatar::simulate/_collisionGroups"); + PerformanceTimer perfTimer("collisions"); Camera* myCamera = Application::getInstance()->getCamera(); float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE; @@ -225,18 +213,18 @@ void MyAvatar::simulate(float deltaTime) { radius *= COLLISION_RADIUS_SCALAR; } if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) { - PerformanceTimer perfTimer("MyAvatar::simulate/updateCollisionWithEnvironment"); + PerformanceTimer perfTimer("environment"); updateCollisionWithEnvironment(deltaTime, radius); } if (_collisionGroups & COLLISION_GROUP_VOXELS) { - PerformanceTimer perfTimer("MyAvatar::simulate/updateCollisionWithVoxels"); + PerformanceTimer perfTimer("voxels"); updateCollisionWithVoxels(deltaTime, radius); } else { _trapDuration = 0.0f; } /* TODO: Andrew to make this work if (_collisionGroups & COLLISION_GROUP_AVATARS) { - PerformanceTimer perfTimer("MyAvatar::simulate/updateCollisionWithAvatars"); + PerformanceTimer perfTimer("avatars"); updateCollisionWithAvatars(deltaTime); } */ @@ -910,7 +898,6 @@ bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode rend } float MyAvatar::computeDistanceToFloor(const glm::vec3& startPoint) { - PerformanceTimer perfTimer("MyAvatar::computeDistanceToFloor()"); glm::vec3 direction = -_worldUpDirection; OctreeElement* elementHit; // output from findRayIntersection float distance = FLT_MAX; // output from findRayIntersection @@ -976,7 +963,6 @@ void MyAvatar::updateOrientation(float deltaTime) { const float NEARBY_FLOOR_THRESHOLD = 5.0f; void MyAvatar::updatePosition(float deltaTime) { - PerformanceTimer perfTimer("MyAvatar::updatePosition"); float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) + fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT]) + fabsf(_driveKeys[UP] - _driveKeys[DOWN]); diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index c163136956..1fdebb66d7 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -121,7 +121,7 @@ static void maybeRelease(QOpenGLFramebufferObject* fbo) { } QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { - PerformanceTimer perfTimer("paintGL/glowEffect"); + PerformanceTimer perfTimer("glowEffect"); QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); primaryFBO->release(); diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 379dd35df7..3de21b449b 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -601,6 +601,8 @@ void Stats::display( drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color); } + PerformanceTimer::tallyAllTimerRecords(); + // TODO: the display of these timing details should all be moved to JavaScript if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayTimingDetails)) { // Timing details... diff --git a/libraries/shared/src/PerfStat.cpp b/libraries/shared/src/PerfStat.cpp index 4dca3f3d49..908dca61e7 100644 --- a/libraries/shared/src/PerfStat.cpp +++ b/libraries/shared/src/PerfStat.cpp @@ -17,6 +17,12 @@ #include "PerfStat.h" +#include "SharedUtil.h" + +// ---------------------------------------------------------------------------- +// PerformanceWarning +// ---------------------------------------------------------------------------- + // Static class members initialization here! bool PerformanceWarning::_suppressShortTimings = false; @@ -52,14 +58,50 @@ PerformanceWarning::~PerformanceWarning() { } }; +// ---------------------------------------------------------------------------- +// PerformanceTimerRecord +// ---------------------------------------------------------------------------- +const quint64 STALE_STAT_PERIOD = 4 * USECS_PER_SECOND; + +void PerformanceTimerRecord::tallyResult(const quint64& now) { + if (_numAccumulations > 0) { + _numTallies++; + _movingAverage.updateAverage(_runningTotal - _lastTotal); + _lastTotal = _runningTotal; + _numAccumulations = 0; + _expiry = now + STALE_STAT_PERIOD; + } +} + +// ---------------------------------------------------------------------------- +// PerformanceTimer +// ---------------------------------------------------------------------------- + +QString PerformanceTimer::_fullName; QMap PerformanceTimer::_records; PerformanceTimer::~PerformanceTimer() { - quint64 end = usecTimestampNow(); - quint64 elapsedusec = (end - _start); - PerformanceTimerRecord& namedRecord = _records[_name]; - namedRecord.recordResult(elapsedusec); + quint64 elapsedusec = (usecTimestampNow() - _start); + PerformanceTimerRecord& namedRecord = _records[_fullName]; + namedRecord.accumulateResult(elapsedusec); + _fullName.resize(_fullName.size() - (_name.size() + 1)); +} + +// static +void PerformanceTimer::tallyAllTimerRecords() { + QMap::iterator recordsItr = _records.begin(); + QMap::const_iterator recordsEnd = _records.end(); + quint64 now = usecTimestampNow(); + while (recordsItr != recordsEnd) { + recordsItr.value().tallyResult(now); + if (recordsItr.value().isStale(now)) { + // purge stale records + recordsItr = _records.erase(recordsItr); + } else { + ++recordsItr; + } + } } void PerformanceTimer::dumpAllTimerRecords() { diff --git a/libraries/shared/src/PerfStat.h b/libraries/shared/src/PerfStat.h index f849fb844c..69bda0af5e 100644 --- a/libraries/shared/src/PerfStat.h +++ b/libraries/shared/src/PerfStat.h @@ -52,16 +52,21 @@ public: class PerformanceTimerRecord { public: - PerformanceTimerRecord() : _runningTotal(0), _totalCalls(0) {} + PerformanceTimerRecord() : _runningTotal(0), _lastTotal(0), _numAccumulations(0), _numTallies(0), _expiry(0) {} - void recordResult(quint64 elapsed) { _runningTotal += elapsed; _totalCalls++; _movingAverage.updateAverage(elapsed); } - quint64 getAverage() const { return (_totalCalls == 0) ? 0 : _runningTotal / _totalCalls; } - quint64 getMovingAverage() const { return (_totalCalls == 0) ? 0 : _movingAverage.getAverage(); } - quint64 getCount() const { return _totalCalls; } + void accumulateResult(const quint64& elapsed) { _runningTotal += elapsed; ++_numAccumulations; } + void tallyResult(const quint64& now); + bool isStale(const quint64& now) const { return now > _expiry; } + quint64 getAverage() const { return (_numTallies == 0) ? 0 : _runningTotal / _numTallies; } + quint64 getMovingAverage() const { return (_numTallies == 0) ? 0 : _movingAverage.getAverage(); } + quint64 getCount() const { return _numTallies; } private: quint64 _runningTotal; - quint64 _totalCalls; + quint64 _lastTotal; + quint64 _numAccumulations; + quint64 _numTallies; + quint64 _expiry; SimpleMovingAverage _movingAverage; }; @@ -69,20 +74,24 @@ class PerformanceTimer { public: PerformanceTimer(const QString& name) : - _start(usecTimestampNow()), - _name(name) { } + _start(0), + _name(name) { + _fullName.append("/"); + _fullName.append(_name); + _start = usecTimestampNow(); + } - quint64 elapsed() const { return (usecTimestampNow() - _start); }; - ~PerformanceTimer(); static const PerformanceTimerRecord& getTimerRecord(const QString& name) { return _records[name]; }; static const QMap& getAllTimerRecords() { return _records; }; + static void tallyAllTimerRecords(); static void dumpAllTimerRecords(); private: quint64 _start; QString _name; + static QString _fullName; static QMap _records; }; From 56eadcb0dcae9d48e5054a97c76cb5ab2c194047 Mon Sep 17 00:00:00 2001 From: TonyPeng Date: Wed, 9 Jul 2014 12:05:34 -0700 Subject: [PATCH 34/43] Get rid of redundant GL calls for fog. Enable and disable fog during rendering stage of voxels. Moved the local light parameters to shader uniform arrays. --- examples/avatarLocalLight.js | 29 +++++----- interface/resources/shaders/model.frag | 17 +++--- interface/resources/shaders/model.vert | 7 --- .../resources/shaders/model_specular_map.frag | 18 ++++++- interface/resources/shaders/skin_model.vert | 9 ---- interface/src/avatar/Avatar.cpp | 54 ++++++++++++++----- interface/src/avatar/Avatar.h | 13 ++--- interface/src/avatar/SkeletonModel.h | 1 + interface/src/renderer/Model.cpp | 22 +++++++- interface/src/renderer/Model.h | 10 ++++ interface/src/renderer/ProgramObject.cpp | 15 ++++++ interface/src/renderer/ProgramObject.h | 1 + interface/src/voxels/VoxelSystem.cpp | 15 ++++-- 13 files changed, 148 insertions(+), 63 deletions(-) diff --git a/examples/avatarLocalLight.js b/examples/avatarLocalLight.js index 600713a037..69b491d430 100644 --- a/examples/avatarLocalLight.js +++ b/examples/avatarLocalLight.js @@ -11,10 +11,11 @@ // var localLightDirections = [ {x: 1.0, y:0.0, z: 0.0}, {x: 0.0, y:1.0, z: 1.0}, {x: 0.0, y:0.0, z: 1.0}, {x: 1.0, y:1.0, z: 1.0} ]; -var localLightColors = [ {x: 0.0, y:0.0, z: 0.0, w: 1.0}, {x: 0.0, y:0.0, z: 0.0, w: 1.0}, {x: 0.0, y:0.0, z: 0.0, w: 1.0}, {x: 0.0, y:0.0, z: 0.0, w: 1.0} ]; +var localLightColors = [ {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0} ]; var currentSelection = 0; var currentNumLights = 1; +var maxNumLights = 2; function keyPressEvent(event) { @@ -92,34 +93,34 @@ function keyPressEvent(event) { MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection); } - else if (event.text == "+" ) { - if (currentNumLights + 1 < 4) { - + else if (event.text == "," ) { + if (currentNumLights + 1 <= maxNumLights) { + var darkGrayColor = {x:0.3, y:0.3, z:0.3}; + // default light - localLightColors[currentNumLights].x = 0.1; - localLightColors[currentNumLights].y = 0.1; - localLightColors[currentNumLights].z = 0.1; + localLightColors[currentNumLights].x = darkGrayColor.x; + localLightColors[currentNumLights].y = darkGrayColor.y; + localLightColors[currentNumLights].z = darkGrayColor.z; + MyAvatar.addLocalLight(); MyAvatar.setLocalLightColor(localLightColors[currentNumLights], currentNumLights); MyAvatar.setLocalLightDirection(localLightDirections[currentNumLights], currentNumLights); - + ++currentNumLights; } } - else if (event.text == "-" ) { + else if (event.text == "." ) { if (currentNumLights - 1 >= 0 ) { // no light contribution localLightColors[currentNumLights - 1].x = 0.0; localLightColors[currentNumLights - 1].y = 0.0; localLightColors[currentNumLights - 1].z = 0.0; - - MyAvatar.setLocalLightColor(localLightColors[currentNumLights - 1], currentNumLights - 1); - + + MyAvatar.removeLocalLight(); --currentNumLights; } - } - + } } Controller.keyPressEvent.connect(keyPressEvent); diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 86bc10179c..95afaa0e5f 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -11,20 +11,22 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -const int MAX_LOCAL_LIGHTS = 4; // the diffuse texture uniform sampler2D diffuseMap; +// local lights +const int MAX_LOCAL_LIGHTS = 2; // 2 lights for now, will probably need more later on +uniform int numLocalLights; +uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS]; +uniform vec3 localLightColors[MAX_LOCAL_LIGHTS]; + // the interpolated position varying vec4 position; // the interpolated normal varying vec4 normal; -// static local light position -varying vec4 localLightPos[MAX_LOCAL_LIGHTS]; - void main(void) { // compute the base color based on OpenGL lighting model vec4 normalizedNormal = normalize(normal); @@ -33,12 +35,12 @@ void main(void) { // the local light that is always present vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - float localDiffuse = dot(normalizedNormal, localLightPos[i]); + for (int i = 0; i < numLocalLights; i++) { + float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0)); float localLight = step(0.0, localDiffuse); float localLightVal = localDiffuse * localLight; - totalLocalLight += (localLightVal * gl_LightSource[i+1].diffuse); + totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0)); } vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + @@ -51,5 +53,4 @@ void main(void) { // modulate texture by base color and add specular contribution gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); - } diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 06ad8a3300..789c90817b 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -19,9 +19,6 @@ varying vec4 position; // the interpolated normal varying vec4 normal; -// local light position that is always present -varying vec4 localLightPos[MAX_LOCAL_LIGHTS]; - void main(void) { // transform and store the normal for interpolation @@ -41,8 +38,4 @@ void main(void) { // use standard pipeline transform gl_Position = ftransform(); - - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLightPos[i] = gl_ModelViewMatrixInverse * gl_LightSource[i+1].position; - } } diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index a07324cd1b..7038ea84f7 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -10,6 +10,10 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +const int MAX_LOCAL_LIGHTS = 2; + +uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS]; +uniform vec3 localLightColors[MAX_LOCAL_LIGHTS]; // the diffuse texture uniform sampler2D diffuseMap; @@ -28,8 +32,19 @@ void main(void) { vec4 normalizedNormal = normalize(normal); float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse); + + // the local light that is always present + vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0); + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0)); + float localLight = step(0.0, localDiffuse); + float localLightVal = localDiffuse * localLight; + + totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0)); + } + vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight); // compute the specular component (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), @@ -38,4 +53,5 @@ void main(void) { // modulate texture by base color and add specular contribution gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); + } diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 44f33da3e2..1ce1baa76f 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -26,9 +26,6 @@ varying vec4 position; // the interpolated normal varying vec4 normal; -// static local light position (inverse from eye space) -varying vec4 localLightPos[MAX_LOCAL_LIGHTS]; - void main(void) { position = vec4(0.0, 0.0, 0.0, 0.0); normal = vec4(0.0, 0.0, 0.0, 0.0); @@ -52,10 +49,4 @@ void main(void) { gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0); gl_Position = gl_ProjectionMatrix * position; - - // inverse view to make the light source position static - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLightPos[i] = gl_ModelViewMatrixInverse * gl_LightSource[i+1].position; - } - } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 38dbb02a14..e6bd204505 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -61,7 +61,8 @@ Avatar::Avatar() : _moving(false), _collisionGroups(0), _initialized(false), - _shouldRenderBillboard(true) + _shouldRenderBillboard(true), + _numLocalLights(1) { // we may have been created in the network thread, but we live in the main thread moveToThread(Application::getInstance()->thread()); @@ -82,16 +83,23 @@ void Avatar::init() { _initialized = true; _shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE); initializeHair(); - + for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - _localLightColors[i] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + _localLightColors[i] = glm::vec3(0.0f, 0.0f, 0.0f); _localLightDirections[i] = glm::vec3(0.0f, 0.0f, 1.0f); } + + glm::vec3 darkGrayColor(0.3f, 0.3f, 0.3f); + glm::vec3 greenColor(0.0f, 1.0f, 0.0f); + glm::vec3 directionX(1.0f, 0.0f, 0.0f); + glm::vec3 directionY(0.0f, 1.0f, 0.0f); + + // initialize local lights + _localLightColors[0] = darkGrayColor; + _localLightColors[1] = greenColor; - // initialize first light - _localLightColors[0].r = 0.2f; _localLightColors[0].g = 0.2f, _localLightColors[0].b = 0.2f; - _localLightDirections[0].x = 1.0f; _localLightDirections[0].y = 0.0f; _localLightDirections[0].z = 0.0f; - + _localLightDirections[0] = directionX; + _localLightDirections[1] = directionY; } glm::vec3 Avatar::getChestPosition() const { @@ -243,13 +251,19 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { : GLOW_FROM_AVERAGE_LOUDNESS; + // local lights directions and colors + getSkeletonModel().setNumLocalLights(_numLocalLights); + getHead()->getFaceModel().setNumLocalLights(_numLocalLights); for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { glm::vec3 normalized = glm::normalize(_localLightDirections[i]); - glm::vec4 localLight = glm::vec4(normalized, 1.0f); - // local light parameters - glLightfv(GL_LIGHT1 + i, GL_POSITION, glm::value_ptr(localLight)); - glLightfv(GL_LIGHT1 + i, GL_DIFFUSE, glm::value_ptr(_localLightColors[i])); + // body + getSkeletonModel().setLocalLightColor(_localLightColors[i], i); + getSkeletonModel().setLocalLightDirection(normalized, i); + + // head + getHead()->getFaceModel().setLocalLightColor(_localLightColors[i], i); + getHead()->getFaceModel().setLocalLightDirection(_localLightDirections[i], i); } // render body @@ -1133,8 +1147,24 @@ void Avatar::setLocalLightDirection(const glm::vec3& direction, int lightIndex) qDebug( "set light %d direction ( %f, %f, %f )\n", lightIndex, direction.x, direction.y, direction.z ); } -void Avatar::setLocalLightColor(const glm::vec4& color, int lightIndex) { +void Avatar::setLocalLightColor(const glm::vec3& color, int lightIndex) { _localLightColors[lightIndex] = color; qDebug( "set light %d color ( %f, %f, %f )\n", lightIndex, color.x, color.y, color.z ); } +void Avatar::addLocalLight() { + if (_numLocalLights + 1 <= MAX_LOCAL_LIGHTS) { + ++_numLocalLights; + } + + qDebug("ADD LOCAL LIGHT (numLocalLights = %d)\n", _numLocalLights); +} + +void Avatar::removeLocalLight() { + if (_numLocalLights - 1 >= 0) { + --_numLocalLights; + } + + qDebug("REMOVE LOCAL LIGHT (numLocalLights = %d)\n", _numLocalLights); +} + diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 059264d43a..79718c40df 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -36,8 +36,6 @@ const int HAIR_STRANDS = 150; // Number of strands of hair const int HAIR_LINKS = 10; // Number of links in a hair strand const int HAIR_MAX_CONSTRAINTS = 2; // Hair verlet is connected to at most how many others -const int MAX_LOCAL_LIGHTS = 6; - enum DriveKeys { FWD = 0, BACK, @@ -157,8 +155,10 @@ public: public slots: void updateCollisionGroups(); void setLocalLightDirection(const glm::vec3& direction, int lightIndex); - void setLocalLightColor(const glm::vec4& color, int lightIndex); - + void setLocalLightColor(const glm::vec3& color, int lightIndex); + void addLocalLight(); + void removeLocalLight(); + signals: void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision); @@ -183,8 +183,9 @@ protected: // always-present local lighting for the avatar glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; - glm::vec4 _localLightColors[MAX_LOCAL_LIGHTS]; - + glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS]; + int _numLocalLights; + // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 76d0d45efa..7a88d890ac 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -109,6 +109,7 @@ public: void resetShapePositionsToDefaultPose(); // DEBUG method void renderRagdoll(); + protected: // virtual overrrides from Ragdoll diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 6fe57ea705..053e928ca3 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1489,14 +1489,18 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances()); } - } else { + // local light + skinProgram->setUniformValue("numLocalLights", _numLocalLights); + skinProgram->setUniformArray("localLightDirections", _localLightDirections, MAX_LOCAL_LIGHTS); + skinProgram->setUniformArray("localLightColors", _localLightColors, MAX_LOCAL_LIGHTS); + } else { glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]); program->bind(); if (cascadedShadows) { program->setUniform(shadowDistancesLocation, Application::getInstance()->getShadowDistances()); } } - + if (mesh.blendshapes.isEmpty()) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); @@ -1623,6 +1627,20 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re } } +void Model::setLocalLightDirection(const glm::vec3& direction, int lightIndex) { + assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS); + _localLightDirections[lightIndex] = direction; +} + +void Model::setLocalLightColor(const glm::vec3& color, int lightIndex) { + assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS); + _localLightColors[lightIndex] = color; +} + +void Model::setNumLocalLights(int numLocalLights) { + _numLocalLights = numLocalLights; +} + void AnimationHandle::setURL(const QUrl& url) { if (_url != url) { _animation = Application::getInstance()->getAnimationCache()->getAnimation(_url = url); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 5e29b869e0..89b8843cf9 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -32,6 +32,8 @@ class Shape; typedef QSharedPointer AnimationHandlePointer; typedef QWeakPointer WeakAnimationHandlePointer; +const int MAX_LOCAL_LIGHTS = 2; + /// A generic 3D model displaying geometry loaded from a URL. class Model : public QObject, public PhysicsEntity { Q_OBJECT @@ -143,6 +145,10 @@ public: /// Sets blended vertices computed in a separate thread. void setBlendedVertices(const QVector& vertices, const QVector& normals); + void setLocalLightDirection(const glm::vec3& direction, int lightIndex); + void setLocalLightColor(const glm::vec3& color, int lightIndex); + void setNumLocalLights(int numLocalLights); + protected: QSharedPointer _geometry; @@ -158,6 +164,10 @@ protected: bool _showTrueJointTransforms; int _rootIndex; + glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; + glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS]; + int _numLocalLights; + QVector _jointStates; class MeshState { diff --git a/interface/src/renderer/ProgramObject.cpp b/interface/src/renderer/ProgramObject.cpp index b88be69f07..bcc80960d7 100644 --- a/interface/src/renderer/ProgramObject.cpp +++ b/interface/src/renderer/ProgramObject.cpp @@ -10,6 +10,7 @@ // #include "ProgramObject.h" +#include ProgramObject::ProgramObject(QObject* parent) : QGLShaderProgram(parent) { } @@ -22,3 +23,17 @@ void ProgramObject::setUniform(const char* name, const glm::vec3& value) { setUniformValue(name, value.x, value.y, value.z); } +void ProgramObject::setUniformArray(const char* name, const glm::vec3* values, int count) { + GLfloat* floatVal = new GLfloat[count*3]; + int index = 0; + for(int i = 0; i < count; i++) { + assert(index < count*3); + const float* valPtr = glm::value_ptr(values[i]); + floatVal[index++] = valPtr[0]; + floatVal[index++] = valPtr[1]; + floatVal[index++] = valPtr[2]; + } + + setUniformValueArray(name, floatVal, count, 3); + delete[] floatVal; +} diff --git a/interface/src/renderer/ProgramObject.h b/interface/src/renderer/ProgramObject.h index 21e01ac8b3..17d0ee0d22 100644 --- a/interface/src/renderer/ProgramObject.h +++ b/interface/src/renderer/ProgramObject.h @@ -23,6 +23,7 @@ public: void setUniform(int location, const glm::vec3& value); void setUniform(const char* name, const glm::vec3& value); + void setUniformArray(const char* name, const glm::vec3* values, int count); }; #endif // hifi_ProgramObject_h diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index e76a1cee7f..2354bbf13e 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -59,6 +59,8 @@ GLubyte identityIndicesRight[] = { 1, 2, 6, 1, 6, 5 }; GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 }; GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 }; +static glm::vec3 grayColor = glm::vec3(0.3f, 0.3f, 0.3f); + VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) : NodeData(), _treeScale(treeScale), @@ -72,7 +74,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) _renderer(0), _drawHaze(false), _farHazeDistance(300.0f), - _hazeColor(0.24f, 0.27f, 0.34f) + _hazeColor(grayColor) { _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; @@ -542,11 +544,8 @@ void VoxelSystem::initVoxelMemory() { GLfloat fogColor[] = {_hazeColor.x, _hazeColor.y, _hazeColor.z, 1.0f}; glFogi(GL_FOG_MODE, GL_LINEAR); glFogfv(GL_FOG_COLOR, fogColor); - glFogf(GL_FOG_DENSITY, 0.25f); - glHint(GL_FOG_HINT, GL_DONT_CARE); glFogf(GL_FOG_START, 0.0f); glFogf(GL_FOG_END, _farHazeDistance); - glEnable(GL_FOG); } } @@ -1431,6 +1430,10 @@ void VoxelSystem::render() { } } else if (!_usePrimitiveRenderer) { + if (_drawHaze) { + glEnable(GL_FOG); + } + PerformanceWarning warn(showWarnings, "render().. TRIANGLES..."); { @@ -1502,6 +1505,10 @@ void VoxelSystem::render() { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + + if (_drawHaze) { + glDisable(GL_FOG); + } } else { applyScaleAndBindProgram(texture); From ef4b95c6e0b1c50da01fce0bce9312e4ce5b8077 Mon Sep 17 00:00:00 2001 From: TonyPeng Date: Wed, 9 Jul 2014 13:27:42 -0700 Subject: [PATCH 35/43] Merged from master. Get rid of redundant GL fog states. Moved local light parameters to shader uniform arrays. --- examples/avatarLocalLight.js | 8 ++++---- interface/resources/shaders/model.frag | 2 +- interface/resources/shaders/model.vert | 1 + interface/resources/shaders/model_specular_map.frag | 3 ++- interface/resources/shaders/skin_model.vert | 1 - interface/src/avatar/Avatar.cpp | 2 +- interface/src/avatar/Avatar.h | 2 +- interface/src/renderer/Model.cpp | 2 +- interface/src/renderer/Model.h | 4 ++-- interface/src/renderer/ProgramObject.cpp | 2 +- interface/src/renderer/ProgramObject.h | 2 +- interface/src/voxels/VoxelSystem.cpp | 2 +- 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/examples/avatarLocalLight.js b/examples/avatarLocalLight.js index 69b491d430..57f9d84ffe 100644 --- a/examples/avatarLocalLight.js +++ b/examples/avatarLocalLight.js @@ -23,19 +23,19 @@ function keyPressEvent(event) { if (event.text == "1") { currentSelection = 0; - print("selection = " + currentSelection); + print("light election = " + currentSelection); } else if (event.text == "2" ) { currentSelection = 1; - print("selection = " + currentSelection); + print("light selection = " + currentSelection); } else if (event.text == "3" ) { currentSelection = 2; - print("selection = " + currentSelection); + print("light selection = " + currentSelection); } else if (event.text == "4" ) { currentSelection = 3; - print("selection = " + currentSelection); + print("light selection = " + currentSelection); } else if (event.text == "5" ) { localLightColors[currentSelection].x += 0.01; diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 95afaa0e5f..468a892686 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -16,7 +16,7 @@ uniform sampler2D diffuseMap; // local lights -const int MAX_LOCAL_LIGHTS = 2; // 2 lights for now, will probably need more later on +const int MAX_LOCAL_LIGHTS = 2; // 2 lights for now, will probably need more later on uniform int numLocalLights; uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS]; uniform vec3 localLightColors[MAX_LOCAL_LIGHTS]; diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 789c90817b..13eee2fa3d 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -39,3 +39,4 @@ void main(void) { // use standard pipeline transform gl_Position = ftransform(); } + diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index 7038ea84f7..329da65e9e 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -12,6 +12,7 @@ // const int MAX_LOCAL_LIGHTS = 2; +uniform int numLocalLights; uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS]; uniform vec3 localLightColors[MAX_LOCAL_LIGHTS]; @@ -35,7 +36,7 @@ void main(void) { // the local light that is always present vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { + for (int i = 0; i < numLocalLights; i++) { float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0)); float localLight = step(0.0, localDiffuse); float localLightVal = localDiffuse * localLight; diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 1ce1baa76f..943daf9061 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -13,7 +13,6 @@ const int MAX_CLUSTERS = 128; const int INDICES_PER_VERTEX = 4; -const int MAX_LOCAL_LIGHTS = 4; uniform mat4 clusterMatrices[MAX_CLUSTERS]; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e6bd204505..83105c9022 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -86,7 +86,7 @@ void Avatar::init() { for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { _localLightColors[i] = glm::vec3(0.0f, 0.0f, 0.0f); - _localLightDirections[i] = glm::vec3(0.0f, 0.0f, 1.0f); + _localLightDirections[i] = glm::vec3(0.0f, 0.0f, 0.0f); } glm::vec3 darkGrayColor(0.3f, 0.3f, 0.3f); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 79718c40df..31161e657b 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -184,7 +184,7 @@ protected: // always-present local lighting for the avatar glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS]; - int _numLocalLights; + int _numLocalLights; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 053e928ca3..8b8557709c 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1489,7 +1489,7 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances()); } - // local light + // local light uniforms skinProgram->setUniformValue("numLocalLights", _numLocalLights); skinProgram->setUniformArray("localLightDirections", _localLightDirections, MAX_LOCAL_LIGHTS); skinProgram->setUniformArray("localLightColors", _localLightColors, MAX_LOCAL_LIGHTS); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 89b8843cf9..9e2e0d8348 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -166,8 +166,8 @@ protected: glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS]; glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS]; - int _numLocalLights; - + int _numLocalLights; + QVector _jointStates; class MeshState { diff --git a/interface/src/renderer/ProgramObject.cpp b/interface/src/renderer/ProgramObject.cpp index bcc80960d7..16b3461ad0 100644 --- a/interface/src/renderer/ProgramObject.cpp +++ b/interface/src/renderer/ProgramObject.cpp @@ -26,7 +26,7 @@ void ProgramObject::setUniform(const char* name, const glm::vec3& value) { void ProgramObject::setUniformArray(const char* name, const glm::vec3* values, int count) { GLfloat* floatVal = new GLfloat[count*3]; int index = 0; - for(int i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { assert(index < count*3); const float* valPtr = glm::value_ptr(values[i]); floatVal[index++] = valPtr[0]; diff --git a/interface/src/renderer/ProgramObject.h b/interface/src/renderer/ProgramObject.h index 17d0ee0d22..8e66ce9bc9 100644 --- a/interface/src/renderer/ProgramObject.h +++ b/interface/src/renderer/ProgramObject.h @@ -23,7 +23,7 @@ public: void setUniform(int location, const glm::vec3& value); void setUniform(const char* name, const glm::vec3& value); - void setUniformArray(const char* name, const glm::vec3* values, int count); + void setUniformArray(const char* name, const glm::vec3* values, int count); }; #endif // hifi_ProgramObject_h diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 2354bbf13e..6c19cfd4c2 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -540,7 +540,7 @@ void VoxelSystem::initVoxelMemory() { _readArraysLock.unlock(); // fog for haze - if(_drawHaze) { + if (_drawHaze) { GLfloat fogColor[] = {_hazeColor.x, _hazeColor.y, _hazeColor.z, 1.0f}; glFogi(GL_FOG_MODE, GL_LINEAR); glFogfv(GL_FOG_COLOR, fogColor); From 6ffa09f9e62b3c2fb2436b19cf9dec7a800fd996 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 13:58:54 -0700 Subject: [PATCH 36/43] modified scope of devices stats --- interface/src/Application.cpp | 21 ++++++++------------- interface/src/devices/Faceshift.cpp | 2 ++ interface/src/devices/JoystickManager.cpp | 4 +++- interface/src/devices/PrioVR.cpp | 2 ++ interface/src/devices/SixenseManager.cpp | 7 ++++++- interface/src/devices/Visage.cpp | 2 ++ 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e5aa1d0050..d7464f57a1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1853,8 +1853,6 @@ void Application::updateMouseRay() { } void Application::updateFaceshift() { - PerformanceTimer perfTimer("faceshift"); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateFaceshift()"); @@ -1868,8 +1866,6 @@ void Application::updateFaceshift() { } void Application::updateVisage() { - PerformanceTimer perfTimer("visage"); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateVisage()"); @@ -2055,18 +2051,17 @@ void Application::update(float deltaTime) { updateLOD(); updateMouseRay(); // check what's under the mouse and update the mouse voxel - updateFaceshift(); - updateVisage(); - + { + PerformanceTimer perfTimer("devices"); + updateFaceshift(); + updateVisage(); + _sixenseManager.update(deltaTime); + _joystickManager.update(); + _prioVR.update(deltaTime); + } { PerformanceTimer perfTimer("myAvatar"); updateMyAvatarLookAtPosition(); - { - PerformanceTimer perfTimer("devices"); - _sixenseManager.update(deltaTime); - _joystickManager.update(); - _prioVR.update(deltaTime); - } updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes } diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index 59f2c245df..a7d50814e2 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -11,6 +11,7 @@ #include +#include #include #include "Application.h" @@ -75,6 +76,7 @@ void Faceshift::update() { if (!isActive()) { return; } + PerformanceTimer perfTimer("faceshift"); // get the euler angles relative to the window glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3( (_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f))))); diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp index 005505441c..8169c6d06e 100644 --- a/interface/src/devices/JoystickManager.cpp +++ b/interface/src/devices/JoystickManager.cpp @@ -12,9 +12,10 @@ #include #include - #include +#include + #include "JoystickManager.h" using namespace std; @@ -46,6 +47,7 @@ JoystickManager::~JoystickManager() { void JoystickManager::update() { #ifdef HAVE_SDL + PerformanceTimer perfTimer("joystick"); SDL_JoystickUpdate(); for (int i = 0; i < _joystickStates.size(); i++) { diff --git a/interface/src/devices/PrioVR.cpp b/interface/src/devices/PrioVR.cpp index e96f4f04d5..195de5705d 100644 --- a/interface/src/devices/PrioVR.cpp +++ b/interface/src/devices/PrioVR.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "Application.h" #include "PrioVR.h" @@ -166,6 +167,7 @@ void PrioVR::update(float deltaTime) { if (!_skeletalDevice) { return; } + PerformanceTimer perfTimer("PrioVR"); unsigned int timestamp; yei_getLastStreamDataAll(_skeletalDevice, (char*)_jointRotations.data(), _jointRotations.size() * sizeof(glm::quat), ×tamp); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 026c1d3eb4..d44bc33dc4 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -11,6 +11,8 @@ #include +#include + #include "Application.h" #include "SixenseManager.h" #include "UserActivityLogger.h" @@ -83,7 +85,10 @@ void SixenseManager::update(float deltaTime) { if (sixenseGetNumActiveControllers() == 0) { _hydrasConnected = false; return; - } else if (!_hydrasConnected) { + } + + PerformanceTimer perfTimer("sixense"); + if (!_hydrasConnected) { _hydrasConnected = true; UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra"); } diff --git a/interface/src/devices/Visage.cpp b/interface/src/devices/Visage.cpp index 119d89654a..5de2746b07 100644 --- a/interface/src/devices/Visage.cpp +++ b/interface/src/devices/Visage.cpp @@ -11,6 +11,7 @@ #include +#include #include #include @@ -128,6 +129,7 @@ void Visage::update() { if (!_active) { return; } + PerformanceTimer perfTimer("visage"); _headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2])); _headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) - _headOrigin) * TRANSLATION_SCALE; From f463099d16a5504f66426456e4a95010529a5d08 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 14:31:47 -0700 Subject: [PATCH 37/43] add "simulate" stat name to Avatar::simulate() --- interface/src/avatar/Avatar.cpp | 1 + interface/src/avatar/MyAvatar.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 26c8e3f2fc..db36300b55 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -99,6 +99,7 @@ float Avatar::getLODDistance() const { } void Avatar::simulate(float deltaTime) { + PerformanceTimer perfTimer("simulate"); if (_scale != _targetScale) { setScale(_targetScale); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 13c11dfefc..04e7b628c9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -130,7 +130,6 @@ void MyAvatar::update(float deltaTime) { void MyAvatar::simulate(float deltaTime) { PerformanceTimer perfTimer("simulate"); - if (_scale != _targetScale) { float scale = (1.0f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale; setScale(scale); From 63bcee02297299f51785585890eb2ee7ba0530d5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 14:33:09 -0700 Subject: [PATCH 38/43] fix whitespace formatting --- libraries/shared/src/PerfStat.cpp | 4 ++-- libraries/shared/src/PerfStat.h | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/shared/src/PerfStat.cpp b/libraries/shared/src/PerfStat.cpp index 908dca61e7..b811a719bc 100644 --- a/libraries/shared/src/PerfStat.cpp +++ b/libraries/shared/src/PerfStat.cpp @@ -90,8 +90,8 @@ PerformanceTimer::~PerformanceTimer() { // static void PerformanceTimer::tallyAllTimerRecords() { - QMap::iterator recordsItr = _records.begin(); - QMap::const_iterator recordsEnd = _records.end(); + QMap::iterator recordsItr = _records.begin(); + QMap::const_iterator recordsEnd = _records.end(); quint64 now = usecTimestampNow(); while (recordsItr != recordsEnd) { recordsItr.value().tallyResult(now); diff --git a/libraries/shared/src/PerfStat.h b/libraries/shared/src/PerfStat.h index 69bda0af5e..3cbf188c83 100644 --- a/libraries/shared/src/PerfStat.h +++ b/libraries/shared/src/PerfStat.h @@ -25,13 +25,13 @@ class PerformanceWarning { private: - quint64 _start; - const char* _message; - bool _renderWarningsOn; - bool _alwaysDisplay; - quint64* _runningTotal; - quint64* _totalCalls; - static bool _suppressShortTimings; + quint64 _start; + const char* _message; + bool _renderWarningsOn; + bool _alwaysDisplay; + quint64* _runningTotal; + quint64* _totalCalls; + static bool _suppressShortTimings; public: PerformanceWarning(bool renderWarnings, const char* message, bool alwaysDisplay = false, @@ -62,13 +62,13 @@ public: quint64 getCount() const { return _numTallies; } private: - quint64 _runningTotal; + quint64 _runningTotal; quint64 _lastTotal; quint64 _numAccumulations; - quint64 _numTallies; + quint64 _numTallies; quint64 _expiry; - SimpleMovingAverage _movingAverage; -}; + SimpleMovingAverage _movingAverage; + class PerformanceTimer { public: @@ -89,10 +89,10 @@ public: static void dumpAllTimerRecords(); private: - quint64 _start; - QString _name; + quint64 _start; + QString _name; static QString _fullName; - static QMap _records; + static QMap _records; }; From 9ce6844e9d50549192b0155f185f8cc6e0f47a7f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 14:39:08 -0700 Subject: [PATCH 39/43] fix accidental broken class definition --- libraries/shared/src/PerfStat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/PerfStat.h b/libraries/shared/src/PerfStat.h index 3cbf188c83..4f94be73b1 100644 --- a/libraries/shared/src/PerfStat.h +++ b/libraries/shared/src/PerfStat.h @@ -68,7 +68,7 @@ private: quint64 _numTallies; quint64 _expiry; SimpleMovingAverage _movingAverage; - +}; class PerformanceTimer { public: From f2d49fa6a1b911118d84a416deaaaa2fa0f5dedf Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 9 Jul 2014 15:12:29 -0700 Subject: [PATCH 40/43] Rename focus indicators menu item and default to off --- interface/src/Menu.cpp | 2 +- interface/src/Menu.h | 2 +- interface/src/avatar/Avatar.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 019ce1df9e..beb6e18e5c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -406,7 +406,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false); - addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::HideFocusIndicators, 0, false); + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::FocusIndicators, 0, false); QMenu* oculusOptionsMenu = developerMenu->addMenu("Oculus Options"); addCheckableActionToQMenuAndActionHash(oculusOptionsMenu, MenuOption::DisplayOculusOverlays, 0, true); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 32458e1883..b66d3f1107 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -369,6 +369,7 @@ namespace MenuOption { const QString Faceshift = "Faceshift"; const QString FilterSixense = "Smooth Sixense Movement"; const QString FirstPerson = "First Person"; + const QString FocusIndicators = "Focus Indicators"; const QString FrameTimer = "Show Timer"; const QString FrustumRenderMode = "Render Mode"; const QString Fullscreen = "Fullscreen"; @@ -382,7 +383,6 @@ namespace MenuOption { const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity"; const QString HandsCollideWithSelf = "Collide With Self"; const QString HeadMouse = "Head Mouse"; - const QString HideFocusIndicators = "Hide Focus Indicators"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; const QString LoadScript = "Open and Run Script File..."; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e2e111c210..c7d01ba996 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -257,7 +257,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { } // If this is the avatar being looked at, render a little ball above their head - if (_isLookAtTarget && !Menu::getInstance()->isOptionChecked(MenuOption::HideFocusIndicators)) { + if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::FocusIndicators)) { const float LOOK_AT_INDICATOR_RADIUS = 0.03f; const float LOOK_AT_INDICATOR_OFFSET = 0.22f; const float LOOK_AT_INDICATOR_COLOR[] = { 0.8f, 0.0f, 0.0f, 0.75f }; From d412e21008ddceff111179e3cdcf0ad371dec8e7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Jul 2014 15:51:37 -0700 Subject: [PATCH 41/43] add two new concert cameras to examples --- examples/concertCamera_kims.js | 72 ++++++++++++++++++++++++++++++++++ examples/concertCamera_kyrs.js | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 examples/concertCamera_kims.js create mode 100644 examples/concertCamera_kyrs.js diff --git a/examples/concertCamera_kims.js b/examples/concertCamera_kims.js new file mode 100644 index 0000000000..3017d3c008 --- /dev/null +++ b/examples/concertCamera_kims.js @@ -0,0 +1,72 @@ +// +// concertCamera.js +// +// Created by Philip Rosedale on June 24, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// Move a camera through a series of pre-set locations by pressing number keys +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var oldMode; +var avatarPosition; + +var cameraNumber = 0; +var freeCamera = false; + +var cameraLocations = [ {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5, z: 7306.6}, {x: 8027.5, y: 237.5, z: 7308.0}, {x: 8027.5, y: 237.5, z: 7303.0}, {x: 8030.8, y: 238.6, z: 7311.4}, {x: 8030.9, y: 237.1, z: 7308.0} ]; +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(); + avatarPosition = MyAvatar.position; + Camera.setModeShiftPeriod(0.0); + Camera.setMode("independent"); +} + +function restoreCameraState() { + Camera.stopLooking(); + Camera.setMode(oldMode); +} + +function update(deltaTime) { + if (freeCamera) { + var delta = Vec3.subtract(MyAvatar.position, avatarPosition); + if (Vec3.length(delta) > 0.05) { + cameraNumber = 0; + freeCamera = false; + restoreCameraState(); + } + } +} + +function keyPressEvent(event) { + + var choice = parseInt(event.text); + + if ((choice > 0) && (choice <= cameraLocations.length)) { + print("camera " + choice); + if (!freeCamera) { + saveCameraState(); + freeCamera = true; + } + Camera.setMode("independent"); + Camera.setPosition(cameraLocations[choice - 1]); + Camera.keepLookingAt(cameraLookAts[choice - 1]); + } + if (event.text == "ESC") { + cameraNumber = 0; + freeCamera = false; + restoreCameraState(); + } + if (event.text == "0") { + // Show camera location in log + var cameraLocation = Camera.getPosition(); + print(cameraLocation.x + ", " + cameraLocation.y + ", " + cameraLocation.z); + } +} + +Script.update.connect(update); +Controller.keyPressEvent.connect(keyPressEvent); diff --git a/examples/concertCamera_kyrs.js b/examples/concertCamera_kyrs.js new file mode 100644 index 0000000000..2b37a84f9e --- /dev/null +++ b/examples/concertCamera_kyrs.js @@ -0,0 +1,72 @@ +// +// concertCamera.js +// +// Created by Philip Rosedale on June 24, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// Move a camera through a series of pre-set locations by pressing number keys +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var oldMode; +var avatarPosition; + +var cameraNumber = 0; +var freeCamera = false; + +var cameraLocations = [ {x: 2921.5, y: 251.3, z: 8254.8}, {x: 2921.5, y: 251.3, z: 8254.4}, {x: 2921.5, y: 251.3, z: 8252.2}, {x: 2921.5, y: 251.3, z: 8247.2}, {x: 2921.4, y: 251.3, z: 8255.7} ]; +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(); + avatarPosition = MyAvatar.position; + Camera.setModeShiftPeriod(0.0); + Camera.setMode("independent"); +} + +function restoreCameraState() { + Camera.stopLooking(); + Camera.setMode(oldMode); +} + +function update(deltaTime) { + if (freeCamera) { + var delta = Vec3.subtract(MyAvatar.position, avatarPosition); + if (Vec3.length(delta) > 0.05) { + cameraNumber = 0; + freeCamera = false; + restoreCameraState(); + } + } +} + +function keyPressEvent(event) { + + var choice = parseInt(event.text); + + if ((choice > 0) && (choice <= cameraLocations.length)) { + print("camera " + choice); + if (!freeCamera) { + saveCameraState(); + freeCamera = true; + } + Camera.setMode("independent"); + Camera.setPosition(cameraLocations[choice - 1]); + Camera.keepLookingAt(cameraLookAts[choice - 1]); + } + if (event.text == "ESC") { + cameraNumber = 0; + freeCamera = false; + restoreCameraState(); + } + if (event.text == "0") { + // Show camera location in log + var cameraLocation = Camera.getPosition(); + print(cameraLocation.x + ", " + cameraLocation.y + ", " + cameraLocation.z); + } +} + +Script.update.connect(update); +Controller.keyPressEvent.connect(keyPressEvent); From 8fa7bf4fa091714b7010b49f16d44f2f794d2adc Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Jul 2014 16:43:46 -0700 Subject: [PATCH 42/43] rename: ParentFrame --> ConstrainedFrame --- interface/src/avatar/FaceModel.cpp | 8 ++--- interface/src/avatar/SkeletonModel.cpp | 6 ++-- interface/src/renderer/JointState.cpp | 48 +++++++++++++------------- interface/src/renderer/JointState.h | 12 +++---- interface/src/renderer/Model.cpp | 8 ++--- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 59e5b08cc0..203dbf2283 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -49,9 +49,9 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) { void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { // get the rotation axes in joint space and use them to adjust the rotation glm::mat3 axes = glm::mat3_cast(glm::quat()); - glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) * + glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInConstrainedFrame()) * joint.preTransform * glm::mat4_cast(joint.preRotation))); - state.setRotationInParentFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2])) + state.setRotationInConstrainedFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2])) * glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getFinalYaw(), glm::normalize(inverse * axes[1])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalPitch(), glm::normalize(inverse * axes[0])) * joint.rotation); @@ -61,14 +61,14 @@ void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJ // likewise with the eye joints // NOTE: at the moment we do the math in the world-frame, hence the inverse transform is more complex than usual. glm::mat4 inverse = glm::inverse(glm::mat4_cast(_rotation) * parentState.getTransform() * - glm::translate(state.getDefaultTranslationInParentFrame()) * + glm::translate(state.getDefaultTranslationInConstrainedFrame()) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)); glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT, 0.0f)); glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() + _owningHead->getSaccade() - _translation, 1.0f)); glm::quat between = rotationBetween(front, lookAt); const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE; - state.setRotationInParentFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * + state.setRotationInConstrainedFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * joint.rotation); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2f35b96181..d9b2340a90 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -219,7 +219,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { JointState& parentState = _jointStates[parentJointIndex]; parentState.setRotationFromBindFrame(palmRotation, PALM_PRIORITY); // lock hand to forearm by slamming its rotation (in parent-frame) to identity - _jointStates[jointIndex].setRotationInParentFrame(glm::quat()); + _jointStates[jointIndex].setRotationInConstrainedFrame(glm::quat()); } else { inverseKinematics(jointIndex, palmPosition, palmRotation, PALM_PRIORITY); } @@ -255,9 +255,9 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const } // get the rotation axes in joint space and use them to adjust the rotation glm::mat3 axes = glm::mat3_cast(glm::quat()); - glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) * + glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInConstrainedFrame()) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation))); - state.setRotationInParentFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), + state.setRotationInConstrainedFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation); } diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index 429084480d..5a2766d39f 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -26,7 +26,7 @@ JointState::JointState() : JointState::JointState(const JointState& other) : _constraint(NULL) { _transform = other._transform; _rotation = other._rotation; - _rotationInParentFrame = other._rotationInParentFrame; + _rotationInConstrainedFrame = other._rotationInConstrainedFrame; _animationPriority = other._animationPriority; _fbxJoint = other._fbxJoint; // DO NOT copy _constraint @@ -43,7 +43,7 @@ JointState::~JointState() { void JointState::setFBXJoint(const FBXJoint* joint) { assert(joint != NULL); - _rotationInParentFrame = joint->rotation; + _rotationInConstrainedFrame = joint->rotation; // NOTE: JointState does not own the FBXJoint to which it points. _fbxJoint = joint; if (_constraint) { @@ -68,24 +68,24 @@ void JointState::copyState(const JointState& state) { _animationPriority = state._animationPriority; _transform = state._transform; _rotation = extractRotation(_transform); - _rotationInParentFrame = state._rotationInParentFrame; + _rotationInConstrainedFrame = state._rotationInConstrainedFrame; _visibleTransform = state._visibleTransform; _visibleRotation = extractRotation(_visibleTransform); - _visibleRotationInParentFrame = state._visibleRotationInParentFrame; + _visibleRotationInConstrainedFrame = state._visibleRotationInConstrainedFrame; // DO NOT copy _fbxJoint or _constraint } void JointState::computeTransform(const glm::mat4& parentTransform) { - glm::quat modifiedRotation = _fbxJoint->preRotation * _rotationInParentFrame * _fbxJoint->postRotation; - glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(modifiedRotation) * _fbxJoint->postTransform; + glm::quat rotationInConstrainedFrame = _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation; + glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform; _transform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform; _rotation = extractRotation(_transform); } void JointState::computeVisibleTransform(const glm::mat4& parentTransform) { - glm::quat modifiedRotation = _fbxJoint->preRotation * _visibleRotationInParentFrame * _fbxJoint->postRotation; - glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(modifiedRotation) * _fbxJoint->postTransform; + glm::quat rotationInConstrainedFrame = _fbxJoint->preRotation * _visibleRotationInConstrainedFrame * _fbxJoint->postRotation; + glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform; _visibleTransform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform; _visibleRotation = extractRotation(_visibleTransform); } @@ -97,7 +97,7 @@ glm::quat JointState::getRotationFromBindToModelFrame() const { void JointState::restoreRotation(float fraction, float priority) { assert(_fbxJoint != NULL); if (priority == _animationPriority || _animationPriority == 0.0f) { - setRotationInParentFrame(safeMix(_rotationInParentFrame, _fbxJoint->rotation, fraction)); + setRotationInConstrainedFrame(safeMix(_rotationInConstrainedFrame, _fbxJoint->rotation, fraction)); _animationPriority = 0.0f; } } @@ -106,11 +106,11 @@ void JointState::setRotationFromBindFrame(const glm::quat& rotation, float prior // rotation is from bind- to model-frame assert(_fbxJoint != NULL); if (priority >= _animationPriority) { - glm::quat targetRotation = _rotationInParentFrame * glm::inverse(_rotation) * rotation * glm::inverse(_fbxJoint->inverseBindRotation); + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * rotation * glm::inverse(_fbxJoint->inverseBindRotation); if (constrain && _constraint) { - _constraint->softClamp(targetRotation, _rotationInParentFrame, 0.5f); + _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); } - setRotationInParentFrame(targetRotation); + setRotationInConstrainedFrame(targetRotation); _animationPriority = priority; } } @@ -137,12 +137,12 @@ void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, floa _animationPriority = priority; if (!constrain || _constraint == NULL) { // no constraints - _rotationInParentFrame = _rotationInParentFrame * glm::inverse(_rotation) * delta * _rotation; + _rotationInConstrainedFrame = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; _rotation = delta * _rotation; return; } - glm::quat targetRotation = _rotationInParentFrame * glm::inverse(_rotation) * delta * _rotation; - setRotationInParentFrame(targetRotation); + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; + setRotationInConstrainedFrame(targetRotation); } /// Applies delta rotation to joint but mixes a little bit of the default pose as well. @@ -154,30 +154,30 @@ void JointState::mixRotationDelta(const glm::quat& delta, float mixFactor, float return; } _animationPriority = priority; - glm::quat targetRotation = _rotationInParentFrame * glm::inverse(_rotation) * delta * _rotation; + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; if (mixFactor > 0.0f && mixFactor <= 1.0f) { targetRotation = safeMix(targetRotation, _fbxJoint->rotation, mixFactor); } if (_constraint) { - _constraint->softClamp(targetRotation, _rotationInParentFrame, 0.5f); + _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); } - setRotationInParentFrame(targetRotation); + setRotationInConstrainedFrame(targetRotation); } glm::quat JointState::computeParentRotation() const { // R = Rp * Rpre * r * Rpost // Rp = R * (Rpre * r * Rpost)^ - return _rotation * glm::inverse(_fbxJoint->preRotation * _rotationInParentFrame * _fbxJoint->postRotation); + return _rotation * glm::inverse(_fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation); } -void JointState::setRotationInParentFrame(const glm::quat& targetRotation) { +void JointState::setRotationInConstrainedFrame(const glm::quat& targetRotation) { glm::quat parentRotation = computeParentRotation(); - _rotationInParentFrame = targetRotation; + _rotationInConstrainedFrame = targetRotation; // R' = Rp * Rpre * r' * Rpost - _rotation = parentRotation * _fbxJoint->preRotation * _rotationInParentFrame * _fbxJoint->postRotation; + _rotation = parentRotation * _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation; } -const glm::vec3& JointState::getDefaultTranslationInParentFrame() const { +const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const { assert(_fbxJoint != NULL); return _fbxJoint->translation; } @@ -185,5 +185,5 @@ const glm::vec3& JointState::getDefaultTranslationInParentFrame() const { void JointState::slaveVisibleTransform() { _visibleTransform = _transform; _visibleRotation = _rotation; - _visibleRotationInParentFrame = _rotationInParentFrame; + _visibleRotationInConstrainedFrame = _rotationInConstrainedFrame; } diff --git a/interface/src/renderer/JointState.h b/interface/src/renderer/JointState.h index 3bd752cdff..049eb6e6b0 100644 --- a/interface/src/renderer/JointState.h +++ b/interface/src/renderer/JointState.h @@ -66,14 +66,14 @@ public: void restoreRotation(float fraction, float priority); /// \param rotation is from bind- to model-frame - /// computes and sets new _rotationInParentFrame + /// computes and sets new _rotationInConstrainedFrame /// NOTE: the JointState's model-frame transform/rotation are NOT updated! void setRotationFromBindFrame(const glm::quat& rotation, float priority, bool constrain = false); - void setRotationInParentFrame(const glm::quat& targetRotation); - const glm::quat& getRotationInParentFrame() const { return _rotationInParentFrame; } + void setRotationInConstrainedFrame(const glm::quat& targetRotation); + const glm::quat& getRotationInConstrainedFrame() const { return _rotationInConstrainedFrame; } - const glm::vec3& getDefaultTranslationInParentFrame() const; + const glm::vec3& getDefaultTranslationInConstrainedFrame() const; void clearTransformTranslation(); @@ -92,11 +92,11 @@ private: glm::mat4 _transform; // joint- to model-frame glm::quat _rotation; // joint- to model-frame - glm::quat _rotationInParentFrame; // joint- to parentJoint-frame + glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied glm::mat4 _visibleTransform; glm::quat _visibleRotation; - glm::quat _visibleRotationInParentFrame; + glm::quat _visibleRotationInConstrainedFrame; const FBXJoint* _fbxJoint; // JointState does NOT own its FBXJoint AngularConstraint* _constraint; // JointState owns its AngularConstraint diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 8b8557709c..cbdbff072b 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -460,7 +460,7 @@ void Model::reset() { } const FBXGeometry& geometry = _geometry->getFBXGeometry(); for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].setRotationInParentFrame(geometry.joints.at(i).rotation); + _jointStates[i].setRotationInConstrainedFrame(geometry.joints.at(i).rotation); } } @@ -688,7 +688,7 @@ bool Model::getJointState(int index, glm::quat& rotation) const { if (index == -1 || index >= _jointStates.size()) { return false; } - rotation = _jointStates.at(index).getRotationInParentFrame(); + rotation = _jointStates.at(index).getRotationInConstrainedFrame(); const glm::quat& defaultRotation = _geometry->getFBXGeometry().joints.at(index).rotation; return glm::abs(rotation.x - defaultRotation.x) >= EPSILON || glm::abs(rotation.y - defaultRotation.y) >= EPSILON || @@ -701,7 +701,7 @@ void Model::setJointState(int index, bool valid, const glm::quat& rotation, floa JointState& state = _jointStates[index]; if (priority >= state._animationPriority) { if (valid) { - state.setRotationInParentFrame(rotation); + state.setRotationInConstrainedFrame(rotation); state._animationPriority = priority; } else { state.restoreRotation(1.0f, priority); @@ -1787,7 +1787,7 @@ void AnimationHandle::applyFrame(float frameIndex) { if (mapping != -1) { JointState& state = _model->_jointStates[mapping]; if (_priority >= state._animationPriority) { - state.setRotationInParentFrame(safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction)); + state.setRotationInConstrainedFrame(safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction)); state._animationPriority = _priority; } } From fdd9acb47768df14819175f9bb802e39995535f0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 10 Jul 2014 10:55:41 -0700 Subject: [PATCH 43/43] bug fix: bad logic for early exit --- interface/src/avatar/AvatarManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 86ec7c2680..debe6489ea 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -41,7 +41,7 @@ void AvatarManager::init() { } void AvatarManager::updateOtherAvatars(float deltaTime) { - if (_avatarHash.size() > 1) { + if (_avatarHash.size() < 2) { return; } bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);