From 59971869f51af504bbc002c0c051bd0e03c8400c Mon Sep 17 00:00:00 2001 From: David Back Date: Tue, 10 Apr 2018 19:06:27 -0700 Subject: [PATCH] desktop equip --- .../controllerModules/equipEntity.js | 117 +++++++++++++++++- scripts/system/controllers/grab.js | 2 +- 2 files changed, 115 insertions(+), 4 deletions(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 252f6efa9e..33091696f3 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -21,6 +21,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var DEFAULT_SPHERE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/equip-Fresnel-3.fbx"; var EQUIP_SPHERE_SCALE_FACTOR = 0.65; +var EMPTY_PARENT_ID = "{00000000-0000-0000-0000-000000000000}"; // Each overlayInfoSet describes a single equip hotspot. @@ -176,6 +177,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var TRIGGER_OFF_VALUE = 0.1; var TRIGGER_ON_VALUE = TRIGGER_OFF_VALUE + 0.05; // Squeezed just enough to activate search or near grab var BUMPER_ON_VALUE = 0.5; + + var UNEQUIP_KEY = "u"; function getWearableData(props) { @@ -270,6 +273,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.shouldSendStart = false; this.equipedWithSecondary = false; this.handHasBeenRightsideUp = false; + this.mouseEquip = false; + this.mouseEquipAnimationHandler; this.parameters = makeDispatcherModuleParameters( 300, @@ -279,10 +284,11 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var equipHotspotBuddy = new EquipHotspotBuddy(); - this.setMessageGrabData = function(entityProperties) { + this.setMessageGrabData = function(entityProperties, mouseEquip) { if (entityProperties) { this.messageGrabEntity = true; this.grabEntityProps = entityProperties; + this.mouseEquip = mouseEquip; } }; @@ -552,6 +558,15 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa // 100 ms seems to be sufficient time to force the check even occur after the object has been initialized. Script.setTimeout(grabEquipCheck, 100); } + + if (this.mouseEquip) { + this.removeMouseEquipAnimation(); + if (this.hand === RIGHT_HAND) { + this.mouseEquipAnimationHandler = MyAvatar.addAnimationStateHandler(this.rightHandMouseEquipAnimation, []); + } else { + this.mouseEquipAnimationHandler = MyAvatar.addAnimationStateHandler(this.leftHandMouseEquipAnimation, []); + } + } }; this.endEquipEntity = function () { @@ -574,6 +589,11 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.targetEntityID = null; this.messageGrabEntity = false; this.grabEntityProps = null; + + if (this.mouseEquip) { + this.removeMouseEquipAnimation(); + this.mouseEquip = false; + } }; this.updateInputs = function (controllerData) { @@ -650,7 +670,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var timestamp = Date.now(); this.updateInputs(controllerData); - if (!this.isTargetIDValid(controllerData)) { + if (!this.mouseEquip && !this.isTargetIDValid(controllerData)) { this.endEquipEntity(); return makeRunningValues(false, [], []); } @@ -740,6 +760,40 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.endEquipEntity(); } }; + + this.removeMouseEquipAnimation = function() { + if (this.mouseEquipAnimationHandler) { + this.mouseEquipAnimationHandler = MyAvatar.removeAnimationStateHandler(this.mouseEquipAnimationHandler); + } + }; + + this.leftHandMouseEquipAnimation = function() { + var result = {}; + var leftHandPosition = MyAvatar.getJointPosition("LeftHand"); + var leftShoulderPosition = MyAvatar.getJointPosition("LeftShoulder"); + var cameraToLeftShoulder = Vec3.subtract(leftShoulderPosition, Camera.position); + var cameraToLeftShoulderNormalized = Vec3.normalize(cameraToLeftShoulder); + var leftHandPositionNew = Vec3.sum(leftShoulderPosition, cameraToLeftShoulderNormalized); + var leftHandPositionNewAvatarFrame = Vec3.subtract(leftHandPositionNew, MyAvatar.position); + result.leftHandType = 1; + result.leftHandPosition = leftHandPositionNewAvatarFrame; + result.leftHandRotation = Quat.multiply(Quat.lookAtSimple(leftHandPositionNew, Camera.position), Quat.fromPitchYawRollDegrees(90, 0, -90)); + return result; + }; + + this.rightHandMouseEquipAnimation = function() { + var result = {}; + var rightHandPosition = MyAvatar.getJointPosition("RightHand"); + var rightShoulderPosition = MyAvatar.getJointPosition("RightShoulder"); + var cameraToRightShoulder = Vec3.subtract(rightShoulderPosition, Camera.position); + var cameraToRightShoulderNormalized = Vec3.normalize(cameraToRightShoulder); + var rightHandPositionNew = Vec3.sum(rightShoulderPosition, cameraToRightShoulderNormalized); + var rightHandPositionNewAvatarFrame = Vec3.subtract(rightHandPositionNew, MyAvatar.position); + result.rightHandType = 1; + result.rightHandPosition = rightHandPositionNewAvatarFrame; + result.rightHandRotation = Quat.multiply(Quat.lookAtSimple(rightHandPositionNew, Camera.position), Quat.fromPitchYawRollDegrees(90, 0, 90)); + return result; + }; } var handleMessage = function(channel, message, sender) { @@ -751,7 +805,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var equipModule = (data.hand === "left") ? leftEquipEntity : rightEquipEntity; var entityProperties = Entities.getEntityProperties(data.entityID, DISPATCHER_PROPERTIES); entityProperties.id = data.entityID; - equipModule.setMessageGrabData(entityProperties); + var mouseEquip = false; + equipModule.setMessageGrabData(entityProperties, mouseEquip); } catch (e) { print("WARNING: equipEntity.js -- error parsing Hifi-Hand-Grab message: " + message); @@ -768,10 +823,63 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } } }; + + var clearGrabActions = function(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.slice(0, 5) == "grab-") { + Entities.deleteAction(entityID, actionID); + } + } + }; + + var onMousePress = function(event) { + if (isInEditMode()) { // ignore any mouse clicks on the entity while create/edit is open + return; + } + var pickRay = Camera.computePickRay(event.x, event.y); + var intersection = Entities.findRayIntersection(pickRay, true); + if (intersection.intersects) { + var entityProperties = Entities.getEntityProperties(intersection.entityID, DISPATCHER_PROPERTIES); + if (entityProperties.parentID === EMPTY_PARENT_ID) { + entityProperties.id = intersection.entityID; + var rightHandPosition = MyAvatar.getJointPosition("RightHand"); + var leftHandPosition = MyAvatar.getJointPosition("LeftHand"); + var distanceToRightHand = Vec3.distance(entityProperties.position, rightHandPosition); + var distanceToLeftHand = Vec3.distance(entityProperties.position, leftHandPosition); + var leftHandAvailable = leftEquipEntity.targetEntityID === null; + var rightHandAvailable = rightEquipEntity.targetEntityID === null; + var mouseEquip = true; + if (rightHandAvailable && (distanceToRightHand < distanceToLeftHand || !leftHandAvailable)) { + clearGrabActions(intersection.entityID); + rightEquipEntity.setMessageGrabData(entityProperties, mouseEquip); + } else if (leftHandAvailable && (distanceToLeftHand < distanceToRightHand || !rightHandAvailable)) { + clearGrabActions(intersection.entityID); + leftEquipEntity.setMessageGrabData(entityProperties, mouseEquip); + } + } + } + }; + + var onKeyPress = function(event) { + if (event.text === UNEQUIP_KEY) { + if (rightEquipEntity.mouseEquip) { + rightEquipEntity.endEquipEntity(); + } + if (leftEquipEntity.mouseEquip) { + leftEquipEntity.endEquipEntity(); + } + } + }; Messages.subscribe('Hifi-Hand-Grab'); Messages.subscribe('Hifi-Hand-Drop'); Messages.messageReceived.connect(handleMessage); + Controller.mousePressEvent.connect(onMousePress); + Controller.keyPressEvent.connect(onKeyPress); var leftEquipEntity = new EquipEntity(LEFT_HAND); var rightEquipEntity = new EquipEntity(RIGHT_HAND); @@ -785,6 +893,9 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa disableDispatcherModule("LeftEquipEntity"); disableDispatcherModule("RightEquipEntity"); clearAttachPoints(); + Messages.messageReceived.disconnect(handleMessage); + Controller.mousePressEvent.disconnect(onMousePress); + Controller.keyPressEvent.disconnect(onKeyPress); } Script.scriptEnding.connect(cleanup); }()); diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 1171703847..b32c64d189 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -567,7 +567,7 @@ Grabber.prototype.moveEventProcess = function() { } if (!this.actionID) { - if (!entityIsGrabbedByOther(this.entityID)) { + if (!entityIsGrabbedByOther(this.entityID) ) && Entities.getEntityProperties(this.entityID, ['parentID']).parentID !== MyAvatar.SELF_ID) { this.actionID = Entities.addAction("far-grab", this.entityID, actionArgs); } } else {