From 72ca62c4afdcbd07e5664d18e6a94ce82fda8bb1 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Thu, 14 Sep 2017 00:25:11 +0100 Subject: [PATCH 01/30] Initial Commit - more to do. --- interface/src/avatar/MyAvatar.cpp | 6 ++++++ interface/src/avatar/MyAvatar.h | 7 ++++++- libraries/physics/src/CharacterController.cpp | 8 +++++--- libraries/physics/src/CharacterController.h | 10 ++++++++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8592ff3d74..d7fc56275d 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -60,6 +60,8 @@ #include "MovingEntitiesOperator.h" #include "SceneScriptingInterface.h" +#include "CharacterController.h" + using namespace std; const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f; @@ -2259,6 +2261,10 @@ float MyAvatar::getDomainMaxScale() { return _domainMaximumScale; } +void MyAvatar::setGravity(float gravity) { + emit gravityChanged(gravity); +} + void MyAvatar::increaseSize() { // make sure we're starting from an allowable scale clampTargetScaleToDomainLimits(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 65dcc12e7d..dbdf8f82fb 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -145,7 +145,9 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled) Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone) Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate) - + + Q_PROPERTY(float gravity WRITE updateGravity NOTIFY gravityChanged); + const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; @@ -540,6 +542,8 @@ public slots: float getDomainMinScale(); float getDomainMaxScale(); + void setGravity(float gravity); + void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), bool shouldFaceLocation = false); @@ -592,6 +596,7 @@ signals: void wentActive(); void skeletonChanged(); void dominantHandChanged(const QString& hand); + void gravityChanged(const float gravity); private: diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 9a7abc4e98..36a4c75168 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -20,6 +20,7 @@ const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); const float JUMP_SPEED = 3.5f; const float MAX_FALL_HEIGHT = 20.0f; +const float DEFAULT_CHARACTER_GRAVITY = -5.0f; #ifdef DEBUG_STATE_CHANGE #define SET_STATE(desiredState, reason) setState(desiredState, reason) @@ -371,19 +372,20 @@ void CharacterController::setState(State desiredState) { } } -void CharacterController::updateGravity() { +void CharacterController::updateGravity(float gravity = DEFAULT_CHARACTER_GRAVITY) { int16_t collisionGroup = computeCollisionGroup(); if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { _gravity = 0.0f; } else { - const float DEFAULT_CHARACTER_GRAVITY = -5.0f; - _gravity = DEFAULT_CHARACTER_GRAVITY; + _gravity = gravity; } if (_rigidBody) { _rigidBody->setGravity(_gravity * _currentUp); } + emit gravityChanged(); } + void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const glm::vec3& scale) { float x = scale.x; float z = scale.z; diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index bf84d318d4..f412e09956 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -42,10 +42,16 @@ const btScalar MAX_CHARACTER_MOTOR_TIMESCALE = 60.0f; // one minute const btScalar MIN_CHARACTER_MOTOR_TIMESCALE = 0.05f; class CharacterController : public btCharacterControllerInterface { + + Q_PROPERTY(float gravity WRITE updateGravity NOTIFY gravityChanged); + +signals: + void gravityChanged(); + public: CharacterController(); virtual ~CharacterController(); - + void updateGravity(float gravity); bool needsRemoval() const; bool needsAddition() const; virtual void setDynamicsWorld(btDynamicsWorld* world); @@ -130,7 +136,7 @@ protected: #endif virtual void updateMassProperties() = 0; - void updateGravity(); + void updateGravity(float gravity); void updateUpAxis(const glm::quat& rotation); bool checkForSupport(btCollisionWorld* collisionWorld); From c2e342ddac9cab175d124a2bb97cb2b1ff8ac1e5 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 15 Sep 2017 06:03:56 +0100 Subject: [PATCH 02/30] Gravity Implementation --- interface/src/avatar/MyAvatar.cpp | 6 ++- interface/src/avatar/MyAvatar.h | 4 +- libraries/physics/src/CharacterController.cpp | 37 +++++++++++-------- libraries/physics/src/CharacterController.h | 11 ++---- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d7fc56275d..ab48138822 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2262,7 +2262,11 @@ float MyAvatar::getDomainMaxScale() { } void MyAvatar::setGravity(float gravity) { - emit gravityChanged(gravity); + _characterController.setGravity(gravity); +} + +float MyAvatar::getGravity() { + return _characterController.getGravity(); } void MyAvatar::increaseSize() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index dbdf8f82fb..724a313296 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -146,8 +146,6 @@ class MyAvatar : public Avatar { Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone) Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate) - Q_PROPERTY(float gravity WRITE updateGravity NOTIFY gravityChanged); - const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; @@ -543,6 +541,7 @@ public slots: float getDomainMaxScale(); void setGravity(float gravity); + float getGravity(); void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), @@ -596,7 +595,6 @@ signals: void wentActive(); void skeletonChanged(); void dominantHandChanged(const QString& hand); - void gravityChanged(const float gravity); private: diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 36a4c75168..a81e1d8624 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -20,7 +20,7 @@ const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); const float JUMP_SPEED = 3.5f; const float MAX_FALL_HEIGHT = 20.0f; -const float DEFAULT_CHARACTER_GRAVITY = -5.0f; +float DEFAULT_CHARACTER_GRAVITY = -5.0f; #ifdef DEBUG_STATE_CHANGE #define SET_STATE(desiredState, reason) setState(desiredState, reason) @@ -354,6 +354,27 @@ static const char* stateToStr(CharacterController::State state) { } #endif // #ifdef DEBUG_STATE_CHANGE +void CharacterController::updateGravity() { + int16_t collisionGroup = computeCollisionGroup(); + if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { + _gravity = 0.0f; + } else { + _gravity = DEFAULT_CHARACTER_GRAVITY; + } + if (_rigidBody) { + _rigidBody->setGravity(_gravity * _currentUp); + } +} + + +void CharacterController::setGravity(float gravity) { + DEFAULT_CHARACTER_GRAVITY = gravity; +} + +float CharacterController::getGravity() { + return DEFAULT_CHARACTER_GRAVITY; +} + #ifdef DEBUG_STATE_CHANGE void CharacterController::setState(State desiredState, const char* reason) { #else @@ -372,20 +393,6 @@ void CharacterController::setState(State desiredState) { } } -void CharacterController::updateGravity(float gravity = DEFAULT_CHARACTER_GRAVITY) { - int16_t collisionGroup = computeCollisionGroup(); - if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { - _gravity = 0.0f; - } else { - _gravity = gravity; - } - if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); - } - emit gravityChanged(); -} - - void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const glm::vec3& scale) { float x = scale.x; float z = scale.z; diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index f412e09956..b7ea17fc71 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -43,20 +43,17 @@ const btScalar MIN_CHARACTER_MOTOR_TIMESCALE = 0.05f; class CharacterController : public btCharacterControllerInterface { - Q_PROPERTY(float gravity WRITE updateGravity NOTIFY gravityChanged); - -signals: - void gravityChanged(); - public: CharacterController(); virtual ~CharacterController(); - void updateGravity(float gravity); bool needsRemoval() const; bool needsAddition() const; virtual void setDynamicsWorld(btDynamicsWorld* world); btCollisionObject* getCollisionObject() { return _rigidBody; } + void setGravity(float gravity); + float getGravity(); + virtual void updateShapeIfNecessary() = 0; // overrides from btCharacterControllerInterface @@ -136,7 +133,7 @@ protected: #endif virtual void updateMassProperties() = 0; - void updateGravity(float gravity); + void updateGravity(); void updateUpAxis(const glm::quat& rotation); bool checkForSupport(btCollisionWorld* collisionWorld); From e86b37f949122822d2711c296ff01f4ec31248af Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 15 Sep 2017 06:07:50 +0100 Subject: [PATCH 03/30] Added script for testing --- scripts/developer/tests/gravityScript.js | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 scripts/developer/tests/gravityScript.js diff --git a/scripts/developer/tests/gravityScript.js b/scripts/developer/tests/gravityScript.js new file mode 100644 index 0000000000..9d3868c078 --- /dev/null +++ b/scripts/developer/tests/gravityScript.js @@ -0,0 +1,47 @@ +// +// Gravity Script 1.0 +// ************ +// +// Created by Cain Kilgore on 9/14/2017 + +// Javascript for the Gravity Modifier Implementation to test +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +function menuParameters(menuNameSelection, menuItemNameSelection) { + Menu.addMenuItem({ + menuName: menuNameSelection, + menuItemName: menuItemNameSelection, + isCheckable: false + }); +} + +function setupMenu() { + if(!Menu.menuExists("Gravity")) { + Menu.addMenu("Gravity"); + for(var i = -5; i <= 5; i++) { + menuParameters("Gravity", i); + } + } +} + +function menuItemEvent(menuItem) { + for(var i = -5; i <= 5; i++) { + if(menuItem == i) { + MyAvatar.setGravity(i); + } + } +} + +function onScriptEnding() { + Menu.removeMenu("Gravity"); +} + +setupMenu(); + +Menu.menuItemEvent.connect(menuItemEvent); + +Script.scriptEnding.connect(onScriptEnding); From 67a5c75a0d92ba4dc811924f6799d509c79483d5 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 15 Sep 2017 06:08:22 +0100 Subject: [PATCH 04/30] Doesn't need to be here anymore --- interface/src/avatar/MyAvatar.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ab48138822..3a84ffd49f 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -60,8 +60,6 @@ #include "MovingEntitiesOperator.h" #include "SceneScriptingInterface.h" -#include "CharacterController.h" - using namespace std; const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f; From 794f3ca69ffc812ad3829998c2f77dcbc105cdb6 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 15 Sep 2017 06:09:03 +0100 Subject: [PATCH 05/30] Indentation --- scripts/developer/tests/gravityScript.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/developer/tests/gravityScript.js b/scripts/developer/tests/gravityScript.js index 9d3868c078..3468de72c3 100644 --- a/scripts/developer/tests/gravityScript.js +++ b/scripts/developer/tests/gravityScript.js @@ -20,17 +20,17 @@ function menuParameters(menuNameSelection, menuItemNameSelection) { } function setupMenu() { - if(!Menu.menuExists("Gravity")) { + if (!Menu.menuExists("Gravity")) { Menu.addMenu("Gravity"); - for(var i = -5; i <= 5; i++) { + for (var i = -5; i <= 5; i++) { menuParameters("Gravity", i); } } } function menuItemEvent(menuItem) { - for(var i = -5; i <= 5; i++) { - if(menuItem == i) { + for (var i = -5; i <= 5; i++) { + if (menuItem == i) { MyAvatar.setGravity(i); } } @@ -41,7 +41,5 @@ function onScriptEnding() { } setupMenu(); - Menu.menuItemEvent.connect(menuItemEvent); - Script.scriptEnding.connect(onScriptEnding); From e2921661e9343b1d090295a1598b453cd58fb4dd Mon Sep 17 00:00:00 2001 From: druiz17 Date: Tue, 19 Sep 2017 09:35:22 -0700 Subject: [PATCH 06/30] scaling entities --- .../controllerModules/nearParentGrabEntity.js | 10 -- .../controllerModules/scaleAvatar.js | 3 +- .../controllerModules/scaleEntity.js | 109 ++++++++++++++++++ .../system/controllers/controllerScripts.js | 3 +- .../libraries/controllerDispatcherUtils.js | 5 +- 5 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 scripts/system/controllers/controllerModules/scaleEntity.js diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index e08b61dbd5..39e9371931 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -44,10 +44,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); return (this.hand === RIGHT_HAND) ? leftNearParentingGrabEntity : rightNearParentingGrabEntity; }; - this.otherHandIsParent = function(props) { - return this.getOtherModule().thisHandIsParent(props); - }; - this.thisHandIsParent = function(props) { if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) { return false; @@ -99,12 +95,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); // this should never happen, but if it does, don't set previous parent to be this hand. // this.previousParentID[targetProps.id] = NULL; // this.previousParentJointIndex[targetProps.id] = -1; - } else if (this.otherHandIsParent(targetProps)) { - // the other hand is parent. Steal the object and information - var otherModule = this.getOtherModule(); - this.previousParentID[targetProps.id] = otherModule.previousParentID[targetProps.id]; - this.previousParentJointIndex[targetProps.id] = otherModule.previousParentJointIndex[targetProps.id]; - otherModule.endNearParentingGrabEntity(); } else { this.previousParentID[targetProps.id] = targetProps.parentID; this.previousParentJointIndex[targetProps.id] = targetProps.parentJointIndex; diff --git a/scripts/system/controllers/controllerModules/scaleAvatar.js b/scripts/system/controllers/controllerModules/scaleAvatar.js index 05804c967b..fc28f4a00f 100644 --- a/scripts/system/controllers/controllerModules/scaleAvatar.js +++ b/scripts/system/controllers/controllerModules/scaleAvatar.js @@ -1,4 +1,4 @@ -// handControllerGrab.js +// scaleAvatar.js // // Created by Dante Ruiz on 9/11/17 // @@ -80,4 +80,5 @@ dispatcherUtils.disableDispatcherModule("LeftScaleAvatar"); dispatcherUtils.disableDispatcherModule("RightScaleAvatar"); }; + Script.scriptEnding.connect(this.cleanup); })(); diff --git a/scripts/system/controllers/controllerModules/scaleEntity.js b/scripts/system/controllers/controllerModules/scaleEntity.js new file mode 100644 index 0000000000..4b504c3733 --- /dev/null +++ b/scripts/system/controllers/controllerModules/scaleEntity.js @@ -0,0 +1,109 @@ +// scaleEntity.js +// +// Created by Dante Ruiz on 9/18/17 +// +// Grabs physically moveable entities with hydra-like controllers; it works for either near or far objects. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +/* global Script, Vec3, MyAvatar, RIGHT_HAND */ +/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ + +(function() { + var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); + + function ScaleEntity(hand) { + this.hand = hand; + this.grabbedThingID = false; + this.scalingStartDistance = false; + this.scalingStartDimensions = false; + + this.parameters = dispatcherUtils.makeDispatcherModuleParameters( + 120, + this.hand === RIGHT_HAND ? ["rightHandTrigger"] : ["leftHandTrigger"], + [], + 100 + ); + + this.otherHand = function() { + return this.hand === dispatcherUtils.RIGHT_HAND ? dispatcherUtils.LEFT_HAND : dispatcherUtils.RIGHT_HAND; + }; + + this.otherModule = function() { + return this.hand === dispatcherUtils.RIGHT_HAND ? leftScaleEntity : rightScaleEntity; + }; + + this.bumperPressed = function(controllerData) { + if ( controllerData.secondaryValues[this.hand] > dispatcherUtils.BUMPER_ON_VALUE) { + return true; + } + return false; + }; + + this.getTargetProps = function(controllerData) { + // nearbyEntityProperties is already sorted by length from controller + var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; + var sensorScaleFactor = MyAvatar.sensorToWorldScale; + for (var i = 0; i < nearbyEntityProperties.length; i++) { + var props = nearbyEntityProperties[i]; + var handPosition = controllerData.controllerLocations[this.hand].position; + var distance = Vec3.distance(props.position, handPosition); + if (distance > dispatcherUtils.NEAR_GRAB_RADIUS * sensorScaleFactor) { + continue; + } + if ((dispatcherUtils.entityIsGrabbable(props) || + dispatcherUtils.propsArePhysical(props)) && !props.locked) { + return props; + } + } + return null; + }; + + this.isReady = function(controllerData) { + var otherModule = this.otherModule(); + if (this.bumperPressed(controllerData) && otherModule.bumperPressed(controllerData)) { + var thisHandTargetProps = this.getTargetProps(controllerData); + var otherHandTargetProps = otherModule.getTargetProps(controllerData); + if (thisHandTargetProps && otherHandTargetProps) { + if (thisHandTargetProps.id === otherHandTargetProps.id) { + this.grabbedThingID = thisHandTargetProps.id; + this.scalingStartDistance = Vec3.length(Vec3.subtract(controllerData.controllerLocations[this.hand].position, + controllerData.controllerLocations[this.otherHand()].position)); + this.scalingStartDimensions = thisHandTargetProps.dimensions; + return dispatcherUtils.makeRunningValues(true, [], []); + } + } + } + return dispatcherUtils.makeRunningValues(false, [], []); + }; + + this.run = function(controllerData) { + var otherModule = this.otherModule(); + if (this.bumperPressed(controllerData) && otherModule.bumperPressed(controllerData)) { + if (this.hand === dispatcherUtils.RIGHT_HAND) { + var scalingCurrentDistance = + Vec3.length(Vec3.subtract(controllerData.controllerLocations[this.hand].position, + controllerData.controllerLocations[this.otherHand()].position)); + var currentRescale = scalingCurrentDistance / this.scalingStartDistance; + var newDimensions = Vec3.multiply(currentRescale, this.scalingStartDimensions); + Entities.editEntity(this.grabbedThingID, { dimensions: newDimensions }); + } + return dispatcherUtils.makeRunningValues(true, [], []); + } + return dispatcherUtils.makeRunningValues(false, [], []); + }; + } + + var leftScaleEntity = new ScaleEntity(dispatcherUtils.LEFT_HAND); + var rightScaleEntity = new ScaleEntity(dispatcherUtils.RIGHT_HAND); + + dispatcherUtils.enableDispatcherModule("LeftScaleEntity", leftScaleEntity); + dispatcherUtils.enableDispatcherModule("RightScaleEntity", rightScaleEntity); + + this.cleanup = function() { + dispatcherUtils.disableDispatcherModule("LeftScaleEntity"); + dispatcherUtils.disableDispatcherModule("RightScaleEntity"); + }; + Script.scriptEnding.connect(this.cleanup); +})(); diff --git a/scripts/system/controllers/controllerScripts.js b/scripts/system/controllers/controllerScripts.js index e8b07c623d..6b140173b8 100644 --- a/scripts/system/controllers/controllerScripts.js +++ b/scripts/system/controllers/controllerScripts.js @@ -29,7 +29,8 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/disableOtherModule.js", "controllerModules/farTrigger.js", "controllerModules/teleport.js", - "controllerModules/scaleAvatar.js" + "controllerModules/scaleAvatar.js", + "controllerModules/scaleEntity.js" ]; var DEBUG_MENU_ITEM = "Debug defaultScripts.js"; diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index 33eec74111..1570f71605 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -318,6 +318,9 @@ if (typeof module !== 'undefined') { makeRunningValues: makeRunningValues, LEFT_HAND: LEFT_HAND, RIGHT_HAND: RIGHT_HAND, - BUMPER_ON_VALUE: BUMPER_ON_VALUE + BUMPER_ON_VALUE: BUMPER_ON_VALUE, + propsArePhysical: propsArePhysical, + entityIsGrabbable: entityIsGrabbable, + NEAR_GRAB_RADIUS: NEAR_GRAB_RADIUS }; } From 4d904bd5ce7d7b1a805c2f8fbdda630afc27576f Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Wed, 20 Sep 2017 18:43:16 +0100 Subject: [PATCH 07/30] Changed naming of avatarGrav --- libraries/physics/src/CharacterController.cpp | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 0dcc0bcbe8..6c78b46b48 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -21,7 +21,8 @@ const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); const float JUMP_SPEED = 3.5f; const float MAX_FALL_HEIGHT = 20.0f; -float DEFAULT_CHARACTER_GRAVITY = -5.0f; +const float DEFAULT_CHARACTER_GRAVITY = -5.0f; +float currentAvatarGravity = DEFAULT_CHARACTER_GRAVITY; #ifdef DEBUG_STATE_CHANGE #define SET_STATE(desiredState, reason) setState(desiredState, reason) @@ -359,7 +360,7 @@ void CharacterController::updateGravity() { if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { _gravity = 0.0f; } else { - _gravity = DEFAULT_CHARACTER_GRAVITY; + _gravity = currentAvatarGravity; } if (_rigidBody) { _rigidBody->setGravity(_gravity * _currentUp); @@ -368,11 +369,11 @@ void CharacterController::updateGravity() { void CharacterController::setGravity(float gravity) { - DEFAULT_CHARACTER_GRAVITY = gravity; + currentAvatarGravity = gravity; } float CharacterController::getGravity() { - return DEFAULT_CHARACTER_GRAVITY; + return currentAvatarGravity; } #ifdef DEBUG_STATE_CHANGE @@ -393,18 +394,6 @@ void CharacterController::setState(State desiredState) { } } -void CharacterController::updateGravity() { - int16_t collisionGroup = computeCollisionGroup(); - if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { - _gravity = 0.0f; - } else { - _gravity = DEFAULT_AVATAR_GRAVITY; - } - if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); - } -} - void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const glm::vec3& scale) { float x = scale.x; float z = scale.z; From 322b7fc0609dd193e9c17807c31914b24a646b04 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Wed, 20 Sep 2017 23:37:33 +0100 Subject: [PATCH 08/30] Cleanup from Merge --- interface/src/avatar/MyAvatar.h | 3 +++ libraries/physics/src/CharacterController.cpp | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index b1351dc498..9620d61a49 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -150,6 +150,9 @@ class MyAvatar : public Avatar { Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone) Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate) + Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight) + Q_PROPERTY(float userEyeHeight READ getUserEyeHeight) + const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 0904e39d25..5e446a52a9 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -393,9 +393,6 @@ void CharacterController::setState(State desiredState) { } } -<<<<<<< HEAD -<<<<<<< HEAD -======= void CharacterController::updateGravity() { int16_t collisionGroup = computeCollisionGroup(); if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { @@ -408,9 +405,6 @@ void CharacterController::updateGravity() { } } ->>>>>>> 5e5b77fbaaeff61a26144a240329eca70765c1a9 -======= ->>>>>>> 4d904bd5ce7d7b1a805c2f8fbdda630afc27576f void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const glm::vec3& scale) { float x = scale.x; float z = scale.z; From 45f79b43412344f2eff7a9c66a2072e5f594599e Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Thu, 21 Sep 2017 00:00:24 +0100 Subject: [PATCH 09/30] Small fix --- libraries/physics/src/CharacterController.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 5e446a52a9..8d32535632 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -393,18 +393,6 @@ void CharacterController::setState(State desiredState) { } } -void CharacterController::updateGravity() { - int16_t collisionGroup = computeCollisionGroup(); - if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { - _gravity = 0.0f; - } else { - _gravity = DEFAULT_AVATAR_GRAVITY; - } - if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); - } -} - void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const glm::vec3& scale) { float x = scale.x; float z = scale.z; From 65e0c99618bf05b704f97715b516cb53ceb43d9c Mon Sep 17 00:00:00 2001 From: druiz17 Date: Thu, 21 Sep 2017 09:07:49 -0700 Subject: [PATCH 10/30] small change --- scripts/system/controllers/controllerModules/scaleEntity.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/system/controllers/controllerModules/scaleEntity.js b/scripts/system/controllers/controllerModules/scaleEntity.js index 4b504c3733..79b1d18db9 100644 --- a/scripts/system/controllers/controllerModules/scaleEntity.js +++ b/scripts/system/controllers/controllerModules/scaleEntity.js @@ -35,10 +35,7 @@ }; this.bumperPressed = function(controllerData) { - if ( controllerData.secondaryValues[this.hand] > dispatcherUtils.BUMPER_ON_VALUE) { - return true; - } - return false; + return ( controllerData.secondaryValues[this.hand] > dispatcherUtils.BUMPER_ON_VALUE); }; this.getTargetProps = function(controllerData) { From 81be62b6f70de4598aa10f845a8ddaaa1ee1f6bc Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 21 Sep 2017 09:34:15 -0700 Subject: [PATCH 11/30] Check if ContextOverlayInterface is enabled before highlighting --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 34aae37175..fed6267c63 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -237,13 +237,13 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& } void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) { - if (contextOverlayFilterPassed(entityID)) { + if (contextOverlayFilterPassed(entityID) && _enabled) { enableEntityHighlight(entityID); } } void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event) { - if (_currentEntityWithContextOverlay != entityID) { + if (_currentEntityWithContextOverlay != entityID && _enabled) { disableEntityHighlight(entityID); } } From 57b5a233739d8dd2af24a84572089ab94000c2fa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 21 Sep 2017 11:18:21 -0700 Subject: [PATCH 12/30] Enable Inspection Mode for all; change Commerce setting name --- .../src/ui/overlays/ContextOverlayInterface.cpp | 13 +------------ interface/src/ui/overlays/ContextOverlayInterface.h | 2 -- libraries/ui/src/ui/types/RequestFilters.cpp | 2 +- scripts/system/commerce/wallet.js | 2 +- scripts/system/html/js/marketplacesInject.js | 4 ++-- scripts/system/marketplaces/marketplaces.js | 4 ++-- 6 files changed, 7 insertions(+), 20 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index fed6267c63..509e201d47 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -38,11 +38,6 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityPropertyFlags += PROP_DIMENSIONS; _entityPropertyFlags += PROP_REGISTRATION_POINT; - // initially, set _enabled to match the switch. Later we enable/disable via the getter/setters - // if we are in edit or pal (for instance). Note this is temporary, as we expect to enable this all - // the time after getting edge highlighting, etc... - _enabled = _settingSwitch.get(); - auto entityTreeRenderer = DependencyManager::get().data(); connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&))); connect(entityTreeRenderer, SIGNAL(hoverEnterEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverEnterEntity(const EntityItemID&, const PointerEvent&))); @@ -81,13 +76,7 @@ static const float CONTEXT_OVERLAY_UNHOVERED_COLORPULSE = 1.0f; static const float CONTEXT_OVERLAY_FAR_OFFSET = 0.1f; void ContextOverlayInterface::setEnabled(bool enabled) { - // only enable/disable if the setting in 'on'. If it is 'off', - // make sure _enabled is always false. - if (_settingSwitch.get()) { - _enabled = enabled; - } else { - _enabled = false; - } + _enabled = enabled; } bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) { diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index c14262029e..fddd1fcdb5 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -76,8 +76,6 @@ private: bool _isInMarketplaceInspectionMode { false }; - Setting::Handle _settingSwitch { "inspectionMode", false }; - void openMarketplace(); void enableEntityHighlight(const EntityItemID& entityItemID); void disableEntityHighlight(const EntityItemID& entityItemID); diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp index 6ef3effa4c..233a9458fe 100644 --- a/libraries/ui/src/ui/types/RequestFilters.cpp +++ b/libraries/ui/src/ui/types/RequestFilters.cpp @@ -61,7 +61,7 @@ void RequestFilters::interceptHFWebEngineRequest(QWebEngineUrlRequestInfo& info) // During the period in which we have HFC commerce in the system, but not applied everywhere: const QString tokenStringCommerce{ "Chrome/48.0 (HighFidelityInterface WithHFC)" }; - static Setting::Handle _settingSwitch{ "inspectionMode", false }; + static Setting::Handle _settingSwitch{ "commerce", false }; bool isMoney = _settingSwitch.get(); const QString tokenString = !isAuthable ? tokenStringMobile : (isMoney ? tokenStringCommerce : tokenStringMetaverse); diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 5a668a3d6e..107160154a 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -131,7 +131,7 @@ var button; var buttonName = "WALLET"; var tablet = null; - var walletEnabled = Settings.getValue("inspectionMode", false); + var walletEnabled = Settings.getValue("commerce", false); function startup() { if (walletEnabled) { tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 84c26d482b..138e3a3956 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -450,7 +450,7 @@ var parsedJsonMessage = JSON.parse(message); if (parsedJsonMessage.type === "marketplaces") { - if (parsedJsonMessage.action === "inspectionModeSetting") { + if (parsedJsonMessage.action === "commerceSetting") { confirmAllPurchases = !!parsedJsonMessage.data; injectCode(); } @@ -458,7 +458,7 @@ } }); - // Request inspection mode setting + // Request commerce setting // Code is injected into the webpage after the setting comes back. EventBridge.emitWebEvent(JSON.stringify({ type: "REQUEST_SETTING" diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 2eaefe7565..7ae0aa3390 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -138,8 +138,8 @@ } else if (parsedJsonMessage.type === "REQUEST_SETTING") { tablet.emitScriptEvent(JSON.stringify({ type: "marketplaces", - action: "inspectionModeSetting", - data: Settings.getValue("inspectionMode", false) + action: "commerceSetting", + data: Settings.getValue("commerce", false) })); } else if (parsedJsonMessage.type === "PURCHASES") { tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH); From 1a571d099125265f18c731063e79fd6c34061710 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 20 Sep 2017 11:12:08 -0700 Subject: [PATCH 13/30] Add Asset Server auto refresh --- interface/resources/qml/AssetServer.qml | 18 +++++-------- .../qml/hifi/dialogs/TabletAssetServer.qml | 19 +++++--------- .../AssetMappingsScriptingInterface.cpp | 26 ++++++++++++++++--- .../AssetMappingsScriptingInterface.h | 6 +++++ 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 23fec03ac2..649ea49153 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -49,9 +49,14 @@ ScrollingWindow { Component.onCompleted: { ApplicationInterface.uploadRequest.connect(uploadClicked); assetMappingsModel.errorGettingMappings.connect(handleGetMappingsError); + assetMappingsModel.autoRefreshEnabled = true; reload(); } + + Component.onDestruction: { + assetMappingsModel.autoRefreshEnabled = false; + } function doDeleteFile(path) { console.log("Deleting " + path); @@ -146,7 +151,6 @@ ScrollingWindow { function reload() { Assets.mappingModel.refresh(); - treeView.selection.clear(); } function handleGetMappingsError(errorString) { @@ -502,16 +506,6 @@ ScrollingWindow { onClicked: root.deleteFile() enabled: treeView.selection.hasSelection } - - HifiControls.GlyphButton { - - glyph: hifi.glyphs.reload - color: hifi.buttons.black - colorScheme: root.colorScheme - width: hifi.dimensions.controlLineHeight - - onClicked: root.reload() - } } } @@ -751,7 +745,7 @@ ScrollingWindow { var path = assetProxyModel.data(index, 0x100); mappings.push(path); } - print("Setting baking enabled:" + mappings + checked); + print("Setting baking enabled:" + mappings + " " + checked); Assets.setBakingEnabled(mappings, checked, function() { reload(); }); diff --git a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml index 61f5a382ad..3f1fcf6bda 100644 --- a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml +++ b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml @@ -49,9 +49,15 @@ Rectangle { isHMD = HMD.active; ApplicationInterface.uploadRequest.connect(uploadClicked); assetMappingsModel.errorGettingMappings.connect(handleGetMappingsError); + assetMappingsModel.autoRefreshEnabled = true; + reload(); } + Component.onDestruction: { + assetMappingsModel.autoRefreshEnabled = false; + } + function doDeleteFile(path) { console.log("Deleting " + path); @@ -145,7 +151,6 @@ Rectangle { function reload() { Assets.mappingModel.refresh(); - treeView.selection.clear(); } function handleGetMappingsError(errorString) { @@ -502,16 +507,6 @@ Rectangle { onClicked: root.deleteFile() enabled: treeView.selection.hasSelection } - - HifiControls.GlyphButton { - - glyph: hifi.glyphs.reload - color: hifi.buttons.black - colorScheme: root.colorScheme - width: hifi.dimensions.controlLineHeight - - onClicked: root.reload() - } } } @@ -748,7 +743,7 @@ Rectangle { var path = assetProxyModel.data(index, 0x100); mappings.push(path); } - print("Setting baking enabled:" + mappings + checked); + print("Setting baking enabled:" + mappings + " " + checked); Assets.setBakingEnabled(mappings, checked, function() { reload(); }); diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index 14e0ef5b28..abe31932c9 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -21,6 +21,10 @@ #include #include +static const int AUTO_REFRESH_INTERVAL = 1000; + +const int assetMappingModelMetatypeId = qRegisterMetaType("AssetMappingModel*"); + AssetMappingsScriptingInterface::AssetMappingsScriptingInterface() { _proxyModel.setSourceModel(&_assetMappingModel); _proxyModel.setSortRole(Qt::DisplayRole); @@ -189,6 +193,25 @@ void AssetMappingsScriptingInterface::setBakingEnabled(QStringList paths, bool e AssetMappingModel::AssetMappingModel() { setupRoles(); + + connect(&_autoRefreshTimer, &QTimer::timeout, this, [this] { + refresh(); + }); + _autoRefreshTimer.setInterval(AUTO_REFRESH_INTERVAL); +} + +bool AssetMappingModel::isAutoRefreshEnabled() { + return _autoRefreshTimer.isActive(); +} + +void AssetMappingModel::setAutoRefreshEnabled(bool enabled) { + if (enabled != _autoRefreshTimer.isActive()) { + if (enabled) { + _autoRefreshTimer.start(); + } else { + _autoRefreshTimer.stop(); + } + } } bool AssetMappingModel::isKnownFolder(QString path) const { @@ -205,10 +228,7 @@ bool AssetMappingModel::isKnownFolder(QString path) const { return false; } -int assetMappingModelMetatypeId = qRegisterMetaType("AssetMappingModel*"); - void AssetMappingModel::refresh() { - qDebug() << "Refreshing asset mapping model"; auto assetClient = DependencyManager::get(); auto request = assetClient->createGetAllMappingsRequest(); diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.h b/interface/src/scripting/AssetMappingsScriptingInterface.h index e4059c1ff7..04ab488838 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.h +++ b/interface/src/scripting/AssetMappingsScriptingInterface.h @@ -25,11 +25,16 @@ class AssetMappingModel : public QStandardItemModel { Q_OBJECT + Q_PROPERTY(bool autoRefreshEnabled READ isAutoRefreshEnabled WRITE setAutoRefreshEnabled) + public: AssetMappingModel(); Q_INVOKABLE void refresh(); + bool isAutoRefreshEnabled(); + void setAutoRefreshEnabled(bool enabled); + bool isKnownMapping(QString path) const { return _pathToItemMap.contains(path); } bool isKnownFolder(QString path) const; @@ -44,6 +49,7 @@ private: void setupRoles(); QHash _pathToItemMap; + QTimer _autoRefreshTimer; }; Q_DECLARE_METATYPE(AssetMappingModel*) From 0d33976035fd2e96a0aec69e3993f9cbbf5be328 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 22 Sep 2017 00:38:30 +0100 Subject: [PATCH 14/30] Real time changes --- libraries/physics/src/CharacterController.cpp | 26 +++++++++---------- libraries/physics/src/CharacterController.h | 6 +++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 8d32535632..32e764bd10 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -20,9 +20,6 @@ const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); -const float DEFAULT_CHARACTER_GRAVITY = -5.0f; -float currentAvatarGravity = DEFAULT_CHARACTER_GRAVITY; - #ifdef DEBUG_STATE_CHANGE #define SET_STATE(desiredState, reason) setState(desiredState, reason) #else @@ -123,7 +120,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { _dynamicsWorld->addRigidBody(_rigidBody, collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR); _dynamicsWorld->addAction(this); // restore gravity settings because adding an object to the world overwrites its gravity setting - _rigidBody->setGravity(_gravity * _currentUp); + _rigidBody->setGravity(_currentGravity * _currentUp); btCollisionShape* shape = _rigidBody->getCollisionShape(); assert(shape && shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE); _ghost.setCharacterShape(static_cast(shape)); @@ -305,7 +302,7 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar // add minimum velocity to counteract gravity's displacement during one step // Note: the 0.5 factor comes from the fact that we really want the // average velocity contribution from gravity during the step - stepUpSpeed -= 0.5f * _gravity * timeToStep; // remember: _gravity is negative scalar + stepUpSpeed -= 0.5f * _currentGravity * timeToStep; // remember: _gravity is negative scalar btScalar vDotUp = velocity.dot(_currentUp); if (vDotUp < stepUpSpeed) { @@ -354,25 +351,26 @@ static const char* stateToStr(CharacterController::State state) { } #endif // #ifdef DEBUG_STATE_CHANGE -void CharacterController::updateGravity() { +void CharacterController::updateCurrentGravity() { int16_t collisionGroup = computeCollisionGroup(); if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { - _gravity = 0.0f; + _currentGravity = 0.0f; } else { - _gravity = currentAvatarGravity; + _currentGravity = _gravity; } if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); + _rigidBody->setGravity(_currentGravity * _currentUp); } } void CharacterController::setGravity(float gravity) { - currentAvatarGravity = gravity; + _gravity = gravity; + updateCurrentGravity(); } float CharacterController::getGravity() { - return currentAvatarGravity; + return _gravity; } #ifdef DEBUG_STATE_CHANGE @@ -389,7 +387,7 @@ void CharacterController::setState(State desiredState) { qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "from" << stateToStr(_state) << "," << reason; #endif _state = desiredState; - updateGravity(); + updateCurrentGravity(); } } @@ -448,14 +446,14 @@ void CharacterController::handleChangedCollisionGroup() { _dynamicsWorld->addRigidBody(_rigidBody, collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR); } _pendingFlags &= ~PENDING_FLAG_UPDATE_COLLISION_GROUP; - updateGravity(); + updateCurrentGravity(); } } void CharacterController::updateUpAxis(const glm::quat& rotation) { _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); + _rigidBody->setGravity(_currentGravity * _currentUp); } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 49db3b9bf4..0f97cc7c16 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -24,6 +24,7 @@ #include "BulletUtil.h" #include "CharacterGhostObject.h" +#include "AvatarConstants.h" const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; @@ -134,7 +135,7 @@ protected: #endif virtual void updateMassProperties() = 0; - void updateGravity(); + void updateCurrentGravity(); void updateUpAxis(const glm::quat& rotation); bool checkForSupport(btCollisionWorld* collisionWorld); @@ -187,7 +188,8 @@ protected: bool _stepUpEnabled { true }; bool _hasSupport; - btScalar _gravity { 0.0f }; + btScalar _currentGravity { 0.0f }; + btScalar _gravity { DEFAULT_AVATAR_GRAVITY }; btScalar _followTime; btVector3 _followLinearDisplacement; From 9f12d3a3658298c6afb7d6a27b65735fdd4e4548 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 21 Sep 2017 17:51:00 -0700 Subject: [PATCH 15/30] fix missing models --- .../src/EntityTreeRenderer.cpp | 8 ++++++ .../src/RenderableEntityItem.cpp | 17 ++++++++++++ .../src/RenderableEntityItem.h | 26 +++++++++++++++++++ .../src/RenderableModelEntityItem.cpp | 16 +++++------- .../src/RenderableModelEntityItem.h | 6 ++--- .../src/model-networking/ModelCache.cpp | 2 +- .../render-utils/src/MeshPartPayload.cpp | 4 +-- libraries/render-utils/src/Model.cpp | 8 ++---- 8 files changed, 66 insertions(+), 21 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index a79e29f003..f303617be0 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -222,6 +222,14 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene _renderablesToUpdate.insert({ entityId, renderable }); } + if (!_entitiesInScene.empty()) { + for (const auto& entry : _entitiesInScene) { + const auto& renderable = entry.second; + if (renderable) { + renderable->update(scene, transaction); + } + } + } if (!_renderablesToUpdate.empty()) { for (const auto& entry : _renderablesToUpdate) { const auto& renderable = entry.second; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 3f1e89b86c..ea514d3181 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -291,6 +291,18 @@ void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& trans }); } +void EntityRenderer::update(const ScenePointer& scene, Transaction& transaction) { + if (!isValidRenderItem()) { + return; + } + + if (!needsUpdate()) { + return; + } + + doUpdate(scene, transaction, _entity); +} + // // Internal methods // @@ -304,6 +316,11 @@ bool EntityRenderer::needsRenderUpdate() const { return needsRenderUpdateFromEntity(_entity); } +// Returns true if the item needs to have update called +bool EntityRenderer::needsUpdate() const { + return needsUpdateFromEntity(_entity); +} + // Returns true if the item in question needs to have updateInScene called because of changes in the entity bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity) const { bool success = false; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 6b47ff8b1d..56cb39252f 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -49,6 +49,8 @@ public: virtual bool addToScene(const ScenePointer& scene, Transaction& transaction) final; virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction); + virtual void update(const ScenePointer& scene, Transaction& transaction); + protected: virtual bool needsRenderUpdateFromEntity() const final { return needsRenderUpdateFromEntity(_entity); } virtual void onAddToScene(const EntityItemPointer& entity); @@ -71,6 +73,12 @@ protected: // Returns true if the item in question needs to have updateInScene called because of changes in the entity virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const; + // Returns true if the item in question needs to have update called + virtual bool needsUpdate() const; + + // Returns true if the item in question needs to have update called because of changes in the entity + virtual bool needsUpdateFromEntity(const EntityItemPointer& entity) const { return false; } + // Will be called on the main thread from updateInScene. This can be used to fetch things like // network textures or model geometry from resource caches virtual void doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { } @@ -80,6 +88,8 @@ protected: // data in this method if using multi-threaded rendering virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity); + virtual void doUpdate(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { } + // Called by the `render` method after `needsRenderUpdate` virtual void doRender(RenderArgs* args) = 0; @@ -148,6 +158,15 @@ protected: onRemoveFromSceneTyped(_typedEntity); } + using Parent::needsUpdateFromEntity; + // Returns true if the item in question needs to have update called because of changes in the entity + virtual bool needsUpdateFromEntity(const EntityItemPointer& entity) const override final { + if (Parent::needsUpdateFromEntity(entity)) { + return true; + } + return needsUpdateFromTypedEntity(_typedEntity); + } + using Parent::needsRenderUpdateFromEntity; // Returns true if the item in question needs to have updateInScene called because of changes in the entity virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const override final { @@ -162,6 +181,11 @@ protected: doRenderUpdateSynchronousTyped(scene, transaction, _typedEntity); } + virtual void doUpdate(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) override final { + Parent::doUpdate(scene, transaction, entity); + doUpdateTyped(scene, transaction, _typedEntity); + } + virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity) override final { Parent::doRenderUpdateAsynchronous(entity); doRenderUpdateAsynchronousTyped(_typedEntity); @@ -170,6 +194,8 @@ protected: virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; } virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { } virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { } + virtual bool needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; } + virtual void doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { } virtual void onAddToSceneTyped(const TypedEntityPointer& entity) { } virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) { } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 2508b598af..a8a7dcdcf7 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -904,7 +904,7 @@ using namespace render; using namespace render::entities; ItemKey ModelEntityRenderer::getKey() { - return ItemKey::Builder::opaqueShape().withTypeMeta(); + return ItemKey::Builder().withTypeMeta(); } uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) { @@ -1026,7 +1026,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { entity->copyAnimationJointDataToModel(); } -bool ModelEntityRenderer::needsRenderUpdate() const { +bool ModelEntityRenderer::needsUpdate() const { ModelPointer model; withReadLock([&] { model = _model; @@ -1057,10 +1057,10 @@ bool ModelEntityRenderer::needsRenderUpdate() const { return true; } } - return Parent::needsRenderUpdate(); + return Parent::needsUpdate(); } -bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { +bool ModelEntityRenderer::needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { if (entity->hasModel() != _hasModel) { return true; @@ -1122,7 +1122,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin return false; } -void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { if (_hasModel != entity->hasModel()) { _hasModel = entity->hasModel(); } @@ -1175,8 +1175,8 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it auto extents = model->getMeshExtents(); properties.setDimensions(extents.maximum - extents.minimum); - qCDebug(entitiesrenderer) << "Autoresizing" - << (!entity->getName().isEmpty() ? entity->getName() : entity->getModelURL()) + qCDebug(entitiesrenderer) << "Autoresizing" + << (!entity->getName().isEmpty() ? entity->getName() : entity->getModelURL()) << "from mesh extents"; QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", @@ -1203,7 +1203,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce entity->updateModelBounds(); } - if (model->isVisible() != _visible) { // FIXME: this seems like it could be optimized if we tracked our last known visible state in // the renderable item. As it stands now the model checks it's visible/invisible state @@ -1234,7 +1233,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce }); } - if (_animating) { if (!jointsMapped()) { mapJoints(entity, model->getJointNames()); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index b9c751761d..e2c7939845 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -138,10 +138,10 @@ protected: virtual ItemKey getKey() override; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) override; - virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual bool needsRenderUpdate() const override; + virtual bool needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual bool needsUpdate() const override; virtual void doRender(RenderArgs* args) override; - virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; private: void animate(const TypedEntityPointer& entity); diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 468d22ce9e..74c8d06736 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -464,7 +464,7 @@ void GeometryResourceWatcher::setResource(GeometryResource::Pointer resource) { _resource = resource; if (_resource) { if (_resource->isLoaded()) { - _geometryRef = std::make_shared(*_resource); + resourceFinished(true); } else { startWatching(); } diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 517fe97dba..924c199239 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -321,8 +321,8 @@ template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, Ren } -ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int _meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) : - _meshIndex(_meshIndex), +ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) : + _meshIndex(meshIndex), _shapeID(shapeIndex) { assert(model && model->isLoaded()); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 42bb91ce94..e729a9519b 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -209,11 +209,6 @@ void Model::updateRenderItems() { return; } - glm::vec3 scale = getScale(); - if (_collisionGeometry) { - // _collisionGeometry is already scaled - scale = glm::vec3(1.0f); - } _needsUpdateClusterMatrices = true; _renderItemsNeedUpdate = false; @@ -221,7 +216,7 @@ void Model::updateRenderItems() { // the application will ensure only the last lambda is actually invoked. void* key = (void*)this; std::weak_ptr weakSelf = shared_from_this(); - AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [weakSelf, scale]() { + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [weakSelf]() { // do nothing, if the model has already been destroyed. auto self = weakSelf.lock(); @@ -1219,6 +1214,7 @@ const render::ItemIDs& Model::fetchRenderItemIDs() const { } void Model::createRenderItemSet() { + updateClusterMatrices(); if (_collisionGeometry) { if (_collisionRenderItems.empty()) { createCollisionRenderItemSet(); From 8583be41ce5a46abd199b3e9b5a54426ee69f27b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 21 Sep 2017 13:23:29 -0700 Subject: [PATCH 16/30] Don't refresh if not connected to the Asset Server --- .../src/scripting/AssetMappingsScriptingInterface.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index abe31932c9..5031016c3f 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -19,11 +19,12 @@ #include #include #include +#include #include static const int AUTO_REFRESH_INTERVAL = 1000; -const int assetMappingModelMetatypeId = qRegisterMetaType("AssetMappingModel*"); +int assetMappingModelMetatypeId = qRegisterMetaType("AssetMappingModel*"); AssetMappingsScriptingInterface::AssetMappingsScriptingInterface() { _proxyModel.setSourceModel(&_assetMappingModel); @@ -195,7 +196,11 @@ AssetMappingModel::AssetMappingModel() { setupRoles(); connect(&_autoRefreshTimer, &QTimer::timeout, this, [this] { - refresh(); + auto nodeList = DependencyManager::get(); + auto assetServer = nodeList->soloNodeOfType(NodeType::AssetServer); + if (assetServer) { + refresh(); + } }); _autoRefreshTimer.setInterval(AUTO_REFRESH_INTERVAL); } From 549cb7790228992c52f51ee8b6ffdd1625829b1f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 21 Sep 2017 20:47:36 -0700 Subject: [PATCH 17/30] Fix dimensions of rendered web entities --- .../src/RenderableWebEntityItem.cpp | 5 ++++ .../src/RenderableWebEntityItem.h | 1 + libraries/ui/src/ui/OffscreenQmlSurface.cpp | 4 +-- tests/render-perf/CMakeLists.txt | 2 +- tests/render-perf/src/main.cpp | 28 +++++++++++++++++-- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 8b5feb15f0..5dc75dad08 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -140,6 +140,11 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene _webSurface->resize(QSize(windowSize.x, windowSize.y)); } +void WebEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + Parent::doRenderUpdateAsynchronousTyped(entity); + _modelTransform.postScale(entity->getDimensions()); +} + void WebEntityRenderer::doRender(RenderArgs* args) { withWriteLock([&] { _lastRenderTime = usecTimestampNow(); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 4b7e7e25a1..a67eb39670 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -29,6 +29,7 @@ protected: virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; virtual bool isTransparent() const override; diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index faf7933d1a..071ccd46b1 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -211,12 +211,12 @@ class UrlHandler : public QObject { public: Q_INVOKABLE bool canHandleUrl(const QString& url) { static auto handler = dynamic_cast(qApp); - return handler->canAcceptURL(url); + return handler && handler->canAcceptURL(url); } Q_INVOKABLE bool handleUrl(const QString& url) { static auto handler = dynamic_cast(qApp); - return handler->acceptURL(url); + return handler && handler->acceptURL(url); } }; diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index 77c8ab2177..5b83ff313b 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -12,7 +12,7 @@ setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared networking model fbx ktx image octree gl gpu gpu-gl render model-networking networking render-utils entities entities-renderer animation audio avatars script-engine physics procedural midi) +link_hifi_libraries(shared networking model fbx ktx image octree gl gpu gpu-gl render model-networking networking render-utils entities entities-renderer animation audio avatars script-engine physics procedural midi ui) package_libraries_for_deployment() diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 3be6ba2f6c..58eb4d16f9 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -42,11 +42,15 @@ #include #include +#include + #include #include #include #include +#include + #include #include #include @@ -427,6 +431,10 @@ namespace render { } } +OffscreenGLCanvas* _chromiumShareContext{ nullptr }; +Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context); + + // Create a simple OpenGL window that renders text in various ways class QTestWindow : public QWindow, public AbstractViewStateInterface { @@ -506,8 +514,6 @@ public: AbstractViewStateInterface::setInstance(this); _octree = DependencyManager::set(false, this, nullptr); _octree->init(); - // Prevent web entities from rendering - REGISTER_ENTITY_TYPE_WITH_FACTORY(Web, WebEntityItem::factory); DependencyManager::set(_octree->getTree()); auto nodeList = DependencyManager::get(); @@ -535,6 +541,23 @@ public: _renderThread.initialize(this, _initContext); _initContext.makeCurrent(); + if (nsightActive()) { + // Prevent web entities from rendering + REGISTER_ENTITY_TYPE_WITH_FACTORY(Web, WebEntityItem::factory); + } else { + _chromiumShareContext = new OffscreenGLCanvas(); + _chromiumShareContext->setObjectName("ChromiumShareContext"); + _chromiumShareContext->create(_initContext.qglContext()); + _chromiumShareContext->makeCurrent(); + qt_gl_set_global_share_context(_chromiumShareContext->getContext()); + + // Make sure all QML surfaces share the main thread GL context + OffscreenQmlSurface::setSharedContext(_initContext.qglContext()); + + _initContext.makeCurrent(); + } + + // FIXME use a wait condition QThread::msleep(1000); _renderThread.submitFrame(gpu::FramePointer()); @@ -679,6 +702,7 @@ private: _renderCount = _renderThread._presentCount.load(); update(); + _initContext.makeCurrent(); RenderArgs renderArgs(_renderThread._gpuContext, DEFAULT_OCTREE_SIZE_SCALE, 0, RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); From d3c60f3057eecaf2038215ccd1fd6d4e16a84a3e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 22 Sep 2017 09:44:51 -0700 Subject: [PATCH 18/30] Fix for TextEntity rendering, the translation was incorrect This was caused by the removal of _dimensions from the SpatiallyNestable scale component. --- libraries/entities-renderer/src/RenderableTextEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 8757bcbb0f..f4e4c0ea8f 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -102,7 +102,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) { glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); transformToTopLeft.setRotation(orientation); } - transformToTopLeft.postTranslate(glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left + transformToTopLeft.postTranslate(dimensions * glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed batch.setModelTransform(transformToTopLeft); From be27376c52d3b37106383a8cab1ab458f3f4d6e1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Sep 2017 10:02:41 -0700 Subject: [PATCH 19/30] add comment about bottleneck --- .../entities-renderer/src/EntityTreeRenderer.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index f303617be0..c29d92bae9 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -222,12 +222,14 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene _renderablesToUpdate.insert({ entityId, renderable }); } - if (!_entitiesInScene.empty()) { - for (const auto& entry : _entitiesInScene) { - const auto& renderable = entry.second; - if (renderable) { - renderable->update(scene, transaction); - } + // NOTE: Looping over all the entity renderers is likely to be a bottleneck in the future + // Currently, this is necessary because the model entity loading logic requires constant polling + // This was working fine because the entity server used to send repeated updates as your view changed, + // but with the improved entity server logic (PR 11141), updateInScene (below) would not be triggered enough + for (const auto& entry : _entitiesInScene) { + const auto& renderable = entry.second; + if (renderable) { + renderable->update(scene, transaction); } } if (!_renderablesToUpdate.empty()) { From bb9db3ef6d7ea6aed0c4dac2f636f93b08029545 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 22 Sep 2017 11:24:30 -0700 Subject: [PATCH 20/30] Updates to behavior and shader appearance --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 9 +++++++-- libraries/render-utils/src/OutlineEffect.h | 8 ++++---- .../controllers/controllerModules/farActionGrabEntity.js | 4 +++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 509e201d47..bf42b300ca 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -82,6 +82,10 @@ void ContextOverlayInterface::setEnabled(bool enabled) { bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) { if (_enabled && event.getButton() == PointerEvent::SecondaryButton) { if (contextOverlayFilterPassed(entityItemID)) { + if (event.getID() == 0) { + enableEntityHighlight(entityItemID); + } + qCDebug(context_overlay) << "Creating Context Overlay on top of entity with ID: " << entityItemID; // Add all necessary variables to the stack @@ -165,6 +169,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& } } else { if (!_currentEntityWithContextOverlay.isNull()) { + disableEntityHighlight(_currentEntityWithContextOverlay); return destroyContextOverlay(_currentEntityWithContextOverlay, event); } return false; @@ -226,13 +231,13 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& } void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) { - if (contextOverlayFilterPassed(entityID) && _enabled) { + if (contextOverlayFilterPassed(entityID) && _enabled && event.getID() != 0) { enableEntityHighlight(entityID); } } void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event) { - if (_currentEntityWithContextOverlay != entityID && _enabled) { + if (_currentEntityWithContextOverlay != entityID && _enabled && event.getID() != 0) { disableEntityHighlight(entityID); } } diff --git a/libraries/render-utils/src/OutlineEffect.h b/libraries/render-utils/src/OutlineEffect.h index 36dc59f29e..f260345c24 100644 --- a/libraries/render-utils/src/OutlineEffect.h +++ b/libraries/render-utils/src/OutlineEffect.h @@ -81,10 +81,10 @@ public: float getColorB() const { return color.b; } glm::vec3 color{ 1.f, 0.7f, 0.2f }; - float width{ 3.f }; - float intensity{ 1.f }; - float fillOpacityUnoccluded{ 0.35f }; - float fillOpacityOccluded{ 0.1f }; + float width{ 1.5f }; + float intensity{ 0.9f }; + float fillOpacityUnoccluded{ 0.0f }; + float fillOpacityOccluded{ 0.0f }; bool glow{ false }; signals: diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index eb73b0f908..d2b5f92fde 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -148,7 +148,9 @@ Script.include("/~/system/libraries/controllers.js"); if (mode === "full") { var fullEndToEdit = PICK_WITH_HAND_RAY ? this.fullEnd : fullEnd; fullEndToEdit.dimensions = dim; - LaserPointers.editRenderState(laserPointerID, mode, {path: fullPath, end: fullEndToEdit}); + LaserPointers.editRenderState(laserPointerID, mode, { path: fullPath, end: fullEndToEdit }); + this.contextOverlayTimer = false; + this.destroyContextOverlay(); } else if (mode === "half") { var halfEndToEdit = PICK_WITH_HAND_RAY ? this.halfEnd : halfEnd; halfEndToEdit.dimensions = dim; From 430d1b22bb3f85c4f168bf7e00bd046c9565c22a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 22 Sep 2017 11:41:28 -0700 Subject: [PATCH 21/30] Update angular size and i behavior --- .../ui/overlays/ContextOverlayInterface.cpp | 27 +++++-------------- libraries/render-utils/src/OutlineEffect.h | 2 +- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index bf42b300ca..7513fdd6a7 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -63,10 +63,8 @@ ContextOverlayInterface::ContextOverlayInterface() { static const uint32_t LEFT_HAND_HW_ID = 1; static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 }; static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters -static const float CONTEXT_OVERLAY_CLOSE_DISTANCE = 1.5f; // in meters -static const float CONTEXT_OVERLAY_CLOSE_SIZE = 0.12f; // in meters, same x and y dims -static const float CONTEXT_OVERLAY_FAR_SIZE = 0.08f; // in meters, same x and y dims -static const float CONTEXT_OVERLAY_CLOSE_OFFSET_ANGLE = 20.0f; +static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims +static const float CONTEXT_OVERLAY_OFFSET_ANGLE = 10.0f; static const float CONTEXT_OVERLAY_UNHOVERED_ALPHA = 0.85f; static const float CONTEXT_OVERLAY_HOVERED_ALPHA = 1.0f; static const float CONTEXT_OVERLAY_UNHOVERED_PULSEMIN = 0.6f; @@ -91,7 +89,6 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& // Add all necessary variables to the stack EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); glm::vec3 cameraPosition = qApp->getCamera().getPosition(); - float distanceFromCameraToEntity = glm::distance(entityProperties.getPosition(), cameraPosition); glm::vec3 entityDimensions = entityProperties.getDimensions(); glm::vec3 entityPosition = entityProperties.getPosition(); glm::vec3 contextOverlayPosition = entityProperties.getPosition(); @@ -124,27 +121,17 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& // If the camera is inside the box... // ...position the Context Overlay 1 meter in front of the camera. contextOverlayPosition = cameraPosition + CONTEXT_OVERLAY_INSIDE_DISTANCE * (qApp->getCamera().getOrientation() * Vectors::FRONT); - contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_CLOSE_SIZE, CONTEXT_OVERLAY_CLOSE_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); - } else if (distanceFromCameraToEntity < CONTEXT_OVERLAY_CLOSE_DISTANCE) { + contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_SIZE, CONTEXT_OVERLAY_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); + } else { // Else if the entity is too close to the camera... - // ...rotate the Context Overlay to the right of the entity. + // ...rotate the Context Overlay some number of degrees offset from the entity. // This makes it easy to inspect things you're holding. - float offsetAngle = -CONTEXT_OVERLAY_CLOSE_OFFSET_ANGLE; + float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE; if (event.getID() == LEFT_HAND_HW_ID) { offsetAngle *= -1; } contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f))) * (entityPosition - cameraPosition)) + cameraPosition; - contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_CLOSE_SIZE, CONTEXT_OVERLAY_CLOSE_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); - } else { - // Else, place the Context Overlay some offset away from the entity's bounding - // box in the direction of the camera. - glm::vec3 direction = glm::normalize(entityPosition - cameraPosition); - float distance; - BoxFace face; - glm::vec3 normal; - boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal); - contextOverlayPosition = (cameraPosition + direction * distance) - direction * CONTEXT_OVERLAY_FAR_OFFSET; - contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_FAR_SIZE, CONTEXT_OVERLAY_FAR_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); + contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_SIZE, CONTEXT_OVERLAY_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); } // Finally, setup and draw the Context Overlay diff --git a/libraries/render-utils/src/OutlineEffect.h b/libraries/render-utils/src/OutlineEffect.h index f260345c24..f88092429f 100644 --- a/libraries/render-utils/src/OutlineEffect.h +++ b/libraries/render-utils/src/OutlineEffect.h @@ -81,7 +81,7 @@ public: float getColorB() const { return color.b; } glm::vec3 color{ 1.f, 0.7f, 0.2f }; - float width{ 1.5f }; + float width{ 2.0f }; float intensity{ 0.9f }; float fillOpacityUnoccluded{ 0.0f }; float fillOpacityOccluded{ 0.0f }; From e3f2e70bca4b728595e874d9882d5bb67f9d2f27 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 22 Sep 2017 11:43:11 -0700 Subject: [PATCH 22/30] No magic numbers --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 7513fdd6a7..e103e85544 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -60,6 +60,7 @@ ContextOverlayInterface::ContextOverlayInterface() { connect(_selectionScriptingInterface.data(), &SelectionScriptingInterface::selectedItemsListChanged, &_selectionToSceneHandler, &SelectionToSceneHandler::selectedItemsListChanged); } +static const uint32_t MOUSE_HW_ID = 0; static const uint32_t LEFT_HAND_HW_ID = 1; static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 }; static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters @@ -80,7 +81,7 @@ void ContextOverlayInterface::setEnabled(bool enabled) { bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) { if (_enabled && event.getButton() == PointerEvent::SecondaryButton) { if (contextOverlayFilterPassed(entityItemID)) { - if (event.getID() == 0) { + if (event.getID() == MOUSE_HW_ID) { enableEntityHighlight(entityItemID); } @@ -218,13 +219,13 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID& } void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) { - if (contextOverlayFilterPassed(entityID) && _enabled && event.getID() != 0) { + if (contextOverlayFilterPassed(entityID) && _enabled && event.getID() != MOUSE_HW_ID) { enableEntityHighlight(entityID); } } void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event) { - if (_currentEntityWithContextOverlay != entityID && _enabled && event.getID() != 0) { + if (_currentEntityWithContextOverlay != entityID && _enabled && event.getID() != MOUSE_HW_ID) { disableEntityHighlight(entityID); } } From bc477608ee873b78f77ff246605a2b6ddc471841 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Sep 2017 13:22:08 -0700 Subject: [PATCH 23/30] fix alpha on glowLines --- libraries/render-utils/src/glowLine.slf | 10 +++++----- libraries/render-utils/src/glowLine.slv | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libraries/render-utils/src/glowLine.slf b/libraries/render-utils/src/glowLine.slf index c0af97930a..580a49dd3e 100644 --- a/libraries/render-utils/src/glowLine.slf +++ b/libraries/render-utils/src/glowLine.slf @@ -9,7 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -layout(location = 0) in vec4 inColor; +in vec4 _color; +in float distanceFromCenter; out vec4 _fragColor; @@ -17,10 +18,10 @@ void main(void) { // The incoming value actually ranges from -1 to 1, so modify it // so that it goes from 0 -> 1 -> 0 with the solid alpha being at // the center of the line - float alpha = 1.0 - abs(inColor.a); + float alpha = 1.0 - abs(distanceFromCenter); // Convert from a linear alpha curve to a sharp peaked one - alpha = pow(alpha, 10); + alpha = _color.a * pow(alpha, 10); // Drop everything where the curve falls off to nearly nothing if (alpha <= 0.05) { @@ -28,6 +29,5 @@ void main(void) { } // Emit the color - _fragColor = vec4(inColor.rgb, alpha); - return; + _fragColor = vec4(_color.rgb, alpha); } diff --git a/libraries/render-utils/src/glowLine.slv b/libraries/render-utils/src/glowLine.slv index e856edc787..fd3a85d254 100644 --- a/libraries/render-utils/src/glowLine.slv +++ b/libraries/render-utils/src/glowLine.slv @@ -18,7 +18,9 @@ layout(std140) uniform lineData { vec4 color; }; -layout(location = 0) out vec4 _color; +out vec4 _color; +// the distance from the center in 'quad space' +out float distanceFromCenter; void main(void) { _color = color; @@ -45,11 +47,10 @@ void main(void) { // Add or subtract the orthogonal vector based on a different vertex ID // calculation if (gl_VertexID < 2) { - // Use the alpha channel to store the distance from the center in 'quad space' - _color.a = -1.0; + distanceFromCenter = -1.0; eye.xyz -= orthogonal; } else { - _color.a = 1.0; + distanceFromCenter = 1.0; eye.xyz += orthogonal; } From 0eafdeab14267c078a4944b9d6cc2e7fa249342b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 22 Sep 2017 13:19:52 -0700 Subject: [PATCH 24/30] Fix hover -> unhover overlay behavior --- .../src/ui/overlays/ContextOverlayInterface.cpp | 14 +++++++++----- .../controllerModules/overlayLaserInput.js | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index e103e85544..3c0dc982a3 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -65,6 +65,7 @@ static const uint32_t LEFT_HAND_HW_ID = 1; static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 }; static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims +static const float CONTEXT_OVERLAY_OFFSET_DISTANCE = 0.1f; static const float CONTEXT_OVERLAY_OFFSET_ANGLE = 10.0f; static const float CONTEXT_OVERLAY_UNHOVERED_ALPHA = 0.85f; static const float CONTEXT_OVERLAY_HOVERED_ALPHA = 1.0f; @@ -72,7 +73,6 @@ static const float CONTEXT_OVERLAY_UNHOVERED_PULSEMIN = 0.6f; static const float CONTEXT_OVERLAY_UNHOVERED_PULSEMAX = 1.0f; static const float CONTEXT_OVERLAY_UNHOVERED_PULSEPERIOD = 1.0f; static const float CONTEXT_OVERLAY_UNHOVERED_COLORPULSE = 1.0f; -static const float CONTEXT_OVERLAY_FAR_OFFSET = 0.1f; void ContextOverlayInterface::setEnabled(bool enabled) { _enabled = enabled; @@ -124,14 +124,18 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& contextOverlayPosition = cameraPosition + CONTEXT_OVERLAY_INSIDE_DISTANCE * (qApp->getCamera().getOrientation() * Vectors::FRONT); contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_SIZE, CONTEXT_OVERLAY_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); } else { - // Else if the entity is too close to the camera... - // ...rotate the Context Overlay some number of degrees offset from the entity. - // This makes it easy to inspect things you're holding. + // Rotate the Context Overlay some number of degrees offset from the entity + // along the line cast from your head to the entity's bounding box. + glm::vec3 direction = glm::normalize(entityPosition - cameraPosition); + float distance; + BoxFace face; + glm::vec3 normal; + boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal); float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE; if (event.getID() == LEFT_HAND_HW_ID) { offsetAngle *= -1; } - contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f))) * (entityPosition - cameraPosition)) + cameraPosition; + contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f)))) * ((cameraPosition + direction * distance) - direction * CONTEXT_OVERLAY_OFFSET_DISTANCE); contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_SIZE, CONTEXT_OVERLAY_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); } diff --git a/scripts/system/controllers/controllerModules/overlayLaserInput.js b/scripts/system/controllers/controllerModules/overlayLaserInput.js index d67672ca7c..7dace85ec4 100644 --- a/scripts/system/controllers/controllerModules/overlayLaserInput.js +++ b/scripts/system/controllers/controllerModules/overlayLaserInput.js @@ -298,6 +298,9 @@ Script.include("/~/system/libraries/controllers.js"); var intersection = controllerData.rayPicks[this.hand]; var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY); var triggerOff = (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE); + if (triggerOff) { + this.deleteContextOverlay(); + } var grabbingOverlay = this.grabModuleWantsNearbyOverlay(controllerData); return offOverlay || grabbingOverlay || triggerOff; }; @@ -308,7 +311,6 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPressExit(); this.laserPressingTarget = false; } - this.deleteContextOverlay(); this.relinquishTouchFocus(); this.reset(); this.updateLaserPointer(); From cbe621f2b7a9a832b812d042e6af1d10f69e7734 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Sep 2017 15:15:15 -0700 Subject: [PATCH 25/30] add searchRay to RayPickResult, fix precision picking caching with multiple lasers, make laser addition/removal immediate --- interface/src/raypick/LaserPointer.cpp | 7 +- interface/src/raypick/LaserPointer.h | 2 +- interface/src/raypick/LaserPointerManager.cpp | 32 ++------- interface/src/raypick/LaserPointerManager.h | 4 -- interface/src/raypick/RayPick.h | 6 ++ interface/src/raypick/RayPickManager.cpp | 68 ++++++------------- interface/src/raypick/RayPickManager.h | 5 -- libraries/shared/src/RegisteredMetaTypes.cpp | 2 + libraries/shared/src/RegisteredMetaTypes.h | 10 +-- 9 files changed, 45 insertions(+), 91 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index b696afa8e5..afd2d14881 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -92,8 +92,7 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& } } -void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const bool defaultState) { - PickRay pickRay = qApp->getRayPickManager().getPickRay(_rayPickUID); +void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) { if (!renderState.getStartID().isNull()) { QVariantMap startProps; startProps.insert("position", vec3toVariant(pickRay.origin)); @@ -186,11 +185,11 @@ void LaserPointer::disableRenderState(const RenderState& renderState) { void LaserPointer::update() { RayPickResult prevRayPickResult = DependencyManager::get()->getPrevRayPickResult(_rayPickUID); if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && prevRayPickResult.type != IntersectionType::NONE) { - updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, prevRayPickResult.distance, prevRayPickResult.objectID, false); + updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, prevRayPickResult.distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false); disableRenderState(_defaultRenderStates[_currentRenderState].second); } else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { disableRenderState(_renderStates[_currentRenderState]); - updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), true); + updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true); } else if (!_currentRenderState.empty()) { disableRenderState(_renderStates[_currentRenderState]); disableRenderState(_defaultRenderStates[_currentRenderState].second); diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 23f023cf7a..5c120d8d22 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -89,7 +89,7 @@ private: QUuid _rayPickUID; void updateRenderStateOverlay(const OverlayID& id, const QVariant& props); - void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const bool defaultState); + void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState); void disableRenderState(const RenderState& renderState); }; diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index 1fd0fe9e88..9c4d38d260 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -14,17 +14,19 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) { std::shared_ptr laserPointer = std::make_shared(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled); if (!laserPointer->getRayUID().isNull()) { - QWriteLocker lock(&_addLock); + QWriteLocker containsLock(&_containsLock); QUuid id = QUuid::createUuid(); - _laserPointersToAdd.push(std::pair>(id, laserPointer)); + _laserPointers[id] = laserPointer; + _laserPointerLocks[id] = std::make_shared(); return id; } return QUuid(); } void LaserPointerManager::removeLaserPointer(const QUuid uid) { - QWriteLocker lock(&_removeLock); - _laserPointersToRemove.push(uid); + QWriteLocker lock(&_containsLock); + _laserPointers.remove(uid); + _laserPointerLocks.remove(uid); } void LaserPointerManager::enableLaserPointer(const QUuid uid) { @@ -69,32 +71,12 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { } void LaserPointerManager::update() { + QReadLocker lock(&_containsLock); for (QUuid& uid : _laserPointers.keys()) { // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts QReadLocker laserLock(_laserPointerLocks[uid].get()); _laserPointers[uid]->update(); } - - QWriteLocker containsLock(&_containsLock); - { - QWriteLocker lock(&_addLock); - while (!_laserPointersToAdd.empty()) { - std::pair> laserPointerToAdd = _laserPointersToAdd.front(); - _laserPointersToAdd.pop(); - _laserPointers[laserPointerToAdd.first] = laserPointerToAdd.second; - _laserPointerLocks[laserPointerToAdd.first] = std::make_shared(); - } - } - - { - QWriteLocker lock(&_removeLock); - while (!_laserPointersToRemove.empty()) { - QUuid uid = _laserPointersToRemove.front(); - _laserPointersToRemove.pop(); - _laserPointers.remove(uid); - _laserPointerLocks.remove(uid); - } - } } void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index b573410fe7..381119507f 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -46,10 +46,6 @@ public: private: QHash> _laserPointers; QHash> _laserPointerLocks; - QReadWriteLock _addLock; - std::queue>> _laserPointersToAdd; - QReadWriteLock _removeLock; - std::queue _laserPointersToRemove; QReadWriteLock _containsLock; }; diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h index 04045b2116..0686a05718 100644 --- a/interface/src/raypick/RayPick.h +++ b/interface/src/raypick/RayPick.h @@ -70,6 +70,9 @@ public: if (doesPickNonCollidable()) { toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE); } + if (doesPickCourse()) { + toReturn |= getBitMask(PICK_COURSE); + } return Flags(toReturn); } Flags getOverlayFlags() const { @@ -80,6 +83,9 @@ public: if (doesPickNonCollidable()) { toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE); } + if (doesPickCourse()) { + toReturn |= getBitMask(PICK_COURSE); + } return Flags(toReturn); } Flags getAvatarFlags() const { return Flags(getBitMask(PICK_AVATARS)); } diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index 1ec8efc331..bfc6e3fcb2 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -38,11 +38,12 @@ void RayPickManager::cacheResult(const bool intersects, const RayPickResult& res res = resTemp; } } else { - cache[ray][mask] = RayPickResult(); + cache[ray][mask] = RayPickResult(res.searchRay); } } void RayPickManager::update() { + QReadLocker lock(&_containsLock); RayPickCache results; for (auto& uid : _rayPicks.keys()) { std::shared_ptr rayPick = _rayPicks[uid]; @@ -58,7 +59,7 @@ void RayPickManager::update() { } QPair rayKey = QPair(ray.origin, ray.direction); - RayPickResult res; + RayPickResult res = RayPickResult(ray); if (rayPick->getFilter().doesPickEntities()) { RayToEntityIntersectionResult entityRes; @@ -73,7 +74,7 @@ void RayPickManager::update() { } if (!fromCache) { - cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, entityRes.surfaceNormal), + cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, ray, entityRes.surfaceNormal), entityMask, res, rayKey, results); } } @@ -91,7 +92,7 @@ void RayPickManager::update() { } if (!fromCache) { - cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, overlayRes.surfaceNormal), + cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, ray, overlayRes.surfaceNormal), overlayMask, res, rayKey, results); } } @@ -100,7 +101,7 @@ void RayPickManager::update() { RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags(); if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) { RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(ray, rayPick->getIncludeAvatars(), rayPick->getIgnoreAvatars()); - cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection), avatarMask, res, rayKey, results); + cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarMask, res, rayKey, results); } } @@ -109,7 +110,7 @@ void RayPickManager::update() { RayPickFilter::Flags hudMask = rayPick->getFilter().getHUDFlags(); if (!checkAndCompareCachedResults(rayKey, results, res, hudMask)) { glm::vec3 hudRes = DependencyManager::get()->calculateRayUICollisionPoint(ray.origin, ray.direction); - cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes), hudMask, res, rayKey, results); + cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudMask, res, rayKey, results); } } @@ -117,56 +118,39 @@ void RayPickManager::update() { if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) { rayPick->setRayPickResult(res); } else { - rayPick->setRayPickResult(RayPickResult()); - } - } - - QWriteLocker containsLock(&_containsLock); - { - QWriteLocker lock(&_addLock); - while (!_rayPicksToAdd.empty()) { - std::pair> rayPickToAdd = _rayPicksToAdd.front(); - _rayPicksToAdd.pop(); - _rayPicks[rayPickToAdd.first] = rayPickToAdd.second; - _rayPickLocks[rayPickToAdd.first] = std::make_shared(); - } - } - - { - QWriteLocker lock(&_removeLock); - while (!_rayPicksToRemove.empty()) { - QUuid uid = _rayPicksToRemove.front(); - _rayPicksToRemove.pop(); - _rayPicks.remove(uid); - _rayPickLocks.remove(uid); + rayPick->setRayPickResult(RayPickResult(ray)); } } } QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) { - QWriteLocker lock(&_addLock); + QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); - _rayPicksToAdd.push(std::pair>(id, std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled))); + _rayPicks[id] = std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled); + _rayPickLocks[id] = std::make_shared(); return id; } QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) { - QWriteLocker lock(&_addLock); + QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); - _rayPicksToAdd.push(std::pair>(id, std::make_shared(filter, maxDistance, enabled))); + _rayPicks[id] = std::make_shared(filter, maxDistance, enabled); + _rayPickLocks[id] = std::make_shared(); return id; } QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled) { - QWriteLocker lock(&_addLock); + QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); - _rayPicksToAdd.push(std::pair>(id, std::make_shared(position, direction, filter, maxDistance, enabled))); + _rayPicks[id] = std::make_shared(position, direction, filter, maxDistance, enabled); + _rayPickLocks[id] = std::make_shared(); return id; } void RayPickManager::removeRayPick(const QUuid uid) { - QWriteLocker lock(&_removeLock); - _rayPicksToRemove.push(uid); + QWriteLocker lock(&_containsLock); + _rayPicks.remove(uid); + _rayPickLocks.remove(uid); } void RayPickManager::enableRayPick(const QUuid uid) { @@ -185,18 +169,6 @@ void RayPickManager::disableRayPick(const QUuid uid) { } } -const PickRay RayPickManager::getPickRay(const QUuid uid) { - QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - bool valid; - PickRay pickRay = _rayPicks[uid]->getPickRay(valid); - if (valid) { - return pickRay; - } - } - return PickRay(); -} - const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { QReadLocker containsLock(&_containsLock); if (_rayPicks.contains(uid)) { diff --git a/interface/src/raypick/RayPickManager.h b/interface/src/raypick/RayPickManager.h index f2b1ff4ae4..9717767f19 100644 --- a/interface/src/raypick/RayPickManager.h +++ b/interface/src/raypick/RayPickManager.h @@ -28,7 +28,6 @@ class RayPickManager { public: void update(); - const PickRay getPickRay(const QUuid uid); QUuid createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled); QUuid createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled); @@ -49,10 +48,6 @@ public: private: QHash> _rayPicks; QHash> _rayPickLocks; - QReadWriteLock _addLock; - std::queue>> _rayPicksToAdd; - QReadWriteLock _removeLock; - std::queue _rayPicksToRemove; QReadWriteLock _containsLock; typedef QHash, std::unordered_map> RayPickCache; diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 8257c883a2..7d0df3ac78 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -762,6 +762,8 @@ QScriptValue rayPickResultToScriptValue(QScriptEngine* engine, const RayPickResu QScriptValue intersection = vec3toScriptValue(engine, rayPickResult.intersection); obj.setProperty("intersection", intersection); obj.setProperty("intersects", rayPickResult.type != NONE); + QScriptValue searchRay = pickRayToScriptValue(engine, rayPickResult.searchRay); + obj.setProperty("searchRay", searchRay); QScriptValue surfaceNormal = vec3toScriptValue(engine, rayPickResult.surfaceNormal); obj.setProperty("surfaceNormal", surfaceNormal); return obj; diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index ed928a6e7b..7b7d8d8f47 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -137,7 +137,7 @@ QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay); enum IntersectionType { - NONE, + NONE = 0, ENTITY, OVERLAY, AVATAR, @@ -147,12 +147,14 @@ enum IntersectionType { class RayPickResult { public: RayPickResult() {} - RayPickResult(const IntersectionType type, const QUuid& objectID, const float distance, const glm::vec3& intersection, const glm::vec3& surfaceNormal = glm::vec3(NAN)) : - type(type), objectID(objectID), distance(distance), intersection(intersection), surfaceNormal(surfaceNormal) {} + RayPickResult(const PickRay& searchRay) : searchRay(searchRay) {} + RayPickResult(const IntersectionType type, const QUuid& objectID, const float distance, const glm::vec3& intersection, const PickRay& searchRay, const glm::vec3& surfaceNormal = glm::vec3(NAN)) : + type(type), objectID(objectID), distance(distance), intersection(intersection), searchRay(searchRay), surfaceNormal(surfaceNormal) {} IntersectionType type { NONE }; - QUuid objectID { 0 }; + QUuid objectID; float distance { FLT_MAX }; glm::vec3 intersection { NAN }; + PickRay searchRay; glm::vec3 surfaceNormal { NAN }; }; Q_DECLARE_METATYPE(RayPickResult) From 702a4e9adeeff9fa0f6e4d4c0e601f1324fe83fb Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 22 Sep 2017 15:32:38 -0700 Subject: [PATCH 26/30] More tweaking to overlay position --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 3c0dc982a3..2366b888e7 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -15,6 +15,10 @@ #include #include +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + static const float CONTEXT_OVERLAY_TABLET_OFFSET = 30.0f; // Degrees static const float CONTEXT_OVERLAY_TABLET_ORIENTATION = 210.0f; // Degrees static const float CONTEXT_OVERLAY_TABLET_DISTANCE = 0.65F; // Meters @@ -66,7 +70,7 @@ static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 }; static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims static const float CONTEXT_OVERLAY_OFFSET_DISTANCE = 0.1f; -static const float CONTEXT_OVERLAY_OFFSET_ANGLE = 10.0f; +static const float CONTEXT_OVERLAY_OFFSET_ANGLE = 5.0f; static const float CONTEXT_OVERLAY_UNHOVERED_ALPHA = 0.85f; static const float CONTEXT_OVERLAY_HOVERED_ALPHA = 1.0f; static const float CONTEXT_OVERLAY_UNHOVERED_PULSEMIN = 0.6f; @@ -135,7 +139,8 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& if (event.getID() == LEFT_HAND_HW_ID) { offsetAngle *= -1; } - contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f)))) * ((cameraPosition + direction * distance) - direction * CONTEXT_OVERLAY_OFFSET_DISTANCE); + contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f)))) * + ((cameraPosition + direction * (distance - CONTEXT_OVERLAY_OFFSET_DISTANCE))); contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_SIZE, CONTEXT_OVERLAY_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); } From 0e3f1c514968ae166aa3ed178b07229f58e9eab2 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Sep 2017 16:11:24 -0700 Subject: [PATCH 27/30] add setLaserLength, setLockEndUUID doesn't use defaultRenderStates --- interface/src/raypick/LaserPointer.cpp | 6 ++++-- interface/src/raypick/LaserPointer.h | 2 ++ interface/src/raypick/LaserPointerManager.cpp | 8 ++++++++ interface/src/raypick/LaserPointerManager.h | 1 + interface/src/raypick/LaserPointerScriptingInterface.h | 1 + 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index afd2d14881..55ddd01123 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -184,8 +184,10 @@ void LaserPointer::disableRenderState(const RenderState& renderState) { void LaserPointer::update() { RayPickResult prevRayPickResult = DependencyManager::get()->getPrevRayPickResult(_rayPickUID); - if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && prevRayPickResult.type != IntersectionType::NONE) { - updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, prevRayPickResult.distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false); + if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && + (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { + float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance; + updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false); disableRenderState(_defaultRenderStates[_currentRenderState].second); } else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { disableRenderState(_renderStates[_currentRenderState]); diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 5c120d8d22..5467a8233e 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -65,6 +65,7 @@ public: void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps); void setPrecisionPicking(const bool precisionPicking) { DependencyManager::get()->setPrecisionPicking(_rayPickUID, precisionPicking); } + void setLaserLength(const float laserLength) { _laserLength = laserLength; } void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get()->setIgnoreEntities(_rayPickUID, ignoreEntities); } void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get()->setIncludeEntities(_rayPickUID, includeEntities); } void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { DependencyManager::get()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); } @@ -78,6 +79,7 @@ public: private: bool _renderingEnabled; + float _laserLength { 0.0f }; std::string _currentRenderState { "" }; RenderStateMap _renderStates; DefaultRenderStateMap _defaultRenderStates; diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index 9c4d38d260..b19ecc14f0 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -87,6 +87,14 @@ void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPic } } +void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { + QReadLocker lock(&_containsLock); + if (_laserPointers.contains(uid)) { + QWriteLocker laserLock(_laserPointerLocks[uid].get()); + _laserPointers[uid]->setLaserLength(laserLength); + } +} + void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { QReadLocker lock(&_containsLock); if (_laserPointers.contains(uid)) { diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index 381119507f..6494bb7056 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -32,6 +32,7 @@ public: const RayPickResult getPrevRayPickResult(const QUuid uid); void setPrecisionPicking(QUuid uid, const bool precisionPicking); + void setLaserLength(QUuid uid, const float laserLength); void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities); void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities); void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays); diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h index d65eb335b3..2f6da87b5f 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.h +++ b/interface/src/raypick/LaserPointerScriptingInterface.h @@ -31,6 +31,7 @@ public slots: Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); } Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking) { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); } + Q_INVOKABLE void setLaserLength(QUuid uid, const float laserLength) { qApp->getLaserPointerManager().setLaserLength(uid, laserLength); } Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); } Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { qApp->getLaserPointerManager().setIncludeEntities(uid, includeEntities); } Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { qApp->getLaserPointerManager().setIgnoreOverlays(uid, ignoreOverlays); } From 86198606e036f7f5cafbc75295983fd0c5421a5a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 22 Sep 2017 11:46:24 -0700 Subject: [PATCH 28/30] add _modelJustLoaded and updateTransforForSkinnedMesh on creation --- .../src/RenderableModelEntityItem.cpp | 12 ++++++++++++ .../src/RenderableModelEntityItem.h | 4 ++++ libraries/render-utils/src/MeshPartPayload.cpp | 8 ++++++++ libraries/render-utils/src/Model.cpp | 1 - 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a8a7dcdcf7..799a84aaee 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1032,6 +1032,10 @@ bool ModelEntityRenderer::needsUpdate() const { model = _model; }); + if (_modelJustLoaded) { + return true; + } + if (model) { if (_needsJointSimulation || _moving || _animating) { return true; @@ -1148,9 +1152,11 @@ void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& return; } + _modelJustLoaded = false; // Check for addition if (_hasModel && !(bool)_model) { model = std::make_shared(nullptr, entity.get()); + connect(model.get(), &Model::setURLFinished, this, &ModelEntityRenderer::handleModelLoaded); model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); model->init(); entity->setModel(model); @@ -1241,6 +1247,12 @@ void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& } } +void ModelEntityRenderer::handleModelLoaded(bool success) { + if (success) { + _modelJustLoaded = true; + } +} + // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items void ModelEntityRenderer::doRender(RenderArgs* args) { PROFILE_RANGE(render_detail, "MetaModelRender"); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index e2c7939845..ad0afeee0a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -151,6 +151,7 @@ private: // Transparency is handled in ModelMeshPartPayload virtual bool isTransparent() const override { return false; } + bool _modelJustLoaded { false }; bool _hasModel { false }; ::ModelPointer _model; GeometryResource::Pointer _compoundShapeResource; @@ -178,6 +179,9 @@ private: bool _animating { false }; uint64_t _lastAnimated { 0 }; float _currentFrame { 0 }; + +private slots: + void handleModelLoaded(bool success); }; } } // namespace diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 924c199239..3f57a1779a 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -328,10 +328,18 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in assert(model && model->isLoaded()); _model = model; auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex); + const Model::MeshState& state = model->getMeshState(_meshIndex); updateMeshPart(modelMesh, partIndex); + computeAdjustedLocalBound(state.clusterMatrices); updateTransform(transform, offsetTransform); + Transform renderTransform = transform; + if (state.clusterMatrices.size() == 1) { + renderTransform = transform.worldTransform(Transform(state.clusterMatrices[0])); + } + updateTransformForSkinnedMesh(renderTransform, transform, state.clusterBuffer); + initCache(); } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e729a9519b..9948a8bddd 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1265,7 +1265,6 @@ void Model::createVisibleRenderItemSet() { shapeID++; } } - computeMeshPartLocalBounds(); } void Model::createCollisionRenderItemSet() { From a73fdf439735fe44cdd386f30820e12d4f3ea55b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 25 Sep 2017 10:19:42 -0700 Subject: [PATCH 29/30] fix pointer event properties --- libraries/shared/src/PointerEvent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/PointerEvent.cpp b/libraries/shared/src/PointerEvent.cpp index 7ec5e78b9f..e35832391d 100644 --- a/libraries/shared/src/PointerEvent.cpp +++ b/libraries/shared/src/PointerEvent.cpp @@ -77,13 +77,13 @@ QScriptValue PointerEvent::toScriptValue(QScriptEngine* engine, const PointerEve normal.setProperty("x", event._normal.x); normal.setProperty("y", event._normal.y); normal.setProperty("z", event._normal.z); - obj.setProperty("pos3D", normal); + obj.setProperty("normal", normal); QScriptValue direction = engine->newObject(); direction.setProperty("x", event._direction.x); direction.setProperty("y", event._direction.y); direction.setProperty("z", event._direction.z); - obj.setProperty("pos3D", direction); + obj.setProperty("direction", direction); bool isPrimaryButton = false; bool isSecondaryButton = false; From 19a290be7046e7ea8aef540f84f49634f299ff08 Mon Sep 17 00:00:00 2001 From: Menithal Date: Mon, 25 Sep 2017 23:22:53 +0300 Subject: [PATCH 30/30] Fixed Entity Shader emmissive Makes sure that the emissiveAmount information is used correctly for a custom shader, instead of using specular rgb information to generate the emissiveness, which was incorrect --- libraries/render-utils/src/simple.slf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 228560f394..0dd10b8e1e 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -75,7 +75,7 @@ void main(void) { max(0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, - specular); + vec3(clamp(emissiveAmount, 0.0, 1.0))); } else { packDeferredFragment( normal,