From 8f25e54027bfaf9e858b4d131a546b839809189a Mon Sep 17 00:00:00 2001 From: James Pollack Date: Fri, 25 Sep 2015 18:34:34 -0700 Subject: [PATCH 01/81] Hoop, ball, ground --- examples/toys/basketball/createHoop.js | 101 +++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 examples/toys/basketball/createHoop.js diff --git a/examples/toys/basketball/createHoop.js b/examples/toys/basketball/createHoop.js new file mode 100644 index 0000000000..778c73915c --- /dev/null +++ b/examples/toys/basketball/createHoop.js @@ -0,0 +1,101 @@ +// +// createFlashlight.js +// examples/entityScripts +// +// Created by Sam Gateau on 9/9/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is a toy script that create a flashlight entity that lit when grabbed +// This can be run from an interface and the flashlight will get deleted from the domain when quitting +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +Script.include("../../utilities.js"); +Script.include("../../libraries/utils.js"); + +var groundURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; +var basketballURL = "https://hifi-public.s3.amazonaws.com/models/content/basketball2.fbx"; +var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_hoop_2.fbx"; +var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_basketball_hoop_collision_hull.obj"; +var ballCollisionSound = "https://hifi-public.s3.amazonaws.com/sounds/basketball/basketball.wav"; + +var basePosition = { + x: 0, + y: 0, + z: 0 +}; + +var hoopStartPosition = { + x: 0, + y: 3.25, + z: 0 +}; + + +var ground = Entities.addEntity({ + type: "Model", + modelURL: groundURL, + dimensions: { + x: 100, + y: 2, + z: 100 + }, + position: basePosition, + shapeType: 'box' +}); + +var BALL_DIAMETER = 0.30; +var DISTANCE_IN_FRONT_OF_ME = 1.0; + +var ballPosition = Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -DISTANCE_IN_FRONT_OF_ME + })); + +var ballRotation = Quat.multiply(MyAvatar.orientation, + Quat.fromPitchYawRollDegrees(0, -90, 0)); + +var basketball = Entities.addEntity({ + type: "Model", + position: ballPosition, + rotation: ballRotation, + dimensions: { + x: BALL_DIAMETER, + y: BALL_DIAMETER, + z: BALL_DIAMETER + }, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + collisionsWillMove: true, + collisionSoundURL: ballCollisionSound, + modelURL: basketballURL, + restitution: 1.0, + linearDamping: 0.00001, + shapeType: "sphere" +}); + + +var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: hoopStartPosition, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL +}); \ No newline at end of file From ade78fda9ec9e739a2d00e2ee56ecc5add5dbb59 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Mon, 28 Sep 2015 12:24:21 -0700 Subject: [PATCH 02/81] balls --- examples/toys/basketball/createHoop.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/toys/basketball/createHoop.js b/examples/toys/basketball/createHoop.js index 778c73915c..9a80ccaace 100644 --- a/examples/toys/basketball/createHoop.js +++ b/examples/toys/basketball/createHoop.js @@ -17,7 +17,7 @@ Script.include("../../libraries/utils.js"); var groundURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; var basketballURL = "https://hifi-public.s3.amazonaws.com/models/content/basketball2.fbx"; -var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_hoop_2.fbx"; +var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_hoop_3.fbx"; var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_basketball_hoop_collision_hull.obj"; var ballCollisionSound = "https://hifi-public.s3.amazonaws.com/sounds/basketball/basketball.wav"; @@ -98,4 +98,13 @@ var hoop = Entities.addEntity({ z: 3.79 }, compoundShapeURL: hoopCollisionHullURL -}); \ No newline at end of file +}); + + + +function cleanup() { + Entities.deleteEntity(basketball); + Entities.deleteEntity(hoop); + Entities.deleteEntity(ground); +} +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 5fc7965042a8b7aa4a3f2e61e134431eb3362bc4 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Sep 2015 13:04:58 -0700 Subject: [PATCH 03/81] Throw held objects with velocity from fingertip --- examples/controllers/handControllerGrab.js | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index a13f1de86d..975c1d2e0b 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -41,10 +41,10 @@ var LINE_LENGTH = 500; // var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected -var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position +var NEAR_GRABBING_ACTION_TIMEFRAME = 0.01; // how quickly objects move to their new position var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. var NEAR_PICK_MAX_DISTANCE = 0.6; // max length of pick-ray for close grabbing to be selected -var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things +var RELEASE_VELOCITY_MULTIPLIER = 1.0; // affects throwing things ///////////////////////////////////////////////////////////////// // @@ -86,7 +86,7 @@ function MyController(hand, triggerAction) { this.triggerAction = triggerAction; this.palm = 2 * hand; - // this.tip = 2 * hand + 1; // unused, but I'm leaving this here for fear it will be needed + this.tip = 2 * hand + 1; this.actionID = null; // action this script created... this.grabbedEntity = null; // on this entity. @@ -343,7 +343,8 @@ function MyController(hand, triggerAction) { } - this.currentHandControllerPosition = Controller.getSpatialControlPosition(this.palm); + this.currentHandControllerTipPosition = Controller.getSpatialControlPosition(this.tip); + this.currentObjectTime = Date.now(); }; @@ -353,15 +354,21 @@ function MyController(hand, triggerAction) { return; } - // keep track of the measured velocity of the held object - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); + // Keep track of the fingertip velocity to impart when we release the object + // Note that the idea of using a constant 'tip' velocity regardless of the + // object's actual held offset is an idea intended to make it easier to throw things: + // Because we might catch something or transfer it between hands without a good idea + // of it's actual offset, let's try imparting a velocity which is at a fixed radius + // from the palm. + + var handControllerPosition = Controller.getSpatialControlPosition(this.tip); var now = Date.now(); - var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerPosition); // meters + var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerTipPosition); // meters var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds this.computeReleaseVelocity(deltaPosition, deltaTime, true); - this.currentHandControllerPosition = handControllerPosition; + this.currentHandControllerTipPosition = handControllerPosition; this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); }; From afa179b9c44d06b56782e18f8dd9d9f587e0aa12 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Mon, 28 Sep 2015 15:08:48 -0700 Subject: [PATCH 04/81] hoop --- examples/toys/basketball/createHoop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/basketball/createHoop.js b/examples/toys/basketball/createHoop.js index 9a80ccaace..a4044d4adf 100644 --- a/examples/toys/basketball/createHoop.js +++ b/examples/toys/basketball/createHoop.js @@ -17,7 +17,7 @@ Script.include("../../libraries/utils.js"); var groundURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; var basketballURL = "https://hifi-public.s3.amazonaws.com/models/content/basketball2.fbx"; -var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_hoop_3.fbx"; +var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/basketball_hoop_10.fbx"; var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_basketball_hoop_collision_hull.obj"; var ballCollisionSound = "https://hifi-public.s3.amazonaws.com/sounds/basketball/basketball.wav"; From 5c7cf76035271ab53cf590d353204a1cb6f4848f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Sep 2015 16:13:35 -0700 Subject: [PATCH 05/81] Distance grab works with walking and turning --- examples/controllers/handControllerGrab.js | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 975c1d2e0b..011a9d434b 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -256,6 +256,9 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); } + this.currentAvatarPosition = MyAvatar.position; + this.currentAvatarOrientation = MyAvatar.orientation; + }; this.continueDistanceHolding = function() { @@ -274,11 +277,44 @@ function MyController(hand, triggerAction) { // the action was set up on a previous call. update the targets. var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR); + // how far did avatar move this timestep? + var currentPosition = MyAvatar.position; + var avatarDeltaPosition = Vec3.subtract(currentPosition, this.currentAvatarPosition); + this.currentAvatarPosition = currentPosition; + + // How far did the avatar turn this timestep? + // Note: The following code is too long because we need a Quat.quatBetween() function + // that returns the minimum quaternion between two quaternions. + var currentOrientation = MyAvatar.orientation; + if (Quat.dot(currentOrientation, this.currentAvatarOrientation) < 0.0) { + var negativeCurrentOrientation = { x: -currentOrientation.x, + y: -currentOrientation.y, + z: -currentOrientation.z, + w: -currentOrientation.w }; + var avatarDeltaOrientation = Quat.multiply(negativeCurrentOrientation, Quat.inverse(this.currentAvatarOrientation)); + } else { + var avatarDeltaOrientation = Quat.multiply(currentOrientation, Quat.inverse(this.currentAvatarOrientation)); + } + var handToAvatar = Vec3.subtract(handControllerPosition, this.currentAvatarPosition); + var objectToAvatar = Vec3.subtract(this.currentObjectPosition, this.currentAvatarPosition); + var handMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, handToAvatar), handToAvatar); + var objectMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, objectToAvatar), objectToAvatar); + this.currentAvatarOrientation = currentOrientation; + + // how far did hand move this timestep? var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; + + // magnify the hand movement but not the change from avatar movement & rotation + handMoved = Vec3.subtract(handMoved, avatarDeltaPosition); + handMoved = Vec3.subtract(handMoved, handMovementFromTurning); var superHandMoved = Vec3.multiply(handMoved, radius); + // Move the object by the magnified amount and then by amount from avatar movement & rotation var newObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved); + newObjectPosition = Vec3.sum(newObjectPosition, avatarDeltaPosition); + newObjectPosition = Vec3.sum(newObjectPosition, objectMovementFromTurning); + var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters var now = Date.now(); var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds From 7b1c04512a34258c7c8ffccb80c9f4a416424160 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 28 Sep 2015 16:20:27 -0700 Subject: [PATCH 06/81] Adding support for accessing IPD in scripts --- examples/example/hmd/colorCube.fs | 10 ++++ examples/example/hmd/colorCube.js | 52 +++++++++++++++++++ .../src/scripting/HMDScriptingInterface.cpp | 6 ++- .../src/scripting/HMDScriptingInterface.h | 2 + .../src/display-plugins/DisplayPlugin.h | 4 ++ .../oculus/OculusBaseDisplayPlugin.cpp | 8 +++ .../oculus/OculusBaseDisplayPlugin.h | 1 + libraries/render-utils/src/simple.slf | 1 + libraries/render-utils/src/simple.slv | 2 + 9 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 examples/example/hmd/colorCube.fs create mode 100644 examples/example/hmd/colorCube.js diff --git a/examples/example/hmd/colorCube.fs b/examples/example/hmd/colorCube.fs new file mode 100644 index 0000000000..2687b70807 --- /dev/null +++ b/examples/example/hmd/colorCube.fs @@ -0,0 +1,10 @@ + +float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) { + + specular = _modelNormal.rgb; + if (any(lessThan(specular, vec3(0.0)))) { + specular = vec3(1.0) + specular; + } + diffuse = vec3(1.0, 1.0, 1.0); + return 1.0; +} \ No newline at end of file diff --git a/examples/example/hmd/colorCube.js b/examples/example/hmd/colorCube.js new file mode 100644 index 0000000000..b36fa6362b --- /dev/null +++ b/examples/example/hmd/colorCube.js @@ -0,0 +1,52 @@ +function avatarRelativePosition(position) { + return Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, position)); +} + +ColorCube = function() {}; +ColorCube.prototype.NAME = "ColorCube"; +ColorCube.prototype.POSITION = { x: 0, y: 0.5, z: -0.5 }; +ColorCube.prototype.USER_DATA = { ProceduralEntity: { + version: 2, shaderUrl: Script.resolvePath("colorCube.fs"), +} }; + +// Clear any previous entities within 50 meters +ColorCube.prototype.clear = function() { + var ids = Entities.findEntities(MyAvatar.position, 50); + var that = this; + ids.forEach(function(id) { + var properties = Entities.getEntityProperties(id); + if (properties.name == that.NAME) { + Entities.deleteEntity(id); + } + }, this); +} + +ColorCube.prototype.create = function() { + var that = this; + var size = HMD.ipd; + var id = Entities.addEntity({ + type: "Box", + position: avatarRelativePosition(that.POSITION), + name: that.NAME, + color: that.COLOR, + ignoreCollisions: true, + collisionsWillMove: false, + dimensions: { x: size, y: size, z: size }, + lifetime: 3600, + userData: JSON.stringify(that.USER_DATA) + }); +} + +var ColorCube = new ColorCube(); +ColorCube.clear(); +ColorCube.create(); + + +var ids = Entities.findEntities(MyAvatar.position, 50); +var that = this; +ids.forEach(function(id) { + var properties = Entities.getEntityProperties(id); + if (properties.name == that.NAME) { + Entities.deleteEntity(id); + } +}, this); diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index f65d638ccc..68ac511eaf 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -10,7 +10,7 @@ // #include "HMDScriptingInterface.h" - +#include "display-plugins/DisplayPlugin.h" #include HMDScriptingInterface& HMDScriptingInterface::getInstance() { @@ -53,3 +53,7 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* conte } return QScriptValue::NullValue; } + +float HMDScriptingInterface::getIPD() const { + return Application::getInstance()->getActiveDisplayPlugin()->getIPD(); +} diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 4bcced1fa2..82b444abaa 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -20,6 +20,7 @@ class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) + Q_PROPERTY(float ipd READ getIPD) public: static HMDScriptingInterface& getInstance(); @@ -33,6 +34,7 @@ private: HMDScriptingInterface() {}; bool getMagnifier() const { return Application::getInstance()->getApplicationCompositor().hasMagnifier(); }; bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } + float getIPD() const; bool getHUDLookAtPosition3D(glm::vec3& result) const; diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h index 86cfabe724..2aaf4ddbc5 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -121,6 +121,10 @@ public: static const glm::mat4 pose; return pose; } + virtual float getIPD() const { + return 0.0f; + } + virtual void abandonCalibration() {} virtual void resetSensors() {} virtual float devicePixelRatio() { return 1.0; } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp index fa9d09e392..f2a7b06510 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp @@ -149,3 +149,11 @@ void OculusBaseDisplayPlugin::deactivate() { void OculusBaseDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) { ++_frameIndex; } + +float OculusBaseDisplayPlugin::getIPD() const { + float result = 0.0f; +#if (OVR_MAJOR_VERSION >= 6) + result = ovr_GetFloat(_hmd, OVR_KEY_IPD, OVR_DEFAULT_IPD); +#endif + return result; +} \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h index 12023db1ae..d879085b8f 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h @@ -31,6 +31,7 @@ public: virtual void resetSensors() override final; virtual glm::mat4 getEyePose(Eye eye) const override final; virtual glm::mat4 getHeadPose() const override final; + virtual float getIPD() const override final; protected: virtual void preRender() override final; diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 5901a72838..576acf9340 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -17,6 +17,7 @@ // the interpolated normal in vec3 _normal; +in vec3 _modelNormal; in vec3 _color; in vec2 _texCoord0; in vec4 _position; diff --git a/libraries/render-utils/src/simple.slv b/libraries/render-utils/src/simple.slv index e7fed4a6b4..823654ec27 100644 --- a/libraries/render-utils/src/simple.slv +++ b/libraries/render-utils/src/simple.slv @@ -22,6 +22,7 @@ uniform bool Instanced = false; // the interpolated normal out vec3 _normal; +out vec3 _modelNormal; out vec3 _color; out vec2 _texCoord0; out vec4 _position; @@ -30,6 +31,7 @@ void main(void) { _color = inColor.rgb; _texCoord0 = inTexCoord0.st; _position = inPosition; + _modelNormal = inNormal.xyz; // standard transform TransformCamera cam = getTransformCamera(); From 56a0456f705e634b6889f5b2967406aef784a8bf Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Sep 2015 16:49:55 -0700 Subject: [PATCH 07/81] Adjust force multiplier and timestep --- examples/controllers/handControllerGrab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 011a9d434b..024b40a885 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -41,10 +41,10 @@ var LINE_LENGTH = 500; // var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected -var NEAR_GRABBING_ACTION_TIMEFRAME = 0.01; // how quickly objects move to their new position +var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. var NEAR_PICK_MAX_DISTANCE = 0.6; // max length of pick-ray for close grabbing to be selected -var RELEASE_VELOCITY_MULTIPLIER = 1.0; // affects throwing things +var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things ///////////////////////////////////////////////////////////////// // From 4c86b1ce03abf3dd92e4c887455f872a3f39ede4 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Sep 2015 18:47:32 -0700 Subject: [PATCH 08/81] ballin --- examples/toys/basketball/createHoop.js | 59 ++++++++++++++------------ 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/examples/toys/basketball/createHoop.js b/examples/toys/basketball/createHoop.js index 778c73915c..bd3fc32411 100644 --- a/examples/toys/basketball/createHoop.js +++ b/examples/toys/basketball/createHoop.js @@ -15,40 +15,40 @@ Script.include("../../utilities.js"); Script.include("../../libraries/utils.js"); -var groundURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; +var courtURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; var basketballURL = "https://hifi-public.s3.amazonaws.com/models/content/basketball2.fbx"; -var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_hoop_2.fbx"; -var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_basketball_hoop_collision_hull.obj"; var ballCollisionSound = "https://hifi-public.s3.amazonaws.com/sounds/basketball/basketball.wav"; - -var basePosition = { - x: 0, - y: 0, - z: 0 -}; - -var hoopStartPosition = { - x: 0, - y: 3.25, - z: 0 -}; - - -var ground = Entities.addEntity({ - type: "Model", - modelURL: groundURL, - dimensions: { - x: 100, - y: 2, - z: 100 - }, - position: basePosition, - shapeType: 'box' -}); +var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; +var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; var BALL_DIAMETER = 0.30; var DISTANCE_IN_FRONT_OF_ME = 1.0; +var hoopStartPosition = + Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -DISTANCE_IN_FRONT_OF_ME * 2 + })); + +// courtStartPosition.y = hoopStartPosition.y - 2 + + +// var court = Entities.addEntity({ +// type: "Model", +// modelURL: courtURL, +// dimensions: { +// x: 28.65, +// y: 0.02, +// z: 15.24 +// }, +// position: courtStartPosition, +// shapeType: 'box' +// }); + + + var ballPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, @@ -56,6 +56,8 @@ var ballPosition = Vec3.sum(MyAvatar.position, z: -DISTANCE_IN_FRONT_OF_ME })); + + var ballRotation = Quat.multiply(MyAvatar.orientation, Quat.fromPitchYawRollDegrees(0, -90, 0)); @@ -92,6 +94,7 @@ var hoop = Entities.addEntity({ y: -9.8, z: 0 }, + // rotation: Quat.fromPitchYawRollDegrees(0, -90, 0)), dimensions: { x: 1.89, y: 3.99, From 35e4ec17ea2ccbe8a135b6cf9c15c01b33e20798 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 10:35:38 -0700 Subject: [PATCH 09/81] add which hand for near grab of non physical objects --- examples/controllers/handControllerGrab.js | 31 ++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 41f36c19d5..1b891f56b5 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -29,9 +29,21 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255}; // line color when pick misses -var INTERSECT_COLOR = { red: 250, green: 10, blue: 10}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000, z: 1000}; +var NO_INTERSECT_COLOR = { + red: 10, + green: 10, + blue: 255 +}; // line color when pick misses +var INTERSECT_COLOR = { + red: 250, + green: 10, + blue: 10 +}; // line color when pick hits +var LINE_ENTITY_DIMENSIONS = { + x: 1000, + y: 1000, + z: 1000 +}; var LINE_LENGTH = 500; @@ -54,7 +66,11 @@ var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var RIGHT_HAND = 1; var LEFT_HAND = 0; -var ZERO_VEC = { x: 0, y: 0, z: 0}; +var ZERO_VEC = { + x: 0, + y: 0, + z: 0 +}; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; @@ -391,6 +407,11 @@ function MyController(hand, triggerAction) { this.state = STATE_RELEASE; return; } + if (this.hand === RIGHT_HAND) { + Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); + } else { + Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); + } Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding"); this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; }; @@ -546,4 +567,4 @@ function cleanup() { } Script.scriptEnding.connect(cleanup); -Script.update.connect(update); +Script.update.connect(update); \ No newline at end of file From 745a59af1c8fd6644e282e122943ee12d0593e2f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 29 Sep 2015 12:48:57 -0700 Subject: [PATCH 10/81] Default animation is anim graph. Remove state change logging from animation graph state machine. --- interface/src/Menu.cpp | 4 ++-- interface/src/avatar/MyAvatar.cpp | 3 ++- libraries/animation/src/AnimStateMachine.cpp | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5793510fb5..96f640b96e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -446,9 +446,9 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::FixGaze, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableAvatarUpdateThreading, 0, false, qApp, SLOT(setAvatarUpdateThreading(bool))); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableRigAnimations, 0, true, + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableRigAnimations, 0, false, avatar, SLOT(setEnableRigAnimations(bool))); - addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableAnimGraph, 0, false, + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableAnimGraph, 0, true, avatar, SLOT(setEnableAnimGraph(bool))); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AnimDebugDrawBindPose, 0, false, avatar, SLOT(setEnableDebugDrawBindPose(bool))); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 16964735da..514a6f9aaa 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -153,7 +153,8 @@ void MyAvatar::reset() { // This should be simpler when we have only graph animations always on. bool isRig = _rig->getEnableRig(); - bool isGraph = _rig->getEnableAnimGraph(); + // seting rig animation to true, below, will clear the graph animation menu item, so grab it now. + bool isGraph = _rig->getEnableAnimGraph() || Menu::getInstance()->isOptionChecked(MenuOption::EnableAnimGraph); qApp->setRawAvatarUpdateThreading(false); _rig->disableHands = true; setEnableRigAnimations(true); diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 758067343d..5304cefe46 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -93,9 +93,9 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, State::Pointe const float dt = 0.0f; Triggers triggers; _nextPoses = nextStateNode->evaluate(animVars, dt, triggers); - +#if WANT_DEBUGa qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID() << "duration =" << duration << "targetFrame =" << desiredState->_interpTarget; - +#endif _currentState = desiredState; } From 06194b6088cdf779fdb644dbb7ba803222827fc4 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 12:51:01 -0700 Subject: [PATCH 11/81] fixed formatting --- examples/controllers/handControllerGrab.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 1b891f56b5..52b1e94e4b 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -29,21 +29,9 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = { - red: 10, - green: 10, - blue: 255 -}; // line color when pick misses -var INTERSECT_COLOR = { - red: 250, - green: 10, - blue: 10 -}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = { - x: 1000, - y: 1000, - z: 1000 -}; +var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255 }; // line color when pick misses +var INTERSECT_COLOR = { red: 250, green: 10, blue: 10}; // line color when pick hits +var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000, z: 1000}; var LINE_LENGTH = 500; From 96e3c722ed2f0df97012ba840fe3dd30bb026343 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 29 Sep 2015 13:04:59 -0700 Subject: [PATCH 12/81] Quiet once/second logging/updating of other people's default avatars. --- libraries/avatars/src/AvatarData.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 104b592c1a..3bd147d398 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -989,8 +989,11 @@ void AvatarData::setFaceModelURL(const QUrl& faceModelURL) { } void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { - _skeletonModelURL = skeletonModelURL.isEmpty() ? AvatarData::defaultFullAvatarModelUrl() : skeletonModelURL; - + const QUrl& expanded = skeletonModelURL.isEmpty() ? AvatarData::defaultFullAvatarModelUrl() : skeletonModelURL; + if (expanded == _skeletonModelURL) { + return; + } + _skeletonModelURL = expanded; qCDebug(avatars) << "Changing skeleton model for avatar to" << _skeletonModelURL.toString(); updateJointMappings(); From fdb94555401b2435260567cddda994fe692ca37b Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 13:12:55 -0700 Subject: [PATCH 13/81] debug --- examples/acScripts/flickeringLight.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index edf8332eb5..ea7f7f9c68 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -77,6 +77,7 @@ function update(deltaTime) { var intensity = (MINIMUM_LIGHT_INTENSITY + (MAXIMUM_LIGHT_INTENSITY + (Math.sin(totalTime) * MAXIMUM_LIGHT_INTENSITY))); intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); var properties = Entities.getEntityProperties(LightMaker.light, "age"); + print("age:" + properties.age); Entities.editEntity(LightMaker.light, { intensity: intensity, lifetime: properties.age + EPHEMERAL_LIFETIME }); } } From 49da3c503431f32adecfa0148d876279eecb9ccd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 13:24:03 -0700 Subject: [PATCH 14/81] disable avatar collisions while holding something --- examples/controllers/handControllerGrab.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 41f36c19d5..0b9e609c77 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -244,6 +244,10 @@ function MyController(hand, triggerAction) { }; this.distanceHolding = function() { + + this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); + Menu.setIsOptionChecked("Enable avatar collisions", false); + var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); @@ -323,6 +327,10 @@ function MyController(hand, triggerAction) { }; this.nearGrabbing = function() { + + this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); + Menu.setIsOptionChecked("Enable avatar collisions", false); + if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -491,6 +499,9 @@ function MyController(hand, triggerAction) { }; this.release = function() { + + Menu.setIsOptionChecked("Enable avatar collisions", this.previousAvCollision); + this.lineOff(); if (this.grabbedEntity !== null && this.actionID !== null) { From cbd55ddba62cfa4558df3459a9cb9834a55aea18 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Tue, 29 Sep 2015 13:24:49 -0700 Subject: [PATCH 15/81] Add the hoop --- examples/toys/basketball/createHoop.js | 113 -------------------- examples/toys/basketball_hoop/createHoop.js | 49 +++++++++ 2 files changed, 49 insertions(+), 113 deletions(-) delete mode 100644 examples/toys/basketball/createHoop.js create mode 100644 examples/toys/basketball_hoop/createHoop.js diff --git a/examples/toys/basketball/createHoop.js b/examples/toys/basketball/createHoop.js deleted file mode 100644 index 7af54767f3..0000000000 --- a/examples/toys/basketball/createHoop.js +++ /dev/null @@ -1,113 +0,0 @@ -// -// createFlashlight.js -// examples/entityScripts -// -// Created by Sam Gateau on 9/9/15. -// Copyright 2015 High Fidelity, Inc. -// -// This is a toy script that create a flashlight entity that lit when grabbed -// This can be run from an interface and the flashlight will get deleted from the domain when quitting -//a -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -Script.include("../../utilities.js"); -Script.include("../../libraries/utils.js"); - -var courtURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; -var basketballURL = "https://hifi-public.s3.amazonaws.com/models/content/basketball2.fbx"; -var ballCollisionSound = "https://hifi-public.s3.amazonaws.com/sounds/basketball/basketball.wav"; -var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; -var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; - -var BALL_DIAMETER = 0.30; -var DISTANCE_IN_FRONT_OF_ME = 1.0; - -var hoopStartPosition = - Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, { - x: 0, - y: 0.0, - z: -DISTANCE_IN_FRONT_OF_ME * 2 - })); - -// courtStartPosition.y = hoopStartPosition.y - 2 - - -// var court = Entities.addEntity({ -// type: "Model", -// modelURL: courtURL, -// dimensions: { -// x: 28.65, -// y: 0.02, -// z: 15.24 -// }, -// position: courtStartPosition, -// shapeType: 'box' -// }); - - - -var ballPosition = Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, { - x: 0, - y: 0.0, - z: -DISTANCE_IN_FRONT_OF_ME - })); - - - -var ballRotation = Quat.multiply(MyAvatar.orientation, - Quat.fromPitchYawRollDegrees(0, -90, 0)); - -var basketball = Entities.addEntity({ - type: "Model", - position: ballPosition, - rotation: ballRotation, - dimensions: { - x: BALL_DIAMETER, - y: BALL_DIAMETER, - z: BALL_DIAMETER - }, - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - collisionsWillMove: true, - collisionSoundURL: ballCollisionSound, - modelURL: basketballURL, - restitution: 1.0, - linearDamping: 0.00001, - shapeType: "sphere" -}); - - -var hoop = Entities.addEntity({ - type: "Model", - modelURL: hoopURL, - position: hoopStartPosition, - shapeType: 'compound', - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - // rotation: Quat.fromPitchYawRollDegrees(0, -90, 0)), - dimensions: { - x: 1.89, - y: 3.99, - z: 3.79 - }, - compoundShapeURL: hoopCollisionHullURL -}); - - - -function cleanup() { - Entities.deleteEntity(basketball); - Entities.deleteEntity(hoop); - // Entities.deleteEntity(court); -} -Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/toys/basketball_hoop/createHoop.js b/examples/toys/basketball_hoop/createHoop.js new file mode 100644 index 0000000000..26fb7347d1 --- /dev/null +++ b/examples/toys/basketball_hoop/createHoop.js @@ -0,0 +1,49 @@ +// +// createHoop.js +// examples/entityScripts +// +// Created by James B. Pollack on 9/29/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This is a script that creates a persistent basketball hoop with a working collision hull. Feel free to move it. +// Run basketball.js to make a basketball. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +Script.include("../../utilities.js"); +Script.include("../../libraries/utils.js"); + +var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; +var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; + + +var DISTANCE_IN_FRONT_OF_ME = 1.0; + +var hoopStartPosition = + Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -DISTANCE_IN_FRONT_OF_ME * 2 + })); + + +var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: hoopStartPosition, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL +}); \ No newline at end of file From 4abb2517289c561101120a744def2b05d1e02c26 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 13:28:45 -0700 Subject: [PATCH 16/81] more debug --- examples/acScripts/flickeringLight.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index ea7f7f9c68..93264e192c 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -76,9 +76,13 @@ function update(deltaTime) { totalTime += deltaTime; var intensity = (MINIMUM_LIGHT_INTENSITY + (MAXIMUM_LIGHT_INTENSITY + (Math.sin(totalTime) * MAXIMUM_LIGHT_INTENSITY))); intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); - var properties = Entities.getEntityProperties(LightMaker.light, "age"); + var properties = Entities.getEntityProperties(LightMaker.light, ["age", "lifetime"]); + print("props:" +JSON.stringify(properties)); print("age:" + properties.age); - Entities.editEntity(LightMaker.light, { intensity: intensity, lifetime: properties.age + EPHEMERAL_LIFETIME }); + print("lifetime:" + properties.lifetime); + var newLifetime = properties.age + EPHEMERAL_LIFETIME; + print("newLifetime:" + newLifetime); + Entities.editEntity(LightMaker.light, { intensity : intensity, lifetime: newLifetime }); } } From 9c199b23a2b9b4240dba1b5bce535783fb9f64dc Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 13:32:28 -0700 Subject: [PATCH 17/81] more debug --- examples/acScripts/flickeringLight.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index 93264e192c..571684b385 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -77,12 +77,12 @@ function update(deltaTime) { var intensity = (MINIMUM_LIGHT_INTENSITY + (MAXIMUM_LIGHT_INTENSITY + (Math.sin(totalTime) * MAXIMUM_LIGHT_INTENSITY))); intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); var properties = Entities.getEntityProperties(LightMaker.light, ["age", "lifetime"]); - print("props:" +JSON.stringify(properties)); - print("age:" + properties.age); - print("lifetime:" + properties.lifetime); + //print("props:" +JSON.stringify(properties)); + //print("age:" + properties.age); + //print("lifetime:" + properties.lifetime); var newLifetime = properties.age + EPHEMERAL_LIFETIME; - print("newLifetime:" + newLifetime); - Entities.editEntity(LightMaker.light, { intensity : intensity, lifetime: newLifetime }); + //print("newLifetime:" + newLifetime); + Entities.editEntity(LightMaker.light, { type: "Light", intensity : intensity, lifetime: newLifetime }); } } From 6a01c10453bfa1dfe73c0be014d15c209ced83c3 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 13:35:16 -0700 Subject: [PATCH 18/81] more debug --- examples/acScripts/flickeringLight.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index 571684b385..03ea4681ef 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -78,10 +78,10 @@ function update(deltaTime) { intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); var properties = Entities.getEntityProperties(LightMaker.light, ["age", "lifetime"]); //print("props:" +JSON.stringify(properties)); - //print("age:" + properties.age); - //print("lifetime:" + properties.lifetime); + print("age:" + properties.age); + print("lifetime:" + properties.lifetime); var newLifetime = properties.age + EPHEMERAL_LIFETIME; - //print("newLifetime:" + newLifetime); + print("newLifetime:" + newLifetime); Entities.editEntity(LightMaker.light, { type: "Light", intensity : intensity, lifetime: newLifetime }); } } From f4bc3f8e388a6b38456f880dd7a3904150dae072 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 29 Sep 2015 16:35:24 -0400 Subject: [PATCH 19/81] fix a timer leak, line width in PacketList --- libraries/networking/src/ThreadedAssignment.cpp | 5 +++-- libraries/networking/src/udt/PacketList.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 5f0db9412c..0422c03297 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -49,7 +49,8 @@ void ThreadedAssignment::setFinished(bool isFinished) { } if (_statsTimer) { - _statsTimer->stop(); + _statsTimer->deleteLater(); + _statsTimer = nullptr; } // call our virtual aboutToFinish method - this gives the ThreadedAssignment subclass a chance to cleanup @@ -105,7 +106,7 @@ void ThreadedAssignment::sendStatsPacket() { void ThreadedAssignment::startSendingStats() { // send the stats packet every 1s if (!_statsTimer) { - _statsTimer = new QTimer(); + _statsTimer = new QTimer; connect(_statsTimer, &QTimer::timeout, this, &ThreadedAssignment::sendStatsPacket); } diff --git a/libraries/networking/src/udt/PacketList.h b/libraries/networking/src/udt/PacketList.h index ae783dabe3..7978e77ad7 100644 --- a/libraries/networking/src/udt/PacketList.h +++ b/libraries/networking/src/udt/PacketList.h @@ -28,7 +28,8 @@ class Packet; class PacketList : public QIODevice { Q_OBJECT public: - static std::unique_ptr create(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false); + static std::unique_ptr create(PacketType packetType, QByteArray extendedHeader = QByteArray(), + bool isReliable = false, bool isOrdered = false); static std::unique_ptr fromReceivedPackets(std::list>&& packets); bool isReliable() const { return _isReliable; } From f7b34f63c10d732bc8f06e87c5bfb97f23904ea1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 13:40:54 -0700 Subject: [PATCH 20/81] try calling updateMotionBehaviorFromMenu --- examples/controllers/handControllerGrab.js | 4 ++++ interface/src/avatar/MyAvatar.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 0b9e609c77..4339c92f28 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -247,6 +247,8 @@ function MyController(hand, triggerAction) { this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); Menu.setIsOptionChecked("Enable avatar collisions", false); + MyAvatar.updateMotionBehaviorFromMenu(); + var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); @@ -330,6 +332,7 @@ function MyController(hand, triggerAction) { this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); Menu.setIsOptionChecked("Enable avatar collisions", false); + MyAvatar.updateMotionBehaviorFromMenu(); if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; @@ -501,6 +504,7 @@ function MyController(hand, triggerAction) { this.release = function() { Menu.setIsOptionChecked("Enable avatar collisions", this.previousAvCollision); + MyAvatar.updateMotionBehaviorFromMenu(); this.lineOff(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index bbc0667015..6efec3be13 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -193,7 +193,7 @@ public slots: glm::vec3 getThrust() { return _thrust; }; void setThrust(glm::vec3 newThrust) { _thrust = newThrust; } - void updateMotionBehaviorFromMenu(); + Q_INVOKABLE void updateMotionBehaviorFromMenu(); glm::vec3 getLeftPalmPosition(); glm::vec3 getLeftPalmVelocity(); From e9dd165b1dc89d91b0d2f585604f60559f2d4756 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 14:00:22 -0700 Subject: [PATCH 21/81] try calling updateMotionBehaviorFromMenu --- examples/controllers/handControllerGrab.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 4339c92f28..d6603a7887 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -92,7 +92,7 @@ function MyController(hand, triggerAction) { this.actionID = null; // action this script created... this.grabbedEntity = null; // on this entity. this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity - this.state = 0; + this.state = STATE_SEARCHING; this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value var _this = this; @@ -247,6 +247,7 @@ function MyController(hand, triggerAction) { this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); Menu.setIsOptionChecked("Enable avatar collisions", false); + print("avatar collisions -->" + this.previousAvCollision); MyAvatar.updateMotionBehaviorFromMenu(); @@ -332,6 +333,7 @@ function MyController(hand, triggerAction) { this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); Menu.setIsOptionChecked("Enable avatar collisions", false); + print("avatar collisions -->" + this.previousAvCollision); MyAvatar.updateMotionBehaviorFromMenu(); if (!this.triggerSmoothedSqueezed()) { @@ -504,6 +506,7 @@ function MyController(hand, triggerAction) { this.release = function() { Menu.setIsOptionChecked("Enable avatar collisions", this.previousAvCollision); + print("avatar collisions -->" + this.previousAvCollision); MyAvatar.updateMotionBehaviorFromMenu(); this.lineOff(); From 644687f3303bdff30dd9ead7e246836cc4513569 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 14:04:03 -0700 Subject: [PATCH 22/81] releaseGrab event now triggered for non physical entities --- examples/controllers/handControllerGrab.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 52b1e94e4b..ea22d77bbc 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -29,7 +29,7 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255 }; // line color when pick misses +var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255}; // line color when pick misses var INTERSECT_COLOR = { red: 250, green: 10, blue: 10}; // line color when pick hits var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000, z: 1000}; var LINE_LENGTH = 500; @@ -502,8 +502,10 @@ function MyController(hand, triggerAction) { this.release = function() { this.lineOff(); - if (this.grabbedEntity !== null && this.actionID !== null) { - Entities.deleteAction(this.grabbedEntity, this.actionID); + if (this.grabbedEntity !== null) { + if(this.actionID !== null) { + Entities.deleteAction(this.grabbedEntity, this.actionID); + } Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); } From 9b13aac37db162a126b7ae1bcf51fa79d50959d6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 29 Sep 2015 14:23:56 -0700 Subject: [PATCH 23/81] PR comments --- examples/example/hmd/colorCube.js | 16 +++------------- .../src/display-plugins/DisplayPlugin.h | 4 +--- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/examples/example/hmd/colorCube.js b/examples/example/hmd/colorCube.js index b36fa6362b..a138f38190 100644 --- a/examples/example/hmd/colorCube.js +++ b/examples/example/hmd/colorCube.js @@ -37,16 +37,6 @@ ColorCube.prototype.create = function() { }); } -var ColorCube = new ColorCube(); -ColorCube.clear(); -ColorCube.create(); - - -var ids = Entities.findEntities(MyAvatar.position, 50); -var that = this; -ids.forEach(function(id) { - var properties = Entities.getEntityProperties(id); - if (properties.name == that.NAME) { - Entities.deleteEntity(id); - } -}, this); +var colorCube = new ColorCube(); +colorCube.clear(); +colorCube.create(); diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h index 2aaf4ddbc5..8b9d249bd4 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -121,9 +121,7 @@ public: static const glm::mat4 pose; return pose; } - virtual float getIPD() const { - return 0.0f; - } + virtual float getIPD() const { return 0.0f; } virtual void abandonCalibration() {} virtual void resetSensors() {} From b9a83be4d33f8ddc1d1e4dacde414467acce0c2f Mon Sep 17 00:00:00 2001 From: James Pollack Date: Tue, 29 Sep 2015 14:31:13 -0700 Subject: [PATCH 24/81] cleanup --- examples/toys/basketball_hoop/createHoop.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/examples/toys/basketball_hoop/createHoop.js b/examples/toys/basketball_hoop/createHoop.js index 26fb7347d1..3887e0b421 100644 --- a/examples/toys/basketball_hoop/createHoop.js +++ b/examples/toys/basketball_hoop/createHoop.js @@ -10,26 +10,19 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -Script.include("../../utilities.js"); -Script.include("../../libraries/utils.js"); var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; - -var DISTANCE_IN_FRONT_OF_ME = 1.0; - var hoopStartPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.0, - z: -DISTANCE_IN_FRONT_OF_ME * 2 + z: -2 })); - var hoop = Entities.addEntity({ type: "Model", modelURL: hoopURL, @@ -46,4 +39,5 @@ var hoop = Entities.addEntity({ z: 3.79 }, compoundShapeURL: hoopCollisionHullURL -}); \ No newline at end of file +}); + From 006650f23bba7672bbeb81063948a76280c23291 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Sep 2015 14:34:23 -0700 Subject: [PATCH 25/81] Fix for PR comments --- examples/controllers/handControllerGrab.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 024b40a885..4b1d6e9648 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -84,9 +84,11 @@ function MyController(hand, triggerAction) { this.getHandRotation = MyAvatar.getLeftPalmRotation; } + var SPATIAL_CONTROLLERS_PER_PALM = 2; + var TIP_CONTROLLER_OFFSET = 1; this.triggerAction = triggerAction; - this.palm = 2 * hand; - this.tip = 2 * hand + 1; + this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; + this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; this.actionID = null; // action this script created... this.grabbedEntity = null; // on this entity. @@ -287,10 +289,12 @@ function MyController(hand, triggerAction) { // that returns the minimum quaternion between two quaternions. var currentOrientation = MyAvatar.orientation; if (Quat.dot(currentOrientation, this.currentAvatarOrientation) < 0.0) { - var negativeCurrentOrientation = { x: -currentOrientation.x, - y: -currentOrientation.y, - z: -currentOrientation.z, - w: -currentOrientation.w }; + var negativeCurrentOrientation = { + x: -currentOrientation.x, + y: -currentOrientation.y, + z: -currentOrientation.z, + w: -currentOrientation.w + }; var avatarDeltaOrientation = Quat.multiply(negativeCurrentOrientation, Quat.inverse(this.currentAvatarOrientation)); } else { var avatarDeltaOrientation = Quat.multiply(currentOrientation, Quat.inverse(this.currentAvatarOrientation)); @@ -482,17 +486,14 @@ function MyController(hand, triggerAction) { }; this.startTouch = function(entityID) { - // print('START TOUCH' + entityID); Entities.callEntityMethod(entityID, "startTouch"); }; this.continueTouch = function(entityID) { - // print('CONTINUE TOUCH' + entityID); Entities.callEntityMethod(entityID, "continueTouch"); }; this.stopTouch = function(entityID) { - // print('STOP TOUCH' + entityID); Entities.callEntityMethod(entityID, "stopTouch"); }; From b1a133e55c188325b714e7a846c03a0c56e47226 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 14:38:47 -0700 Subject: [PATCH 26/81] working on disabling avatar collisions during grab --- examples/controllers/handControllerGrab.js | 87 +++++++++++++++------- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index d6603a7887..0c042a1f22 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -9,7 +9,6 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ Script.include("../libraries/utils.js"); @@ -63,18 +62,22 @@ var startTime = Date.now(); var LIFETIME = 10; // states for the state machine -var STATE_SEARCHING = 0; -var STATE_DISTANCE_HOLDING = 1; -var STATE_CONTINUE_DISTANCE_HOLDING = 2; -var STATE_NEAR_GRABBING = 3; -var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_NEAR_GRABBING_NON_COLLIDING = 5; -var STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING = 6; -var STATE_RELEASE = 7; +var STATE_OFF = 0; +var STATE_SEARCHING = 1; +var STATE_DISTANCE_HOLDING = 2; +var STATE_CONTINUE_DISTANCE_HOLDING = 3; +var STATE_NEAR_GRABBING = 4; +var STATE_CONTINUE_NEAR_GRABBING = 5; +var STATE_NEAR_GRABBING_NON_COLLIDING = 6; +var STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING = 7; +var STATE_RELEASE = 8; var GRAB_USER_DATA_KEY = "grabKey"; var GRABBABLE_DATA_KEY = "grabbableKey"; +// HACK -- until we have collision groups, don't allow held object to collide with avatar +var AVATAR_COLLISIONS_MENU_ITEM = "Enable avatar collisions"; + function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -92,13 +95,28 @@ function MyController(hand, triggerAction) { this.actionID = null; // action this script created... this.grabbedEntity = null; // on this entity. this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity - this.state = STATE_SEARCHING; + this.state = STATE_OFF; this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value + + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.initialavatarCollisionsMenu = Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM); + var _this = this; this.update = function() { + + // XXX + if (this.state != this.previousState) { + print("state --> " + this.state); + } + this.previousState = this.state; + // XXX + switch (this.state) { + case STATE_OFF: + this.off(); + break; case STATE_SEARCHING: this.search(); this.touchTest(); @@ -171,6 +189,16 @@ function MyController(hand, triggerAction) { return triggerValue > TRIGGER_ON_VALUE; }; + this.off = function() { + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.revertAvatarCollisions(); + + if (this.triggerSmoothedSqueezed()) { + this.state = STATE_SEARCHING; + return; + } + } + this.search = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; @@ -243,13 +271,26 @@ function MyController(hand, triggerAction) { }; + this.disableAvatarCollisions = function() { + if (Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM) != false) { + Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, false); + print("avatar collisions --> off"); + MyAvatar.updateMotionBehaviorFromMenu(); + } + } + + this.revertAvatarCollisions = function() { + if (Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM) != this.initialavatarCollisionsMenu) { + Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, this.initialavatarCollisionsMenu); + print("avatar collisions --> revert"); + MyAvatar.updateMotionBehaviorFromMenu(); + } + } + this.distanceHolding = function() { - this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); - Menu.setIsOptionChecked("Enable avatar collisions", false); - print("avatar collisions -->" + this.previousAvCollision); - MyAvatar.updateMotionBehaviorFromMenu(); - + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.disableAvatarCollisions(); var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); @@ -331,10 +372,8 @@ function MyController(hand, triggerAction) { this.nearGrabbing = function() { - this.previousAvCollision = Menu.isOptionChecked("Enable avatar collisions"); - Menu.setIsOptionChecked("Enable avatar collisions", false); - print("avatar collisions -->" + this.previousAvCollision); - MyAvatar.updateMotionBehaviorFromMenu(); + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.disableAvatarCollisions(); if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; @@ -504,11 +543,6 @@ function MyController(hand, triggerAction) { }; this.release = function() { - - Menu.setIsOptionChecked("Enable avatar collisions", this.previousAvCollision); - print("avatar collisions -->" + this.previousAvCollision); - MyAvatar.updateMotionBehaviorFromMenu(); - this.lineOff(); if (this.grabbedEntity !== null && this.actionID !== null) { @@ -526,7 +560,7 @@ function MyController(hand, triggerAction) { this.grabbedVelocity = ZERO_VEC; this.grabbedEntity = null; this.actionID = null; - this.state = STATE_SEARCHING; + this.state = STATE_OFF; }; this.cleanup = function() { @@ -565,3 +599,6 @@ function cleanup() { Script.scriptEnding.connect(cleanup); Script.update.connect(update); + +// this comment keeps jslint quiet. +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ From 1bd07b58c3371df3f1e1e548bdd145f22330fa5d Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 29 Sep 2015 14:40:37 -0700 Subject: [PATCH 27/81] Fixing the lighting view matrix for stereo again --- libraries/render-utils/src/DeferredLightingEffect.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a9d83aa9d6..dbcbe3c05e 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -442,7 +442,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { deferredTransforms[i].projection = projMats[i]; - auto sideViewMat = eyeViews[i] * monoViewMat; + auto sideViewMat = monoViewMat * glm::inverse(eyeViews[i]); viewTransforms[i].evalFromRawMatrix(sideViewMat); deferredTransforms[i].viewInverse = sideViewMat; @@ -574,10 +574,8 @@ void DeferredLightingEffect::render(RenderArgs* args) { for (auto lightID : _pointLights) { auto& light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); - if (_pointLightLocations->lightBufferUnit >= 0) { - batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); - } + // IN DEBUG: light->setShowContour(true); + batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, @@ -612,8 +610,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { for (auto lightID : _spotLights) { auto light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); - + // IN DEBUG: light->setShowContour(true); batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); auto eyeLightPos = eyePoint - light->getPosition(); From f83eae4d4259e56d657863eb2a73ca51ade4858c Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 14:45:24 -0700 Subject: [PATCH 28/81] more debugging --- examples/acScripts/flickeringLight.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index 03ea4681ef..367b604567 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -43,7 +43,7 @@ var totalTime = 0; var MINIMUM_LIGHT_INTENSITY = 0.75; var MAXIMUM_LIGHT_INTENSITY = 2.75; var LIGHT_INTENSITY_RANDOMNESS = 0.3; -var EPHEMERAL_LIFETIME = 10; // ephemeral entities will live for 10 seconds after script stops running +var EPHEMERAL_LIFETIME = 60; // ephemeral entities will live for 60 seconds after script stops running var LightMaker = { light: null, @@ -78,11 +78,13 @@ function update(deltaTime) { intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); var properties = Entities.getEntityProperties(LightMaker.light, ["age", "lifetime"]); //print("props:" +JSON.stringify(properties)); - print("age:" + properties.age); - print("lifetime:" + properties.lifetime); + //print("deltaTime:" + deltaTime); + //print("age:" + properties.age); + //print("lifetime:" + properties.lifetime); var newLifetime = properties.age + EPHEMERAL_LIFETIME; - print("newLifetime:" + newLifetime); - Entities.editEntity(LightMaker.light, { type: "Light", intensity : intensity, lifetime: newLifetime }); + //print("newLifetime:" + newLifetime); + Entities.editEntity(LightMaker.light, { type: "Light", intensity: intensity, lifetime: newLifetime }); + //print("packetsToSendCount:" + Entities.packetsToSendCount()); } } From 2ba686ed890999c6271f4c8fcab2a0dd86e68bbd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 15:11:52 -0700 Subject: [PATCH 29/81] cleanups --- examples/controllers/handControllerGrab.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index bc8fd504ef..24aa88cc65 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -115,13 +115,6 @@ function MyController(hand, triggerAction) { this.update = function() { - // XXX - if (this.state != this.previousState) { - print("state --> " + this.state); - } - this.previousState = this.state; - // XXX - this.updateSmoothedTrigger(); switch (this.state) { @@ -158,7 +151,6 @@ function MyController(hand, triggerAction) { this.disableAvatarCollisions = function() { if (this.currentAvatarCollisionsMenu != false) { - print("avatar collisions --> off"); this.currentAvatarCollisionsMenu = false; Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, false); MyAvatar.updateMotionBehaviorFromMenu(); @@ -167,7 +159,6 @@ function MyController(hand, triggerAction) { this.revertAvatarCollisions = function() { if (this.currentAvatarCollisionsMenu != this.initialAvatarCollisionsMenu) { - print("avatar collisions --> revert"); this.currentAvatarCollisionsMenu = this.initialAvatarCollisionsMenu; Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, this.initialAvatarCollisionsMenu); MyAvatar.updateMotionBehaviorFromMenu(); From 8f2f14c9e5f86c19ae5c829e6395028164bb27d5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 15:30:24 -0700 Subject: [PATCH 30/81] keep track of state of avatar-collisions menu-item with global variables rather than per object ones --- examples/controllers/handControllerGrab.js | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 24aa88cc65..0b9238e7c9 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -84,6 +84,13 @@ var GRABBABLE_DATA_KEY = "grabbableKey"; // HACK -- until we have collision groups, don't allow held object to collide with avatar var AVATAR_COLLISIONS_MENU_ITEM = "Enable avatar collisions"; + +// HACK -- until we have collision groups, don't allow held object to collide with avatar +var initialAvatarCollisionsMenu = Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM); +var currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; +var noCollisionsCount = 0; // how many hands want collisions disabled? + + function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -107,10 +114,6 @@ function MyController(hand, triggerAction) { this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.initialAvatarCollisionsMenu = Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM); - this.currentAvatarCollisionsMenu = this.initialAvatarCollisionsMenu; - var _this = this; this.update = function() { @@ -120,10 +123,10 @@ function MyController(hand, triggerAction) { switch (this.state) { case STATE_OFF: this.off(); + this.touchTest(); break; case STATE_SEARCHING: this.search(); - this.touchTest(); break; case STATE_DISTANCE_HOLDING: this.distanceHolding(); @@ -149,19 +152,25 @@ function MyController(hand, triggerAction) { } }; + // HACK -- until we have collision groups, don't allow held object to collide with avatar this.disableAvatarCollisions = function() { - if (this.currentAvatarCollisionsMenu != false) { - this.currentAvatarCollisionsMenu = false; + noCollisionsCount += 1; + if (currentAvatarCollisionsMenu != false) { + currentAvatarCollisionsMenu = false; Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, false); MyAvatar.updateMotionBehaviorFromMenu(); } } + // HACK -- until we have collision groups, don't allow held object to collide with avatar this.revertAvatarCollisions = function() { - if (this.currentAvatarCollisionsMenu != this.initialAvatarCollisionsMenu) { - this.currentAvatarCollisionsMenu = this.initialAvatarCollisionsMenu; - Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, this.initialAvatarCollisionsMenu); - MyAvatar.updateMotionBehaviorFromMenu(); + noCollisionsCount -= 1; + if (noCollisionsCount < 1) { + if (currentAvatarCollisionsMenu != initialAvatarCollisionsMenu) { + currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; + Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, initialAvatarCollisionsMenu); + MyAvatar.updateMotionBehaviorFromMenu(); + } } } @@ -217,9 +226,6 @@ function MyController(hand, triggerAction) { }; this.off = function() { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - if (this.triggerSmoothedSqueezed()) { this.state = STATE_SEARCHING; return; @@ -601,6 +607,10 @@ function MyController(hand, triggerAction) { }; this.release = function() { + + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.revertAvatarCollisions(); + this.lineOff(); if (this.grabbedEntity !== null) { From e7834365f5cd17cc97f1b44e208341d4c5d99412 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 15:33:39 -0700 Subject: [PATCH 31/81] Made polyline painting experience smoother- no more flickering --- .../src/RenderablePolyLineEntityItem.cpp | 212 +++++------ libraries/entities/src/PolyLineEntityItem.cpp | 330 +++++++++--------- 2 files changed, 271 insertions(+), 271 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index c6b7b58538..f7057ff906 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -25,12 +25,12 @@ EntityItemPointer RenderablePolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties)); + return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties)); } RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : PolyLineEntityItem(entityItemID, properties) { - _numVertices = 0; + _numVertices = 0; } @@ -40,119 +40,119 @@ gpu::TexturePointer RenderablePolyLineEntityItem::_texture; GLint RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT; void RenderablePolyLineEntityItem::createPipeline() { - static const int NORMAL_OFFSET = 12; - static const int COLOR_OFFSET = 24; - static const int TEXTURE_OFFSET = 28; - - auto textureCache = DependencyManager::get(); - QString path = PathUtils::resourcesPath() + "images/paintStroke.png"; - _texture = textureCache->getImageTexture(path); - _format.reset(new gpu::Stream::Format()); - _format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET); - _format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32, COLOR_OFFSET); - _format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET); - - auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(paintStroke_vert))); - auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(paintStroke_frag))); - gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); - - gpu::Shader::BindingSet slotBindings; - PAINTSTROKE_GPU_SLOT = 0; - slotBindings.insert(gpu::Shader::Binding(std::string("paintStrokeTextureBinding"), PAINTSTROKE_GPU_SLOT)); - gpu::Shader::makeProgram(*program, slotBindings); - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setDepthTest(true, true, gpu::LESS_EQUAL); - state->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + static const int NORMAL_OFFSET = 12; + static const int COLOR_OFFSET = 24; + static const int TEXTURE_OFFSET = 28; + + auto textureCache = DependencyManager::get(); + QString path = PathUtils::resourcesPath() + "images/paintStroke.png"; + _texture = textureCache->getImageTexture(path); + _format.reset(new gpu::Stream::Format()); + _format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); + _format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET); + _format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32, COLOR_OFFSET); + _format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET); + + auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(paintStroke_vert))); + auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(paintStroke_frag))); + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); + + gpu::Shader::BindingSet slotBindings; + PAINTSTROKE_GPU_SLOT = 0; + slotBindings.insert(gpu::Shader::Binding(std::string("paintStrokeTextureBinding"), PAINTSTROKE_GPU_SLOT)); + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); } void RenderablePolyLineEntityItem::updateGeometry() { - _numVertices = 0; - _verticesBuffer.reset(new gpu::Buffer()); - int vertexIndex = 0; - vec2 uv; - float tailStart = 0.0f; - float tailEnd = 0.25f; - float tailLength = tailEnd - tailStart; - - float headStart = 0.76f; - float headEnd = 1.0f; - float headLength = headEnd - headStart; - float uCoord, vCoord; - - int numTailStrips = 5; - int numHeadStrips = 10; - int startHeadIndex = _normals.size() - numHeadStrips; - for (int i = 0; i < _normals.size(); i++) { - uCoord = 0.26f; - vCoord = 0.0f; - //tail - if(i < numTailStrips) { - uCoord = float(i)/numTailStrips * tailLength + tailStart; - } - - //head - if( i > startHeadIndex) { - uCoord = float( (i+ 1) - startHeadIndex)/numHeadStrips * headLength + headStart; - } + _numVertices = 0; + _verticesBuffer.reset(new gpu::Buffer()); + int vertexIndex = 0; + vec2 uv; + float tailStart = 0.0f; + float tailEnd = 0.25f; + float tailLength = tailEnd - tailStart; - uv = vec2(uCoord, vCoord); - - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); - _verticesBuffer->append(sizeof(int), (gpu::Byte*)&_color); - _verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv); - vertexIndex++; + float headStart = 0.76f; + float headEnd = 1.0f; + float headLength = headEnd - headStart; + float uCoord, vCoord; + + int numTailStrips = 5; + int numHeadStrips = 10; + int startHeadIndex = _vertices.size() / 2 - numHeadStrips; + for (int i = 0; i < _vertices.size() / 2; i++) { + uCoord = 0.26f; + vCoord = 0.0f; + //tail + if (i < numTailStrips) { + uCoord = float(i) / numTailStrips * tailLength + tailStart; + } + + //head + if (i > startHeadIndex) { + uCoord = float((i + 1) - startHeadIndex) / numHeadStrips * headLength + headStart; + } + + uv = vec2(uCoord, vCoord); + + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); + _verticesBuffer->append(sizeof(int), (gpu::Byte*)&_color); + _verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv); + vertexIndex++; + + uv.y = 1.0f; + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); + _verticesBuffer->append(sizeof(int), (gpu::Byte*)_color); + _verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv); + vertexIndex++; + + _numVertices += 2; + } + _pointsChanged = false; - uv.y = 1.0f; - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); - _verticesBuffer->append(sizeof(int), (gpu::Byte*)_color); - _verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv); - vertexIndex++; - - _numVertices +=2; - } - _pointsChanged = false; - } void RenderablePolyLineEntityItem::render(RenderArgs* args) { - QWriteLocker lock(&_quadReadWriteLock); - if (_points.size() < 2 || _vertices.size() != _normals.size() * 2) { - return; - } - - if (!_pipeline) { - createPipeline(); - } - - PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render"); - Q_ASSERT(getType() == EntityTypes::PolyLine); - - Q_ASSERT(args->_batch); - if (_pointsChanged) { - updateGeometry(); - } - - gpu::Batch& batch = *args->_batch; - Transform transform = Transform(); - transform.setTranslation(getPosition()); - transform.setRotation(getRotation()); - batch.setModelTransform(transform); + QWriteLocker lock(&_quadReadWriteLock); + if (_points.size() < 2) { + return; + } - batch.setPipeline(_pipeline); - batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture); + if (!_pipeline) { + createPipeline(); + } - batch.setInputFormat(_format); - batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); - - batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); - - RenderableDebugableEntityItem::render(this, args); + PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render"); + Q_ASSERT(getType() == EntityTypes::PolyLine); + + Q_ASSERT(args->_batch); + if (_pointsChanged) { + updateGeometry(); + } + + gpu::Batch& batch = *args->_batch; + Transform transform = Transform(); + transform.setTranslation(getPosition()); + transform.setRotation(getRotation()); + batch.setModelTransform(transform); + + batch.setPipeline(_pipeline); + batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture); + + batch.setInputFormat(_format); + batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); + + batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); + + RenderableDebugableEntityItem::render(this, args); }; diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 29a44547ff..09ddc4ec76 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -27,12 +27,12 @@ const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70; EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result { new PolyLineEntityItem(entityID, properties) }; - return result; + EntityItemPointer result{ new PolyLineEntityItem(entityID, properties) }; + return result; } PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : -EntityItem(entityItemID) , +EntityItem(entityItemID), _lineWidth(DEFAULT_LINE_WIDTH), _pointsChanged(true), _points(QVector(0.0f)), @@ -40,200 +40,200 @@ _vertices(QVector(0.0f)), _normals(QVector(0.0f)), _strokeWidths(QVector(0.0f)) { - _type = EntityTypes::PolyLine; - _created = properties.getCreated(); - setProperties(properties); + _type = EntityTypes::PolyLine; + _created = properties.getCreated(); + setProperties(properties); } EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { - QWriteLocker lock(&_quadReadWriteLock); - EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class - - - properties._color = getXColor(); - properties._colorChanged = false; - - COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths); - - properties._glowLevel = getGlowLevel(); - properties._glowLevelChanged = false; - return properties; + QWriteLocker lock(&_quadReadWriteLock); + EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class + + + properties._color = getXColor(); + properties._colorChanged = false; + + COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths); + + properties._glowLevel = getGlowLevel(); + properties._glowLevelChanged = false; + return properties; } bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) { - QWriteLocker lock(&_quadReadWriteLock); - bool somethingChanged = false; - somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class - - SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths); - - if (somethingChanged) { - bool wantDebug = false; - if (wantDebug) { - uint64_t now = usecTimestampNow(); - int elapsed = now - getLastEdited(); - qCDebug(entities) << "PolyLineEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << - "now=" << now << " getLastEdited()=" << getLastEdited(); - } - setLastEdited(properties._lastEdited); - } - return somethingChanged; + QWriteLocker lock(&_quadReadWriteLock); + bool somethingChanged = false; + somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class + + SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths); + + if (somethingChanged) { + bool wantDebug = false; + if (wantDebug) { + uint64_t now = usecTimestampNow(); + int elapsed = now - getLastEdited(); + qCDebug(entities) << "PolyLineEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << + "now=" << now << " getLastEdited()=" << getLastEdited(); + } + setLastEdited(properties._lastEdited); + } + return somethingChanged; } bool PolyLineEntityItem::appendPoint(const glm::vec3& point) { - if (_points.size() > MAX_POINTS_PER_LINE - 1) { - qDebug() << "MAX POINTS REACHED!"; - return false; - } - glm::vec3 halfBox = getDimensions() * 0.5f; - if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) { - qDebug() << "Point is outside entity's bounding box"; - return false; - } - _points << point; - _pointsChanged = true; - return true; + if (_points.size() > MAX_POINTS_PER_LINE - 1) { + qDebug() << "MAX POINTS REACHED!"; + return false; + } + glm::vec3 halfBox = getDimensions() * 0.5f; + if ((point.x < -halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < -halfBox.z || point.z > halfBox.z)) { + qDebug() << "Point is outside entity's bounding box"; + return false; + } + _points << point; + _pointsChanged = true; + return true; } -bool PolyLineEntityItem::setStrokeWidths(const QVector& strokeWidths ) { - _strokeWidths = strokeWidths; - return true; +bool PolyLineEntityItem::setStrokeWidths(const QVector& strokeWidths) { + _strokeWidths = strokeWidths; + return true; } bool PolyLineEntityItem::setNormals(const QVector& normals) { - _normals = normals; - if (_points.size () < 2 || _normals.size() < 2) { - return false; - } - - int minVectorSize = _normals.size(); - if (_points.size() < minVectorSize) { - minVectorSize = _points.size(); - } - if (_strokeWidths.size() < minVectorSize) { - minVectorSize = _strokeWidths.size(); - } + _normals = normals; + if (_points.size() < 2 || _normals.size() < 2) { + return false; + } - _vertices.clear(); - glm::vec3 v1, v2, tangent, binormal, point; - - for (int i = 0; i < minVectorSize-1; i++) { - float width = _strokeWidths.at(i); - point = _points.at(i); - - tangent = _points.at(i+1) - point; - glm::vec3 normal = normals.at(i); - binormal = glm::normalize(glm::cross(tangent, normal)) * width; - - //This checks to make sure binormal is not a NAN - assert(binormal.x == binormal.x); - v1 = point + binormal; - v2 = point - binormal; - _vertices << v1 << v2; - } - //for last point we can just assume binormals are same since it represents last two vertices of quad - point = _points.at(_points.size() - 1); - v1 = point + binormal; - v2 = point - binormal; - _vertices << v1 << v2; - - return true; + int minVectorSize = _normals.size(); + if (_points.size() < minVectorSize) { + minVectorSize = _points.size(); + } + if (_strokeWidths.size() < minVectorSize) { + minVectorSize = _strokeWidths.size(); + } + + _vertices.clear(); + glm::vec3 v1, v2, tangent, binormal, point; + + for (int i = 0; i < minVectorSize - 1; i++) { + float width = _strokeWidths.at(i); + point = _points.at(i); + + tangent = _points.at(i + 1) - point; + glm::vec3 normal = normals.at(i); + binormal = glm::normalize(glm::cross(tangent, normal)) * width; + + //This checks to make sure binormal is not a NAN + assert(binormal.x == binormal.x); + v1 = point + binormal; + v2 = point - binormal; + _vertices << v1 << v2; + } + //for last point we can just assume binormals are same since it represents last two vertices of quad + point = _points.at(minVectorSize - 1); + v1 = point + binormal; + v2 = point - binormal; + _vertices << v1 << v2; + + return true; } bool PolyLineEntityItem::setLinePoints(const QVector& points) { - if (points.size() > MAX_POINTS_PER_LINE) { - return false; - } - if (points.size() != _points.size()) { - _pointsChanged = true; - } - //Check to see if points actually changed. If they haven't, return before doing anything else - else if (points.size() == _points.size()) { - //same number of points, so now compare every point - for (int i = 0; i < points.size(); i++ ) { - if (points.at(i) != _points.at(i)){ - _pointsChanged = true; - break; - } - } - } - if (!_pointsChanged) { - return false; - } + if (points.size() > MAX_POINTS_PER_LINE) { + return false; + } + if (points.size() != _points.size()) { + _pointsChanged = true; + } + //Check to see if points actually changed. If they haven't, return before doing anything else + else if (points.size() == _points.size()) { + //same number of points, so now compare every point + for (int i = 0; i < points.size(); i++) { + if (points.at(i) != _points.at(i)){ + _pointsChanged = true; + break; + } + } + } + if (!_pointsChanged) { + return false; + } - for (int i = 0; i < points.size(); i++) { - glm::vec3 point = points.at(i); - glm::vec3 halfBox = getDimensions() * 0.5f; - if ((point.x < - halfBox.x || point.x > halfBox.x) || - (point.y < -halfBox.y || point.y > halfBox.y) || - (point.z < - halfBox.z || point.z > halfBox.z)) { - qDebug() << "Point is outside entity's bounding box"; - return false; - } - } - _points = points; - return true; + for (int i = 0; i < points.size(); i++) { + glm::vec3 point = points.at(i); + glm::vec3 halfBox = getDimensions() * 0.5f; + if ((point.x < -halfBox.x || point.x > halfBox.x) || + (point.y < -halfBox.y || point.y > halfBox.y) || + (point.z < -halfBox.z || point.z > halfBox.z)) { + qDebug() << "Point is outside entity's bounding box"; + return false; + } + } + _points = points; + return true; } int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, - ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { - QWriteLocker lock(&_quadReadWriteLock); - int bytesRead = 0; - const unsigned char* dataAt = data; - - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); - READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); - READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); - READ_ENTITY_PROPERTY(PROP_NORMALS, QVector, setNormals); - READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector, setStrokeWidths); - - return bytesRead; + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + QWriteLocker lock(&_quadReadWriteLock); + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); + READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); + READ_ENTITY_PROPERTY(PROP_NORMALS, QVector, setNormals); + READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector, setStrokeWidths); + + return bytesRead; } // TODO: eventually only include properties changed since the params.lastViewFrustumSent time EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { - EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); - requestedProperties += PROP_COLOR; - requestedProperties += PROP_LINE_WIDTH; - requestedProperties += PROP_LINE_POINTS; - requestedProperties += PROP_NORMALS; - requestedProperties += PROP_STROKE_WIDTHS; - return requestedProperties; + EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); + requestedProperties += PROP_COLOR; + requestedProperties += PROP_LINE_WIDTH; + requestedProperties += PROP_LINE_POINTS; + requestedProperties += PROP_NORMALS; + requestedProperties += PROP_STROKE_WIDTHS; + return requestedProperties; } void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, - EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, - EntityPropertyFlags& requestedProperties, - EntityPropertyFlags& propertyFlags, - EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, - OctreeElement::AppendState& appendState) const { - - QWriteLocker lock(&_quadReadWriteLock); - bool successPropertyFits = true; - - APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); - APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth()); - APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints()); - APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals()); - APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths()); + EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + QWriteLocker lock(&_quadReadWriteLock); + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth()); + APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints()); + APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals()); + APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths()); } void PolyLineEntityItem::debugDump() const { - quint64 now = usecTimestampNow(); - qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; - qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; - qCDebug(entities) << " position:" << debugTreeVector(getPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); - qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); + quint64 now = usecTimestampNow(); + qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; + qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; + qCDebug(entities) << " position:" << debugTreeVector(getPosition()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } From 90afeb4ce1ad9692af4b38e3d23648832478d587 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 15:45:29 -0700 Subject: [PATCH 32/81] more debugging --- examples/acScripts/flickeringLight.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index 367b604567..cf3dd70934 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -39,11 +39,13 @@ var ZERO_VEC = { }; var totalTime = 0; +var lastUpdate = 0; +var UPDATE_INTERVAL = 1 / 30; // 30fps var MINIMUM_LIGHT_INTENSITY = 0.75; var MAXIMUM_LIGHT_INTENSITY = 2.75; var LIGHT_INTENSITY_RANDOMNESS = 0.3; -var EPHEMERAL_LIFETIME = 60; // ephemeral entities will live for 60 seconds after script stops running +var EPHEMERAL_LIFETIME = 10; // ephemeral entities will live for 60 seconds after script stops running var LightMaker = { light: null, @@ -74,17 +76,17 @@ function update(deltaTime) { LightMaker.spawnLight(); } else { totalTime += deltaTime; - var intensity = (MINIMUM_LIGHT_INTENSITY + (MAXIMUM_LIGHT_INTENSITY + (Math.sin(totalTime) * MAXIMUM_LIGHT_INTENSITY))); - intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); - var properties = Entities.getEntityProperties(LightMaker.light, ["age", "lifetime"]); - //print("props:" +JSON.stringify(properties)); - //print("deltaTime:" + deltaTime); - //print("age:" + properties.age); - //print("lifetime:" + properties.lifetime); - var newLifetime = properties.age + EPHEMERAL_LIFETIME; - //print("newLifetime:" + newLifetime); - Entities.editEntity(LightMaker.light, { type: "Light", intensity: intensity, lifetime: newLifetime }); - //print("packetsToSendCount:" + Entities.packetsToSendCount()); + + // We don't want to edit the entity EVERY update cycle, because that's just a lot + // of wasted bandwidth and extra effort on the server for very little visual gain + if (totalTime - lastUpdate > UPDATE_INTERVAL) { + var intensity = (MINIMUM_LIGHT_INTENSITY + (MAXIMUM_LIGHT_INTENSITY + (Math.sin(totalTime) * MAXIMUM_LIGHT_INTENSITY))); + intensity += randFloat(-LIGHT_INTENSITY_RANDOMNESS, LIGHT_INTENSITY_RANDOMNESS); + var properties = Entities.getEntityProperties(LightMaker.light, "age"); + var newLifetime = properties.age + EPHEMERAL_LIFETIME; + Entities.editEntity(LightMaker.light, { type: "Light", intensity: intensity, lifetime: newLifetime }); + lastUpdate = totalTime; + } } } From 67823b79d5de72120e2c1b33478dd29ffdb370d8 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 15:48:46 -0700 Subject: [PATCH 33/81] change additional lifetime to 60 seconds to avoid processing hiccups --- examples/acScripts/flickeringLight.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/acScripts/flickeringLight.js b/examples/acScripts/flickeringLight.js index cf3dd70934..ed60d56c86 100644 --- a/examples/acScripts/flickeringLight.js +++ b/examples/acScripts/flickeringLight.js @@ -45,7 +45,7 @@ var UPDATE_INTERVAL = 1 / 30; // 30fps var MINIMUM_LIGHT_INTENSITY = 0.75; var MAXIMUM_LIGHT_INTENSITY = 2.75; var LIGHT_INTENSITY_RANDOMNESS = 0.3; -var EPHEMERAL_LIFETIME = 10; // ephemeral entities will live for 60 seconds after script stops running +var EPHEMERAL_LIFETIME = 60; // ephemeral entities will live for 60 seconds after script stops running var LightMaker = { light: null, From 472ff89f48ce9ba69cabd630011295b984ba2012 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 29 Sep 2015 15:52:38 -0700 Subject: [PATCH 34/81] rearrange when avatar collisions are adjusted --- examples/controllers/handControllerGrab.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 0b9238e7c9..388c042285 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -348,6 +348,9 @@ function MyController(hand, triggerAction) { this.continueDistanceHolding = function() { if (this.triggerSmoothedReleased()) { + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.revertAvatarCollisions(); + this.state = STATE_RELEASE; return; } @@ -431,6 +434,9 @@ function MyController(hand, triggerAction) { this.disableAvatarCollisions(); if (this.triggerSmoothedReleased()) { + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.revertAvatarCollisions(); + this.state = STATE_RELEASE; return; } @@ -477,6 +483,9 @@ function MyController(hand, triggerAction) { this.continueNearGrabbing = function() { if (this.triggerSmoothedReleased()) { + // HACK -- until we have collision groups, don't allow held object to collide with avatar + this.revertAvatarCollisions(); + this.state = STATE_RELEASE; return; } @@ -608,9 +617,6 @@ function MyController(hand, triggerAction) { this.release = function() { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.lineOff(); if (this.grabbedEntity !== null) { From cdae16e07bd2e8649d310b7c5e0e2a49e5075d20 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 29 Sep 2015 16:11:27 -0700 Subject: [PATCH 35/81] fix bug: IK attenuates fast underpose animations --- .../animation/src/AnimInverseKinematics.cpp | 61 ++++++++++++------- .../animation/src/AnimInverseKinematics.h | 2 +- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index de226092f1..ff5d2a6a3f 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -89,7 +89,7 @@ static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int inde return rootIndex; } -void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::vector& targets) { +void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::vector& targets, const AnimPoseVec& underPoses) { // build a list of valid targets from _targetVarVec and animVars _maxTargetIndex = -1; bool removeUnfoundJoints = false; @@ -107,7 +107,7 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } } else { IKTarget target; - AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, _relativePoses); + AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); target.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans); target.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot); target.setType(animVars.lookup(targetVar.typeVar, QString(""))); @@ -154,7 +154,6 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector& targets); + void computeTargets(const AnimVariantMap& animVars, std::vector& targets, const AnimPoseVec& underPoses); void solveWithCyclicCoordinateDescent(const std::vector& targets); virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton); From a052f5e125f7d75fb4d36929c05b2ba2cc6e28df Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 29 Sep 2015 16:21:08 -0700 Subject: [PATCH 36/81] remove commented out debug line --- libraries/animation/src/AnimInverseKinematics.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index ff5d2a6a3f..c0adba0ad6 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -371,7 +371,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } } return _relativePoses; - //return underPoses; } RotationConstraint* AnimInverseKinematics::getConstraint(int index) { From 36be35a8363a02669c626d865cf57c370582fcff Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Tue, 29 Sep 2015 16:30:42 -0700 Subject: [PATCH 37/81] Update RenderablePolyLineEntityItem.cpp --- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index f7057ff906..7d95d472ee 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -25,7 +25,7 @@ EntityItemPointer RenderablePolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties)); + return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties)); } RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : From 614312f04f5c6e68fc555b36e031916a7dfbf158 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Tue, 29 Sep 2015 16:32:07 -0700 Subject: [PATCH 38/81] Update PolyLineEntityItem.cpp --- libraries/entities/src/PolyLineEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 09ddc4ec76..f5e6a98423 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -139,7 +139,7 @@ bool PolyLineEntityItem::setNormals(const QVector& normals) { _vertices << v1 << v2; } //for last point we can just assume binormals are same since it represents last two vertices of quad - point = _points.at(minVectorSize - 1); + point = _points.at(minVectorSize - 1); v1 = point + binormal; v2 = point - binormal; _vertices << v1 << v2; From c901a749c2c300b84cb745b36c2dddb70e000d51 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Tue, 29 Sep 2015 16:33:18 -0700 Subject: [PATCH 39/81] Update RenderablePolyLineEntityItem.cpp --- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 7d95d472ee..d87138637d 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -124,7 +124,7 @@ void RenderablePolyLineEntityItem::updateGeometry() { void RenderablePolyLineEntityItem::render(RenderArgs* args) { QWriteLocker lock(&_quadReadWriteLock); - if (_points.size() < 2) { + if (_points.size() < 2) { return; } From d1b016b483be465df722ab76062a018cd341718d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 16:38:21 -0700 Subject: [PATCH 40/81] untabbified lines --- .../src/RenderablePolyLineEntityItem.cpp | 178 +++++------ libraries/entities/src/PolyLineEntityItem.cpp | 294 +++++++++--------- 2 files changed, 236 insertions(+), 236 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 7d95d472ee..27981d2530 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -30,7 +30,7 @@ EntityItemPointer RenderablePolyLineEntityItem::factory(const EntityItemID& enti RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : PolyLineEntityItem(entityItemID, properties) { - _numVertices = 0; + _numVertices = 0; } @@ -40,119 +40,119 @@ gpu::TexturePointer RenderablePolyLineEntityItem::_texture; GLint RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT; void RenderablePolyLineEntityItem::createPipeline() { - static const int NORMAL_OFFSET = 12; - static const int COLOR_OFFSET = 24; - static const int TEXTURE_OFFSET = 28; + static const int NORMAL_OFFSET = 12; + static const int COLOR_OFFSET = 24; + static const int TEXTURE_OFFSET = 28; - auto textureCache = DependencyManager::get(); - QString path = PathUtils::resourcesPath() + "images/paintStroke.png"; - _texture = textureCache->getImageTexture(path); - _format.reset(new gpu::Stream::Format()); - _format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET); - _format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32, COLOR_OFFSET); - _format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET); + auto textureCache = DependencyManager::get(); + QString path = PathUtils::resourcesPath() + "images/paintStroke.png"; + _texture = textureCache->getImageTexture(path); + _format.reset(new gpu::Stream::Format()); + _format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); + _format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET); + _format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32, COLOR_OFFSET); + _format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET); - auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(paintStroke_vert))); - auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(paintStroke_frag))); - gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); + auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(paintStroke_vert))); + auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(paintStroke_frag))); + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); - gpu::Shader::BindingSet slotBindings; - PAINTSTROKE_GPU_SLOT = 0; - slotBindings.insert(gpu::Shader::Binding(std::string("paintStrokeTextureBinding"), PAINTSTROKE_GPU_SLOT)); - gpu::Shader::makeProgram(*program, slotBindings); + gpu::Shader::BindingSet slotBindings; + PAINTSTROKE_GPU_SLOT = 0; + slotBindings.insert(gpu::Shader::Binding(std::string("paintStrokeTextureBinding"), PAINTSTROKE_GPU_SLOT)); + gpu::Shader::makeProgram(*program, slotBindings); - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setDepthTest(true, true, gpu::LESS_EQUAL); - state->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); } void RenderablePolyLineEntityItem::updateGeometry() { - _numVertices = 0; - _verticesBuffer.reset(new gpu::Buffer()); - int vertexIndex = 0; - vec2 uv; - float tailStart = 0.0f; - float tailEnd = 0.25f; - float tailLength = tailEnd - tailStart; + _numVertices = 0; + _verticesBuffer.reset(new gpu::Buffer()); + int vertexIndex = 0; + vec2 uv; + float tailStart = 0.0f; + float tailEnd = 0.25f; + float tailLength = tailEnd - tailStart; - float headStart = 0.76f; - float headEnd = 1.0f; - float headLength = headEnd - headStart; - float uCoord, vCoord; + float headStart = 0.76f; + float headEnd = 1.0f; + float headLength = headEnd - headStart; + float uCoord, vCoord; - int numTailStrips = 5; - int numHeadStrips = 10; - int startHeadIndex = _vertices.size() / 2 - numHeadStrips; - for (int i = 0; i < _vertices.size() / 2; i++) { - uCoord = 0.26f; - vCoord = 0.0f; - //tail - if (i < numTailStrips) { - uCoord = float(i) / numTailStrips * tailLength + tailStart; - } + int numTailStrips = 5; + int numHeadStrips = 10; + int startHeadIndex = _vertices.size() / 2 - numHeadStrips; + for (int i = 0; i < _vertices.size() / 2; i++) { + uCoord = 0.26f; + vCoord = 0.0f; + //tail + if (i < numTailStrips) { + uCoord = float(i) / numTailStrips * tailLength + tailStart; + } - //head - if (i > startHeadIndex) { - uCoord = float((i + 1) - startHeadIndex) / numHeadStrips * headLength + headStart; - } + //head + if (i > startHeadIndex) { + uCoord = float((i + 1) - startHeadIndex) / numHeadStrips * headLength + headStart; + } - uv = vec2(uCoord, vCoord); + uv = vec2(uCoord, vCoord); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); - _verticesBuffer->append(sizeof(int), (gpu::Byte*)&_color); - _verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv); - vertexIndex++; + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); + _verticesBuffer->append(sizeof(int), (gpu::Byte*)&_color); + _verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv); + vertexIndex++; - uv.y = 1.0f; - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); - _verticesBuffer->append(sizeof(int), (gpu::Byte*)_color); - _verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv); - vertexIndex++; + uv.y = 1.0f; + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); + _verticesBuffer->append(sizeof(int), (gpu::Byte*)_color); + _verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv); + vertexIndex++; - _numVertices += 2; - } - _pointsChanged = false; + _numVertices += 2; + } + _pointsChanged = false; } void RenderablePolyLineEntityItem::render(RenderArgs* args) { - QWriteLocker lock(&_quadReadWriteLock); - if (_points.size() < 2) { - return; - } + QWriteLocker lock(&_quadReadWriteLock); + if (_points.size() < 2) { + return; + } - if (!_pipeline) { - createPipeline(); - } + if (!_pipeline) { + createPipeline(); + } - PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render"); - Q_ASSERT(getType() == EntityTypes::PolyLine); + PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render"); + Q_ASSERT(getType() == EntityTypes::PolyLine); - Q_ASSERT(args->_batch); - if (_pointsChanged) { - updateGeometry(); - } + Q_ASSERT(args->_batch); + if (_pointsChanged) { + updateGeometry(); + } - gpu::Batch& batch = *args->_batch; - Transform transform = Transform(); - transform.setTranslation(getPosition()); - transform.setRotation(getRotation()); - batch.setModelTransform(transform); + gpu::Batch& batch = *args->_batch; + Transform transform = Transform(); + transform.setTranslation(getPosition()); + transform.setRotation(getRotation()); + batch.setModelTransform(transform); - batch.setPipeline(_pipeline); - batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture); + batch.setPipeline(_pipeline); + batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture); - batch.setInputFormat(_format); - batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); + batch.setInputFormat(_format); + batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); - batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); + batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); - RenderableDebugableEntityItem::render(this, args); + RenderableDebugableEntityItem::render(this, args); }; diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index f5e6a98423..c29ed43041 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -27,8 +27,8 @@ const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70; EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result{ new PolyLineEntityItem(entityID, properties) }; - return result; + EntityItemPointer result{ new PolyLineEntityItem(entityID, properties) }; + return result; } PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : @@ -40,200 +40,200 @@ _vertices(QVector(0.0f)), _normals(QVector(0.0f)), _strokeWidths(QVector(0.0f)) { - _type = EntityTypes::PolyLine; - _created = properties.getCreated(); - setProperties(properties); + _type = EntityTypes::PolyLine; + _created = properties.getCreated(); + setProperties(properties); } EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { - QWriteLocker lock(&_quadReadWriteLock); - EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class + QWriteLocker lock(&_quadReadWriteLock); + EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class - properties._color = getXColor(); - properties._colorChanged = false; + properties._color = getXColor(); + properties._colorChanged = false; - COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths); - properties._glowLevel = getGlowLevel(); - properties._glowLevelChanged = false; - return properties; + properties._glowLevel = getGlowLevel(); + properties._glowLevelChanged = false; + return properties; } bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) { - QWriteLocker lock(&_quadReadWriteLock); - bool somethingChanged = false; - somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class + QWriteLocker lock(&_quadReadWriteLock); + bool somethingChanged = false; + somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class - SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths); - if (somethingChanged) { - bool wantDebug = false; - if (wantDebug) { - uint64_t now = usecTimestampNow(); - int elapsed = now - getLastEdited(); - qCDebug(entities) << "PolyLineEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << - "now=" << now << " getLastEdited()=" << getLastEdited(); - } - setLastEdited(properties._lastEdited); - } - return somethingChanged; + if (somethingChanged) { + bool wantDebug = false; + if (wantDebug) { + uint64_t now = usecTimestampNow(); + int elapsed = now - getLastEdited(); + qCDebug(entities) << "PolyLineEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << + "now=" << now << " getLastEdited()=" << getLastEdited(); + } + setLastEdited(properties._lastEdited); + } + return somethingChanged; } bool PolyLineEntityItem::appendPoint(const glm::vec3& point) { - if (_points.size() > MAX_POINTS_PER_LINE - 1) { - qDebug() << "MAX POINTS REACHED!"; - return false; - } - glm::vec3 halfBox = getDimensions() * 0.5f; - if ((point.x < -halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < -halfBox.z || point.z > halfBox.z)) { - qDebug() << "Point is outside entity's bounding box"; - return false; - } - _points << point; - _pointsChanged = true; - return true; + if (_points.size() > MAX_POINTS_PER_LINE - 1) { + qDebug() << "MAX POINTS REACHED!"; + return false; + } + glm::vec3 halfBox = getDimensions() * 0.5f; + if ((point.x < -halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < -halfBox.z || point.z > halfBox.z)) { + qDebug() << "Point is outside entity's bounding box"; + return false; + } + _points << point; + _pointsChanged = true; + return true; } bool PolyLineEntityItem::setStrokeWidths(const QVector& strokeWidths) { - _strokeWidths = strokeWidths; - return true; + _strokeWidths = strokeWidths; + return true; } bool PolyLineEntityItem::setNormals(const QVector& normals) { - _normals = normals; - if (_points.size() < 2 || _normals.size() < 2) { - return false; - } + _normals = normals; + if (_points.size() < 2 || _normals.size() < 2) { + return false; + } - int minVectorSize = _normals.size(); - if (_points.size() < minVectorSize) { - minVectorSize = _points.size(); - } - if (_strokeWidths.size() < minVectorSize) { - minVectorSize = _strokeWidths.size(); - } + int minVectorSize = _normals.size(); + if (_points.size() < minVectorSize) { + minVectorSize = _points.size(); + } + if (_strokeWidths.size() < minVectorSize) { + minVectorSize = _strokeWidths.size(); + } - _vertices.clear(); - glm::vec3 v1, v2, tangent, binormal, point; + _vertices.clear(); + glm::vec3 v1, v2, tangent, binormal, point; - for (int i = 0; i < minVectorSize - 1; i++) { - float width = _strokeWidths.at(i); - point = _points.at(i); + for (int i = 0; i < minVectorSize - 1; i++) { + float width = _strokeWidths.at(i); + point = _points.at(i); - tangent = _points.at(i + 1) - point; - glm::vec3 normal = normals.at(i); - binormal = glm::normalize(glm::cross(tangent, normal)) * width; + tangent = _points.at(i + 1) - point; + glm::vec3 normal = normals.at(i); + binormal = glm::normalize(glm::cross(tangent, normal)) * width; - //This checks to make sure binormal is not a NAN - assert(binormal.x == binormal.x); - v1 = point + binormal; - v2 = point - binormal; - _vertices << v1 << v2; - } - //for last point we can just assume binormals are same since it represents last two vertices of quad + //This checks to make sure binormal is not a NAN + assert(binormal.x == binormal.x); + v1 = point + binormal; + v2 = point - binormal; + _vertices << v1 << v2; + } + //for last point we can just assume binormals are same since it represents last two vertices of quad point = _points.at(minVectorSize - 1); - v1 = point + binormal; - v2 = point - binormal; - _vertices << v1 << v2; + v1 = point + binormal; + v2 = point - binormal; + _vertices << v1 << v2; - return true; + return true; } bool PolyLineEntityItem::setLinePoints(const QVector& points) { - if (points.size() > MAX_POINTS_PER_LINE) { - return false; - } - if (points.size() != _points.size()) { - _pointsChanged = true; - } - //Check to see if points actually changed. If they haven't, return before doing anything else - else if (points.size() == _points.size()) { - //same number of points, so now compare every point - for (int i = 0; i < points.size(); i++) { - if (points.at(i) != _points.at(i)){ - _pointsChanged = true; - break; - } - } - } - if (!_pointsChanged) { - return false; - } + if (points.size() > MAX_POINTS_PER_LINE) { + return false; + } + if (points.size() != _points.size()) { + _pointsChanged = true; + } + //Check to see if points actually changed. If they haven't, return before doing anything else + else if (points.size() == _points.size()) { + //same number of points, so now compare every point + for (int i = 0; i < points.size(); i++) { + if (points.at(i) != _points.at(i)){ + _pointsChanged = true; + break; + } + } + } + if (!_pointsChanged) { + return false; + } - for (int i = 0; i < points.size(); i++) { - glm::vec3 point = points.at(i); - glm::vec3 halfBox = getDimensions() * 0.5f; - if ((point.x < -halfBox.x || point.x > halfBox.x) || - (point.y < -halfBox.y || point.y > halfBox.y) || - (point.z < -halfBox.z || point.z > halfBox.z)) { - qDebug() << "Point is outside entity's bounding box"; - return false; - } - } - _points = points; - return true; + for (int i = 0; i < points.size(); i++) { + glm::vec3 point = points.at(i); + glm::vec3 halfBox = getDimensions() * 0.5f; + if ((point.x < -halfBox.x || point.x > halfBox.x) || + (point.y < -halfBox.y || point.y > halfBox.y) || + (point.z < -halfBox.z || point.z > halfBox.z)) { + qDebug() << "Point is outside entity's bounding box"; + return false; + } + } + _points = points; + return true; } int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, - ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { - QWriteLocker lock(&_quadReadWriteLock); - int bytesRead = 0; - const unsigned char* dataAt = data; + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + QWriteLocker lock(&_quadReadWriteLock); + int bytesRead = 0; + const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); - READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); - READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); - READ_ENTITY_PROPERTY(PROP_NORMALS, QVector, setNormals); - READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector, setStrokeWidths); + READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); + READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); + READ_ENTITY_PROPERTY(PROP_NORMALS, QVector, setNormals); + READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector, setStrokeWidths); - return bytesRead; + return bytesRead; } // TODO: eventually only include properties changed since the params.lastViewFrustumSent time EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { - EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); - requestedProperties += PROP_COLOR; - requestedProperties += PROP_LINE_WIDTH; - requestedProperties += PROP_LINE_POINTS; - requestedProperties += PROP_NORMALS; - requestedProperties += PROP_STROKE_WIDTHS; - return requestedProperties; + EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); + requestedProperties += PROP_COLOR; + requestedProperties += PROP_LINE_WIDTH; + requestedProperties += PROP_LINE_POINTS; + requestedProperties += PROP_NORMALS; + requestedProperties += PROP_STROKE_WIDTHS; + return requestedProperties; } void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, - EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, - EntityPropertyFlags& requestedProperties, - EntityPropertyFlags& propertyFlags, - EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, - OctreeElement::AppendState& appendState) const { + EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { - QWriteLocker lock(&_quadReadWriteLock); - bool successPropertyFits = true; + QWriteLocker lock(&_quadReadWriteLock); + bool successPropertyFits = true; - APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); - APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth()); - APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints()); - APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals()); - APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths()); + APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth()); + APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints()); + APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals()); + APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths()); } void PolyLineEntityItem::debugDump() const { - quint64 now = usecTimestampNow(); - qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; - qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; - qCDebug(entities) << " position:" << debugTreeVector(getPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); - qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); + quint64 now = usecTimestampNow(); + qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; + qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; + qCDebug(entities) << " position:" << debugTreeVector(getPosition()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } From 5ce3b13a4c006406656ecb65f99668f0d8debcc9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 17:31:02 -0700 Subject: [PATCH 41/81] Fixed spacing issues --- libraries/entities/src/PolyLineEntityItem.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index c29ed43041..a01c2ce17b 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -183,9 +183,9 @@ bool PolyLineEntityItem::setLinePoints(const QVector& points) { } int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, - ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { - QWriteLocker lock(&_quadReadWriteLock); + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + QWriteLocker lock(&_quadReadWriteLock); int bytesRead = 0; const unsigned char* dataAt = data; @@ -211,12 +211,12 @@ EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParam } void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, - EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, - EntityPropertyFlags& requestedProperties, - EntityPropertyFlags& propertyFlags, - EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, - OctreeElement::AppendState& appendState) const { + EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { QWriteLocker lock(&_quadReadWriteLock); bool successPropertyFits = true; From b192d0a9cdfdada443fc3957804287cfff0d08ab Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 29 Sep 2015 17:39:17 -0700 Subject: [PATCH 42/81] make neck IK target type same as head --- .../meshes/defaultAvatar_full/avatar-animation.json | 5 +++-- libraries/animation/src/Rig.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 72eefaf7e8..dceecddfe0 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -26,13 +26,14 @@ { "jointName": "Neck", "positionVar": "neckPosition", - "rotationVar": "neckRotation" + "rotationVar": "neckRotation", + "typeVar": "headAndNeckType" }, { "jointName": "Head", "positionVar": "headPosition", "rotationVar": "headRotation", - "typeVar": "headType" + "typeVar": "headAndNeckType" } ] }, diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0022749d51..ceef68f85b 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1079,7 +1079,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.set("headPosition", headPos); _animVars.set("headRotation", headRot); - _animVars.set("headType", QString("RotationAndPosition")); + _animVars.set("headAndNeckType", QString("RotationAndPosition")); _animVars.set("neckPosition", neckPos); _animVars.set("neckRotation", neckRot); @@ -1092,7 +1092,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.unset("headPosition"); _animVars.set("headRotation", realLocalHeadOrientation); - _animVars.set("headType", QString("RotationOnly")); + _animVars.set("headAndNeckType", QString("RotationOnly")); _animVars.unset("neckPosition"); _animVars.unset("neckRotation"); } From 1760720b2be77e53278ff8fa325d400f86f204b5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 29 Sep 2015 17:42:20 -0700 Subject: [PATCH 43/81] added check for normals and vertices --- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 27981d2530..572b24e99f 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -124,7 +124,7 @@ void RenderablePolyLineEntityItem::updateGeometry() { void RenderablePolyLineEntityItem::render(RenderArgs* args) { QWriteLocker lock(&_quadReadWriteLock); - if (_points.size() < 2) { + if (_points.size() < 2 || _normals.size () < 2 || _vertices.size() < 2) { return; } From 4dc2c9a58f26cbd8a1dc183215ec69da05c43897 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 29 Sep 2015 18:42:52 -0700 Subject: [PATCH 44/81] Create symbol files on Windows release builds. Added --release to windeployqt.exe, otherwise it gets confused and copies debug DLLs instead of release. --- CMakeLists.txt | 3 +++ cmake/macros/CopyDllsBesideWindowsExecutable.cmake | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47560576b2..79d8a0c0e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,9 @@ if (WIN32) # Caveats: http://stackoverflow.com/questions/2288728/drawbacks-of-using-largeaddressaware-for-32-bit-windows-executables # TODO: Remove when building 64-bit. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") + # always produce symbols as PDB files + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG /OPT:REF /OPT:ICF") else () set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-strict-aliasing -Wno-unused-parameter") if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) diff --git a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake b/cmake/macros/CopyDllsBesideWindowsExecutable.cmake index e8d499bab8..cecdae3696 100644 --- a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake +++ b/cmake/macros/CopyDllsBesideWindowsExecutable.cmake @@ -37,7 +37,7 @@ macro(COPY_DLLS_BESIDE_WINDOWS_EXECUTABLE) add_custom_command( TARGET ${TARGET_NAME} POST_BUILD - COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} $" + COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} --release $" ) endif () endmacro() \ No newline at end of file From de8848f7bcf693d8e3047e973aac3043b32012c6 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 30 Sep 2015 08:11:16 -0700 Subject: [PATCH 45/81] Fix to only pass --release to windeployqt on release builds --- cmake/macros/CopyDllsBesideWindowsExecutable.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake b/cmake/macros/CopyDllsBesideWindowsExecutable.cmake index cecdae3696..b57c781eff 100644 --- a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake +++ b/cmake/macros/CopyDllsBesideWindowsExecutable.cmake @@ -37,7 +37,7 @@ macro(COPY_DLLS_BESIDE_WINDOWS_EXECUTABLE) add_custom_command( TARGET ${TARGET_NAME} POST_BUILD - COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} --release $" + COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} $<$,$,$>:--release> $" ) endif () endmacro() \ No newline at end of file From 76825c2be70e4773dfce770de671fe879c506e1d Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 09:06:45 -0700 Subject: [PATCH 46/81] only show hand cursors when menu is enabled --- interface/src/ui/ApplicationCompositor.cpp | 27 ++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 497a94bb86..98c2efc8f3 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -313,18 +313,21 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int glm::mat4 overlayXfm; _modelTransform.getMatrix(overlayXfm); - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { - PalmData& palm = myAvatar->getHand()->getPalms()[i]; - if (palm.isActive()) { - glm::vec2 polar = getPolarCoordinates(palm); - // Convert to quaternion - mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); - mat4 reticleXfm = overlayXfm * pointerXfm; - reticleXfm = glm::scale(reticleXfm, reticleScale); - batch.setModelTransform(reticleXfm); - // Render reticle at location - geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); + // Only render the hand pointers if the HandMouseInput is enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { + PalmData& palm = myAvatar->getHand()->getPalms()[i]; + if (palm.isActive()) { + glm::vec2 polar = getPolarCoordinates(palm); + // Convert to quaternion + mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); + mat4 reticleXfm = overlayXfm * pointerXfm; + reticleXfm = glm::scale(reticleXfm, reticleScale); + batch.setModelTransform(reticleXfm); + // Render reticle at location + geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); + } } } From c3dfea47122abd200dcbd257af5003e603c61033 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 10:26:24 -0700 Subject: [PATCH 47/81] initial files --- .../toys/ping_pong_gun/createPingPongGun.js | 43 +++++ examples/toys/ping_pong_gun/pingPongGun.js | 154 ++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 examples/toys/ping_pong_gun/createPingPongGun.js create mode 100644 examples/toys/ping_pong_gun/pingPongGun.js diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js new file mode 100644 index 0000000000..350fe63d02 --- /dev/null +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -0,0 +1,43 @@ +// createPingPongGun.js +// +// Script Type: Entity Spawner +// Created by James B. Pollack on 9/30/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script creates a gun that shoots ping pong balls when you pull the trigger on a hand controller. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); + + +var scriptURL = Script.resolvePath('pingPongGun.js'); + +var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' +var COLLISION_HULL_URL = ''; +var center = Vec3.sum(Vec3.sum(MyAvatar.position, { + x: 0, + y: 0.5, + z: 0 +}), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); + +var pingPongGun = Entities.addEntity({ + type: "Model", + modelURL: MODEL_URL, + position: center, + dimensions: { + x: 0.1, + y: 0.06, + z: 0.03 + }, + collisionsWillMove: true, + shapeType: 'compound', + compoundShapeURL: COLLISION_HULL_URL, + script: scriptURL +}); + +function cleanUp() { + +} +Script.scriptEnding.connect(cleanup) \ No newline at end of file diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js new file mode 100644 index 0000000000..48c0347d98 --- /dev/null +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -0,0 +1,154 @@ +// pingPongGun.js +// +// Script Type: Entity +// Created by James B. Pollack @imgntn on 9/21/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script shoots a ping pong ball. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +(function() { + + Script.include("../../libraries/utils.js"); + + var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + function PingPongGun() { + return; + } + + //if the trigger value goes below this value, reload the gun. + var RELOAD_THRESHOLD = 0.7; + + var GUN_TIP_OFFSET = 0.095; + // Evaluate the world light entity positions and orientations from the model ones + function evalLightWorldTransform(modelPos, modelRot) { + + return { + p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), + q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) + }; + } + + PingPongGun.prototype = { + hand: null, + whichHand: null, + gunTipPosition: null, + setRightHand: function() { + this.hand = 'RIGHT'; + }, + + setLeftHand: function() { + this.hand = 'LEFT'; + }, + + startNearGrab: function() { + setWhichHand(); + }, + + setWhichHand: function() { + this.whichHand = this.hand; + }, + + continueNearGrab: function() { + if (this.whichHand === null) { + //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten + this.setWhichHand(); + } else { + this.checkTriggerPressure(this.whichHand); + } + }, + + releaseGrab: function() { + + }, + + checkTriggerPressure: function(gunHand) { + var handClickString = gunHand + "_HAND_CLICK"; + + var handClick = Controller.findAction(handClickString); + + this.triggerValue = Controller.getActionValue(handClick); + + if (this.triggerValue < RELOAD_THRESHOLD) { + this.canShoot = true; + } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { + var gunProperties = Entities.getEntityProperties(this.entityID,["position","rotation"]) + this.shootBall(gunProperties); + this.canShoot = false; + } + return; + }, + + shootBall: function(gunProperties,triggerValue) { + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); + //forwardVec = Vec3.normalize(forwardVec); + + var properties = { + type: 'Sphere' + color: { + red: 0, + green: 0, + blue: 255 + }, + dimensions: { + x: 0.04, + y: 0.04, + z: 0.04 + }, + linearDamping: 0.2, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + rotation:gunProperties.rotation, + position: this.gunTipPosition, + velocity: velocity, + lifetime: 10 + }; + var pingPongBall = Entities.addEntity(properties); + }, + + playSoundAtCurrentPosition: function(playOnSound) { + var position = Entities.getEntityProperties(this.entityID, "position").position; + + var audioProperties = { + volume: 0.25, + position: position + }; + + if (playOnSound) { + Audio.playSound(this.ON_SOUND, audioProperties); + } else { + Audio.playSound(this.OFF_SOUND, audioProperties); + } + }, + + getGunTipPosition: function(properties) { + //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position + var upVector = Quat.getUp(properties.rotation); + var upOffset = Vec3.multiply(upVector, GUN_TIP_OFFSET); + var wandTipPosition = Vec3.sum(properties.position, upOffset); + return wandTipPosition; + }, + preload: function(entityID) { + this.entityID = entityID; + this.ON_SOUND = SoundCache.getSound(SHOOT_SOUND_URL); + + }, + + unload: function() { + + }, + + }; + + // entity scripts always need to return a newly constructed object of our type + return new Flashlight(); +}); \ No newline at end of file From 96d0df49e478a436c33e6546993b0722a15d40ac Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 10:41:39 -0700 Subject: [PATCH 48/81] script to display entity-action details in an overlay --- examples/actionInspector.js | 127 ++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 examples/actionInspector.js diff --git a/examples/actionInspector.js b/examples/actionInspector.js new file mode 100644 index 0000000000..74f5912fc0 --- /dev/null +++ b/examples/actionInspector.js @@ -0,0 +1,127 @@ +// +// actionInspector.js +// examples +// +// Created by Seth Alves on 2015-9-30. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("libraries/utils.js"); + + +var INSPECT_RADIUS = 10; +var overlays = {}; + + +var toType = function(obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase() +} + + +function actionArgumentsToString(actionArguments) { + var result = "type: " + actionArguments["type"] + "\n"; + for (var argumentName in actionArguments) { + if (actionArguments.hasOwnProperty(argumentName)) { + if (argumentName == "type") { + continue; + } + var arg = actionArguments[argumentName]; + var argType = toType(arg); + var argString = arg; + if (argType == "object") { + if (Object.keys(arg).length == 3) { + argString = vec3toStr(arg, 1); + } + } else if (argType == "number") { + argString = arg.toFixed(2); + } + result += argumentName + ": " + // + toType(arg) + " -- " + + argString + "\n"; + } + } + + return result; +} + + +function updateOverlay(entityID, actionText) { + var properties = Entities.getEntityProperties(entityID, ["position"]); + var position = Vec3.sum(properties.position, {x:0, y:1, z:0}); + // print("position: " + vec3toStr(position) + " " + actionText); + if (entityID in overlays) { + var overlay = overlays[entityID]; + Overlays.editOverlay(overlay, { + text: actionText, + position: position + }); + } else { + var lines = actionText.split(/\r\n|\r|\n/); + + var maxLineLength = lines[0].length; + for (var i = 1; i < lines.length; i++) { + if (lines[i].length > maxLineLength) { + maxLineLength = lines[i].length; + } + } + + var textWidth = maxLineLength * 0.034; // XXX how to know this? + var textHeight = .5; + var numberOfLines = lines.length; + var textMargin = 0.05; + var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; + + overlays[entityID] = Overlays.addOverlay("text3d", { + position: position, + dimensions: { x: textWidth, y: textHeight }, + backgroundColor: { red: 0, green: 0, blue: 0}, + color: { red: 255, green: 255, blue: 255}, + topMargin: textMargin, + leftMargin: textMargin, + bottomMargin: textMargin, + rightMargin: textMargin, + text: actionText, + lineHeight: lineHeight, + alpha: 0.9, + backgroundAlpha: 0.9, + ignoreRayIntersection: true, + visible: true, + isFacingAvatar: true + }); + } +} + + +function cleanup() { + for (var entityID in overlays) { + Overlays.deleteOverlay(overlays[entityID]); + } +} + + +Script.setInterval(function() { + var nearbyEntities = Entities.findEntities(MyAvatar.position, INSPECT_RADIUS); + for (var entityIndex = 0; entityIndex < nearbyEntities.length; entityIndex++) { + var entityID = nearbyEntities[entityIndex]; + var actionIDs = Entities.getActionIDs(entityID); + var actionText = "" + for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) { + var actionID = actionIDs[actionIndex]; + var actionArguments = Entities.getActionArguments(entityID, actionID); + var actionArgumentText = actionArgumentsToString(actionArguments); + if (actionArgumentText != "") { + actionText += "-----------------\n"; + actionText += actionArgumentText; + } + } + if (actionText != "") { + updateOverlay(entityID, actionText); + } + } +}, 1000); + + +Script.scriptEnding.connect(cleanup); From 99fbed6143c17d9061b65889538808fe6ba15272 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 10:49:47 -0700 Subject: [PATCH 49/81] mostly working --- .../toys/ping_pong_gun/createPingPongGun.js | 11 +-- examples/toys/ping_pong_gun/pingPongGun.js | 69 ++++++++++--------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index 350fe63d02..d045516fc4 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -15,7 +15,8 @@ Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); var scriptURL = Script.resolvePath('pingPongGun.js'); var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' -var COLLISION_HULL_URL = ''; +var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; + var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, y: 0.5, @@ -25,6 +26,9 @@ var center = Vec3.sum(Vec3.sum(MyAvatar.position, { var pingPongGun = Entities.addEntity({ type: "Model", modelURL: MODEL_URL, + shapeType: 'compound', + compoundShapeURL: COLLISION_HULL_URL, + script: scriptURL, position: center, dimensions: { x: 0.1, @@ -32,12 +36,9 @@ var pingPongGun = Entities.addEntity({ z: 0.03 }, collisionsWillMove: true, - shapeType: 'compound', - compoundShapeURL: COLLISION_HULL_URL, - script: scriptURL }); function cleanUp() { - +Entities.deleteEntity(pingPongGun); } Script.scriptEnding.connect(cleanup) \ No newline at end of file diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 48c0347d98..415b62c71e 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -14,7 +14,6 @@ Script.include("../../libraries/utils.js"); var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx' // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) @@ -24,21 +23,21 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.7; - var GUN_TIP_OFFSET = 0.095; - // Evaluate the world light entity positions and orientations from the model ones - function evalLightWorldTransform(modelPos, modelRot) { + // // Evaluate the world light entity positions and orientations from the model ones + // function evalLightWorldTransform(modelPos, modelRot) { - return { - p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), - q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) - }; - } + // return { + // p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), + // q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) + // }; + // } PingPongGun.prototype = { hand: null, whichHand: null, gunTipPosition: null, + canShoot: false, setRightHand: function() { this.hand = 'RIGHT'; }, @@ -48,7 +47,7 @@ }, startNearGrab: function() { - setWhichHand(); + this.setWhichHand(); }, setWhichHand: function() { @@ -76,21 +75,23 @@ this.triggerValue = Controller.getActionValue(handClick); if (this.triggerValue < RELOAD_THRESHOLD) { + print('RELOAD'); this.canShoot = true; } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { - var gunProperties = Entities.getEntityProperties(this.entityID,["position","rotation"]) + var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); this.shootBall(gunProperties); this.canShoot = false; } return; }, - shootBall: function(gunProperties,triggerValue) { - var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); - //forwardVec = Vec3.normalize(forwardVec); + shootBall: function(gunProperties, triggerValue) { + print('SHOOT BALL'); + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + forwardVec = Vec3.normalize(forwardVec); var properties = { - type: 'Sphere' + type: 'Sphere', color: { red: 0, green: 0, @@ -104,42 +105,46 @@ linearDamping: 0.2, gravity: { x: 0, - y: -9.8, + y: -0.05, z: 0 }, - rotation:gunProperties.rotation, - position: this.gunTipPosition, - velocity: velocity, + collisionsWillMove: true, + collisionSoundURL: SHOOTING_SOUND_URL, + rotation: gunProperties.rotation, + position: this.getGunTipPosition(gunProperties), + velocity: forwardVec, lifetime: 10 }; var pingPongBall = Entities.addEntity(properties); + var audioOptions = { + position: gunProperties.position + } + this.playSoundAtCurrentPosition(gunProperties.position); }, - playSoundAtCurrentPosition: function(playOnSound) { - var position = Entities.getEntityProperties(this.entityID, "position").position; + playSoundAtCurrentPosition: function(position) { var audioProperties = { volume: 0.25, position: position }; - if (playOnSound) { - Audio.playSound(this.ON_SOUND, audioProperties); - } else { - Audio.playSound(this.OFF_SOUND, audioProperties); - } + + Audio.playSound(this.SHOOTING_SOUND, audioProperties); + }, getGunTipPosition: function(properties) { //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position - var upVector = Quat.getUp(properties.rotation); - var upOffset = Vec3.multiply(upVector, GUN_TIP_OFFSET); - var wandTipPosition = Vec3.sum(properties.position, upOffset); - return wandTipPosition; + var frontVector = Quat.getFront(properties.rotation); + var frontOffset = Vec3.multiply(frontVector, GUN_TIP_OFFSET); + var gunTipPosition = Vec3.sum(properties.position, frontOffset); + return gunTipPosition; }, preload: function(entityID) { + print('PRELOAD PING PONG GUN'); this.entityID = entityID; - this.ON_SOUND = SoundCache.getSound(SHOOT_SOUND_URL); + this.SHOOTING_SOUND = SoundCache.getSound(SHOOTING_SOUND_URL); }, @@ -150,5 +155,5 @@ }; // entity scripts always need to return a newly constructed object of our type - return new Flashlight(); + return new PingPongGun(); }); \ No newline at end of file From 898e3917e3fd0a9221c24911be592077da2fc204 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 10:57:52 -0700 Subject: [PATCH 50/81] improve actionInspector.js --- examples/actionInspector.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/actionInspector.js b/examples/actionInspector.js index 74f5912fc0..7e342b9e11 100644 --- a/examples/actionInspector.js +++ b/examples/actionInspector.js @@ -120,8 +120,27 @@ Script.setInterval(function() { if (actionText != "") { updateOverlay(entityID, actionText); } + + // if an entity no longer has an action, remove its overlay + if (actionIDs.length == 0) { + if (entityID in overlays) { + Overlays.deleteOverlay(overlays[entityID]); + delete overlays[entityID]; + } + } } -}, 1000); + + + // if an entity is too far away, remove its overlay + for (var entityID in overlays) { + var position = Entities.getEntityProperties(entityID, ["position"]).position; + if (Vec3.distance(position, MyAvatar.position) > INSPECT_RADIUS) { + Overlays.deleteOverlay(overlays[entityID]); + delete overlays[entityID]; + } + } + +}, 100); Script.scriptEnding.connect(cleanup); From ecad7f34f6afd1417e2f2a10863c90a47ded3821 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 10:58:21 -0700 Subject: [PATCH 51/81] moar --- examples/toys/ping_pong_gun/pingPongGun.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 415b62c71e..c3d10e7198 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -86,21 +86,20 @@ }, shootBall: function(gunProperties, triggerValue) { - print('SHOOT BALL'); var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); - forwardVec = Vec3.normalize(forwardVec); + // forwardVec = Vec3.normalize(forwardVec); var properties = { type: 'Sphere', color: { - red: 0, - green: 0, + red: 255, + green: 255, blue: 255 }, dimensions: { - x: 0.04, - y: 0.04, - z: 0.04 + x: 0.02, + y: 0.02, + z: 0.02 }, linearDamping: 0.2, gravity: { From cc6b0adb7d1263fe5eb84d3b16919655ea6f9288 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 30 Sep 2015 14:13:36 -0400 Subject: [PATCH 52/81] guard insert/get in SentPacketHistory --- libraries/networking/src/SentPacketHistory.cpp | 6 ++++-- libraries/networking/src/SentPacketHistory.h | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/SentPacketHistory.cpp b/libraries/networking/src/SentPacketHistory.cpp index c6eec8eb63..d0fcecd171 100644 --- a/libraries/networking/src/SentPacketHistory.cpp +++ b/libraries/networking/src/SentPacketHistory.cpp @@ -35,10 +35,11 @@ void SentPacketHistory::packetSent(uint16_t sequenceNumber, const NLPacket& pack } _newestSequenceNumber = sequenceNumber; + QWriteLocker locker(&_packetsLock); _sentPackets.insert(NLPacket::createCopy(packet)); } -const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) const { +const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) { const int UINT16_RANGE = std::numeric_limits::max() + 1; @@ -48,6 +49,7 @@ const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) const { if (seqDiff < 0) { seqDiff += UINT16_RANGE; } - + + QReadLocker locker(&_packetsLock); return _sentPackets.get(seqDiff)->get(); } diff --git a/libraries/networking/src/SentPacketHistory.h b/libraries/networking/src/SentPacketHistory.h index 1808e0020b..78b6914c2d 100644 --- a/libraries/networking/src/SentPacketHistory.h +++ b/libraries/networking/src/SentPacketHistory.h @@ -12,7 +12,9 @@ #define hifi_SentPacketHistory_h #include -#include + +#include +#include #include "NLPacket.h" #include "RingBufferHistory.h" @@ -26,9 +28,10 @@ public: SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP); void packetSent(uint16_t sequenceNumber, const NLPacket& packet); - const NLPacket* getPacket(uint16_t sequenceNumber) const; + const NLPacket* getPacket(uint16_t sequenceNumber); private: + QReadWriteLock _packetsLock { QReadWriteLock::Recursive }; RingBufferHistory> _sentPackets; // circular buffer uint16_t _newestSequenceNumber; From f7e7b07441e014f3875cb1db0440252cee354342 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 30 Sep 2015 14:15:22 -0400 Subject: [PATCH 53/81] fix constness of SentPacketHistory in OEPS --- libraries/networking/src/NLPacketList.cpp | 3 ++- libraries/octree/src/OctreeEditPacketSender.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/NLPacketList.cpp b/libraries/networking/src/NLPacketList.cpp index 3b115c558b..318fb037a1 100644 --- a/libraries/networking/src/NLPacketList.cpp +++ b/libraries/networking/src/NLPacketList.cpp @@ -23,7 +23,8 @@ std::unique_ptr NLPacketList::create(PacketType packetType, QByteA } std::unique_ptr NLPacketList::fromPacketList(std::unique_ptr packetList) { - auto nlPacketList = std::unique_ptr(new NLPacketList(std::move(*packetList.release()))); nlPacketList->open(ReadOnly); + auto nlPacketList = std::unique_ptr(new NLPacketList(std::move(*packetList.release()))); + nlPacketList->open(ReadOnly); return nlPacketList; } diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 1be271cbdd..d4bd939196 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -346,7 +346,7 @@ void OctreeEditPacketSender::processNackPacket(NLPacket& packet, SharedNodePoint if (_sentPacketHistories.count(sendingNode->getUUID()) == 0) { return; } - const SentPacketHistory& sentPacketHistory = _sentPacketHistories[sendingNode->getUUID()]; + SentPacketHistory& sentPacketHistory = _sentPacketHistories[sendingNode->getUUID()]; // read sequence numbers and queue packets for resend while (packet.bytesLeftToRead() > 0) { From 8bdf428f41663a74afc125a9c038e2dd3403f59e Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 11:21:51 -0700 Subject: [PATCH 54/81] First version of ping pong gun --- .../toys/ping_pong_gun/createPingPongGun.js | 4 +- examples/toys/ping_pong_gun/pingPongGun.js | 51 +++++++------------ 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index d045516fc4..1bf0415ebd 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -39,6 +39,6 @@ var pingPongGun = Entities.addEntity({ }); function cleanUp() { -Entities.deleteEntity(pingPongGun); + Entities.deleteEntity(pingPongGun); } -Script.scriptEnding.connect(cleanup) \ No newline at end of file +Script.scriptEnding.connect(cleanUp); \ No newline at end of file diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index c3d10e7198..31681bc2d8 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -15,23 +15,14 @@ var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) function PingPongGun() { return; } //if the trigger value goes below this value, reload the gun. - var RELOAD_THRESHOLD = 0.7; - var GUN_TIP_OFFSET = 0.095; - // // Evaluate the world light entity positions and orientations from the model ones - // function evalLightWorldTransform(modelPos, modelRot) { - - // return { - // p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), - // q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) - // }; - // } + var RELOAD_THRESHOLD = 0.95; + var GUN_TIP_FWD_OFFSET = -0.056; + var GUN_TIP_UP_OFFSET = 0.001; PingPongGun.prototype = { hand: null, @@ -64,7 +55,7 @@ }, releaseGrab: function() { - + this.canShoot = false; }, checkTriggerPressure: function(gunHand) { @@ -75,7 +66,7 @@ this.triggerValue = Controller.getActionValue(handClick); if (this.triggerValue < RELOAD_THRESHOLD) { - print('RELOAD'); + // print('RELOAD'); this.canShoot = true; } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); @@ -85,10 +76,10 @@ return; }, - shootBall: function(gunProperties, triggerValue) { + shootBall: function(gunProperties) { var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); - // forwardVec = Vec3.normalize(forwardVec); - + forwardVec = Vec3.normalize(forwardVec); + forwardVec = Vec3.multiply(forwardVec, 2); var properties = { type: 'Sphere', color: { @@ -114,42 +105,36 @@ velocity: forwardVec, lifetime: 10 }; - var pingPongBall = Entities.addEntity(properties); - var audioOptions = { - position: gunProperties.position - } + + Entities.addEntity(properties); + this.playSoundAtCurrentPosition(gunProperties.position); }, playSoundAtCurrentPosition: function(position) { - var audioProperties = { volume: 0.25, position: position }; - Audio.playSound(this.SHOOTING_SOUND, audioProperties); - }, getGunTipPosition: function(properties) { //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position - var frontVector = Quat.getFront(properties.rotation); - var frontOffset = Vec3.multiply(frontVector, GUN_TIP_OFFSET); + var frontVector = Quat.getRight(properties.rotation); + var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET); + var upVector = Quat.getRight(properties.rotation); + var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET); var gunTipPosition = Vec3.sum(properties.position, frontOffset); + gunTipPosition = Vec3.sum(gunTipPosition, upOffset); return gunTipPosition; }, + preload: function(entityID) { - print('PRELOAD PING PONG GUN'); this.entityID = entityID; this.SHOOTING_SOUND = SoundCache.getSound(SHOOTING_SOUND_URL); - - }, - - unload: function() { - - }, + } }; From 82ac0b1a27da3600dfca483c39ef495e877ce384 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 30 Sep 2015 14:23:18 -0400 Subject: [PATCH 55/81] use a mutable mutex to keep const-ness --- libraries/networking/src/SentPacketHistory.cpp | 2 +- libraries/networking/src/SentPacketHistory.h | 4 ++-- libraries/octree/src/OctreeEditPacketSender.cpp | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/SentPacketHistory.cpp b/libraries/networking/src/SentPacketHistory.cpp index d0fcecd171..14b4677fc3 100644 --- a/libraries/networking/src/SentPacketHistory.cpp +++ b/libraries/networking/src/SentPacketHistory.cpp @@ -39,7 +39,7 @@ void SentPacketHistory::packetSent(uint16_t sequenceNumber, const NLPacket& pack _sentPackets.insert(NLPacket::createCopy(packet)); } -const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) { +const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) const { const int UINT16_RANGE = std::numeric_limits::max() + 1; diff --git a/libraries/networking/src/SentPacketHistory.h b/libraries/networking/src/SentPacketHistory.h index 78b6914c2d..72150658e3 100644 --- a/libraries/networking/src/SentPacketHistory.h +++ b/libraries/networking/src/SentPacketHistory.h @@ -28,10 +28,10 @@ public: SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP); void packetSent(uint16_t sequenceNumber, const NLPacket& packet); - const NLPacket* getPacket(uint16_t sequenceNumber); + const NLPacket* getPacket(uint16_t sequenceNumber) const; private: - QReadWriteLock _packetsLock { QReadWriteLock::Recursive }; + mutable QReadWriteLock _packetsLock { QReadWriteLock::Recursive }; RingBufferHistory> _sentPackets; // circular buffer uint16_t _newestSequenceNumber; diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index d4bd939196..495effc825 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -346,7 +346,8 @@ void OctreeEditPacketSender::processNackPacket(NLPacket& packet, SharedNodePoint if (_sentPacketHistories.count(sendingNode->getUUID()) == 0) { return; } - SentPacketHistory& sentPacketHistory = _sentPacketHistories[sendingNode->getUUID()]; + + const SentPacketHistory& sentPacketHistory = _sentPacketHistories[sendingNode->getUUID()]; // read sequence numbers and queue packets for resend while (packet.bytesLeftToRead() > 0) { From 0865f94106111e1483fad157cb3ef8e6e8de37ef Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 11:31:33 -0700 Subject: [PATCH 56/81] magic numbers --- examples/toys/ping_pong_gun/pingPongGun.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 31681bc2d8..da7a4a6d28 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -15,14 +15,21 @@ var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; + function PingPongGun() { return; } //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.056; - var GUN_TIP_UP_OFFSET = 0.001; + var GUN_TIP_FWD_OFFSET = -0.08; + var GUN_TIP_UP_OFFSET = 0.020; + var GUN_FORCE = 5; + var BALL_GRAVITY = { + x: 0, + y: -1, + z: 0 + }; PingPongGun.prototype = { hand: null, @@ -79,7 +86,7 @@ shootBall: function(gunProperties) { var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - forwardVec = Vec3.multiply(forwardVec, 2); + forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { type: 'Sphere', color: { @@ -93,11 +100,7 @@ z: 0.02 }, linearDamping: 0.2, - gravity: { - x: 0, - y: -0.05, - z: 0 - }, + gravity: BALL_GRAVITY, collisionsWillMove: true, collisionSoundURL: SHOOTING_SOUND_URL, rotation: gunProperties.rotation, From 1e9593029c260c5c346479972e13be7417c3a038 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 30 Sep 2015 11:32:41 -0700 Subject: [PATCH 57/81] Fix infinite recursion error with CC rng On some std::random implementations tryin get a range [low, high) where high < low will cause infinite recursion. --- .../networking/src/udt/CongestionControl.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/udt/CongestionControl.cpp b/libraries/networking/src/udt/CongestionControl.cpp index ea46d60acb..c1feae3911 100644 --- a/libraries/networking/src/udt/CongestionControl.cpp +++ b/libraries/networking/src/udt/CongestionControl.cpp @@ -161,13 +161,16 @@ void DefaultCC::onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) { _lastDecreaseMaxSeq = _sendCurrSeqNum; - // avoid synchronous rate decrease across connections using randomization - std::random_device rd; - std::mt19937 generator(rd()); - std::uniform_int_distribution<> distribution(1, _avgNAKNum); - - _randomDecreaseThreshold = distribution(generator); - + if (_avgNAKNum < 1) { + _randomDecreaseThreshold = 1; + } else { + // avoid synchronous rate decrease across connections using randomization + std::random_device rd; + std::mt19937 generator(rd()); + std::uniform_int_distribution<> distribution(1, std::max(1, _avgNAKNum)); + + _randomDecreaseThreshold = distribution(generator); + } } else if ((_decreaseCount++ < MAX_DECREASES_PER_CONGESTION_EPOCH) && ((++_nakCount % _randomDecreaseThreshold) == 0)) { // there have been fewer than MAX_DECREASES_PER_CONGESTION_EPOCH AND this NAK matches the random count at which we // decided we would decrease the packet send period From 83c3f65b1f6c8f92c4cf2c9681ab1d307d84f4a4 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 30 Sep 2015 11:34:38 -0700 Subject: [PATCH 58/81] Prevent taking a reference to a QUrl rvalue. --- libraries/avatars/src/AvatarData.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3bd147d398..f64504d662 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -966,7 +966,8 @@ bool AvatarData::hasIdentityChangedAfterParsing(NLPacket& packet) { QByteArray AvatarData::identityByteArray() { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); - const QUrl& urlToSend = (_skeletonModelURL == AvatarData::defaultFullAvatarModelUrl()) ? QUrl("") : _skeletonModelURL; + QUrl emptyURL(""); + const QUrl& urlToSend = (_skeletonModelURL == AvatarData::defaultFullAvatarModelUrl()) ? emptyURL : _skeletonModelURL; identityStream << QUuid() << _faceModelURL << urlToSend << _attachmentData << _displayName; From 7c6846c260b89f52ecc34aba67b52d0703152a9a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 13:09:41 -0700 Subject: [PATCH 59/81] add lifetime and tag arguments to actions --- examples/controllers/handControllerGrab.js | 7 ++- examples/grab.js | 6 +- interface/src/InterfaceActionFactory.cpp | 7 +++ interface/src/avatar/AvatarActionHold.cpp | 5 +- .../entities/src/EntityActionInterface.h | 2 + libraries/physics/src/ObjectAction.cpp | 57 +++++++++++++++++++ libraries/physics/src/ObjectAction.h | 12 ++-- libraries/physics/src/ObjectActionOffset.cpp | 13 ++++- libraries/physics/src/ObjectActionSpring.cpp | 11 +++- 9 files changed, 106 insertions(+), 14 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 388c042285..144500e4de 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -324,7 +324,9 @@ function MyController(hand, triggerAction) { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + tag: "grab", + lifetime: 5 }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -424,7 +426,8 @@ function MyController(hand, triggerAction) { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + lifetime: 5 }); }; diff --git a/examples/grab.js b/examples/grab.js index 05bcf128e2..15bab17f20 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -288,7 +288,7 @@ Grabber.prototype.moveEvent = function(event) { } this.currentPosition = entityProperties.position; - var actionArgs = {}; + var actionArgs = {tag: "grab", lifetime: 5}; if (this.mode === "rotate") { var drag = mouse.getDrag(); @@ -303,7 +303,7 @@ Grabber.prototype.moveEvent = function(event) { // var qZero = entityProperties.rotation; //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1}; + actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: "grab", lifetime: 5}; } else { var newPointOnPlane; if (this.mode === "verticalCylinder") { @@ -327,7 +327,7 @@ Grabber.prototype.moveEvent = function(event) { } } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1}; + actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: "grab", lifetime: 5}; beacon.updatePosition(this.targetPosition); } diff --git a/interface/src/InterfaceActionFactory.cpp b/interface/src/InterfaceActionFactory.cpp index dca1015ecc..2879c19eaa 100644 --- a/interface/src/InterfaceActionFactory.cpp +++ b/interface/src/InterfaceActionFactory.cpp @@ -43,6 +43,9 @@ EntityActionPointer InterfaceActionFactory::factory(EntityActionType type, if (action) { bool ok = action->updateArguments(arguments); if (ok) { + if (action->lifetimeIsOver()) { + return nullptr; + } return action; } } @@ -63,5 +66,9 @@ EntityActionPointer InterfaceActionFactory::factoryBA(EntityItemPointer ownerEnt if (action) { action->deserialize(data); } + if (action->lifetimeIsOver()) { + return nullptr; + } + return action; } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 4ecdb692ac..1fa50b79fd 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -84,6 +84,9 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool AvatarActionHold::updateArguments(QVariantMap arguments) { + if (!ObjectAction::updateArguments(arguments)) { + return false; + } bool ok = true; glm::vec3 relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); @@ -134,7 +137,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { QVariantMap AvatarActionHold::getArguments() { - QVariantMap arguments; + QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&]{ if (!_mine) { arguments = ObjectActionSpring::getArguments(); diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index a4f1c8ea15..e61019c98c 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -46,6 +46,8 @@ public: static EntityActionType actionTypeFromString(QString actionTypeString); static QString actionTypeToString(EntityActionType actionType); + virtual bool lifetimeIsOver() { return false; } + protected: virtual glm::vec3 getPosition() = 0; virtual void setPosition(glm::vec3 position) = 0; diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 5205e08c62..8c382f8dad 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -30,6 +30,18 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta dynamicsWorld->removeAction(this); return; } + + if (_expires > 0.0f) { + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (now > _expires) { + EntityItemPointer ownerEntity = _ownerEntity.lock(); + _active = false; + if (ownerEntity) { + ownerEntity->removeAction(nullptr, getID()); + } + } + } + if (!_active) { return; } @@ -37,6 +49,40 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta updateActionWorker(deltaTimeStep); } +bool ObjectAction::updateArguments(QVariantMap arguments) { + bool lifetimeSet = true; + float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); + if (lifetimeSet) { + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + _expires = now + lifetime; + } else { + _expires = 0.0f; + } + + bool tagSet = true; + QString tag = EntityActionInterface::extractStringArgument("action", arguments, "tag", tagSet, false); + if (tagSet) { + _tag = tag; + } else { + tag = ""; + } + + return true; +} + +QVariantMap ObjectAction::getArguments() { + QVariantMap arguments; + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (_expires == 0.0f) { + arguments["lifetime"] = 0.0f; + } else { + arguments["lifetime"] = _expires - now; + } + arguments["tag"] = _tag; + return arguments; +} + + void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) { } @@ -136,3 +182,14 @@ void ObjectAction::activateBody() { } } +bool ObjectAction::lifetimeIsOver() { + if (_expires == 0.0f) { + return false; + } + + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (now >= _expires) { + return true; + } + return false; +} diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 4d91d0dbb1..380263577a 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -33,8 +33,8 @@ public: virtual EntityItemWeakPointer getOwnerEntity() const { return _ownerEntity; } virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; } - virtual bool updateArguments(QVariantMap arguments) = 0; - virtual QVariantMap getArguments() = 0; + virtual bool updateArguments(QVariantMap arguments); + virtual QVariantMap getArguments(); // this is called from updateAction and should be overridden by subclasses virtual void updateActionWorker(float deltaTimeStep) = 0; @@ -46,6 +46,8 @@ public: virtual QByteArray serialize() const = 0; virtual void deserialize(QByteArray serializedArguments) = 0; + virtual bool lifetimeIsOver(); + protected: virtual btRigidBody* getRigidBody(); @@ -59,11 +61,11 @@ protected: virtual void setAngularVelocity(glm::vec3 angularVelocity); virtual void activateBody(); -private: - -protected: bool _active; EntityItemWeakPointer _ownerEntity; + + float _expires; // in seconds since epoch + QString _tag; }; #endif // hifi_ObjectAction_h diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index 2c1b391ba5..448ec34689 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -80,6 +80,9 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) { bool ObjectActionOffset::updateArguments(QVariantMap arguments) { + if (!ObjectAction::updateArguments(arguments)) { + return false; + } bool ok = true; glm::vec3 pointToOffsetFrom = EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", ok, true); @@ -90,7 +93,7 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { ok = true; float linearTimeScale = EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", ok, false); - if (!ok) { + if (!ok) { linearTimeScale = _linearTimeScale; } @@ -119,7 +122,7 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { } QVariantMap ObjectActionOffset::getArguments() { - QVariantMap arguments; + QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&] { arguments["pointToOffsetFrom"] = glmToQMap(_pointToOffsetFrom); arguments["linearTimeScale"] = _linearTimeScale; @@ -140,6 +143,9 @@ QByteArray ObjectActionOffset::serialize() const { dataStream << _linearTimeScale; dataStream << _positionalTargetSet; + dataStream << _expires; + dataStream << _tag; + return ba; } @@ -165,5 +171,8 @@ void ObjectActionOffset::deserialize(QByteArray serializedArguments) { dataStream >> _linearTimeScale; dataStream >> _positionalTargetSet; + dataStream >> _expires; + dataStream >> _tag; + _active = true; } diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index d163933299..7d0bab5143 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -109,6 +109,9 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { const float MIN_TIMESCALE = 0.1f; bool ObjectActionSpring::updateArguments(QVariantMap arguments) { + if (!ObjectAction::updateArguments(arguments)) { + return false; + } // targets are required, spring-constants are optional bool ok = true; glm::vec3 positionalTarget = @@ -155,7 +158,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { } QVariantMap ObjectActionSpring::getArguments() { - QVariantMap arguments; + QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&] { arguments["linearTimeScale"] = _linearTimeScale; arguments["targetPosition"] = glmToQMap(_positionalTarget); @@ -182,6 +185,9 @@ QByteArray ObjectActionSpring::serialize() const { dataStream << _angularTimeScale; dataStream << _rotationalTargetSet; + dataStream << _expires; + dataStream << _tag; + return serializedActionArguments; } @@ -210,5 +216,8 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { dataStream >> _angularTimeScale; dataStream >> _rotationalTargetSet; + dataStream >> _expires; + dataStream >> _tag; + _active = true; } From b34ea6ded499a401f92057b1b7ac5936ba82d52f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 13:46:23 -0700 Subject: [PATCH 60/81] store action lifetime as an expires integer --- examples/grab.js | 37 +++++++++++++++++++++++--- libraries/physics/src/ObjectAction.cpp | 20 +++++++------- libraries/physics/src/ObjectAction.h | 2 +- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 15bab17f20..52b2a66546 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -15,6 +15,33 @@ var ZERO_VEC3 = {x: 0, y: 0, z: 0}; var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0}; +if (typeof String.prototype.startsWith != 'function') { + // see below for better implementation! + String.prototype.startsWith = function (str){ + return this.indexOf(str) === 0; + }; +} + +function getTag() { + return "grab-" + MyAvatar.sessionUUID; +} + +function entityIsGrabbedByOther(entityID) { + var actionIDs = Entities.getActionIDs(entityID); + for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) { + var actionID = actionIDs[actionIndex]; + var actionArguments = Entities.getActionArguments(entityID, actionID); + var tag = actionArguments["tag"]; + if (tag == getTag()) { + continue; + } + if (tag.startsWith("grab-")) { + return true; + } + } + return false; +} + // helper function function mouseIntersectionWithPlane(pointOnPlane, planeNormal, event, maxDistance) { var cameraPosition = Camera.getPosition(); @@ -288,7 +315,7 @@ Grabber.prototype.moveEvent = function(event) { } this.currentPosition = entityProperties.position; - var actionArgs = {tag: "grab", lifetime: 5}; + var actionArgs = {tag: getTag(), lifetime: 5}; if (this.mode === "rotate") { var drag = mouse.getDrag(); @@ -303,7 +330,7 @@ Grabber.prototype.moveEvent = function(event) { // var qZero = entityProperties.rotation; //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: "grab", lifetime: 5}; + actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), lifetime: 5}; } else { var newPointOnPlane; if (this.mode === "verticalCylinder") { @@ -327,13 +354,15 @@ Grabber.prototype.moveEvent = function(event) { } } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: "grab", lifetime: 5}; + actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), lifetime: 5}; beacon.updatePosition(this.targetPosition); } if (!this.actionID) { - this.actionID = Entities.addAction("spring", this.entityID, actionArgs); + if (!entityIsGrabbedByOther(this.entityID)) { + this.actionID = Entities.addAction("spring", this.entityID, actionArgs); + } } else { Entities.updateAction(this.entityID, this.actionID, actionArgs); } diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 8c382f8dad..82395c21cf 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -31,8 +31,8 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta return; } - if (_expires > 0.0f) { - float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (_expires > 0) { + quint64 now = usecTimestampNow(); if (now > _expires) { EntityItemPointer ownerEntity = _ownerEntity.lock(); _active = false; @@ -53,10 +53,10 @@ bool ObjectAction::updateArguments(QVariantMap arguments) { bool lifetimeSet = true; float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); if (lifetimeSet) { - float now = (float)usecTimestampNow() / USECS_PER_SECOND; - _expires = now + lifetime; + quint64 now = usecTimestampNow(); + _expires = now + (quint64)(lifetime * USECS_PER_SECOND); } else { - _expires = 0.0f; + _expires = 0; } bool tagSet = true; @@ -72,11 +72,11 @@ bool ObjectAction::updateArguments(QVariantMap arguments) { QVariantMap ObjectAction::getArguments() { QVariantMap arguments; - float now = (float)usecTimestampNow() / USECS_PER_SECOND; - if (_expires == 0.0f) { + if (_expires == 0) { arguments["lifetime"] = 0.0f; } else { - arguments["lifetime"] = _expires - now; + quint64 now = usecTimestampNow(); + arguments["lifetime"] = (float)(_expires - now) / (float)USECS_PER_SECOND; } arguments["tag"] = _tag; return arguments; @@ -183,11 +183,11 @@ void ObjectAction::activateBody() { } bool ObjectAction::lifetimeIsOver() { - if (_expires == 0.0f) { + if (_expires == 0) { return false; } - float now = (float)usecTimestampNow() / USECS_PER_SECOND; + quint64 now = usecTimestampNow(); if (now >= _expires) { return true; } diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 380263577a..5c29ac9892 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -64,7 +64,7 @@ protected: bool _active; EntityItemWeakPointer _ownerEntity; - float _expires; // in seconds since epoch + quint64 _expires; // in seconds since epoch QString _tag; }; From f746a970de5c849d5c687ca9ddb1c3c1a015c380 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:03:10 -0700 Subject: [PATCH 61/81] don't grab something if someone else is already grabbing it --- examples/controllers/handControllerGrab.js | 69 ++++++++++++++++------ 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 144500e4de..6bd1949cd3 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -91,6 +91,27 @@ var currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; var noCollisionsCount = 0; // how many hands want collisions disabled? +function getTag() { + return "grab-" + MyAvatar.sessionUUID; +} + +function entityIsGrabbedByOther(entityID) { + var actionIDs = Entities.getActionIDs(entityID); + for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) { + var actionID = actionIDs[actionIndex]; + var actionArguments = Entities.getActionArguments(entityID, actionID); + var tag = actionArguments["tag"]; + if (tag == getTag()) { + continue; + } + if (tag.startsWith("grab-")) { + return true; + } + } + return false; +} + + function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -320,14 +341,17 @@ function MyController(hand, triggerAction) { this.handPreviousPosition = handControllerPosition; this.handPreviousRotation = handRotation; - this.actionID = Entities.addAction("spring", this.grabbedEntity, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - tag: "grab", - lifetime: 5 - }); + this.actionID = NULL_ACTION_ID; + if (!entityIsGrabbedByOther(this.grabbedEntity)) { + this.actionID = Entities.addAction("spring", this.grabbedEntity, { + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + tag: getTag(), + lifetime: 5 + }); + } if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } @@ -392,11 +416,11 @@ function MyController(hand, triggerAction) { var handMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, handToAvatar), handToAvatar); var objectMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, objectToAvatar), objectToAvatar); this.currentAvatarOrientation = currentOrientation; - + // how far did hand move this timestep? var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; - + // magnify the hand movement but not the change from avatar movement & rotation handMoved = Vec3.subtract(handMoved, avatarDeltaPosition); handMoved = Vec3.subtract(handMoved, handMovementFromTurning); @@ -439,7 +463,7 @@ function MyController(hand, triggerAction) { if (this.triggerSmoothedReleased()) { // HACK -- until we have collision groups, don't allow held object to collide with avatar this.revertAvatarCollisions(); - + this.state = STATE_RELEASE; return; } @@ -460,12 +484,17 @@ function MyController(hand, triggerAction) { var offset = Vec3.subtract(currentObjectPosition, handPosition); var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: offsetPosition, - relativeRotation: offsetRotation - }); + this.actionID = NULL_ACTION_ID; + if (!entityIsGrabbedByOther(this.grabbedEntity)) { + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: offsetPosition, + relativeRotation: offsetRotation, + tag: getTag(), + lifetime: 5 + }); + } if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { @@ -488,7 +517,7 @@ function MyController(hand, triggerAction) { if (this.triggerSmoothedReleased()) { // HACK -- until we have collision groups, don't allow held object to collide with avatar this.revertAvatarCollisions(); - + this.state = STATE_RELEASE; return; } @@ -498,7 +527,7 @@ function MyController(hand, triggerAction) { // object's actual held offset is an idea intended to make it easier to throw things: // Because we might catch something or transfer it between hands without a good idea // of it's actual offset, let's try imparting a velocity which is at a fixed radius - // from the palm. + // from the palm. var handControllerPosition = Controller.getSpatialControlPosition(this.tip); var now = Date.now(); @@ -510,6 +539,8 @@ function MyController(hand, triggerAction) { this.currentHandControllerTipPosition = handControllerPosition; this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); + + Entities.updateAction(this.grabbedEntity, this.actionID, {lifetime: 5}); }; this.nearGrabbingNonColliding = function() { From c27766facbcaad439d98127a031a781c23f0efec Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:07:23 -0700 Subject: [PATCH 62/81] move string startswith to utils.js --- examples/grab.js | 8 -------- examples/libraries/utils.js | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 52b2a66546..3a9ce9921d 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -14,14 +14,6 @@ var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be gr var ZERO_VEC3 = {x: 0, y: 0, z: 0}; var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0}; - -if (typeof String.prototype.startsWith != 'function') { - // see below for better implementation! - String.prototype.startsWith = function (str){ - return this.indexOf(str) === 0; - }; -} - function getTag() { return "grab-" + MyAvatar.sessionUUID; } diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index f6f635c73a..2ee9bdd5fb 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -179,3 +179,9 @@ pointInExtents = function(point, minPoint, maxPoint) { (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z); } + +if (typeof String.prototype.startsWith != 'function') { + String.prototype.startsWith = function (str){ + return this.slice(0, str.length) == str; + }; +} From b417abc3de44acda7caadd4e76b64e88433dd2d3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:16:07 -0700 Subject: [PATCH 63/81] try again on string startswith --- examples/controllers/handControllerGrab.js | 2 +- examples/grab.js | 2 +- examples/libraries/utils.js | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 6bd1949cd3..aaa894a887 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -104,7 +104,7 @@ function entityIsGrabbedByOther(entityID) { if (tag == getTag()) { continue; } - if (tag.startsWith("grab-")) { + if (tag.slice(0, 5) == "grab-") { return true; } } diff --git a/examples/grab.js b/examples/grab.js index 3a9ce9921d..3e0212bbba 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -27,7 +27,7 @@ function entityIsGrabbedByOther(entityID) { if (tag == getTag()) { continue; } - if (tag.startsWith("grab-")) { + if (tag.slice(0, 5) == "grab-") { return true; } } diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index 2ee9bdd5fb..f6f635c73a 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -179,9 +179,3 @@ pointInExtents = function(point, minPoint, maxPoint) { (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z); } - -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; -} From 9cf49597a69bba1dee45d0a14d01d877990c3cd9 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 14:16:41 -0700 Subject: [PATCH 64/81] fix possible crash from null coming from _sentPackets --- libraries/networking/src/SentPacketHistory.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/SentPacketHistory.cpp b/libraries/networking/src/SentPacketHistory.cpp index 14b4677fc3..fbb7eff41a 100644 --- a/libraries/networking/src/SentPacketHistory.cpp +++ b/libraries/networking/src/SentPacketHistory.cpp @@ -51,5 +51,9 @@ const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) const { } QReadLocker locker(&_packetsLock); - return _sentPackets.get(seqDiff)->get(); + auto packet = _sentPackets.get(seqDiff); + if (packet) { + return packet->get(); + } + return nullptr; } From dd0a16df047d9472088c469defe6c7d486f6a803 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:19:59 -0700 Subject: [PATCH 65/81] don't leave search state if we intersect something that someone else is already grabbing --- examples/actionInspector.js | 4 ++-- examples/controllers/handControllerGrab.js | 21 ++++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/actionInspector.js b/examples/actionInspector.js index 7e342b9e11..934120ddf6 100644 --- a/examples/actionInspector.js +++ b/examples/actionInspector.js @@ -49,8 +49,8 @@ function actionArgumentsToString(actionArguments) { function updateOverlay(entityID, actionText) { - var properties = Entities.getEntityProperties(entityID, ["position"]); - var position = Vec3.sum(properties.position, {x:0, y:1, z:0}); + var properties = Entities.getEntityProperties(entityID, ["position", "dimensions"]); + var position = Vec3.sum(properties.position, {x:0, y:properties.dimensions.y, z:0}); // print("position: " + vec3toStr(position) + " " + actionText); if (entityID in overlays) { var overlay = overlays[entityID]; diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index aaa894a887..4037ae66dc 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -273,7 +273,8 @@ function MyController(hand, triggerAction) { var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && - intersection.properties.locked === 0) { + intersection.properties.locked === 0 && + !entityIsGrabbedByOther(intersection.entityID)) { // the ray is intersecting something we can move. var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); @@ -342,16 +343,14 @@ function MyController(hand, triggerAction) { this.handPreviousRotation = handRotation; this.actionID = NULL_ACTION_ID; - if (!entityIsGrabbedByOther(this.grabbedEntity)) { - this.actionID = Entities.addAction("spring", this.grabbedEntity, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - tag: getTag(), - lifetime: 5 - }); - } + this.actionID = Entities.addAction("spring", this.grabbedEntity, { + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + tag: getTag(), + lifetime: 5 + }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } From 0063eee4a07b9d39c5993b4fd11cd0a0d3fc89d3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 30 Sep 2015 14:47:12 -0700 Subject: [PATCH 66/81] Fix issue with nackPacketList being accessed after being moved --- .../octree/OctreeInboundPacketProcessor.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index 4ae07042e8..cb94990037 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -238,7 +238,6 @@ int OctreeInboundPacketProcessor::sendNackPackets() { return 0; } - auto nackPacketList = NLPacketList::create(_myServer->getMyEditNackType()); auto nodeList = DependencyManager::get(); int packetsSent = 0; @@ -272,18 +271,19 @@ int OctreeInboundPacketProcessor::sendNackPackets() { auto it = missingSequenceNumbers.constBegin(); - while (it != missingSequenceNumbers.constEnd()) { - unsigned short int sequenceNumber = *it; - nackPacketList->writePrimitive(sequenceNumber); - ++it; - } - - - if (nackPacketList->getNumPackets()) { + if (it != missingSequenceNumbers.constEnd()) { + auto nackPacketList = NLPacketList::create(_myServer->getMyEditNackType()); + + while (it != missingSequenceNumbers.constEnd()) { + unsigned short int sequenceNumber = *it; + nackPacketList->writePrimitive(sequenceNumber); + ++it; + } + qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID; - + packetsSent += nackPacketList->getNumPackets(); - + // send the list of nack packets nodeList->sendPacketList(std::move(nackPacketList), *destinationNode); } From 34dc8bdbcb8de07f6e6726efefd9462c67f241d5 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 15:34:35 -0700 Subject: [PATCH 67/81] fix possible crash in agent --- assignment-client/src/Agent.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 157154606f..47db78b5e4 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -364,10 +364,14 @@ void Agent::processAgentAvatarAndAudio(float deltaTime) { } void Agent::aboutToFinish() { - _scriptEngine->stop(); + if (_scriptEngine) { + _scriptEngine->stop(); + } - _pingTimer->stop(); - delete _pingTimer; + if (_pingTimer) { + _pingTimer->stop(); + delete _pingTimer; + } // our entity tree is going to go away so tell that to the EntityScriptingInterface DependencyManager::get()->setEntityTree(NULL); From 42d90457707248eff86e10b15626d3bf42387005 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 16:02:33 -0700 Subject: [PATCH 68/81] possible fix for crashing agents acting like avatars --- assignment-client/src/Agent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 47db78b5e4..4438782ae5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -364,6 +364,7 @@ void Agent::processAgentAvatarAndAudio(float deltaTime) { } void Agent::aboutToFinish() { + setIsAvatar(false);// will stop timers for sending billboards and identity packets if (_scriptEngine) { _scriptEngine->stop(); } From 4e057e5adafcbc47b48cdc724d9d8a46c2c14064 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 16:03:54 -0700 Subject: [PATCH 69/81] increase action lifetime to be more forgiving of clock skew. remove code that makes avatar a ghost while holding something --- examples/controllers/handControllerGrab.js | 56 ++-------------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index aaa894a887..cf2562af62 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -66,6 +66,7 @@ var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line will hang around var startTime = Date.now(); var LIFETIME = 10; +var ACTION_LIFETIME = 120; // 2 minutes // states for the state machine var STATE_OFF = 0; @@ -81,16 +82,6 @@ var STATE_RELEASE = 8; var GRAB_USER_DATA_KEY = "grabKey"; var GRABBABLE_DATA_KEY = "grabbableKey"; -// HACK -- until we have collision groups, don't allow held object to collide with avatar -var AVATAR_COLLISIONS_MENU_ITEM = "Enable avatar collisions"; - - -// HACK -- until we have collision groups, don't allow held object to collide with avatar -var initialAvatarCollisionsMenu = Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM); -var currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; -var noCollisionsCount = 0; // how many hands want collisions disabled? - - function getTag() { return "grab-" + MyAvatar.sessionUUID; } @@ -173,28 +164,6 @@ function MyController(hand, triggerAction) { } }; - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.disableAvatarCollisions = function() { - noCollisionsCount += 1; - if (currentAvatarCollisionsMenu != false) { - currentAvatarCollisionsMenu = false; - Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, false); - MyAvatar.updateMotionBehaviorFromMenu(); - } - } - - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions = function() { - noCollisionsCount -= 1; - if (noCollisionsCount < 1) { - if (currentAvatarCollisionsMenu != initialAvatarCollisionsMenu) { - currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; - Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, initialAvatarCollisionsMenu); - MyAvatar.updateMotionBehaviorFromMenu(); - } - } - } - this.lineOn = function(closePoint, farPoint, color) { // draw a line if (this.pointer === null) { @@ -327,9 +296,6 @@ function MyController(hand, triggerAction) { this.distanceHolding = function() { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.disableAvatarCollisions(); - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); @@ -349,7 +315,7 @@ function MyController(hand, triggerAction) { targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, tag: getTag(), - lifetime: 5 + lifetime: ACTION_LIFETIME }); } if (this.actionID === NULL_ACTION_ID) { @@ -374,9 +340,6 @@ function MyController(hand, triggerAction) { this.continueDistanceHolding = function() { if (this.triggerSmoothedReleased()) { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.state = STATE_RELEASE; return; } @@ -451,19 +414,13 @@ function MyController(hand, triggerAction) { linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - lifetime: 5 + lifetime: ACTION_LIFETIME }); }; this.nearGrabbing = function() { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.disableAvatarCollisions(); - if (this.triggerSmoothedReleased()) { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.state = STATE_RELEASE; return; } @@ -492,7 +449,7 @@ function MyController(hand, triggerAction) { relativePosition: offsetPosition, relativeRotation: offsetRotation, tag: getTag(), - lifetime: 5 + lifetime: ACTION_LIFETIME }); } if (this.actionID === NULL_ACTION_ID) { @@ -515,9 +472,6 @@ function MyController(hand, triggerAction) { this.continueNearGrabbing = function() { if (this.triggerSmoothedReleased()) { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.state = STATE_RELEASE; return; } @@ -540,7 +494,7 @@ function MyController(hand, triggerAction) { this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - Entities.updateAction(this.grabbedEntity, this.actionID, {lifetime: 5}); + Entities.updateAction(this.grabbedEntity, this.actionID, {lifetime: ACTION_LIFETIME}); }; this.nearGrabbingNonColliding = function() { From 91965db5abc61ce3d4a8601bc9ecab2451f3746b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 16:07:22 -0700 Subject: [PATCH 70/81] increase action lifetime to be more forgiving of clock skew. remove code that makes avatar a ghost while holding something --- examples/grab.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 3e0212bbba..43a5ed220b 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -13,6 +13,7 @@ var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be grabbed var ZERO_VEC3 = {x: 0, y: 0, z: 0}; var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0}; +var ACTION_LIFETIME = 120; // 2 minutes function getTag() { return "grab-" + MyAvatar.sessionUUID; @@ -307,7 +308,7 @@ Grabber.prototype.moveEvent = function(event) { } this.currentPosition = entityProperties.position; - var actionArgs = {tag: getTag(), lifetime: 5}; + var actionArgs = {tag: getTag(), lifetime: ACTION_LIFETIME}; if (this.mode === "rotate") { var drag = mouse.getDrag(); @@ -322,7 +323,7 @@ Grabber.prototype.moveEvent = function(event) { // var qZero = entityProperties.rotation; //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), lifetime: 5}; + actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), lifetime: ACTION_LIFETIME}; } else { var newPointOnPlane; if (this.mode === "verticalCylinder") { @@ -346,7 +347,7 @@ Grabber.prototype.moveEvent = function(event) { } } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), lifetime: 5}; + actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), lifetime: ACTION_LIFETIME}; beacon.updatePosition(this.targetPosition); } From c55d627e9bd33f302d4e33a1c323dfb07d2343ad Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 16:12:27 -0700 Subject: [PATCH 71/81] Different model, different sounds, release interval --- .../toys/ping_pong_gun/createPingPongGun.js | 6 +-- examples/toys/ping_pong_gun/pingPongGun.js | 54 ++++++++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index 1bf0415ebd..d8509d8a63 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -31,9 +31,9 @@ var pingPongGun = Entities.addEntity({ script: scriptURL, position: center, dimensions: { - x: 0.1, - y: 0.06, - z: 0.03 + x:0.67, + y: 0.14, + z: 0.09 }, collisionsWillMove: true, }); diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index da7a4a6d28..0a589fb3fb 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -13,8 +13,7 @@ Script.include("../../libraries/utils.js"); - var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - + var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav'; function PingPongGun() { return; @@ -22,20 +21,36 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.08; - var GUN_TIP_UP_OFFSET = 0.020; - var GUN_FORCE = 5; + var GUN_TIP_FWD_OFFSET = -0.55; + var GUN_TIP_UP_OFFSET = 0.040; + var GUN_FORCE = 15; + var BALL_RESTITUTION = 0.6; + var BALL_LINEAR_DAMPING = 0.4; var BALL_GRAVITY = { x: 0, - y: -1, + y: -9.8, z: 0 }; + var BALL_DIMENSIONS = { + x: 0.04, + y: 0.04, + z: 0.04 + } + + + var BALL_COLOR = { + red: 255, + green: 255, + blue: 255 + } + PingPongGun.prototype = { hand: null, whichHand: null, gunTipPosition: null, canShoot: false, + canShootTimeout: null, setRightHand: function() { this.hand = 'RIGHT'; }, @@ -53,16 +68,23 @@ }, continueNearGrab: function() { + if (this.whichHand === null) { //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten this.setWhichHand(); } else { + if (this.canShootTimeout !== null) { + Script.clearTimeout(this.canShootTimeout); + } this.checkTriggerPressure(this.whichHand); } }, releaseGrab: function() { - this.canShoot = false; + var _t = this; + this.canShootTimeout = Script.setTimeout(function() { + _t.canShoot = false; + }, 250) }, checkTriggerPressure: function(gunHand) { @@ -89,20 +111,12 @@ forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { type: 'Sphere', - color: { - red: 255, - green: 255, - blue: 255 - }, - dimensions: { - x: 0.02, - y: 0.02, - z: 0.02 - }, - linearDamping: 0.2, + color: BALL_COLOR, + dimensions: BALL_DIMENSIONS, + linearDamping: BALL_LINEAR_DAMPING, gravity: BALL_GRAVITY, + restitution: BALL_RESTITUTION, collisionsWillMove: true, - collisionSoundURL: SHOOTING_SOUND_URL, rotation: gunProperties.rotation, position: this.getGunTipPosition(gunProperties), velocity: forwardVec, @@ -116,7 +130,7 @@ playSoundAtCurrentPosition: function(position) { var audioProperties = { - volume: 0.25, + volume: 0.1, position: position }; From d993d397184a24d3d7b742fcadee6821cc96d10c Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 30 Sep 2015 16:28:33 -0700 Subject: [PATCH 72/81] Bug fix for deriveBodyFromHMDSensor calculations The calculation that determined where the body position relative to the HMD was incorrect, one of the components was in the wrong coordinate frame. Now use the skeleton's bind pose to compute the proper avatar offsets for the eyes, neck and hips. Use these offsets to calculate where the hips should be given a specific hmd position and orientation. Also, added a bug fix for Rig, which would cause a -1 index deference when an avatar was missing certain named joints, such as, "LeftEye", "Neck" and "Head". --- interface/src/avatar/MyAvatar.cpp | 62 +++++++++++++++++++++++++++---- libraries/animation/src/Rig.cpp | 17 +++++++-- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8f7af63a81..a57740a691 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -271,6 +271,25 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } +// returns true if pos is OUTSIDE of the vertical capsule +// where the middle cylinder length is defined by capsuleLen and the radius by capsuleRad. +static bool capsuleCheck(const glm::vec3& pos, float capsuleLen, float capsuleRad) { + const float halfCapsuleLen = capsuleLen / 2.0f; + if (fabs(pos.y) <= halfCapsuleLen) { + // cylinder check for middle capsule + glm::vec2 horizPos(pos.x, pos.z); + return glm::length(horizPos) > capsuleRad; + } else if (pos.y > halfCapsuleLen) { + glm::vec3 center(0.0f, halfCapsuleLen, 0.0f); + return glm::length(center - pos) > capsuleRad; + } else if (pos.y < halfCapsuleLen) { + glm::vec3 center(0.0f, -halfCapsuleLen, 0.0f); + return glm::length(center - pos) > capsuleRad; + } else { + return false; + } +} + // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD // as it moves through the world. @@ -289,11 +308,14 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); const float STRAIGHTING_LEAN_DURATION = 0.5f; // seconds - const float STRAIGHTING_LEAN_THRESHOLD = 0.2f; // meters + + // define a vertical capsule + const float STRAIGHTING_LEAN_CAPSULE_RADIUS = 0.2f; // meters + const float STRAIGHTING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - if (!_straightingLean && glm::length(diff) > STRAIGHTING_LEAN_THRESHOLD) { + if (!_straightingLean && capsuleCheck(diff, STRAIGHTING_LEAN_CAPSULE_LENGTH, STRAIGHTING_LEAN_CAPSULE_RADIUS)) { // begin homing toward derived body position. _straightingLean = true; @@ -1854,13 +1876,39 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { const glm::quat hmdOrientation = getHMDSensorOrientation(); const glm::quat hmdOrientationYawOnly = cancelOutRollAndPitch(hmdOrientation); - // In sensor space, figure out where the avatar body should be, - // by applying offsets from the avatar's neck & head joints. - vec3 localEyes = _skeletonModel.getDefaultEyeModelPosition(); - vec3 localNeck(0.0f, 0.48f, 0.0f); // start with some kind of guess if the skeletonModel is not loaded yet. - _skeletonModel.getLocalNeckPosition(localNeck); + const glm::vec3 DEFAULT_RIGHT_EYE_POS(-0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_LEFT_EYE_POS(0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_NECK_POS(0.0f, 1.5f, 0.0f); + const glm::vec3 DEFAULT_HIPS_POS(0.0f, 1.0f, 0.0f); + + vec3 localEyes, localNeck; + if (!_debugDrawSkeleton) { + const glm::quat rotY180 = glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)); + localEyes = rotY180 * (((DEFAULT_RIGHT_EYE_POS + DEFAULT_LEFT_EYE_POS) / 2.0f) - DEFAULT_HIPS_POS); + localNeck = rotY180 * (DEFAULT_NECK_POS - DEFAULT_HIPS_POS); + } else { + // TODO: At the moment MyAvatar does not have access to the rig, which has the skeleton, which has the bind poses. + // for now use the _debugDrawSkeleton, which is initialized with the same FBX model as the rig. + + // TODO: cache these indices. + int rightEyeIndex = _debugDrawSkeleton->nameToJointIndex("RightEye"); + int leftEyeIndex = _debugDrawSkeleton->nameToJointIndex("LeftEye"); + int neckIndex = _debugDrawSkeleton->nameToJointIndex("Neck"); + int hipsIndex = _debugDrawSkeleton->nameToJointIndex("Hips"); + + glm::vec3 absRightEyePos = rightEyeIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(rightEyeIndex).trans : DEFAULT_RIGHT_EYE_POS; + glm::vec3 absLeftEyePos = leftEyeIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(leftEyeIndex).trans : DEFAULT_LEFT_EYE_POS; + glm::vec3 absNeckPos = neckIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(neckIndex).trans : DEFAULT_NECK_POS; + glm::vec3 absHipsPos = neckIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(hipsIndex).trans : DEFAULT_HIPS_POS; + + const glm::quat rotY180 = glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)); + localEyes = rotY180 * (((absRightEyePos + absLeftEyePos) / 2.0f) - absHipsPos); + localNeck = rotY180 * (absNeckPos - absHipsPos); + } // apply simplistic head/neck model + // figure out where the avatar body should be by applying offsets from the avatar's neck & head joints. + // eyeToNeck offset is relative full HMD orientation. // while neckToRoot offset is only relative to HMDs yaw. glm::vec3 eyeToNeck = hmdOrientation * (localNeck - localEyes); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0022749d51..1e512ee767 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1026,12 +1026,21 @@ static void computeHeadNeckAnimVars(AnimSkeleton::ConstPointer skeleton, const A const glm::quat hmdOrientation = hmdPose.rot * rotY180; // rotY180 will make z forward not -z // TODO: cache jointIndices + int rightEyeIndex = skeleton->nameToJointIndex("RightEye"); + int leftEyeIndex = skeleton->nameToJointIndex("LeftEye"); + int headIndex = skeleton->nameToJointIndex("Head"); + int neckIndex = skeleton->nameToJointIndex("Neck"); + + const glm::vec3 DEFAULT_RIGHT_EYE_POS(-0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_LEFT_EYE_POS(0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_HEAD_POS(0.0f, 1.55f, 0.0f); + const glm::vec3 DEFAULT_NECK_POS(0.0f, 1.5f, 0.0f); // Use absolute bindPose positions just in case the relBindPose have rotations we don't expect. - glm::vec3 absRightEyePos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("RightEye")).trans; - glm::vec3 absLeftEyePos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("LeftEye")).trans; - glm::vec3 absHeadPos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Head")).trans; - glm::vec3 absNeckPos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Neck")).trans; + glm::vec3 absRightEyePos = rightEyeIndex != -1 ? skeleton->getAbsoluteBindPose(rightEyeIndex).trans : DEFAULT_RIGHT_EYE_POS; + glm::vec3 absLeftEyePos = leftEyeIndex != -1 ? skeleton->getAbsoluteBindPose(leftEyeIndex).trans : DEFAULT_LEFT_EYE_POS; + glm::vec3 absHeadPos = headIndex != -1 ? skeleton->getAbsoluteBindPose(headIndex).trans : DEFAULT_HEAD_POS; + glm::vec3 absNeckPos = neckIndex != -1 ? skeleton->getAbsoluteBindPose(neckIndex).trans : DEFAULT_NECK_POS; glm::vec3 absCenterEyePos = (absRightEyePos + absLeftEyePos) / 2.0f; glm::vec3 eyeOffset = absCenterEyePos - absHeadPos; From c01077a0d7c425ceadac7f9f3f1335c5107b44ca Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 17:30:34 -0700 Subject: [PATCH 73/81] real fix --- assignment-client/src/Agent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 4438782ae5..d9109703cb 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -233,8 +233,8 @@ void Agent::setIsAvatar(bool isAvatar) { } if (_avatarBillboardTimer) { - _avatarIdentityTimer->stop(); - delete _avatarIdentityTimer; + _avatarBillboardTimer->stop(); + delete _avatarBillboardTimer; _avatarBillboardTimer = nullptr; } } From 5da5bd47af36c83eb5d19bdb7f494c93b509abb9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 30 Sep 2015 21:45:22 -0400 Subject: [PATCH 74/81] add a missing rename for socket Q_ASSERT_X --- libraries/networking/src/udt/Connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 1bda840a6c..e8b22f6ab8 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -32,7 +32,7 @@ Connection::Connection(Socket* parentSocket, HifiSockAddr destination, std::uniq _destination(destination), _congestionControl(move(congestionControl)) { - Q_ASSERT_X(socket, "Connection::Connection", "Must be called with a valid Socket*"); + Q_ASSERT_X(parentSocket, "Connection::Connection", "Must be called with a valid Socket*"); Q_ASSERT_X(_congestionControl, "Connection::Connection", "Must be called with a valid CongestionControl object"); _congestionControl->init(); From d4f954a0e2ee1c5c27bcd161bb6fd1a8be880923 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Oct 2015 10:25:30 -0700 Subject: [PATCH 75/81] allow more than one near-grab on an object --- examples/controllers/handControllerGrab.js | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index e756866b1c..4dd9dca7a2 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -242,8 +242,7 @@ function MyController(hand, triggerAction) { var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && - intersection.properties.locked === 0 && - !entityIsGrabbedByOther(intersection.entityID)) { + intersection.properties.locked === 0) { // the ray is intersecting something we can move. var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); @@ -258,6 +257,10 @@ function MyController(hand, triggerAction) { this.state = STATE_NEAR_GRABBING; } else { + if (entityIsGrabbedByOther(intersection.entityID)) { + // don't allow two people to distance grab the same object + return; + } // the hand is far from the intersected object. go into distance-holding mode this.state = STATE_DISTANCE_HOLDING; this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); @@ -441,16 +444,13 @@ function MyController(hand, triggerAction) { var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); this.actionID = NULL_ACTION_ID; - if (!entityIsGrabbedByOther(this.grabbedEntity)) { - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: offsetPosition, - relativeRotation: offsetRotation, - tag: getTag(), - lifetime: ACTION_LIFETIME - }); - } + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: offsetPosition, + relativeRotation: offsetRotation, + lifetime: ACTION_LIFETIME + }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { From 2700529b33921a9c2fc1f526256faca759a42c47 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Oct 2015 10:41:43 -0700 Subject: [PATCH 76/81] lower action lifetime --- examples/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 4dd9dca7a2..5705bd4498 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -66,7 +66,7 @@ var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line will hang around var startTime = Date.now(); var LIFETIME = 10; -var ACTION_LIFETIME = 120; // 2 minutes +var ACTION_LIFETIME = 10; // seconds // states for the state machine var STATE_OFF = 0; From 335d87134b73d80adaf14ad40984dbfab7a0f0c0 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 1 Oct 2015 10:58:31 -0700 Subject: [PATCH 77/81] Squash compiler warning in AnimVariant. --- libraries/animation/src/AnimVariant.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h index 700a8b4121..cb886cd369 100644 --- a/libraries/animation/src/AnimVariant.h +++ b/libraries/animation/src/AnimVariant.h @@ -184,6 +184,8 @@ public: case AnimVariant::Type::String: qCDebug(animation) << " " << pair.first << "=" << pair.second.getString(); break; + default: + assert("AnimVariant::Type" == "valid"); } } } From d0bec38603a9de2b97852ca5e96797826aec53e8 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 1 Oct 2015 11:30:50 -0700 Subject: [PATCH 78/81] Fix currentAPI.js --- examples/utilities/tools/currentAPI.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/utilities/tools/currentAPI.js b/examples/utilities/tools/currentAPI.js index 30b24910f9..cb9f152794 100644 --- a/examples/utilities/tools/currentAPI.js +++ b/examples/utilities/tools/currentAPI.js @@ -10,22 +10,21 @@ // var array = []; -var buffer = "\n\n\n\n\n======= JS API list ======="; function listKeys(string, object) { - if (string == "listKeys" || string == "array" || string == "buffer" || string == "i") { + if (string === "listKeys" || string === "array" || string === "buffer" || string === "i") { return; } - if (typeof(object) != "object") { + if (typeof(object) !== "object" || object === null) { array.push(string + " " + typeof(object)); return; } var keys = Object.keys(object); for (var i = 0; i < keys.length; ++i) { - if (string == "") { + if (string === "") { listKeys(keys[i], object[keys[i]]); - } else { + } else if (keys[i] !== "parent") { listKeys(string + "." + keys[i], object[keys[i]]); } } @@ -34,9 +33,10 @@ function listKeys(string, object) { listKeys("", this); array.sort(); +var buffer = "\n======= JS API list ======="; for (var i = 0; i < array.length; ++i) { - buffer = buffer + "\n" + array[i]; + buffer += "\n" + array[i]; } -buffer = buffer + "\n========= API END =========\n\n\n\n\n"; +buffer += "\n========= API END =========\n"; print(buffer); From 861aa91572d6c56c1f9357b641be9149a283eb47 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 12:27:45 -0700 Subject: [PATCH 79/81] shoot out of the right end of the gun --- examples/toys/ping_pong_gun/pingPongGun.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 0a589fb3fb..a980fc1bd3 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -21,7 +21,7 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.55; + var GUN_TIP_FWD_OFFSET = 0.45; var GUN_TIP_UP_OFFSET = 0.040; var GUN_FORCE = 15; var BALL_RESTITUTION = 0.6; @@ -106,7 +106,7 @@ }, shootBall: function(gunProperties) { - var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, -90, 0))); forwardVec = Vec3.normalize(forwardVec); forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { From b37bf2b1b68cb191bc8e01760b107a5f0cb22300 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 1 Oct 2015 13:18:22 -0700 Subject: [PATCH 80/81] Remove extra debug --- interface/resources/qml/VrMenu.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/qml/VrMenu.qml b/interface/resources/qml/VrMenu.qml index ef7ae852d4..14a4a449fd 100644 --- a/interface/resources/qml/VrMenu.qml +++ b/interface/resources/qml/VrMenu.qml @@ -196,7 +196,6 @@ Hifi.VrMenu { function insertItem(menu, beforeItem, newMenuItem) { for (var i = 0; i < menu.items.length; ++i) { - console.log(menu.items[i]); if (menu.items[i] === beforeItem) { return menu.insertItem(i, newMenuItem); } From 4a7e3c66bd80eb1dbe2b6dc6ad7b2151d0276e9f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 15:05:25 -0700 Subject: [PATCH 81/81] Update createPingPongGun.js use relative paths --- examples/toys/ping_pong_gun/createPingPongGun.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index d8509d8a63..4b7ed27643 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -9,8 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); - +Script.include("../../utilities.js"); var scriptURL = Script.resolvePath('pingPongGun.js'); @@ -41,4 +40,4 @@ var pingPongGun = Entities.addEntity({ function cleanUp() { Entities.deleteEntity(pingPongGun); } -Script.scriptEnding.connect(cleanUp); \ No newline at end of file +Script.scriptEnding.connect(cleanUp);