From 7c6846c260b89f52ecc34aba67b52d0703152a9a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 13:09:41 -0700 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 dd0a16df047d9472088c469defe6c7d486f6a803 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:19:59 -0700 Subject: [PATCH 6/6] 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; }