From 5eff12af34f8a047afa58dfd088faa171fc4c837 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 6 Jan 2017 18:09:23 -0700 Subject: [PATCH 01/29] add hover effect to PAL --- scripts/system/pal.js | 55 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index ef16889035..6428749bee 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -19,9 +19,13 @@ const UNSELECTED_TEXTURES = {"idle-D": Script.resolvePath("./assets/models/Avata const SELECTED_TEXTURES = { "idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png"), "idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png") }; +const HOVER_TEXTURES = { "idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png"), + "idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png") +}; const UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6}; -const SELECTED_COLOR = {red: 0xf3, green: 0x91, blue: 0x29}; +const SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29}; +const HOVER_COLOR = {red: 0xFF, green: 0xFF, blue: 0xFF}; // white for now (function() { // BEGIN LOCAL_SCOPE @@ -46,6 +50,7 @@ function ExtendedOverlay(key, type, properties, selected, hasModel) { // A wrapp } this.key = key; this.selected = selected || false; // not undefined + this.hovering = false; this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected... } // Instance methods: @@ -58,20 +63,38 @@ ExtendedOverlay.prototype.editOverlay = function (properties) { // change displa Overlays.editOverlay(this.activeOverlay, properties); }; -function color(selected) { - return selected ? SELECTED_COLOR : UNSELECTED_COLOR; +function color(selected, hovering) { + + return hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR; } -function textures(selected) { - return selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES; +function textures(selected, hovering) { + return hovering ? HOVER_TEXTURES : selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES; +} +// so we don't have to traverse the overlays to get the last one +var lastHoveringId = 0; +ExtendedOverlay.prototype.hover = function (hovering) { + if (this.key === lastHoveringId) { + if (hovering) { + return; + } else { + lastHoveringId = 0; + } + } + this.editOverlay({color: color(this.selected, hovering)}); + if (this.model) { + this.model.editOverlay({textures: textures(this.selected, hovering)}); + } + if (hovering) { + lastHoveringId = this.key; + } } - ExtendedOverlay.prototype.select = function (selected) { if (this.selected === selected) { return; } - this.editOverlay({color: color(selected)}); + this.editOverlay({color: color(selected, this.hovering)}); if (this.model) { this.model.editOverlay({textures: textures(selected)}); } @@ -93,9 +116,12 @@ ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator } } }; -ExtendedOverlay.applyPickRay = function (pickRay, cb) { // cb(overlay) on the one overlay intersected by pickRay, if any. +ExtendedOverlay.applyPickRay = function (pickRay, cb, noHit) { // cb(overlay) on the one overlay intersected by pickRay, if any. var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones. if (!pickedOverlay.intersects) { + if (noHit) { + return noHit(); + } return; } ExtendedOverlay.some(function (overlay) { // See if pickedOverlay is one of ours. @@ -311,6 +337,7 @@ function updateOverlays() { } function removeOverlays() { selectedIds = []; + lastHoveringId = 0; HighlightedEntity.clearOverlays(); ExtendedOverlay.some(function (overlay) { overlay.deleteOverlay(); }); } @@ -332,6 +359,16 @@ function handleMouseEvent(mousePressEvent) { // handleClick if we get one. } handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y)); } +function handleMouseMoveEvent(event) { + // find out which overlay (if any) is over the mouse position + // var overlayAtPoint = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + var pickRay = Camera.computePickRay(event.x, event.y); + var hit = ExtendedOverlay.applyPickRay(pickRay, function (overlay) { + overlay.hover(true); + }, function () { + ExtendedOverlay.some(function (overlay) { overlay.hover(false); }); + }); +} // We get mouseMoveEvents from the handControllers, via handControllerPointer. // But we don't get mousePressEvents. var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); @@ -371,6 +408,7 @@ function off() { if (isWired) { // It is not ok to disconnect these twice, hence guard. Script.update.disconnect(updateOverlays); Controller.mousePressEvent.disconnect(handleMouseEvent); + Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); isWired = false; } triggerMapping.disable(); // It's ok if we disable twice. @@ -385,6 +423,7 @@ function onClicked() { isWired = true; Script.update.connect(updateOverlays); Controller.mousePressEvent.connect(handleMouseEvent); + Controller.mouseMoveEvent.connect(handleMouseMoveEvent); triggerMapping.enable(); } else { off(); From 32a0225f48088177aa58f6a5acc391ead827ee26 Mon Sep 17 00:00:00 2001 From: jmferrer Date: Sun, 8 Jan 2017 08:51:56 +0100 Subject: [PATCH 02/29] Fix: $ cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.6.1/5.6/gcc_64/lib/cmake -- Performing Test COMPILER_SUPPORTS_CXX11 -- Performing Test COMPILER_SUPPORTS_CXX11 - Success -- Performing Test COMPILER_SUPPORTS_CXX0X -- Performing Test COMPILER_SUPPORTS_CXX0X - Success -- The BUILD_BRANCH variable is: -- The BRANCH environment variable is: -- The RELEASE_TYPE variable is: -- The BUILD_GLOBAL_SERVICES variable is: DEVELOPMENT -- The USE_STABLE_GLOBAL_SERVICES variable is: 0 -- Found GLM: /home/jmferrerm/trabajo/SL/hifi/build/ext/makefiles/glm/project/include -- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.8") CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message): Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIR) Call Stack (most recent call first): /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE) cmake/modules/FindOpenSSL.cmake:217 (find_package_handle_standard_args) libraries/networking/CMakeLists.txt:15 (find_package) -- Configuring incomplete, errors occurred! See also "/home/jmferrerm/trabajo/SL/hifi/build/CMakeFiles/CMakeOutput.log". --- BUILD_LINUX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 55cd647f66..34ba41894c 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -3,4 +3,4 @@ Please read the [general build guide](BUILD.md) for information on dependencies ###Qt5 Dependencies Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: - libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev + libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev From 409e785aa3d4baeac8d7eb70d5ab5852aeffb77c Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 9 Jan 2017 08:42:43 -0700 Subject: [PATCH 03/29] fix un-hover, add some comments --- scripts/system/pal.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 6428749bee..72955bf3ab 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -86,6 +86,10 @@ ExtendedOverlay.prototype.hover = function (hovering) { this.model.editOverlay({textures: textures(this.selected, hovering)}); } if (hovering) { + // un-hover the last hovering overlay + if (lastHoveringId && lastHoveringId != this.key) { + ExtendedOverlay.get(lastHoveringId).hover(false); + } lastHoveringId = this.key; } } @@ -116,7 +120,10 @@ ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator } } }; -ExtendedOverlay.applyPickRay = function (pickRay, cb, noHit) { // cb(overlay) on the one overlay intersected by pickRay, if any. + +// hit(overlay) on the one overlay intersected by pickRay, if any. +// noHit() if no ExtendedOverlay was intersected (helps with hover) +ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) { // cb(overlay) on the one overlay intersected by pickRay, if any. var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones. if (!pickedOverlay.intersects) { if (noHit) { @@ -126,7 +133,7 @@ ExtendedOverlay.applyPickRay = function (pickRay, cb, noHit) { // cb(overlay) on } ExtendedOverlay.some(function (overlay) { // See if pickedOverlay is one of ours. if ((overlay.activeOverlay) === pickedOverlay.overlayID) { - cb(overlay); + hit(overlay); return true; } }); @@ -363,7 +370,7 @@ function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position // var overlayAtPoint = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); var pickRay = Camera.computePickRay(event.x, event.y); - var hit = ExtendedOverlay.applyPickRay(pickRay, function (overlay) { + ExtendedOverlay.applyPickRay(pickRay, function (overlay) { overlay.hover(true); }, function () { ExtendedOverlay.some(function (overlay) { overlay.hover(false); }); From 5c6ae6fe95ca1a6d71799f139f8d7484173a8dad Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 10 Jan 2017 14:47:34 -0700 Subject: [PATCH 04/29] HMD hover working now Had to hack a bit -- the trigger mappings were not firing so instead I just get the hand that is triggering (when HMD is active) and handle the hover almost as before, with mouse move events. Some thought about how to map a 'mouse move' event into something where 2 triggers can both be pressed at same time was in order. --- scripts/system/pal.js | 71 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 6a9ac1195b..ef65fb0a88 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -120,6 +120,11 @@ ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator } } }; +ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId (if any) + if (lastHoveringId) { + ExtendedOverlay.get(lastHoveringId).hover(false); + } +}; // hit(overlay) on the one overlay intersected by pickRay, if any. // noHit() if no ExtendedOverlay was intersected (helps with hover) @@ -366,16 +371,70 @@ function handleMouseEvent(mousePressEvent) { // handleClick if we get one. } handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y)); } -function handleMouseMoveEvent(event) { - // find out which overlay (if any) is over the mouse position - // var overlayAtPoint = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - var pickRay = Camera.computePickRay(event.x, event.y); +function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position + if (HMD.active) { + var hand = whichHand(); + if (hand != 0) { + print("pick ray for " + hand); + pickRay = controllerComputePickRay(hand); + } else { + // nothing should hover, so + ExtendedOverlay.unHover(); + return; + } + } else { + pickRay = Camera.computePickRay(event.x, event.y); + } + handleMouseMove(pickRay); +} +const TRIGGER_THRESHOLD = 0.85; +// for some reason, I could not get trigger mappings for the LT and RT to fire. So, since we can read the +// value of the RT and LT, and the messages come through as mouse moves, we have the hack below to figure out +// which hand is being triggered, and compute the pick ray accordingly. +// +function isPressed(hand) { // helper to see if the hand passed in has the trigger pulled + var controller = (hand === Controller.Standard.RightHand ? Controller.Standard.RT : Controller.Standard.LT); + return Controller.getValue(controller) > TRIGGER_THRESHOLD; +} +// helpful globals +var currentHandPressed = 0; +var hands = [Controller.Standard.RightHand, Controller.Standard.LeftHand]; + +function whichHand() { + // for HMD, decide which hand is the "mouse". The 'logic' is to use the first one that + // is triggered, until that one is released. There are interesting effects when both + // are held that this avoids. Mapping the 2 triggers and their lasers to one mouse move + // message is a bit problematic, this mitigates some of it. + if (HMD.active) { + var pressed = {}; + for (var i = 0; i 0.85) { + if (clicked > TRIGGER_THRESHOLD) { var pickRay = controllerComputePickRay(hand); handleClick(pickRay); } From 2d55ed265807eafa43a7d23cd34957ba848f90af Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 10 Jan 2017 15:51:24 -0700 Subject: [PATCH 05/29] Fix hover - probably my merge didn't get this line --- scripts/system/pal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 05d8194c08..9104e96350 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -78,6 +78,7 @@ function textures(selected, hovering) { // so we don't have to traverse the overlays to get the last one var lastHoveringId = 0; ExtendedOverlay.prototype.hover = function (hovering) { + this.hovering = hovering; if (this.key === lastHoveringId) { if (hovering) { return; From 5fd11ade9cfbe9445480b947d2c4c16fd3627281 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 10 Jan 2017 16:00:19 -0700 Subject: [PATCH 06/29] minor tweak to hover color for glow effect --- scripts/system/pal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 9104e96350..d385b5331e 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -25,7 +25,7 @@ const HOVER_TEXTURES = { "idle-D": Script.resolvePath("./assets/models/Avatar-Ov const UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6}; const SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29}; -const HOVER_COLOR = {red: 0xFF, green: 0xFF, blue: 0xFF}; // white for now +const HOVER_COLOR = {red: 0xD0, green: 0xD0, blue: 0xD0}; // almost white for now (function() { // BEGIN LOCAL_SCOPE From 4fade3a53eb07db6d2b7d980c832b99194ea606d Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 10 Jan 2017 16:12:02 -0700 Subject: [PATCH 07/29] CR feedback --- scripts/system/pal.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index d385b5331e..d45e1fc7bc 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -133,7 +133,7 @@ ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId // hit(overlay) on the one overlay intersected by pickRay, if any. // noHit() if no ExtendedOverlay was intersected (helps with hover) -ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) { // cb(overlay) on the one overlay intersected by pickRay, if any. +ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) { var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones. if (!pickedOverlay.intersects) { if (noHit) { @@ -377,6 +377,13 @@ function handleMouseEvent(mousePressEvent) { // handleClick if we get one. } handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y)); } +function handleMouseMove(pickRay) { // given the pickRay, just do the hover logic + ExtendedOverlay.applyPickRay(pickRay, function (overlay) { + overlay.hover(true); + }, function () { + ExtendedOverlay.unHover(); + }); +} function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position if (HMD.active) { var hand = whichHand(); @@ -433,14 +440,6 @@ function whichHand() { return currentHandPressed; } -function handleMouseMove(pickRay) { // given the pickRay, just do the hover logic - ExtendedOverlay.applyPickRay(pickRay, function (overlay) { - overlay.hover(true); - }, function () { - ExtendedOverlay.unHover(); - }); -} - // We get mouseMoveEvents from the handControllers, via handControllerPointer. // But we don't get mousePressEvents. var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); From 44699fc661e397ebe40ed68c2cefc08871c38e69 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Jan 2017 16:21:13 -0800 Subject: [PATCH 08/29] modelToWorld rotation not in cluster matrices --- .../render-utils/src/MeshPartPayload.cpp | 26 +++++++------------ libraries/render-utils/src/MeshPartPayload.h | 7 +++-- libraries/render-utils/src/Model.cpp | 10 +++---- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 037d58a67b..66f4f577b7 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -63,8 +63,7 @@ void MeshPartPayload::updateMeshPart(const std::shared_ptr& d void MeshPartPayload::updateTransform(const Transform& transform, const Transform& offsetTransform) { _transform = transform; - _offsetTransform = offsetTransform; - Transform::mult(_drawTransform, _transform, _offsetTransform); + Transform::mult(_drawTransform, _transform, offsetTransform); _worldBound = _localBound; _worldBound.transform(_drawTransform); } @@ -360,8 +359,8 @@ void ModelMeshPartPayload::notifyLocationChanged() { } -void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transform, const Transform& offsetTransform, const QVector& clusterMatrices) { - ModelMeshPartPayload::updateTransform(transform, offsetTransform); +void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transform, const QVector& clusterMatrices) { + _transform = transform; if (clusterMatrices.size() > 0) { _worldBound = AABox(); @@ -371,8 +370,10 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transf _worldBound += clusterBound; } - // clusterMatrix has world rotation but not world translation. - _worldBound.translate(transform.getTranslation()); + _worldBound.transform(transform); + if (clusterMatrices.size() == 1) { + _transform.worldTransform(Transform(clusterMatrices[0])); + } } } @@ -520,23 +521,15 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline: // Still relying on the raw data from the model const Model::MeshState& state = _model->_meshStates.at(_meshIndex); - Transform transform; if (state.clusterBuffer) { if (canCauterize && _model->getCauterizeBones()) { batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, state.cauterizedClusterBuffer); } else { batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, state.clusterBuffer); } - } else { - if (canCauterize && _model->getCauterizeBones()) { - transform = Transform(state.cauterizedClusterMatrices[0]); - } else { - transform = Transform(state.clusterMatrices[0]); - } } - transform.preTranslate(_transform.getTranslation()); - batch.setModelTransform(transform); + batch.setModelTransform(_transform); } void ModelMeshPartPayload::startFade() { @@ -570,7 +563,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { } - // When an individual mesh parts like this finishes its fade, we will mark the Model as + // When an individual mesh parts like this finishes its fade, we will mark the Model as // having render items that need updating bool nextIsFading = _isFading ? isStillFading() : false; bool startFading = !_isFading && !_hasFinishedFade && _hasStartedFade; @@ -592,6 +585,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { // Bind the model transform and the skinCLusterMatrices if needed bool canCauterize = args->_renderMode != RenderArgs::SHADOW_RENDER_MODE; + // TODO: maybe get rid of this call? _model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation()); bindTransform(batch, locations, canCauterize); diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 3b882a9bb9..a09bb8626d 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -56,13 +56,12 @@ public: model::Mesh::Part _drawPart; std::shared_ptr _drawMaterial; - + model::Box _localBound; Transform _drawTransform; Transform _transform; - Transform _offsetTransform; mutable model::Box _worldBound; - + bool _hasColorAttrib = false; size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; } @@ -86,7 +85,7 @@ public: typedef Payload::DataPointer Pointer; void notifyLocationChanged() override; - void updateTransformForSkinnedMesh(const Transform& transform, const Transform& offsetTransform, const QVector& clusterMatrices); + void updateTransformForSkinnedMesh(const Transform& transform, const QVector& clusterMatrices); // Entity fade in void startFade(); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ffbe1fb34c..bc74a073ab 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -245,7 +245,7 @@ void Model::updateRenderItems() { // update the model transform and bounding box for this render item. const Model::MeshState& state = data._model->_meshStates.at(data._meshIndex); - data.updateTransformForSkinnedMesh(modelTransform, modelMeshOffset, state.clusterMatrices); + data.updateTransformForSkinnedMesh(modelTransform, state.clusterMatrices); } } }); @@ -1167,7 +1167,6 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig->getJointTransform(geometry.neckJointIndex) * zeroScale; - glm::mat4 modelToWorld = glm::mat4_cast(modelOrientation); for (int i = 0; i < _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); @@ -1176,11 +1175,10 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); #if GLM_ARCH & GLM_ARCH_SSE2 glm::mat4 temp, out, inverseBindMatrix = cluster.inverseBindMatrix; - glm_mat4_mul((glm_vec4*)&modelToWorld, (glm_vec4*)&jointMatrix, (glm_vec4*)&temp); glm_mat4_mul((glm_vec4*)&temp, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); state.clusterMatrices[j] = out; -#else - state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; +#else + state.clusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix; #endif // as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty. @@ -1188,7 +1186,7 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) { jointMatrix = cauterizeMatrix; } - state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; + state.cauterizedClusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix; } } From 0a018e133dfcf63e80a54da41474165dd024d38d Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 10 Jan 2017 18:23:39 -0700 Subject: [PATCH 09/29] Blue laser should be enough to hover --- scripts/system/pal.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index d45e1fc7bc..ef3e37101a 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -400,14 +400,15 @@ function handleMouseMoveEvent(event) { // find out which overlay (if any) is ove } handleMouseMove(pickRay); } -const TRIGGER_THRESHOLD = 0.85; +const TRIGGER_CLICK_THRESHOLD = 0.85; +const TRIGGER_PRESS_THRESHOLD = 0.05; // for some reason, I could not get trigger mappings for the LT and RT to fire. So, since we can read the // value of the RT and LT, and the messages come through as mouse moves, we have the hack below to figure out // which hand is being triggered, and compute the pick ray accordingly. // function isPressed(hand) { // helper to see if the hand passed in has the trigger pulled var controller = (hand === Controller.Standard.RightHand ? Controller.Standard.RT : Controller.Standard.LT); - return Controller.getValue(controller) > TRIGGER_THRESHOLD; + return Controller.getValue(controller) > TRIGGER_PRESS_THRESHOLD; } // helpful globals var currentHandPressed = 0; @@ -451,7 +452,7 @@ function controllerComputePickRay(hand) { } function makeClickHandler(hand) { return function (clicked) { - if (clicked > TRIGGER_THRESHOLD) { + if (clicked > TRIGGER_CLICK_THRESHOLD) { var pickRay = controllerComputePickRay(hand); handleClick(pickRay); } From 7a01b856f7dd62430c044a0253d0b7b17a746ceb Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 11 Jan 2017 02:33:56 -0800 Subject: [PATCH 10/29] Factorization of the modelTransform out of the cluster matrices --- libraries/render-utils/src/MeshPartPayload.cpp | 4 ++-- libraries/render-utils/src/Model.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 66f4f577b7..bba658c75c 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -372,7 +372,7 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transf _worldBound.transform(transform); if (clusterMatrices.size() == 1) { - _transform.worldTransform(Transform(clusterMatrices[0])); + _transform = _transform.worldTransform(Transform(clusterMatrices[0])); } } } @@ -586,7 +586,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { // Bind the model transform and the skinCLusterMatrices if needed bool canCauterize = args->_renderMode != RenderArgs::SHADOW_RENDER_MODE; // TODO: maybe get rid of this call? - _model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation()); + // _model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation()); bindTransform(batch, locations, canCauterize); //Bind the index buffer and vertex buffer and Blend shapes if needed diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index bc74a073ab..b7e0492413 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1174,8 +1174,8 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient const FBXCluster& cluster = mesh.clusters.at(j); auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); #if GLM_ARCH & GLM_ARCH_SSE2 - glm::mat4 temp, out, inverseBindMatrix = cluster.inverseBindMatrix; - glm_mat4_mul((glm_vec4*)&temp, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); + glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix; + glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); state.clusterMatrices[j] = out; #else state.clusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix; From e88f02d7b6c7931700b0400e7be7fcbbf3838253 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 06:55:13 -0800 Subject: [PATCH 11/29] remove cruft --- libraries/render-utils/src/MeshPartPayload.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index bba658c75c..650b8934ee 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -562,7 +562,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { return; } - // When an individual mesh parts like this finishes its fade, we will mark the Model as // having render items that need updating bool nextIsFading = _isFading ? isStillFading() : false; @@ -585,8 +584,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { // Bind the model transform and the skinCLusterMatrices if needed bool canCauterize = args->_renderMode != RenderArgs::SHADOW_RENDER_MODE; - // TODO: maybe get rid of this call? - // _model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation()); bindTransform(batch, locations, canCauterize); //Bind the index buffer and vertex buffer and Blend shapes if needed From 5d880487a031c56788a318e6285b60b9376669a7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 06:56:07 -0800 Subject: [PATCH 12/29] cleanup class method declarations --- libraries/render-utils/src/MeshPartPayload.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index a09bb8626d..b048dc903f 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -34,7 +34,7 @@ public: virtual void updateMeshPart(const std::shared_ptr& drawMesh, int partIndex); virtual void notifyLocationChanged() {} - virtual void updateTransform(const Transform& transform, const Transform& offsetTransform); + void updateTransform(const Transform& transform, const Transform& offsetTransform); virtual void updateMaterial(model::MaterialPointer drawMaterial); @@ -100,7 +100,7 @@ public: // ModelMeshPartPayload functions to perform render void bindMesh(gpu::Batch& batch) const override; - void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, bool canCauterize) const override; + void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, bool canCauterize = true) const override; void initCache(); From 1804f33b98f4d52e14882b245c4aae51f0a6b71f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 06:56:35 -0800 Subject: [PATCH 13/29] add assert and TODO comment --- libraries/render-utils/src/Model.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b7e0492413..b7848bc717 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -295,6 +295,7 @@ bool Model::updateGeometry() { if (_rig->jointStatesEmpty() && getFBXGeometry().joints.size() > 0) { initJointStates(); + assert(_meshStates.empty()); const FBXGeometry& fbxGeometry = getFBXGeometry(); foreach (const FBXMesh& mesh, fbxGeometry.meshes) { @@ -304,6 +305,9 @@ bool Model::updateGeometry() { _meshStates.append(state); + // Note: we add empty buffers for meshes that lack blendshapes so we can access the buffers by index + // later in ModelMeshPayload, however the vast majority of meshes will not have them. + // TODO? make _blendedVertexBuffers a map instead of vector and only add for meshes with blendshapes? auto buffer = std::make_shared(); if (!mesh.blendshapes.isEmpty()) { buffer->resize((mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3)); From bd16824d55a574bd2182db913964e07d24168b8f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 06:57:05 -0800 Subject: [PATCH 14/29] remove cruft: Model::_pupilDilation --- libraries/render-utils/src/Model.cpp | 1 - libraries/render-utils/src/Model.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b7848bc717..e0a378176f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -92,7 +92,6 @@ Model::Model(RigPointer rig, QObject* parent) : _snapModelToRegistrationPoint(false), _snappedToRegistrationPoint(false), _cauterizeBones(false), - _pupilDilation(0.0f), _url(HTTP_INVALID_COM), _isVisible(true), _blendNumber(0), diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index d4387a6a9a..92b718d487 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -251,9 +251,6 @@ signals: protected: bool addedToScene() const { return _addedToScene; } - void setPupilDilation(float dilation) { _pupilDilation = dilation; } - float getPupilDilation() const { return _pupilDilation; } - void setBlendshapeCoefficients(const QVector& coefficients) { _blendshapeCoefficients = coefficients; } const QVector& getBlendshapeCoefficients() const { return _blendshapeCoefficients; } @@ -347,7 +344,6 @@ protected: void deleteGeometry(); void initJointTransforms(); - float _pupilDilation; QVector _blendshapeCoefficients; QUrl _url; From 083c7bc52379c1128564704a47e90b1397ec581f Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 11 Jan 2017 10:05:39 -0800 Subject: [PATCH 15/29] Add a local HRTF gain adjustment. Gain adjustments are persistent and properly interpolated. --- libraries/audio/src/AudioHRTF.cpp | 7 +++++-- libraries/audio/src/AudioHRTF.h | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 84e3622498..2a191b5821 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -392,8 +392,8 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame // linear interpolation with gain static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { - __m128 f0 = _mm_set1_ps(HRTF_GAIN * gain * (1.0f - frac)); - __m128 f1 = _mm_set1_ps(HRTF_GAIN * gain * frac); + __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); + __m128 f1 = _mm_set1_ps(gain * frac); assert(HRTF_TAPS % 4 == 0); @@ -861,6 +861,9 @@ void AudioHRTF::render(int16_t* input, float* output, int index, float azimuth, ALIGN32 float bqBuffer[4 * HRTF_BLOCK]; // 4-channel (interleaved) int delay[4]; // 4-channel (interleaved) + // apply global and local gain adjustment + gain *= _gainAdjust; + // to avoid polluting the cache, old filters are recomputed instead of stored setFilters(firCoef, bqCoef, delay, index, _azimuthState, _distanceState, _gainState, L0); diff --git a/libraries/audio/src/AudioHRTF.h b/libraries/audio/src/AudioHRTF.h index 08ae82b854..c9d053bec4 100644 --- a/libraries/audio/src/AudioHRTF.h +++ b/libraries/audio/src/AudioHRTF.h @@ -44,6 +44,11 @@ public: // void renderSilent(int16_t* input, float* output, int index, float azimuth, float distance, float gain, int numFrames); + // + // HRTF local gain adjustment + // + void setGainAdjustment(float gain) { _gainAdjust = HRTF_GAIN * gain; }; + private: AudioHRTF(const AudioHRTF&) = delete; AudioHRTF& operator=(const AudioHRTF&) = delete; @@ -73,6 +78,9 @@ private: float _distanceState = 0.0f; float _gainState = 0.0f; + // global and local gain adjustment + float _gainAdjust = HRTF_GAIN; + bool _silentState = false; }; From 87bdaae05acc2aa9fe82e71d80d1a183cbaa9846 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 12:38:47 -0800 Subject: [PATCH 16/29] remove scale from ModelMeshPartPayload's transform --- libraries/render-utils/src/Model.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e0a378176f..6292abea3b 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -216,10 +216,12 @@ void Model::updateRenderItems() { render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); Transform modelTransform; - modelTransform.setScale(scale); modelTransform.setTranslation(self->_translation); modelTransform.setRotation(self->_rotation); + Transform scaledModelTransform(modelTransform); + scaledModelTransform.setScale(scale); + Transform modelMeshOffset; if (self->isLoaded()) { // includes model offset and unitScale. @@ -254,9 +256,9 @@ void Model::updateRenderItems() { Transform collisionMeshOffset; collisionMeshOffset.setIdentity(); foreach (auto itemID, self->_collisionRenderItems.keys()) { - pendingChanges.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) { + pendingChanges.updateItem(itemID, [scaledModelTransform, collisionMeshOffset](MeshPartPayload& data) { // update the model transform for this render item. - data.updateTransform(modelTransform, collisionMeshOffset); + data.updateTransform(scaledModelTransform, collisionMeshOffset); }); } From 1e3a00d1fbb621548e20d856833c411972bb8dc9 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 11 Jan 2017 14:43:37 -0700 Subject: [PATCH 17/29] Enable the LT and RT signals, use them A bit cleaner. Still have to keep track of which hand is the mouse, but this removes some of the hacky code. --- scripts/system/pal.js | 75 ++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index ef3e37101a..48f44570fd 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -384,12 +384,16 @@ function handleMouseMove(pickRay) { // given the pickRay, just do the hover logi ExtendedOverlay.unHover(); }); } + +// handy global to keep track of which hand is the mouse (if any) +var currentHandPressed = 0; +const TRIGGER_CLICK_THRESHOLD = 0.85; +const TRIGGER_PRESS_THRESHOLD = 0.05; + function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position if (HMD.active) { - var hand = whichHand(); - if (hand != 0) { - print("pick ray for " + hand); - pickRay = controllerComputePickRay(hand); + if (currentHandPressed != 0) { + pickRay = controllerComputePickRay(currentHandPressed); } else { // nothing should hover, so ExtendedOverlay.unHover(); @@ -400,50 +404,27 @@ function handleMouseMoveEvent(event) { // find out which overlay (if any) is ove } handleMouseMove(pickRay); } -const TRIGGER_CLICK_THRESHOLD = 0.85; -const TRIGGER_PRESS_THRESHOLD = 0.05; -// for some reason, I could not get trigger mappings for the LT and RT to fire. So, since we can read the -// value of the RT and LT, and the messages come through as mouse moves, we have the hack below to figure out -// which hand is being triggered, and compute the pick ray accordingly. -// -function isPressed(hand) { // helper to see if the hand passed in has the trigger pulled - var controller = (hand === Controller.Standard.RightHand ? Controller.Standard.RT : Controller.Standard.LT); - return Controller.getValue(controller) > TRIGGER_PRESS_THRESHOLD; -} -// helpful globals -var currentHandPressed = 0; -var hands = [Controller.Standard.RightHand, Controller.Standard.LeftHand]; - -function whichHand() { - // for HMD, decide which hand is the "mouse". The 'logic' is to use the first one that - // is triggered, until that one is released. There are interesting effects when both - // are held that this avoids. Mapping the 2 triggers and their lasers to one mouse move - // message is a bit problematic, this mitigates some of it. - if (HMD.active) { - var pressed = {}; - for (var i = 0; i TRIGGER_PRESS_THRESHOLD; + if (currentHandPressed == 0) { + currentHandPressed = isPressed ? hand : 0; + return; } - return currentHandPressed; + if (currentHandPressed == hand) { + currentHandPressed = isPressed ? hand : 0; + return; + } + // otherwise, the other hand is still triggered + // so do nothing. } // We get mouseMoveEvents from the handControllers, via handControllerPointer. // But we don't get mousePressEvents. var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); +var triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press'); function controllerComputePickRay(hand) { var controllerPose = getControllerWorldLocation(hand, true); if (controllerPose.valid) { @@ -458,9 +439,15 @@ function makeClickHandler(hand) { } }; } +function makePressHandler(hand) { + return function (value) { + handleTriggerPressed(hand, value); + } +} triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand)); triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand)); - +triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand)); +triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand)); // // Manage the connection between the button and the window. // @@ -484,6 +471,7 @@ function off() { isWired = false; } triggerMapping.disable(); // It's ok if we disable twice. + triggerPressMapping.disable(); // see above removeOverlays(); Users.requestsDomainListData = false; } @@ -497,6 +485,7 @@ function onClicked() { Controller.mousePressEvent.connect(handleMouseEvent); Controller.mouseMoveEvent.connect(handleMouseMoveEvent); triggerMapping.enable(); + triggerPressMapping.enable(); } else { off(); } From f235a52a6d5bc681e6e208d38cf495d6686f0c45 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 11 Jan 2017 13:54:25 -0800 Subject: [PATCH 18/29] Eagerly cache QML surfaces for Web3D overlays to prevent stutter on loading the tablet --- interface/src/Application.cpp | 6 ++ interface/src/ui/overlays/Web3DOverlay.cpp | 23 +++----- interface/src/ui/overlays/Web3DOverlay.h | 1 + .../gl/src/gl/OffscreenQmlSurfaceCache.cpp | 57 +++++++++++++++++++ .../gl/src/gl/OffscreenQmlSurfaceCache.h | 34 +++++++++++ 5 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp create mode 100644 libraries/gl/src/gl/OffscreenQmlSurfaceCache.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ad869ddae3..b0502a88fc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -512,6 +513,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(true, qApp, qApp); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -2003,6 +2005,10 @@ void Application::initializeUi() { showCursor(compositorHelper->getAllowMouseCapture() ? Qt::BlankCursor : Qt::ArrowCursor); } }); + + // Pre-create a couple of Web3D overlays to speed up tablet UI + auto offscreenSurfaceCache = DependencyManager::get(); + offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); } void Application::paintGL() { diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index ee1a0f5256..c987735367 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -28,14 +28,15 @@ #include #include +#include static const float DPI = 30.47f; static const float INCHES_TO_METERS = 1.0f / 39.3701f; static const float METERS_TO_INCHES = 39.3701f; static const float OPAQUE_ALPHA_THRESHOLD = 0.99f; -QString const Web3DOverlay::TYPE = "web3d"; - +const QString Web3DOverlay::TYPE = "web3d"; +const QString Web3DOverlay::QML = "Web3DOverlay.qml"; Web3DOverlay::Web3DOverlay() : _dpi(DPI) { _touchDevice.setCapabilities(QTouchDevice::Position); _touchDevice.setType(QTouchDevice::TouchScreen); @@ -80,8 +81,9 @@ Web3DOverlay::~Web3DOverlay() { // is no longer valid auto webSurface = _webSurface; AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] { - webSurface->deleteLater(); + DependencyManager::get()->release(QML, webSurface); }); + _webSurface.reset(); } auto geometryCache = DependencyManager::get(); if (geometryCache) { @@ -109,23 +111,14 @@ void Web3DOverlay::render(RenderArgs* args) { QOpenGLContext * currentContext = QOpenGLContext::currentContext(); QSurface * currentSurface = currentContext->surface(); if (!_webSurface) { - auto deleter = [](OffscreenQmlSurface* webSurface) { - AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] { - webSurface->deleteLater(); - }); - }; - _webSurface = QSharedPointer(new OffscreenQmlSurface(), deleter); + _webSurface = DependencyManager::get()->acquire(QML); + _webSurface->setMaxFps(10); // FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces // and the current rendering load) - _webSurface->setMaxFps(10); - _webSurface->create(currentContext); - _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); - _webSurface->load("Web3DOverlay.qml"); _webSurface->resume(); + _webSurface->resize(QSize(_resolution.x, _resolution.y)); _webSurface->getRootItem()->setProperty("url", _url); _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); - _webSurface->getRootContext()->setContextProperty("ApplicationInterface", qApp); - _webSurface->resize(QSize(_resolution.x, _resolution.y)); currentContext->makeCurrent(currentSurface); auto forwardPointerEvent = [=](unsigned int overlayID, const PointerEvent& event) { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 45ec9fbc50..c389f5e6f9 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -21,6 +21,7 @@ class Web3DOverlay : public Billboard3DOverlay { Q_OBJECT public: + static const QString QML; static QString const TYPE; virtual QString getType() const override { return TYPE; } diff --git a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp new file mode 100644 index 0000000000..ad370a1f43 --- /dev/null +++ b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp @@ -0,0 +1,57 @@ +// +// Created by Bradley Austin Davis on 2017-01-11 +// Copyright 2013-2017 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 +// +#include "OffscreenQmlSurfaceCache.h" + +#include +#include + +#include +#include "OffscreenQmlSurface.h" + +OffscreenQmlSurfaceCache::OffscreenQmlSurfaceCache() { +} + +OffscreenQmlSurfaceCache::~OffscreenQmlSurfaceCache() { + _cache.clear(); +} + +QSharedPointer OffscreenQmlSurfaceCache::acquire(const QString& rootSource) { + auto& list = _cache[rootSource]; + if (list.empty()) { + list.push_back(buildSurface(rootSource)); + } + auto result = list.front(); + list.pop_front(); + return result; +} + +void OffscreenQmlSurfaceCache::reserve(const QString& rootSource, int count) { + auto& list = _cache[rootSource]; + while (list.size() < count) { + list.push_back(buildSurface(rootSource)); + } +} + +void OffscreenQmlSurfaceCache::release(const QString& rootSource, const QSharedPointer& surface) { + surface->pause(); + _cache[rootSource].push_back(surface); +} + +QSharedPointer OffscreenQmlSurfaceCache::buildSurface(const QString& rootSource) { + auto surface = QSharedPointer(new OffscreenQmlSurface()); + QOpenGLContext* currentContext = QOpenGLContext::currentContext(); + QSurface* currentSurface = currentContext->surface(); + surface->create(currentContext); + surface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); + surface->load(rootSource); + surface->getRootContext()->setContextProperty("ApplicationInterface", qApp); + surface->resize(QSize(100, 100)); + currentContext->makeCurrent(currentSurface); + return surface; +} + diff --git a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.h b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.h new file mode 100644 index 0000000000..02382a791b --- /dev/null +++ b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.h @@ -0,0 +1,34 @@ +// +// Created by Bradley Austin Davis on 2017-01-11 +// Copyright 2013-2017 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 +// +#pragma once +#ifndef hifi_OffscreenQmlSurfaceCache_h +#define hifi_OffscreenQmlSurfaceCahce_h + +#include "DependencyManager.h" + +#include + +class OffscreenQmlSurface; + +class OffscreenQmlSurfaceCache : public Dependency { + SINGLETON_DEPENDENCY + +public: + OffscreenQmlSurfaceCache(); + virtual ~OffscreenQmlSurfaceCache(); + + QSharedPointer acquire(const QString& rootSource); + void release(const QString& rootSource, const QSharedPointer& surface); + void reserve(const QString& rootSource, int count = 1); + +private: + QSharedPointer buildSurface(const QString& rootSource); + QHash>> _cache; +}; + +#endif From a808a8c7499287300cb21cda3c10376afce12757 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 11 Jan 2017 14:23:18 -0800 Subject: [PATCH 19/29] revert "fix competition between seek mouse and lasers" --- .../controllers/handControllerPointer.js | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 4d478fbdd5..0623ddf100 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -20,9 +20,6 @@ // When partially squeezing over a HUD element, a laser or the reticle is shown where the active hand // controller beam intersects the HUD. -var systemLaserOn = false; - - Script.include("../libraries/controllers.js"); // UTILITIES ------------- @@ -124,12 +121,6 @@ function ignoreMouseActivity() { if (!Reticle.allowMouseCapture) { return true; } - - // if the lasers are on, then reticle/mouse should be hidden and we can ignore it for seeking or depth updating - if (systemLaserOn) { - return true; - } - var pos = Reticle.position; if (!pos || (pos.x == -1 && pos.y == -1)) { return true; @@ -270,12 +261,6 @@ var ONE_MINUS_WEIGHTING = 1 - WEIGHTING; var AVERAGE_MOUSE_VELOCITY_FOR_SEEK_TO = 20; function isShakingMouse() { // True if the person is waving the mouse around trying to find it. var now = Date.now(), mouse = Reticle.position, isShaking = false; - - // if the lasers are on, then we ignore mouse shaking - if (systemLaserOn) { - return false; - } - if (lastIntegration && (lastIntegration !== now)) { var velocity = Vec3.length(Vec3.subtract(mouse, lastMouse)) / (now - lastIntegration); averageMouseVelocity = (ONE_MINUS_WEIGHTING * averageMouseVelocity) + (WEIGHTING * velocity); @@ -290,14 +275,9 @@ function isShakingMouse() { // True if the person is waving the mouse around try var NON_LINEAR_DIVISOR = 2; var MINIMUM_SEEK_DISTANCE = 0.1; function updateSeeking(doNotStartSeeking) { - // if the lasers are on, then we never do seeking - if (systemLaserOn) { - isSeeking = false; - return; - } - if (!doNotStartSeeking && (!Reticle.visible || isShakingMouse())) { if (!isSeeking) { + print('Start seeking mouse.'); isSeeking = true; } } // e.g., if we're about to turn it on with first movement. @@ -307,6 +287,7 @@ function updateSeeking(doNotStartSeeking) { averageMouseVelocity = lastIntegration = 0; var lookAt2D = HMD.getHUDLookAtPosition2D(); if (!lookAt2D) { // If this happens, something has gone terribly wrong. + print('Cannot seek without lookAt position'); isSeeking = false; return; // E.g., if parallel to location in HUD } @@ -322,6 +303,7 @@ function updateSeeking(doNotStartSeeking) { } var okX = !updateDimension('x'), okY = !updateDimension('y'); // Evaluate both. Don't short-circuit. if (okX && okY) { + print('Finished seeking mouse'); isSeeking = false; } else { Reticle.setPosition(copy); // Not setReticlePosition @@ -340,7 +322,7 @@ function updateMouseActivity(isClick) { return; } // Bug: mouse clicks should keep going. Just not hand controller clicks handControllerLockOut.update(now); - Reticle.visible = !systemLaserOn; + Reticle.visible = true; } function expireMouseCursor(now) { if (!isPointingAtOverlay() && mouseCursorActivity.expired(now)) { @@ -492,6 +474,7 @@ var LASER_ALPHA = 0.5; var LASER_SEARCH_COLOR_XYZW = {x: 10 / 255, y: 10 / 255, z: 255 / 255, w: LASER_ALPHA}; var LASER_TRIGGER_COLOR_XYZW = {x: 250 / 255, y: 10 / 255, z: 10 / 255, w: LASER_ALPHA}; var SYSTEM_LASER_DIRECTION = {x: 0, y: 0, z: -1}; +var systemLaserOn = false; function clearSystemLaser() { if (!systemLaserOn) { return; From 357b4db1db3261fd25d55204b934e02cf0c39165 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 11 Jan 2017 14:24:24 -0800 Subject: [PATCH 20/29] fix mouse vs lasers, again --- scripts/system/controllers/handControllerPointer.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 0623ddf100..2a64b856bc 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -20,6 +20,10 @@ // When partially squeezing over a HUD element, a laser or the reticle is shown where the active hand // controller beam intersects the HUD. +var activeTrigger; +function isLaserOn() { + return activeTrigger.partial(); +} Script.include("../libraries/controllers.js"); // UTILITIES ------------- @@ -275,7 +279,7 @@ function isShakingMouse() { // True if the person is waving the mouse around try var NON_LINEAR_DIVISOR = 2; var MINIMUM_SEEK_DISTANCE = 0.1; function updateSeeking(doNotStartSeeking) { - if (!doNotStartSeeking && (!Reticle.visible || isShakingMouse())) { + if (!doNotStartSeeking && !isLaserOn() && (!Reticle.visible || isShakingMouse())) { if (!isSeeking) { print('Start seeking mouse.'); isSeeking = true; @@ -374,7 +378,7 @@ setupHandler(Controller.mouseDoublePressEvent, onMouseClick); var leftTrigger = new Trigger('left'); var rightTrigger = new Trigger('right'); -var activeTrigger = rightTrigger; +activeTrigger = rightTrigger; var activeHand = Controller.Standard.RightHand; var LEFT_HUD_LASER = 1; var RIGHT_HUD_LASER = 2; From e256f7cccc5186c98261ebd8c3688b57bf43387c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 11 Jan 2017 14:27:27 -0800 Subject: [PATCH 21/29] Remove sendqueue spam in traces --- libraries/networking/src/udt/SendQueue.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 82f4084bb2..31d61bde5d 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -88,8 +88,6 @@ SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) : _socket(socket), _destination(dest) { - PROFILE_ASYNC_BEGIN(network, "SendQueue", _destination.toString()); - // setup psuedo-random number generation for all instances of SendQueue static std::random_device rd; static std::mt19937 generator(rd()); @@ -108,7 +106,6 @@ SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) : } SendQueue::~SendQueue() { - PROFILE_ASYNC_END(network, "SendQueue", _destination.toString()); } void SendQueue::queuePacket(std::unique_ptr packet) { @@ -229,8 +226,6 @@ void SendQueue::sendHandshake() { if (!_hasReceivedHandshakeACK) { // we haven't received a handshake ACK from the client, send another now auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, sizeof(SequenceNumber)); - PROFILE_ASYNC_BEGIN(network, "SendQueue:Handshake", _destination.toString()); - handshakePacket->writePrimitive(_initialSequenceNumber); _socket->writeBasePacket(*handshakePacket, _destination); @@ -246,8 +241,6 @@ void SendQueue::handshakeACK(SequenceNumber initialSequenceNumber) { std::lock_guard locker { _handshakeMutex }; _hasReceivedHandshakeACK = true; } - PROFILE_ASYNC_END(network, "SendQueue:Handshake", _destination.toString()); - // Notify on the handshake ACK condition _handshakeACKCondition.notify_one(); } From 27293c342ce5ec9de4c8904ad5e991fb07973aa4 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 11 Jan 2017 14:27:46 -0800 Subject: [PATCH 22/29] Change present rate to be an average over 1/10th of a second --- .../src/display-plugins/OpenGLDisplayPlugin.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ee0bcf91a9..f4efc0267b 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -114,10 +114,10 @@ protected: bool _vsyncEnabled { true }; QThread* _presentThread{ nullptr }; std::queue _newFrameQueue; - RateCounter<> _droppedFrameRate; - RateCounter<> _newFrameRate; - RateCounter<> _presentRate; - RateCounter<> _renderRate; + RateCounter<100> _droppedFrameRate; + RateCounter<100> _newFrameRate; + RateCounter<100> _presentRate; + RateCounter<100> _renderRate; gpu::FramePointer _currentFrame; gpu::Frame* _lastFrame { nullptr }; From b3e336de3dd0d2e696eff0b7aa63b30fd4d3e4d4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 15:02:18 -0800 Subject: [PATCH 23/29] remove cruft: unused function arguments --- interface/src/avatar/SoftAttachmentModel.cpp | 13 +++++++++---- interface/src/avatar/SoftAttachmentModel.h | 2 +- libraries/render-utils/src/Model.cpp | 14 +++----------- libraries/render-utils/src/Model.h | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/interface/src/avatar/SoftAttachmentModel.cpp b/interface/src/avatar/SoftAttachmentModel.cpp index c2e8dab2a1..6351495598 100644 --- a/interface/src/avatar/SoftAttachmentModel.cpp +++ b/interface/src/avatar/SoftAttachmentModel.cpp @@ -37,7 +37,7 @@ int SoftAttachmentModel::getJointIndexOverride(int i) const { // virtual // use the _rigOverride matrices instead of the Model::_rig -void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) { +void SoftAttachmentModel::updateClusterMatrices() { if (!_needsUpdateClusterMatrices) { return; } @@ -45,7 +45,6 @@ void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::qu const FBXGeometry& geometry = getFBXGeometry(); - glm::mat4 modelToWorld = glm::mat4_cast(modelOrientation); for (int i = 0; i < _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); @@ -53,7 +52,7 @@ void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::qu for (int j = 0; j < mesh.clusters.size(); j++) { const FBXCluster& cluster = mesh.clusters.at(j); - // TODO: cache these look ups as an optimization + // TODO: cache these look-ups as an optimization int jointIndexOverride = getJointIndexOverride(cluster.jointIndex); glm::mat4 jointMatrix; if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride->getJointStateCount()) { @@ -61,7 +60,13 @@ void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::qu } else { jointMatrix = _rig->getJointTransform(cluster.jointIndex); } - state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; +#if GLM_ARCH & GLM_ARCH_SSE2 + glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix; + glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); + state.clusterMatrices[j] = out; +#else + state.clusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix; +#endif } // Once computed the cluster matrices, update the buffer(s) diff --git a/interface/src/avatar/SoftAttachmentModel.h b/interface/src/avatar/SoftAttachmentModel.h index 84a8b4cc66..cdf957514c 100644 --- a/interface/src/avatar/SoftAttachmentModel.h +++ b/interface/src/avatar/SoftAttachmentModel.h @@ -31,7 +31,7 @@ public: ~SoftAttachmentModel(); virtual void updateRig(float deltaTime, glm::mat4 parentTransform) override; - virtual void updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) override; + virtual void updateClusterMatrices() override; protected: int getJointIndexOverride(int i) const; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6292abea3b..ccfea99066 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -222,19 +222,11 @@ void Model::updateRenderItems() { Transform scaledModelTransform(modelTransform); scaledModelTransform.setScale(scale); - Transform modelMeshOffset; - if (self->isLoaded()) { - // includes model offset and unitScale. - modelMeshOffset = Transform(self->_rig->getGeometryToRigTransform()); - } else { - modelMeshOffset.postTranslate(self->_offset); - } - uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; render::PendingChanges pendingChanges; foreach (auto itemID, self->_modelMeshRenderItems.keys()) { - pendingChanges.updateItem(itemID, [modelTransform, modelMeshOffset, deleteGeometryCounter](ModelMeshPartPayload& data) { + pendingChanges.updateItem(itemID, [modelTransform, deleteGeometryCounter](ModelMeshPartPayload& data) { if (data._model && data._model->isLoaded()) { if (!data.hasStartedFade() && data._model->getGeometry()->areTexturesLoaded()) { data.startFade(); @@ -242,7 +234,7 @@ void Model::updateRenderItems() { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == data._model->_deleteGeometryCounter) { // lazy update of cluster matrices used for rendering. We need to update them here, so we can correctly update the bounding box. - data._model->updateClusterMatrices(modelTransform.getTranslation(), modelTransform.getRotation()); + data._model->updateClusterMatrices(); // update the model transform and bounding box for this render item. const Model::MeshState& state = data._model->_meshStates.at(data._meshIndex); @@ -1157,7 +1149,7 @@ void Model::simulateInternal(float deltaTime) { } // virtual -void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) { +void Model::updateClusterMatrices() { PerformanceTimer perfTimer("Model::updateClusterMatrices"); if (!_needsUpdateClusterMatrices || !isLoaded()) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 92b718d487..55806b27e1 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -126,7 +126,7 @@ public: bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; } virtual void simulate(float deltaTime, bool fullUpdate = true); - virtual void updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation); + virtual void updateClusterMatrices(); /// Returns a reference to the shared geometry. const Geometry::Pointer& getGeometry() const { return _renderGeometry; } From e2130d33d9e70eb7f892715db0e4bc07fe0cf72f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 15:10:44 -0800 Subject: [PATCH 24/29] speedup cauterizedClusterMatrices math --- libraries/render-utils/src/Model.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ccfea99066..55c8d92333 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1183,7 +1183,13 @@ void Model::updateClusterMatrices() { if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) { jointMatrix = cauterizeMatrix; } +#if GLM_ARCH & GLM_ARCH_SSE2 + glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix; + glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out); + state.cauterizedClusterMatrices[j] = out; +#else state.cauterizedClusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix; +#endif } } From 5c068417329cbafb0cc4e849585ed404ffb13839 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 11 Jan 2017 16:24:05 -0800 Subject: [PATCH 25/29] use update signal instead of timer --- scripts/system/controllers/handControllerPointer.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 2a64b856bc..1f8f0f53e6 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -571,12 +571,6 @@ function update() { Reticle.visible = false; } -var BASIC_TIMER_INTERVAL = 20; // 20ms = 50hz good enough -var updateIntervalTimer = Script.setInterval(function(){ - update(); -}, BASIC_TIMER_INTERVAL); - - // Check periodically for changes to setup. var SETTINGS_CHANGE_RECHECK_INTERVAL = 10 * 1000; // 10 seconds function checkSettings() { @@ -586,9 +580,10 @@ function checkSettings() { checkSettings(); var settingsChecker = Script.setInterval(checkSettings, SETTINGS_CHANGE_RECHECK_INTERVAL); +Script.update.connect(update); Script.scriptEnding.connect(function () { Script.clearInterval(settingsChecker); - Script.clearInterval(updateIntervalTimer); + Script.update.disconnect(update); OffscreenFlags.navigationFocusDisabled = false; }); From 9298bcf628b4c56108e491769a47adbfb6f3e546 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 11 Jan 2017 16:32:15 -0800 Subject: [PATCH 26/29] remove log spam --- scripts/system/controllers/handControllerPointer.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 1f8f0f53e6..b7dfcaeb56 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -280,10 +280,7 @@ var NON_LINEAR_DIVISOR = 2; var MINIMUM_SEEK_DISTANCE = 0.1; function updateSeeking(doNotStartSeeking) { if (!doNotStartSeeking && !isLaserOn() && (!Reticle.visible || isShakingMouse())) { - if (!isSeeking) { - print('Start seeking mouse.'); - isSeeking = true; - } + isSeeking = true; } // e.g., if we're about to turn it on with first movement. if (!isSeeking) { return; @@ -291,7 +288,6 @@ function updateSeeking(doNotStartSeeking) { averageMouseVelocity = lastIntegration = 0; var lookAt2D = HMD.getHUDLookAtPosition2D(); if (!lookAt2D) { // If this happens, something has gone terribly wrong. - print('Cannot seek without lookAt position'); isSeeking = false; return; // E.g., if parallel to location in HUD } @@ -307,7 +303,6 @@ function updateSeeking(doNotStartSeeking) { } var okX = !updateDimension('x'), okY = !updateDimension('y'); // Evaluate both. Don't short-circuit. if (okX && okY) { - print('Finished seeking mouse'); isSeeking = false; } else { Reticle.setPosition(copy); // Not setReticlePosition From 88c2c534ad5b4656f7cc1523098a981eedabd5e4 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 11 Jan 2017 17:01:46 -0800 Subject: [PATCH 27/29] don't set bogus values --- scripts/system/controllers/handControllerPointer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index b7dfcaeb56..2c732b4cdc 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -482,7 +482,6 @@ function clearSystemLaser() { HMD.disableExtraLaser(); systemLaserOn = false; weMovedReticle = true; - Reticle.position = { x: -1, y: -1 }; } function setColoredLaser() { // answer trigger state if lasers supported, else falsey. var color = (activeTrigger.state === 'full') ? LASER_TRIGGER_COLOR_XYZW : LASER_SEARCH_COLOR_XYZW; From c060fd6a68b3d669cca61d050d2bfd1a07f0998a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Jan 2017 17:33:30 -0800 Subject: [PATCH 28/29] restore updateClusterMatrices() in render() --- libraries/render-utils/src/MeshPartPayload.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 650b8934ee..5c4c0890a7 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -584,6 +584,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { // Bind the model transform and the skinCLusterMatrices if needed bool canCauterize = args->_renderMode != RenderArgs::SHADOW_RENDER_MODE; + _model->updateClusterMatrices(); bindTransform(batch, locations, canCauterize); //Bind the index buffer and vertex buffer and Blend shapes if needed From 2de83d42bc16a1cf98116280c09fb3c004afaded Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 12 Jan 2017 09:19:08 -0800 Subject: [PATCH 29/29] Add process and system CPU usage to traces --- interface/src/Application.cpp | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ad869ddae3..62a4b2c438 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3298,6 +3298,66 @@ bool Application::shouldPaint(float nsecsElapsed) { return true; } +#ifdef Q_OS_WIN +#include +#include +#include +#pragma comment(lib, "pdh.lib") + +static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU; +static int numProcessors; +static HANDLE self; +static PDH_HQUERY cpuQuery; +static PDH_HCOUNTER cpuTotal; + +void initCpuUsage() { + SYSTEM_INFO sysInfo; + FILETIME ftime, fsys, fuser; + + GetSystemInfo(&sysInfo); + numProcessors = sysInfo.dwNumberOfProcessors; + + GetSystemTimeAsFileTime(&ftime); + memcpy(&lastCPU, &ftime, sizeof(FILETIME)); + + self = GetCurrentProcess(); + GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser); + memcpy(&lastSysCPU, &fsys, sizeof(FILETIME)); + memcpy(&lastUserCPU, &fuser, sizeof(FILETIME)); + + PdhOpenQuery(NULL, NULL, &cpuQuery); + PdhAddCounter(cpuQuery, "\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal); + PdhCollectQueryData(cpuQuery); +} + +void getCpuUsage(vec3& systemAndUser) { + FILETIME ftime, fsys, fuser; + ULARGE_INTEGER now, sys, user; + + GetSystemTimeAsFileTime(&ftime); + memcpy(&now, &ftime, sizeof(FILETIME)); + + GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser); + memcpy(&sys, &fsys, sizeof(FILETIME)); + memcpy(&user, &fuser, sizeof(FILETIME)); + systemAndUser.x = (sys.QuadPart - lastSysCPU.QuadPart); + systemAndUser.y = (user.QuadPart - lastUserCPU.QuadPart); + systemAndUser /= (float)(now.QuadPart - lastCPU.QuadPart); + systemAndUser /= (float)numProcessors; + systemAndUser *= 100.0f; + lastCPU = now; + lastUserCPU = user; + lastSysCPU = sys; + + PDH_FMT_COUNTERVALUE counterVal; + PdhCollectQueryData(cpuQuery); + PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal); + systemAndUser.z = (float)counterVal.doubleValue; +} + +#endif + + void Application::idle(float nsecsElapsed) { PerformanceTimer perfTimer("idle"); @@ -3314,6 +3374,18 @@ void Application::idle(float nsecsElapsed) { connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop); } +#ifdef Q_OS_WIN + static std::once_flag once; + std::call_once(once, [] { + initCpuUsage(); + }); + + vec3 kernelUserAndSystem; + getCpuUsage(kernelUserAndSystem); + PROFILE_COUNTER(app, "cpuProcess", { { "system", kernelUserAndSystem.x }, { "user", kernelUserAndSystem.y } }); + PROFILE_COUNTER(app, "cpuSystem", { { "system", kernelUserAndSystem.z } }); +#endif + auto displayPlugin = getActiveDisplayPlugin(); if (displayPlugin) { PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate()); @@ -3324,6 +3396,9 @@ void Application::idle(float nsecsElapsed) { PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get()->getStat("Processing").toInt()); PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get()->getStat("PendingProcessing").toInt()); + + + PROFILE_RANGE(app, __FUNCTION__); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {