From 776dc767c2b6b5be8f6889a808691b6cf75a3c5f Mon Sep 17 00:00:00 2001 From: Kevin Lee <kevin@infinite-lee.com> Date: Wed, 18 Jul 2018 18:59:21 -0700 Subject: [PATCH] activatable component and sticky behavior Added activatable component, which allows a button to cause secondary activations to occur while an object is grabbed. Also made the pen "sticky" so it stays attached to your hand when you grab it. It can then only be dropped by using the "primary" grab button (e.g. grip buttons). The triggers now are "secondary_action" buttons, which work like normal except in the case that you are holding a sticky object, in which case they will not cause the object to be dropped. --- src/components/tools/pen.js | 12 +++++----- src/hub.html | 12 +++++----- src/input-mappings.js | 8 +++---- src/utils/action-event-handler.js | 37 ++++++++++++++++++++++++------- yarn.lock | 4 ++-- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/components/tools/pen.js b/src/components/tools/pen.js index 9bd18ac7e..8abd375a0 100644 --- a/src/components/tools/pen.js +++ b/src/components/tools/pen.js @@ -53,7 +53,7 @@ AFRAME.registerComponent("pen", { }, play() { - if (this.data.useMouse) { + if (this.data.useMouse && false) { document.addEventListener("mousedown", this.onMouseDown); document.addEventListener("mouseup", this.onMouseUp); } @@ -61,8 +61,10 @@ AFRAME.registerComponent("pen", { // this.el.parentNode.addEventListener("index_down", this.startDraw); // this.el.parentNode.addEventListener("index_up", this.endDraw); - this.el.parentNode.addEventListener("drag-start", this.startDraw); - this.el.parentNode.addEventListener("drag-end", this.endDraw); + if (!this.data.useMouse) { + this.el.parentNode.addEventListener("activate-start", this.startDraw); + this.el.parentNode.addEventListener("activate-end", this.endDraw); + } }, pause() { @@ -72,8 +74,8 @@ AFRAME.registerComponent("pen", { this.el.parentNode.removeEventListener("index_down", this.startDraw); this.el.parentNode.removeEventListener("index_up", this.endDraw); - this.el.parentNode.removeEventListener("drag-start", this.startDraw); - this.el.parentNode.removeEventListener("drag-end", this.endDraw); + this.el.parentNode.removeEventListener("activate-start", this.startDraw); + this.el.parentNode.removeEventListener("activate-end", this.endDraw); }, tick(t, dt) { diff --git a/src/hub.html b/src/hub.html index af24a06ce..7830dce38 100644 --- a/src/hub.html +++ b/src/hub.html @@ -220,12 +220,12 @@ <template id="pen-interactable"> <a-entity gltf-model-plus="src: #interactable-pen; inflate: true;" - class="interactable" + class="interactable sticky" super-networked-interactable="counter: #counter; mass: 1;" body="type: dynamic; shape: none; mass: 1;" - grabbable + grabbable="maxGrabbers: 1; maxGrabBehavior: drop;" hoverable - draggable + activatable="buttonStartEvent: secondary_action_grab; buttonEndEvent: secondary_action_release;" scale="0.5 0.5 0.5" > <a-sphere @@ -271,7 +271,8 @@ colliderEndEvent: collisions; colliderEndEventProperty: clearedEls; grabStartButtons: hand_grab; grabEndButtons: hand_release; stretchStartButtons: hand_grab; stretchEndButtons: hand_release; - dragDropStartButtons: index_down; dragDropEndButtons: index_up;" + dragDropStartButtons: hand_grab; dragDropEndButtons: hand_release; + activateStartButtons: secondary_action_grab; activateEndButtons: secondary_action_release;" collision-filter="collisionForces: false" physics-collider ></a-mixin> @@ -301,7 +302,8 @@ colliderEndEvent: raycaster-intersection-cleared; colliderEndEventProperty: clearedEls; grabStartButtons: cursor-grab; grabEndButtons: cursor-release; stretchStartButtons: cursor-grab; stretchEndButtons: cursor-release; - dragDropStartButtons: cursor-grab; dragDropEndButtons: cursor-release;" + dragDropStartButtons: cursor-grab; dragDropEndButtons: cursor-release; + activateStartButtons: TODO; activateEndButtons: TODO;" segments-height="9" segments-width="9" event-repeater="events: raycaster-intersection, raycaster-intersection-cleared; eventSource: #cursor-controller" diff --git a/src/input-mappings.js b/src/input-mappings.js index d1784c8d1..3bf06cc84 100644 --- a/src/input-mappings.js +++ b/src/input-mappings.js @@ -61,8 +61,8 @@ const config = { gripup: ["action_release", "middle_ring_pinky_up"], trackpadtouchstart: "thumb_down", trackpadtouchend: "thumb_up", - triggerdown: ["index_down"], - triggerup: ["index_up"], + triggerdown: ["secondary_action_grab", "index_down"], + triggerup: ["secondary_action_release", "index_up"], scroll: { right: "move_duck" } }, "oculus-touch-controls": { @@ -86,8 +86,8 @@ const config = { surfacetouchend: "thumb_up", thumbsticktouchstart: "thumb_down", thumbsticktouchend: "thumb_up", - triggerdown: ["action_grab", "index_down"], - triggerup: ["action_release", "index_up"], + triggerdown: ["secondary_action_grab", "index_down"], + triggerup: ["secondary_action_release", "index_up"], "axismove.reverseY": { left: "move", right: "move_duck" }, abuttondown: "action_primary_down", abuttonup: "action_primary_up" diff --git a/src/utils/action-event-handler.js b/src/utils/action-event-handler.js index 6288c34e0..fcb9aa736 100644 --- a/src/utils/action-event-handler.js +++ b/src/utils/action-event-handler.js @@ -7,6 +7,7 @@ export default class ActionEventHandler { this.isTeleporting = false; this.handThatAlsoDrivesCursor = null; this.hovered = false; + this.currentlyGrabbingSticky = {}; this.onPrimaryDown = this.onPrimaryDown.bind(this); this.onPrimaryUp = this.onPrimaryUp.bind(this); @@ -23,6 +24,8 @@ export default class ActionEventHandler { this.scene.addEventListener("action_primary_up", this.onPrimaryUp); this.scene.addEventListener("action_grab", this.onGrab); this.scene.addEventListener("action_release", this.onRelease); + this.scene.addEventListener("secondary_action_grab", this.onGrab); + this.scene.addEventListener("secondary_action_release", this.onRelease); this.scene.addEventListener("move_duck", this.onMoveDuck); this.scene.addEventListener("cardboardbuttondown", this.onCardboardButtonDown); // TODO: These should be actions this.scene.addEventListener("cardboardbuttonup", this.onCardboardButtonUp); @@ -33,6 +36,8 @@ export default class ActionEventHandler { this.scene.removeEventListener("action_primary_up", this.onPrimaryUp); this.scene.removeEventListener("action_grab", this.onGrab); this.scene.removeEventListener("action_release", this.onRelease); + this.scene.removeEventListener("secondary_action_grab", this.onGrab); + this.scene.removeEventListener("secondary_action_release", this.onRelease); this.scene.removeEventListener("move_duck", this.onMoveDuck); this.scene.removeEventListener("cardboardbuttondown", this.onCardboardButtonDown); this.scene.removeEventListener("cardboardbuttonup", this.onCardboardButtonUp); @@ -46,27 +51,43 @@ export default class ActionEventHandler { this.handThatAlsoDrivesCursor = handThatAlsoDrivesCursor; } + isSticky(el) { + return el && el.classList.contains("sticky"); + } + onGrab(e) { - if (this.handThatAlsoDrivesCursor && this.handThatAlsoDrivesCursor === e.target) { - if (this.isCursorInteracting) { - return; - } else if (e.target.components["super-hands"].state.has("hover-start")) { + const superHand = e.target.components["super-hands"]; + const grabbed = superHand.state.get("grab-start"); + if (this.currentlyGrabbingSticky[e.target.id] && !grabbed) { + this.currentlyGrabbingSticky[e.target.id] = false; + } + const validGrab = !this.isSticky(grabbed) || !this.currentlyGrabbingSticky[e.target.id] || e.type == "action_grab"; + if (this.handThatAlsoDrivesCursor && this.handThatAlsoDrivesCursor === e.target && !this.isCursorInteracting) { + if (superHand.state.has("hover-start") && validGrab) { e.target.emit("hand_grab"); - return; } else { this.isCursorInteracting = this.cursor.startInteraction(); if (this.isCursorInteracting) { this.isCursorInteractingOnGrab = true; } - return; } - } else { + } else if (validGrab) { e.target.emit("hand_grab"); - return; } } onRelease(e) { + const grabbed = e.target.components["super-hands"].state.get("grab-start"); + if ( + (!this.currentlyGrabbingSticky[e.target.id] && this.isSticky(grabbed)) || + (this.currentlyGrabbingSticky[e.target.id] && e.type != "action_release") + ) { + this.currentlyGrabbingSticky[e.target.id] = true; + return; + } else { + this.currentlyGrabbingSticky[e.target.id] = false; + } + if ( this.isCursorInteracting && this.isCursorInteractingOnGrab && diff --git a/yarn.lock b/yarn.lock index 0dc13a86a..e94fc5e45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7859,8 +7859,8 @@ subarg@^1.0.0: minimist "^1.1.0" "super-hands@https://github.com/mozillareality/aframe-super-hands-component#hubs/master": - version "2.1.0" - resolved "https://github.com/mozillareality/aframe-super-hands-component#579024a260f8b9821cf1cbabd403055116bc2eb9" + version "3.0.0" + resolved "https://github.com/mozillareality/aframe-super-hands-component#2fc7697793005e187f343e59f98a33a5ed45c698" supports-color@1.3.1: version "1.3.1" -- GitLab