From e25d4c17e8943092f9046dab7fe1d7361dc9747c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 25 Nov 2015 09:29:40 +1300 Subject: [PATCH 01/27] Fix InputController (Leap Motion) not able to be created --- .../src/scripting/ControllerScriptingInterface.cpp | 12 ++++++------ .../src/scripting/ControllerScriptingInterface.h | 4 ++-- libraries/script-engine/src/ScriptEngine.cpp | 5 +++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 547f16ea8b..719bfe7f1f 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -84,11 +84,11 @@ glm::vec2 ControllerScriptingInterface::getViewportDimensions() const { return qApp->getUiSize(); } -controller::InputController::Pointer ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) { - // This is where we retreive the Device Tracker category and then the sub tracker within it +controller::InputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) { + // This is where we retrieve the Device Tracker category and then the sub tracker within it auto icIt = _inputControllers.find(0); if (icIt != _inputControllers.end()) { - return (*icIt).second; + return (*icIt).second.get(); } @@ -110,15 +110,15 @@ controller::InputController::Pointer ControllerScriptingInterface::createInputCo controller::InputController::Pointer inputController = std::make_shared(deviceID, trackerID, this); controller::InputController::Key key = inputController->getKey(); _inputControllers.insert(InputControllerMap::value_type(key, inputController)); - return inputController; + return inputController.get(); } } } - return controller::InputController::Pointer(); + return nullptr; } -void ControllerScriptingInterface::releaseInputController(controller::InputController::Pointer input) { +void ControllerScriptingInterface::releaseInputController(controller::InputController* input) { _inputControllers.erase(input->getKey()); } diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index 4c69551dd2..22d8f8be1f 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -96,8 +96,8 @@ public slots: virtual glm::vec2 getViewportDimensions() const; /// Factory to create an InputController - virtual controller::InputController::Pointer createInputController(const QString& deviceName, const QString& tracker); - virtual void releaseInputController(controller::InputController::Pointer input); + virtual controller::InputController* createInputController(const QString& deviceName, const QString& tracker); + virtual void releaseInputController(controller::InputController* input); signals: void keyPressEvent(const KeyEvent& event); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 995a92bf83..49009a3ad2 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -81,6 +81,9 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { out = qobject_cast(object.toQObject()); } +Q_DECLARE_METATYPE(controller::InputController*) +static int inputControllerPointerId = qRegisterMetaType(); + QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) { return engine->newQObject(in); } @@ -89,8 +92,6 @@ void inputControllerFromScriptValue(const QScriptValue &object, controller::Inpu out = qobject_cast(object.toQObject()); } - - static bool hasCorrectSyntax(const QScriptProgram& program) { const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { From 5ecbaa5b93b92ac821db8b3db7af2022990dfef1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 25 Nov 2015 09:43:55 +1300 Subject: [PATCH 02/27] Fix InputController (Leap Motion) not being updated --- interface/src/Application.cpp | 2 ++ interface/src/scripting/ControllerScriptingInterface.cpp | 9 +++++++-- interface/src/scripting/ControllerScriptingInterface.h | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4dc218ecdc..189234894d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2825,6 +2825,8 @@ void Application::update(float deltaTime) { } } + _controllerScriptingInterface->updateInputControllers(); + // Transfer the user inputs to the driveKeys // FIXME can we drop drive keys and just have the avatar read the action states directly? myAvatar->clearDriveKeys(); diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 719bfe7f1f..11053154b6 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -89,8 +89,7 @@ controller::InputController* ControllerScriptingInterface::createInputController auto icIt = _inputControllers.find(0); if (icIt != _inputControllers.end()) { return (*icIt).second.get(); - } - + } // Look for device DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString()); @@ -122,6 +121,12 @@ void ControllerScriptingInterface::releaseInputController(controller::InputContr _inputControllers.erase(input->getKey()); } +void ControllerScriptingInterface::updateInputControllers() { + for (auto it = _inputControllers.begin(); it != _inputControllers.end(); it++) { + (*it).second->update(); + } +} + InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) : _deviceTrackerId(deviceTrackerId), _subTrackerId(subTrackerId), diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index 22d8f8be1f..8bd698cfb2 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -85,6 +85,8 @@ public: bool isKeyCaptured(const KeyEvent& event) const; bool isJoystickCaptured(int joystickIndex) const; + void updateInputControllers(); + public slots: virtual void captureKeyEvents(const KeyEvent& event); From 6736eefbc11e7932d476d0acecd2624dae06fe13 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 25 Nov 2015 14:14:22 +1300 Subject: [PATCH 03/27] Fix arm and finger joint control in leapHands.js for desktop mode --- examples/controllers/leap/leapHands.js | 33 ++++++++++---------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/examples/controllers/leap/leapHands.js b/examples/controllers/leap/leapHands.js index 6bdca051be..04b65349a9 100644 --- a/examples/controllers/leap/leapHands.js +++ b/examples/controllers/leap/leapHands.js @@ -193,13 +193,12 @@ var leapHands = (function () { } // Set avatar arms vertical, forearms horizontal, as "zero" position for calibration - MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, -90.0)); - MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0)); - MyAvatar.setJointData("LeftHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); - MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 90.0)); - MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0)); - MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); - + MyAvatar.setJointRotation("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 0.0)); + MyAvatar.setJointRotation("LeftForeArm", Quat.fromPitchYawRollDegrees(0.0, 90.0, 90.0)); + MyAvatar.setJointRotation("LeftHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); + MyAvatar.setJointRotation("RightArm", Quat.fromPitchYawRollDegrees(90.0,0.0, 0.0)); + MyAvatar.setJointRotation("RightForeArm", Quat.fromPitchYawRollDegrees(0.0, -90.0, -90.0)); + MyAvatar.setJointRotation("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); // Wait for arms to assume their positions before calculating Script.setTimeout(finishCalibration, CALIBRATION_TIME); @@ -421,22 +420,14 @@ var leapHands = (function () { // Hand rotation in camera coordinates ... handRotation = { - x: handRotation.z, - y: handRotation.y, - z: handRotation.x, - w: handRotation.w + x: -handRotation.x, + y: -handRotation.z, + z: -handRotation.y, + w: handRotation.w, }; // Hand rotation in avatar coordinates ... - if (h === 0) { - handRotation.x = -handRotation.x; - handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }), - handRotation); - } else { - handRotation.z = -handRotation.z; - handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 1, z: 0 }), - handRotation); - } + handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation); } // Set hand position and orientation ... @@ -462,7 +453,7 @@ var leapHands = (function () { w: locRotation.w }; } - MyAvatar.setJointData(fingers[h][i][j].jointName, locRotation); + MyAvatar.setJointRotation(fingers[h][i][j].jointName, locRotation); } } } From 566b27156c710a08ef294f3f3ce6508ec70f675a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 25 Nov 2015 15:45:33 +1300 Subject: [PATCH 04/27] Fix hand and finger joint control in leapHands.js for HMD mode --- examples/controllers/leap/leapHands.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/examples/controllers/leap/leapHands.js b/examples/controllers/leap/leapHands.js index 04b65349a9..42df89084d 100644 --- a/examples/controllers/leap/leapHands.js +++ b/examples/controllers/leap/leapHands.js @@ -381,23 +381,14 @@ var leapHands = (function () { // Hand rotation in camera coordinates ... handRotation = { - x: handRotation.z, - y: handRotation.y, - z: handRotation.x, - w: handRotation.w + x: -handRotation.x, + y: -handRotation.z, + z: -handRotation.y, + w: handRotation.w, }; // Hand rotation in avatar coordinates ... - if (h === 0) { - handRotation.x = -handRotation.x; - handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation); - handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 0, z: 1 }), handRotation); - } else { - handRotation.z = -handRotation.z; - handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation); - handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 0, z: 1 }), handRotation); - } - + handRotation = Quat.multiply(Quat.angleAxis(180.0, { x: 0, y: 1, z: 0 }), handRotation); cameraOrientation.x = -cameraOrientation.x; cameraOrientation.z = -cameraOrientation.z; handRotation = Quat.multiply(cameraOrientation, handRotation); From 46cbc349d15d7f103e4568abb42fa183f2e9f7d8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 25 Nov 2015 16:39:09 +1300 Subject: [PATCH 05/27] Fix laserPointer.js for Hydras Leap Motion working already. --- examples/controllers/leap/laserPointer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/controllers/leap/laserPointer.js b/examples/controllers/leap/laserPointer.js index 156e9ba298..c8c3cf372a 100644 --- a/examples/controllers/leap/laserPointer.js +++ b/examples/controllers/leap/laserPointer.js @@ -23,7 +23,8 @@ var laserPointer = (function () { function isHandPointing(hand) { var MINIMUM_TRIGGER_PULL = 0.9; - return Controller.getTriggerValue(hand) > MINIMUM_TRIGGER_PULL; + var controller = hand === 0 ? Controller.Standard.LT : Controller.Standard.RT; + return Controller.getValue(controller) > MINIMUM_TRIGGER_PULL; } function isFingerPointing(hand) { From 6e076985f2ececbb2013cb14d7f72e346ce91394 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 25 Nov 2015 16:46:53 +1300 Subject: [PATCH 06/27] JSLint --- examples/controllers/leap/laserPointer.js | 5 +++-- examples/controllers/leap/leapHands.js | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/controllers/leap/laserPointer.js b/examples/controllers/leap/laserPointer.js index c8c3cf372a..c7d72e6cff 100644 --- a/examples/controllers/leap/laserPointer.js +++ b/examples/controllers/leap/laserPointer.js @@ -22,8 +22,9 @@ var laserPointer = (function () { ]; function isHandPointing(hand) { - var MINIMUM_TRIGGER_PULL = 0.9; - var controller = hand === 0 ? Controller.Standard.LT : Controller.Standard.RT; + var MINIMUM_TRIGGER_PULL = 0.9, + controller; + controller = hand === 0 ? Controller.Standard.LT : Controller.Standard.RT; return Controller.getValue(controller) > MINIMUM_TRIGGER_PULL; } diff --git a/examples/controllers/leap/leapHands.js b/examples/controllers/leap/leapHands.js index 42df89084d..7835df7452 100644 --- a/examples/controllers/leap/leapHands.js +++ b/examples/controllers/leap/leapHands.js @@ -196,7 +196,7 @@ var leapHands = (function () { MyAvatar.setJointRotation("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 0.0)); MyAvatar.setJointRotation("LeftForeArm", Quat.fromPitchYawRollDegrees(0.0, 90.0, 90.0)); MyAvatar.setJointRotation("LeftHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); - MyAvatar.setJointRotation("RightArm", Quat.fromPitchYawRollDegrees(90.0,0.0, 0.0)); + MyAvatar.setJointRotation("RightArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 0.0)); MyAvatar.setJointRotation("RightForeArm", Quat.fromPitchYawRollDegrees(0.0, -90.0, -90.0)); MyAvatar.setJointRotation("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); @@ -384,7 +384,7 @@ var leapHands = (function () { x: -handRotation.x, y: -handRotation.z, z: -handRotation.y, - w: handRotation.w, + w: handRotation.w }; // Hand rotation in avatar coordinates ... @@ -414,7 +414,7 @@ var leapHands = (function () { x: -handRotation.x, y: -handRotation.z, z: -handRotation.y, - w: handRotation.w, + w: handRotation.w }; // Hand rotation in avatar coordinates ... From 1ba6bfa2e010a06a702a91b0b99dba1ec74ae2dc Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 30 Nov 2015 18:58:53 -0800 Subject: [PATCH 07/27] lazers --- examples/controllers/handControllerGrab.js | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 0812dc8980..28e52e0dee 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -318,6 +318,34 @@ function MyController(hand) { }); } + this.overlayLineOn = function(color) { + + var handPosition = this.getHandPosition(); + var distantPickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()), + length: PICK_MAX_DISTANCE + }; + + var end = Vec3.Sum(handPosition, Vec3.multiply(distantPickRay.direction, NEAR_PICK_MAX_DISTANCE)); + + var lineProperties = { + lineWidth: 5, + //get palm position + start: distantPickRay.origin, + end: end, + color: color || { + red: 255, + green: 0, + blue: 255 + }, + ignoreRayIntersection: true, // always ignore this + visible: true, + }; + + this.pointerOverlay = Overlays.addOverlay("line3d", lineProperties); + } + this.lineOn = function(closePoint, farPoint, color) { // draw a line if (this.pointer === null) { From d80bfc0af615d23449bc884f4898b11ac4e43358 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 1 Dec 2015 09:41:04 -0800 Subject: [PATCH 08/27] more gravity for spraycan --- unpublishedScripts/hiddenEntityReset.js | 2 +- unpublishedScripts/masterReset.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index e54be00761..d18b717f7e 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -1134,7 +1134,7 @@ shapeType: 'box', gravity: { x: 0, - y: -0.5, + y: -3.0, z: 0 }, velocity: { diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 4700126e97..185cf4217e 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -1114,7 +1114,7 @@ MasterReset = function() { shapeType: 'box', gravity: { x: 0, - y: -0.5, + y: -3.0, z: 0 }, velocity: { From a3f8c52aa39e518d7d8c2d3d2da7fab5159827d3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 1 Dec 2015 10:09:29 -0800 Subject: [PATCH 09/27] temp fix for doll, moved cat --- examples/toybox/doll/doll.js | 14 ++++++-------- unpublishedScripts/hiddenEntityReset.js | 7 ++++--- unpublishedScripts/masterReset.js | 6 +++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/examples/toybox/doll/doll.js b/examples/toybox/doll/doll.js index 577f86cae2..c8cfbfb72f 100644 --- a/examples/toybox/doll/doll.js +++ b/examples/toybox/doll/doll.js @@ -36,14 +36,10 @@ Entities.editEntity(this.entityID, { animation: { url: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", - currentFrame: 0 + running: true } }); - Entities.editEntity(_this.entityID, { - animationIsPlaying: true - }); - var position = Entities.getEntityProperties(this.entityID, "position").position; this.audioInjector = Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { position: position, @@ -67,8 +63,10 @@ this.audioInjector.stop(); Entities.editEntity(this.entityID, { animation: { - url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - currentFrame: 0 + // Providing actual model fbx for animation used to work, now contorts doll into a weird ball + // See bug: + // url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + running: false, } }); @@ -82,4 +80,4 @@ }; // entity scripts always need to return a newly constructed object of our type return new Doll(); -}); +}); \ No newline at end of file diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index d18b717f7e..9518a6ad45 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -125,11 +125,12 @@ createLights(); createCat({ - x: 551.09, - y: 494.98, - z: 503.49 + x: 551.0, + y: 495.3, + z: 503.3 }); + createSprayCan({ x: 549.7, y: 495.6, diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 185cf4217e..03ee110d7a 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -102,9 +102,9 @@ MasterReset = function() { createCat({ - x: 551.09, - y: 494.98, - z: 503.49 + x: 551.0, + y: 495.3, + z: 503.3 }); From 27227181f0acb8f66f8b02601956b92b39671a2a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Dec 2015 10:40:43 -0800 Subject: [PATCH 10/27] fix for infinite loop in OctreeeInboundPacketProcessor --- .../src/octree/OctreeInboundPacketProcessor.cpp | 10 +++++++--- .../src/octree/OctreeInboundPacketProcessor.h | 3 ++- assignment-client/src/octree/OctreeServer.cpp | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index 0cdc7f9921..e22f241453 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -43,6 +43,7 @@ void OctreeInboundPacketProcessor::resetStats() { _totalPackets = 0; _lastNackTime = usecTimestampNow(); + QWriteLocker locker(&_senderStatsLock); _singleSenderStats.clear(); } @@ -220,6 +221,8 @@ void OctreeInboundPacketProcessor::trackInboundPacket(const QUuid& nodeUUID, uns _totalElementsInPacket += editsInPacket; _totalPackets++; + QWriteLocker locker(&_senderStatsLock); + // find the individual senders stats and track them there too... // see if this is the first we've heard of this node... if (_singleSenderStats.find(nodeUUID) == _singleSenderStats.end()) { @@ -242,6 +245,8 @@ int OctreeInboundPacketProcessor::sendNackPackets() { int packetsSent = 0; int totalBytesSent = 0; + QWriteLocker locker(&_senderStatsLock); + NodeToSenderStatsMapIterator i = _singleSenderStats.begin(); while (i != _singleSenderStats.end()) { @@ -262,10 +267,9 @@ int OctreeInboundPacketProcessor::sendNackPackets() { } const SharedNodePointer& destinationNode = DependencyManager::get()->nodeWithUUID(nodeUUID); - // If the node no longer exists, wait until the ReceivedPacketProcessor has cleaned up the node - // to remove it from our stats list. - // FIXME Is it safe to clean it up here before ReceivedPacketProcess has? + // if the node no longer exists, remove its stats if (!destinationNode) { + i = _singleSenderStats.erase(i); continue; } diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.h b/assignment-client/src/octree/OctreeInboundPacketProcessor.h index 3ddb76b3fa..f95a402b15 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.h +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.h @@ -72,7 +72,7 @@ public: void resetStats(); - NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; } + NodeToSenderStatsMap getSingleSenderStats() { QReadLocker locker(&_senderStatsLock); return _singleSenderStats; } virtual void terminating() { _shuttingDown = true; ReceivedPacketProcessor::terminating(); } @@ -101,6 +101,7 @@ private: quint64 _totalPackets; NodeToSenderStatsMap _singleSenderStats; + QReadWriteLock _senderStatsLock; quint64 _lastNackTime; bool _shuttingDown; diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 297f872108..7cd3e59edf 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -711,7 +711,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url int senderNumber = 0; - NodeToSenderStatsMap& allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats(); + NodeToSenderStatsMap allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats(); for (NodeToSenderStatsMapConstIterator i = allSenderStats.begin(); i != allSenderStats.end(); i++) { senderNumber++; QUuid senderID = i.key(); From 71f1be2b3804261d73c2db2ee60e19bc9e9dd1d8 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 1 Dec 2015 10:46:04 -0800 Subject: [PATCH 11/27] Avatar Sim Rate Display fix Division by zero on first update was causing the displayed avatar simulation rate to be incorrect. --- interface/src/avatar/AvatarUpdate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index 89b208d86f..52fa568879 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -44,9 +44,11 @@ void AvatarUpdate::synchronousProcess() { bool AvatarUpdate::process() { PerformanceTimer perfTimer("AvatarUpdate"); quint64 start = usecTimestampNow(); - quint64 deltaMicroseconds = 0; + quint64 deltaMicroseconds = 10000; if (_lastAvatarUpdate > 0) { deltaMicroseconds = start - _lastAvatarUpdate; + } else { + deltaMicroseconds = 10000; // 10 ms } float deltaSeconds = (float) deltaMicroseconds / (float) USECS_PER_SECOND; _lastAvatarUpdate = start; From 557ab315d9f991ee4fba13a227101cfa4664980c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Dec 2015 10:51:52 -0800 Subject: [PATCH 12/27] make resettable stats atomic --- .../src/octree/OctreeInboundPacketProcessor.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.h b/assignment-client/src/octree/OctreeInboundPacketProcessor.h index f95a402b15..83960abaa6 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.h +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.h @@ -94,16 +94,16 @@ private: OctreeServer* _myServer; int _receivedPacketCount; - quint64 _totalTransitTime; - quint64 _totalProcessTime; - quint64 _totalLockWaitTime; - quint64 _totalElementsInPacket; - quint64 _totalPackets; + std::atomic _totalTransitTime; + std::atomic _totalProcessTime; + std::atomic _totalLockWaitTime; + std::atomic _totalElementsInPacket; + std::atomic _totalPackets; NodeToSenderStatsMap _singleSenderStats; QReadWriteLock _senderStatsLock; - quint64 _lastNackTime; + std::atomic _lastNackTime; bool _shuttingDown; }; #endif // hifi_OctreeInboundPacketProcessor_h From 6e15ae9d7d91de96a174c9ca0b9107401c2bf01f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 1 Dec 2015 11:49:17 -0800 Subject: [PATCH 13/27] Update robot agent script to randomly select among all HiFi avatars, identified by name, and with a random turn from front. --- examples/acScripts/animatedAvatarAgent.js | 53 +++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/examples/acScripts/animatedAvatarAgent.js b/examples/acScripts/animatedAvatarAgent.js index 3e5c90ed1a..74b1032328 100644 --- a/examples/acScripts/animatedAvatarAgent.js +++ b/examples/acScripts/animatedAvatarAgent.js @@ -1,6 +1,6 @@ "use strict"; /*jslint vars: true, plusplus: true*/ -/*global Agent, Avatar, Script, Entities, Vec3, print*/ +/*global Agent, Avatar, Script, Entities, Vec3, Quat, print*/ // // animatedAvatar.js // examples/acScripts @@ -16,15 +16,62 @@ var origin = {x: 500, y: 500, z: 500}; var spread = 20; // meters +var turnSpread = 90; // How many degrees should turn from front range over. var animationData = {url: "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_fwd.fbx", lastFrame: 35}; -Avatar.skeletonModelURL = "https://hifi-public.s3.amazonaws.com/marketplace/contents/dd03b8e3-52fb-4ab3-9ac9-3b17e00cd85d/98baa90b3b66803c5d7bd4537fca6993.fst"; //lovejoy -Avatar.displayName = "'Bot"; +var models = [ // Commented-out avatars do not animate properly on AC's. Presumably because ScriptableAvatar doesn't use model pre-rotations. + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/alan/alan.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/andrew/andrew.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/austin/austin.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/birarda/birarda.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/brad/brad.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/chris/chris2.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/clement/clement.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/emily/emily.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/ewing/ewing.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/howard/howard.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/huffman/huffman.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/james/james.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/philip/philip.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/ryan/ryan.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/sam/sam.fst", + "https://hifi-public.s3.amazonaws.com/ozan/avatars/hifi_team/tony/tony.fst", + + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/1e57c395-612e-4acd-9561-e79dbda0bc49/faafb83c63a3e5e265884d270fc29f8b.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/615ca447-06ee-4215-8dd1-a609c2fcd0cd/c7af6d4224c501fdd9cb54e0101ff281.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/731c39d7-559a-4ce2-947c-3e2768f5471c/8d5eba2fd5bf068259556aec1861c5dd.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/8bdaa1ec-99df-4a29-a249-6941c7fd1930/37351a18a3dea468088fc3d822aaf29c.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/0909d7b7-c67e-45fb-acd9-a07380dc6b9c/da76b8c59dbc680bdda90df4b9a46faa.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/ad0dffd7-f811-487b-a20a-2509235491ef/29106da1f7e6a42c7907603421fd7df5.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/3ebe5c84-8b88-4d91-86ac-f104f3620fe3/3534b032d079514aa8960a316500ce13.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/dd03b8e3-52fb-4ab3-9ac9-3b17e00cd85d/98baa90b3b66803c5d7bd4537fca6993.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/ff060580-2fc7-4b6c-8e12-f023d05363cf/dadef29b1e60f23b413d1850d7e0dd4a.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/b55d3baf-4eb3-4cac-af4c-0fb66d0c907b/ad2c9157f3924ab1f7f6ea87a8cce6cc.fst", + "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/d029ae8d-2905-4eb7-ba46-4bd1b8cb9d73/4618d52e711fbb34df442b414da767bb.fst" +]; +var nameMap = { + faafb83c63a3e5e265884d270fc29f8b: 'albert', + c7af6d4224c501fdd9cb54e0101ff281: 'boss', + '8d5eba2fd5bf068259556aec1861c5dd': 'dougland', + '37351a18a3dea468088fc3d822aaf29c': 'fightbot blue', + da76b8c59dbc680bdda90df4b9a46faa: 'judd', + '29106da1f7e6a42c7907603421fd7df5': 'kate', + '3534b032d079514aa8960a316500ce13': 'lenny', + '98baa90b3b66803c5d7bd4537fca6993': 'lovejoy', + dadef29b1e60f23b413d1850d7e0dd4a: 'mery', // eyes no good + ad2c9157f3924ab1f7f6ea87a8cce6cc: 'owen', + '4618d52e711fbb34df442b414da767bb': 'will' +}; + +Avatar.skeletonModelURL = models[Math.round(Math.random() * (models.length - 1))]; // pick one +Avatar.displayName = Avatar.skeletonModelURL.match(/\/(\w*).fst/)[1]; // grab the file basename +Avatar.displayName = nameMap[Avatar.displayName] || Avatar.displayName; var millisecondsToWaitBeforeStarting = 10 * 1000; // To give the various servers a chance to start. Agent.isAvatar = true; function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2. Script.setTimeout(function () { Avatar.position = Vec3.sum(origin, {x: coord(), y: 0, z: coord()}); + Avatar.orientation = Quat.fromPitchYawRollDegrees(0, turnSpread * (Math.random() - 0.5), 0); print("Starting at", JSON.stringify(Avatar.position)); Avatar.startAnimation(animationData.url, animationData.fps || 30, 1, true, false, animationData.firstFrame || 0, animationData.lastFrame); }, millisecondsToWaitBeforeStarting); From ef32853d4666ad29afc35cb6e351138b302cd0a3 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 1 Dec 2015 11:51:22 -0800 Subject: [PATCH 14/27] When AvatarData parses the .fst, store the (merged) .fbx filename. (Interface gets the .fbx by a separate path, but agents don't have that chance.) --- libraries/avatars/src/AvatarData.cpp | 9 ++++++++- libraries/avatars/src/AvatarData.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0f588b5013..e25e4f243f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1212,7 +1212,14 @@ void AvatarData::setJointMappingsFromNetworkReply() { QByteArray line; while (!(line = networkReply->readLine()).isEmpty()) { - if (!(line = line.trimmed()).startsWith("jointIndex")) { + line = line.trimmed(); + if (line.startsWith("filename")) { + int filenameIndex = line.indexOf('=') + 1; + if (filenameIndex > 0) { + _skeletonFBXURL = _skeletonModelURL.resolved(QString(line.mid(filenameIndex).trimmed())); + } + } + if (!line.startsWith("jointIndex")) { continue; } int jointNameIndex = line.indexOf('=') + 1; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index bc71bc52cd..2d5a395e2a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -392,6 +392,7 @@ protected: QUrl _faceModelURL; // These need to be empty so that on first time setting them they will not short circuit QUrl _skeletonModelURL; // These need to be empty so that on first time setting them they will not short circuit + QUrl _skeletonFBXURL; QVector _attachmentData; QString _displayName; From 8f7f3eed6e351c831859619cf9e38d44300381b4 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 1 Dec 2015 11:52:42 -0800 Subject: [PATCH 15/27] ScriptAvatar now gets the .fbx joints: Because the joint mappings in the .fst can be wrong when the .fst isn't updated for quick changes in the .fbx. Because models now really need the preRotation, which is only in the avatar .fbx. --- .../src/avatars/ScriptableAvatar.cpp | 31 ++++++++++++------- .../src/avatars/ScriptableAvatar.h | 1 + 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 9b3d2ed24e..82e88f67ef 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -12,7 +12,6 @@ #include #include - #include "ScriptableAvatar.h" // hold and priority unused but kept so that client side JS can run. @@ -48,14 +47,12 @@ AnimationDetails ScriptableAvatar::getAnimationDetails() { } void ScriptableAvatar::update(float deltatime) { + if (_bind.isNull() && !_skeletonFBXURL.isEmpty()) { // AvatarData will parse the .fst, but not get the .fbx skeleton. + _bind = DependencyManager::get()->getAnimation(_skeletonFBXURL); + } + // Run animation - if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0) { - QStringList modelJoints = getJointNames(); - QStringList animationJoints = _animation->getJointNames(); - - if (_jointData.size() != modelJoints.size()) { - _jointData.resize(modelJoints.size()); - } + if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && _bind->isLoaded()) { float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps; if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) { @@ -63,19 +60,29 @@ void ScriptableAvatar::update(float deltatime) { currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame); } _animationDetails.currentFrame = currentFrame; + + const QVector& modelJoints = _bind->getGeometry().joints; + QStringList animationJointNames = _animation->getJointNames(); + + if (_jointData.size() != modelJoints.size()) { + _jointData.resize(modelJoints.size()); + } const int frameCount = _animation->getFrames().size(); const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount); const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount); const float frameFraction = glm::fract(currentFrame); - for (int i = 0; i < animationJoints.size(); i++) { - const QString& name = animationJoints[i]; - int mapping = getJointIndex(name); + for (int i = 0; i < animationJointNames.size(); i++) { + const QString& name = animationJointNames[i]; + // As long as we need the model preRotations anyway, let's get the jointIndex from the bind skeleton rather than + // trusting the .fst (which is sometimes not updated to match changes to .fbx). + int mapping = _bind->getGeometry().getJointIndex(name); if (mapping != -1 && !_maskedJoints.contains(name)) { JointData& data = _jointData[mapping]; - auto newRotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + auto newRotation = modelJoints[mapping].preRotation * + safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); // We could probably do translations as in interpolation in model space (rather than the parent space that each frame is in), // but we don't do so for MyAvatar yet, so let's not be different here. if (data.rotation != newRotation) { diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h index 78b2be1057..30c48d02bf 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.h +++ b/assignment-client/src/avatars/ScriptableAvatar.h @@ -33,6 +33,7 @@ private: AnimationPointer _animation; AnimationDetails _animationDetails; QStringList _maskedJoints; + AnimationPointer _bind; // a sleazy way to get the skeleton, given the various library/cmake dependencies }; #endif // hifi_ScriptableAvatar_h \ No newline at end of file From 25422084b9eec57b00fd2a98688ef8d5f30ed901 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 1 Dec 2015 13:02:40 -0800 Subject: [PATCH 16/27] make it so that only you can see your beams until youre grabbing something --- examples/controllers/handControllerGrab.js | 67 ++++++++++++++-------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 28e52e0dee..703ac8dffd 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -200,6 +200,7 @@ function entityIsGrabbedByOther(entityID) { return false; } + function MyController(hand) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -223,6 +224,8 @@ function MyController(hand) { this.rawTriggerValue = 0; this.rawBumperValue = 0; + this.overlayLine = null; + this.offsetPosition = { x: 0.0, y: 0.0, @@ -318,32 +321,35 @@ function MyController(hand) { }); } - this.overlayLineOn = function(color) { + this.overlayLineOn = function(closePoint, farPoint, color) { + if (this.overlayLine === null) { + print('creating handline') - var handPosition = this.getHandPosition(); - var distantPickRay = { - origin: handPosition, - direction: Quat.getUp(this.getHandRotation()), - length: PICK_MAX_DISTANCE - }; + var lineProperties = { + lineWidth: 5, + start: closePoint, + end: farPoint, + color: color, + ignoreRayIntersection: true, // always ignore this + visible: true, + alpha: 1 + }; - var end = Vec3.Sum(handPosition, Vec3.multiply(distantPickRay.direction, NEAR_PICK_MAX_DISTANCE)); + this.overlayLine = Overlays.addOverlay("line3d", lineProperties); - var lineProperties = { - lineWidth: 5, - //get palm position - start: distantPickRay.origin, - end: end, - color: color || { - red: 255, - green: 0, - blue: 255 - }, - ignoreRayIntersection: true, // always ignore this - visible: true, - }; + } else { + print('editing handline' + this.overlayLine) + var success = Overlays.editOverlay(this.overlayLine, { + lineWidth: 5, + start: closePoint, + end: farPoint, + color: color, + visible: true, + ignoreRayIntersection: true, // always ignore this + alpha: 1 + }); + } - this.pointerOverlay = Overlays.addOverlay("line3d", lineProperties); } this.lineOn = function(closePoint, farPoint, color) { @@ -384,6 +390,13 @@ function MyController(hand) { this.pointer = null; }; + this.overlayLineOff = function() { + if (this.overlayLine !== null) { + Overlays.deleteOverlay(this.overlayLine); + } + this.overlayLine = null; + }; + this.triggerPress = function(value) { _this.rawTriggerValue = value; }; @@ -626,7 +639,8 @@ function MyController(hand) { } } - this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); + //this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); + this.overlayLineOn(distantPickRay.origin, Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR); }; this.distanceHolding = function() { @@ -672,6 +686,9 @@ function MyController(hand) { this.currentAvatarPosition = MyAvatar.position; this.currentAvatarOrientation = MyAvatar.orientation; + this.overlayLineOff(); + + }; this.continueDistanceHolding = function() { @@ -779,6 +796,7 @@ function MyController(hand) { } this.lineOff(); + this.overlayLineOff(); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); this.activateEntity(this.grabbedEntity, grabbedProperties); @@ -918,6 +936,7 @@ function MyController(hand) { this.pullTowardEquipPosition = function() { this.lineOff(); + this.overlayLineOff(); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); @@ -1121,7 +1140,7 @@ function MyController(hand) { this.release = function() { this.lineOff(); - + this.overlayLineOff(); if (this.grabbedEntity !== null) { if (this.actionID !== null) { Entities.deleteAction(this.grabbedEntity, this.actionID); From 31d2f6463f262998c504565829b69ee3e5aa2a6a Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 1 Dec 2015 13:03:51 -0800 Subject: [PATCH 17/27] cleanup --- examples/controllers/handControllerGrab.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 703ac8dffd..6bf18d154f 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -323,8 +323,6 @@ function MyController(hand) { this.overlayLineOn = function(closePoint, farPoint, color) { if (this.overlayLine === null) { - print('creating handline') - var lineProperties = { lineWidth: 5, start: closePoint, @@ -338,7 +336,6 @@ function MyController(hand) { this.overlayLine = Overlays.addOverlay("line3d", lineProperties); } else { - print('editing handline' + this.overlayLine) var success = Overlays.editOverlay(this.overlayLine, { lineWidth: 5, start: closePoint, @@ -349,7 +346,6 @@ function MyController(hand) { alpha: 1 }); } - } this.lineOn = function(closePoint, farPoint, color) { From b787e7158785000c6d954406c54fc781d322beef Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 1 Dec 2015 13:06:30 -0800 Subject: [PATCH 18/27] Update doll.js --- examples/toybox/doll/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/doll/doll.js b/examples/toybox/doll/doll.js index c8cfbfb72f..04712f0e1d 100644 --- a/examples/toybox/doll/doll.js +++ b/examples/toybox/doll/doll.js @@ -64,7 +64,7 @@ Entities.editEntity(this.entityID, { animation: { // Providing actual model fbx for animation used to work, now contorts doll into a weird ball - // See bug: + // See bug: https://app.asana.com/0/26225263936266/70097355490098 // url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", running: false, } @@ -80,4 +80,4 @@ }; // entity scripts always need to return a newly constructed object of our type return new Doll(); -}); \ No newline at end of file +}); From fb8316ff12baa5980dfdee91b80aefaa3d186aaa Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 1 Dec 2015 13:15:08 -0800 Subject: [PATCH 19/27] reduce pistol vol --- examples/toybox/pistol/pistol.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/pistol/pistol.js b/examples/toybox/pistol/pistol.js index 94c4ce039f..4c8913086e 100644 --- a/examples/toybox/pistol/pistol.js +++ b/examples/toybox/pistol/pistol.js @@ -36,7 +36,7 @@ this.fireSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/GUN-SHOT2.raw"); this.ricochetSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/Ricochet.L.wav"); this.playRichochetSoundChance = 0.1; - this.fireVolume = 0.5; + this.fireVolume = 0.2; this.bulletForce = 10; From aca0fa7beb17c5157601b39ebf4f45ffed5b3961 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 1 Dec 2015 16:03:19 -0800 Subject: [PATCH 20/27] support disabling both hands --- examples/controllers/handControllerGrab.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 272c2903af..287f57ca30 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1266,10 +1266,10 @@ Controller.enableMapping(MAPPING_NAME); var handToDisable = 'none'; function update() { - if (handToDisable !== LEFT_HAND) { + if (handToDisable !== LEFT_HAND && handToDisable!=='both') { leftController.update(); } - if (handToDisable !== RIGHT_HAND) { + if (handToDisable !== RIGHT_HAND && handToDisable!=='both') { rightController.update(); } } @@ -1279,13 +1279,18 @@ Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { if (sender === MyAvatar.sessionUUID) { - handToDisable = message; if (message === 'left') { handToDisable = LEFT_HAND; } if (message === 'right') { handToDisable = RIGHT_HAND; } + if(message==='both'){ + handToDisable='both'; + } + if(message==='none'){ + handToDisable='none'; + } } } From 386afa272c99193e377b0fc78197cdd66960d718 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 1 Dec 2015 16:50:09 -0800 Subject: [PATCH 21/27] disable grab while attachment version of pistol script is running --- examples/example/games/exterminatorGame/pistol.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/example/games/exterminatorGame/pistol.js b/examples/example/games/exterminatorGame/pistol.js index 365e29fbe5..e1923835c3 100644 --- a/examples/example/games/exterminatorGame/pistol.js +++ b/examples/example/games/exterminatorGame/pistol.js @@ -18,6 +18,7 @@ Script.include("../../../libraries/constants.js"); var GUN_FORCE =20; +Messages.sendMessage('Hifi-Hand-Disabler', "both"); var gameName = "Kill All The Rats!" // var HOST = "localhost:5000" @@ -194,6 +195,7 @@ function fire(side, value) { function scriptEnding() { + Messages.sendMessage('Hifi-Hand-Disabler', 'none'); mapping.disable(); for (var i = 0; i < pointers.length; ++i) { Overlays.deleteOverlay(pointers[i]); From e4199439af6a89db8a19c1a856d839ddd34a6f37 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 1 Dec 2015 17:00:43 -0800 Subject: [PATCH 22/27] added collision sounds to some toys --- examples/controllers/handControllerGrab.js | 1 - unpublishedScripts/hiddenEntityReset.js | 3 +++ unpublishedScripts/masterReset.js | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 287f57ca30..3902963a61 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1277,7 +1277,6 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { - if (sender === MyAvatar.sessionUUID) { if (message === 'left') { handToDisable = LEFT_HAND; diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index af914259a3..982c65fc08 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -241,6 +241,7 @@ gravity: BOW_GRAVITY, shapeType: 'compound', compoundShapeURL: COLLISION_HULL_URL, + collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/bow_fall.L.wav", script: bowScriptURL, userData: JSON.stringify({ resetMe: { @@ -649,6 +650,7 @@ z: 0.08 }, collisionsWillMove: true, + collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/flashlight_drop.L.wav", gravity: { x: 0, y: -3.5, @@ -1185,6 +1187,7 @@ z: 0.07 }, collisionsWillMove: true, + collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/SpryPntCnDrp1.L.wav", shapeType: 'box', gravity: { x: 0, diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 667dc3aa96..6e89e12d41 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -220,6 +220,7 @@ MasterReset = function() { gravity: BOW_GRAVITY, shapeType: 'compound', compoundShapeURL: COLLISION_HULL_URL, + collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/bow_fall.L.wav", script: bowScriptURL, userData: JSON.stringify({ resetMe: { @@ -629,6 +630,7 @@ MasterReset = function() { z: 0.08 }, collisionsWillMove: true, + collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/flashlight_drop.L.wav", gravity: { x: 0, y: -3.5, @@ -1165,6 +1167,7 @@ MasterReset = function() { z: 0.07 }, collisionsWillMove: true, + collisionSoundURL: "http://hifi-public.s3.amazonaws.com/sounds/SpryPntCnDrp1.L.wav", shapeType: 'box', gravity: { x: 0, From 0fd1bdaec508c9edefc15989d4b1919065a97478 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 1 Dec 2015 17:03:11 -0800 Subject: [PATCH 23/27] fixed accidental newline in handgrab --- examples/controllers/handControllerGrab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 3902963a61..ebfa248f58 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1277,6 +1277,7 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { + if (sender === MyAvatar.sessionUUID) { if (message === 'left') { handToDisable = LEFT_HAND; From 40fb45c6d39453126b94443369c4f907a2fe746a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 1 Dec 2015 17:04:10 -0800 Subject: [PATCH 24/27] fixed accidental newline in handgrab --- examples/controllers/handControllerGrab.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index ebfa248f58..3902963a61 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1277,7 +1277,6 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { - if (sender === MyAvatar.sessionUUID) { if (message === 'left') { handToDisable = LEFT_HAND; From 34234da2d1de9b593d92687b125df6f80625fbd1 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Tue, 1 Dec 2015 17:05:51 -0800 Subject: [PATCH 25/27] fixed spacing --- examples/controllers/handControllerGrab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 3902963a61..ebfa248f58 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1277,6 +1277,7 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { + if (sender === MyAvatar.sessionUUID) { if (message === 'left') { handToDisable = LEFT_HAND; From e67f372bcf12a251db32878feafb9a33a9707cf6 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 1 Dec 2015 18:24:13 -0800 Subject: [PATCH 26/27] make pistol shoot differently and not alter controller mappings --- examples/toybox/pistol/pistol.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/toybox/pistol/pistol.js b/examples/toybox/pistol/pistol.js index 4c8913086e..8ef26b94c1 100644 --- a/examples/toybox/pistol/pistol.js +++ b/examples/toybox/pistol/pistol.js @@ -22,6 +22,8 @@ Controller.Standard.LT, Controller.Standard.RT, ]; + var RELOAD_THRESHOLD = 0.95; + Pistol = function() { _this = this; this.equipped = false; @@ -45,6 +47,7 @@ }; Pistol.prototype = { + canShoot: false, startEquip: function(id, params) { this.equipped = true; @@ -62,6 +65,17 @@ }, toggleWithTriggerPressure: function() { this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]); + + if (this.triggerValue < RELOAD_THRESHOLD) { + // print('RELOAD'); + this.canShoot = true; + } + if (this.canShoot === true && this.triggerValue === 1) { + // print('SHOOT'); + this.fire(); + this.canShoot = false; + } + if (this.triggerValue < DISABLE_LASER_THRESHOLD && this.showLaser === true) { this.showLaser = false; Overlays.editOverlay(this.laser, { @@ -74,6 +88,7 @@ }); } + }, updateLaser: function() { var gunProps = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); @@ -101,7 +116,7 @@ preload: function(entityID) { this.entityID = entityID; - this.initControllerMapping(); + // this.initControllerMapping(); this.laser = Overlays.addOverlay("line3d", { start: ZERO_VECTOR, end: ZERO_VECTOR, @@ -150,22 +165,7 @@ } }, - initControllerMapping: function() { - this.mapping = Controller.newMapping(); - this.mapping.from(Controller.Standard.LT).hysteresis(0.0, 0.75).to(function(value) { - _this.triggerPress(0, value); - }); - - - this.mapping.from(Controller.Standard.RT).hysteresis(0.0, 0.75).to(function(value) { - _this.triggerPress(1, value); - }); - this.mapping.enable(); - - }, - unload: function() { - this.mapping.disable(); Overlays.deleteOverlay(this.laser); }, From 9b6ec34f092d1ab80f765050f0f088a510513080 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 1 Dec 2015 20:50:03 -0800 Subject: [PATCH 27/27] Fixing avatar orientation in recordings --- libraries/avatars/src/AvatarData.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index e25e4f243f..597c4c5986 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -116,7 +116,7 @@ void AvatarData::setOrientation(const glm::quat& orientation, bool overideRefere glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation)); _bodyPitch = eulerAngles.x; _bodyYaw = eulerAngles.y; - _bodyRoll = eulerAngles.z; + _bodyRoll = eulerAngles.z; } } @@ -1529,6 +1529,17 @@ QJsonObject AvatarData::toJson() const { } void AvatarData::fromJson(const QJsonObject& json) { + // The head setOrientation likes to overwrite the avatar orientation, + // so lets do the head first + // Most head data is relative to the avatar, and needs no basis correction, + // but the lookat vector does need correction + if (json.contains(JSON_AVATAR_HEAD)) { + if (!_headData) { + _headData = new HeadData(this); + } + _headData->fromJson(json[JSON_AVATAR_HEAD].toObject()); + } + if (json.contains(JSON_AVATAR_HEAD_MODEL)) { auto faceModelURL = json[JSON_AVATAR_HEAD_MODEL].toString(); if (faceModelURL != getFaceModelURL().toString()) { @@ -1600,15 +1611,6 @@ void AvatarData::fromJson(const QJsonObject& json) { } setRawJointData(jointArray); } - - // Most head data is relative to the avatar, and needs no basis correction, - // but the lookat vector does need correction - if (json.contains(JSON_AVATAR_HEAD)) { - if (!_headData) { - _headData = new HeadData(this); - } - _headData->fromJson(json[JSON_AVATAR_HEAD].toObject()); - } } // Every frame will store both a basis for the recording and a relative transform