Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add interaction system #1091

Merged
merged 104 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
7a58f91
Remove super-hands
johnshaughnessy Mar 3, 2019
569a4d2
Remove references to super-hands component
johnshaughnessy Mar 3, 2019
5054f41
Remove functionality related to reaction components
johnshaughnessy Mar 3, 2019
ca515a1
Attempt to recognize hovering
johnshaughnessy Mar 3, 2019
8b6e769
Write down notes about what I'm thinking
johnshaughnessy Mar 3, 2019
a9fb0fc
Implement hovering on any object3D beneath the entity.
johnshaughnessy Mar 3, 2019
e5fcccf
Record observations and progress in notes.txt
johnshaughnessy Mar 3, 2019
0488efe
Update notes
johnshaughnessy Mar 3, 2019
5b47cf5
Merge branch 'master' into try-replacing-super-hands
johnshaughnessy Mar 5, 2019
f78fce5
wip
johnshaughnessy Mar 6, 2019
7cf7565
Merge branch 'master' into try-replacing-super-hands
johnshaughnessy Mar 14, 2019
5db4da5
Get cursor working more cleanly
johnshaughnessy Mar 14, 2019
922b381
Try using physics constraint. Encounter bugs
johnshaughnessy Mar 15, 2019
abec11a
Fix initialization bug related to offset-relative-to
johnshaughnessy Mar 15, 2019
be27784
Crawl up when raycasting, rather than crawling down to descendents
johnshaughnessy Mar 16, 2019
6b4b00a
Cursor works with duck and camera. Not pen yet.
johnshaughnessy Mar 16, 2019
7648edc
Get pen working with cursor
johnshaughnessy Mar 16, 2019
42bbb81
Remove expired notes
johnshaughnessy Mar 16, 2019
1b6d921
Fix issue where pen did not spawn on the cursor
johnshaughnessy Mar 16, 2019
1205d84
Remove some uses of grab-start and grab-end events
johnshaughnessy Mar 16, 2019
867ad0e
Don't use grab-start and grab-end for pen
johnshaughnessy Mar 16, 2019
adc3534
Map the hoverable components in gltf to is-remote-hover-target
johnshaughnessy Mar 16, 2019
67bf452
Replace hoverable with is-remote-hover-target in spawner
johnshaughnessy Mar 16, 2019
5e01303
Simplify control flow a bit
johnshaughnessy Mar 18, 2019
dd2b99d
Merge branch 'simplify-super-networked-interactable' into try-replaci…
johnshaughnessy Mar 18, 2019
985ce03
Disable scalabe-when-grabbed
johnshaughnessy Mar 18, 2019
e5f1234
Move cursor intersection logic to cursor-controller
johnshaughnessy Mar 18, 2019
4ac1b4a
Don't need a closure around tick
johnshaughnessy Mar 18, 2019
3613773
Unused ACTIVATION_STATES
johnshaughnessy Mar 18, 2019
a582824
Immediately add body and shape to loaded entity
johnshaughnessy Mar 18, 2019
f3ecda6
Merge branch 'immediately-add-body-and-shape-to-loaded-media' into tr…
johnshaughnessy Mar 18, 2019
2341c71
Get super-spawners working
johnshaughnessy Mar 18, 2019
0e9debc
Random tiny cleanups
johnshaughnessy Mar 20, 2019
3687dd6
Get right hand and right cursor interactions working
johnshaughnessy Mar 20, 2019
ef194a6
Various cleanups
johnshaughnessy Mar 20, 2019
ee8bbea
Remove unused sticky-object-zone
johnshaughnessy Mar 20, 2019
9a69251
Get buttons working with THREE's EventDispatcher
johnshaughnessy Mar 21, 2019
9dabf73
Get left hand working
johnshaughnessy Mar 21, 2019
2ee4728
Remove comments
johnshaughnessy Mar 21, 2019
6e68ef3
Replace hovering state with events and interaction system state.
johnshaughnessy Mar 21, 2019
683aa22
Fix a regression I made to stick-object autoLockOnLoad
johnshaughnessy Mar 22, 2019
dd5ae85
Fix icon-button hovering
johnshaughnessy Mar 22, 2019
7c9b0e9
Hide cursor while teleporting
johnshaughnessy Mar 22, 2019
20d3f30
Reintroduce cursor rotation on tick
johnshaughnessy Mar 22, 2019
f365b64
Reintroduce hover-visuals
johnshaughnessy Mar 22, 2019
2cdab9d
Reintroduce scaling on the cursor
johnshaughnessy Mar 22, 2019
8c2144f
Move cursor hover target resolution back to interaction system.
johnshaughnessy Mar 22, 2019
6fb7905
Move pen related code out of interaction system
johnshaughnessy Mar 22, 2019
ef2cf8b
Lint
johnshaughnessy Mar 22, 2019
a6c2285
Merge branch 'master' into try-replacing-super-hands
johnshaughnessy Mar 22, 2019
a127478
We call that an "oops"
johnshaughnessy Mar 22, 2019
4001378
Reuse events
johnshaughnessy Mar 22, 2019
83f102e
Emit events rather than call named functions on components
johnshaughnessy Mar 22, 2019
8a6645f
Refactor super-networked-interactable to listen to the events
johnshaughnessy Mar 22, 2019
b7766e8
Get super-spawners working
johnshaughnessy Mar 22, 2019
cd1b1e1
typo
johnshaughnessy Mar 22, 2019
e58b069
Handle ownership transfer
johnshaughnessy Mar 23, 2019
acae398
Rename grab to rightRemoteGrab
johnshaughnessy Mar 23, 2019
865c248
Move cursor target finding into its own system. Note perf problems.
johnshaughnessy Mar 26, 2019
943233b
Lint
johnshaughnessy Mar 26, 2019
7cfbf1c
Move check for rightRemoteConstraintTarget before right hand routine
johnshaughnessy Mar 26, 2019
1401a7d
Reintroduce camera snapping while grabbed
johnshaughnessy Mar 26, 2019
039dc8a
Introduce hovered/held abstraction to interaction system
johnshaughnessy Mar 27, 2019
92901ed
Introduce hubs-systems system
johnshaughnessy Mar 27, 2019
06a61dd
Rename constants to options.
johnshaughnessy Mar 27, 2019
d5dc394
Move CursorTargettingSystem
johnshaughnessy Mar 27, 2019
ac2c82d
Factor out constraints system
johnshaughnessy Mar 27, 2019
3c6822a
Add TwoPointStretchingSystem
johnshaughnessy Mar 27, 2019
8923173
Create tags component
johnshaughnessy Mar 28, 2019
b078e79
lint
johnshaughnessy Mar 28, 2019
6666bdd
Move button firing to systems
johnshaughnessy Mar 28, 2019
a48ab41
Implement hovering and hover menus
johnshaughnessy Mar 28, 2019
c3d4e35
Fix spawn transform
johnshaughnessy Mar 28, 2019
8b48060
Disable interaction until you enter the scene
johnshaughnessy Mar 28, 2019
05226ea
lint
johnshaughnessy Mar 28, 2019
ac2910b
Get pinned object constraint behavior working
johnshaughnessy Mar 29, 2019
77236a6
Handle ownership lost in super-networked-interactable
johnshaughnessy Mar 29, 2019
aaa9374
Replace super-networked-interactable
johnshaughnessy Mar 29, 2019
b96affd
Reimplement networked-counter
johnshaughnessy Mar 29, 2019
788a75f
Simplify pinnable grab-end replacement
johnshaughnessy Mar 29, 2019
a805f9f
Fix bug where scene objects couldn't be moved
johnshaughnessy Mar 29, 2019
0801271
Merge branch 'master' into try-replacing-super-hands
johnshaughnessy Mar 29, 2019
db6b990
Fix all the buttons
johnshaughnessy Mar 29, 2019
f043f9e
Simplify spawn event reaction
johnshaughnessy Mar 29, 2019
9ff5846
Fix camera constraint on touchscreen
johnshaughnessy Mar 29, 2019
59c6fc9
Fix pen interaction in 6DOF
johnshaughnessy Mar 30, 2019
6473d00
Lint
johnshaughnessy Mar 30, 2019
4c50054
Merge branch 'master' into try-replacing-super-hands
johnshaughnessy Mar 30, 2019
f38e0dd
Move cursor-controller tick
johnshaughnessy Mar 30, 2019
606e036
Merge branch 'master' into try-replacing-super-hands
johnshaughnessy Mar 30, 2019
932500a
Fix spawning animation
johnshaughnessy Mar 30, 2019
0211af6
Reimplement pen spawning animation
johnshaughnessy Apr 1, 2019
920ccca
Move spawning code out of interaction system
johnshaughnessy Apr 1, 2019
997d893
Add isHoldable tag
johnshaughnessy Apr 1, 2019
880764b
Reintroduce haptic feedback
johnshaughnessy Apr 1, 2019
22b51b2
Early out if there are no actuators to pulse
johnshaughnessy Apr 1, 2019
0d841bf
Remove (now unused) haptic-feedback component and events
johnshaughnessy Apr 2, 2019
46422e5
Remove unused code
johnshaughnessy Apr 2, 2019
7f22e41
Fix gltf component mappings
johnshaughnessy Apr 2, 2019
a00385e
Remove unused component
johnshaughnessy Apr 2, 2019
6fd6f82
Remove map entries to prevent memory leak.
johnshaughnessy Apr 2, 2019
c57e41b
Fix static-controlled-media template
johnshaughnessy Apr 2, 2019
27d713f
Remove (currently unused) sounds
johnshaughnessy Apr 2, 2019
984372b
Toggle teleportation action sets
johnshaughnessy Apr 2, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
- [mute-mic](#components/network/mute-mic)
- [networked-counter](#components/network/networked-counter)
- [networked-video-player](#components/network/networked-video-player)
- [super-networked-interactable](#components/network/super-networked-interactable)
- [super-spawner](#components/network/super-spawner)
- [ui](#components/ui)
- [hud-controller](#components/ui/hud-controller)
Expand All @@ -58,7 +57,6 @@
- [cardboard-controls](#components/user-input/cardboard-controls)
- [cursor-controller](#components/user-input/cursor-controller)
- [hand-controls2](#components/user-input/hand-controls2)
- [haptic-feedback](#components/user-input/haptic-feedback)
- [virtual-gamepad-controls](#components/user-input/virtual-gamepad-controls)
- [wasd-to-analog2d](#components/user-input/wasd-to-analog2d)
- [vr-mode](#components/vr-mode)
Expand Down Expand Up @@ -295,15 +293,6 @@ Instantiates and plays a network video stream, setting the video as the source m

`src/components/networked-video-player.js`


<a name="components/network/super-networked-interactable"></a>
#### super-networked-interactable

Manages ownership and haptics on an interatable

`src/components/super-networked-interactable.js`


<a name="components/network/super-spawner"></a>
#### super-spawner

Expand Down Expand Up @@ -339,14 +328,6 @@ Converts events from various 6DoF and 3DoF controllers into hand-pose events.
`src/components/hand-controls2.js`


<a name="components/user-input/haptic-feedback"></a>
#### haptic-feedback

Listens for haptic events and actuates hardware controllers accordingly

`src/components/haptic-feedback.js`


<a name="components/user-input/virtual-gamepad-controls"></a>
#### virtual-gamepad-controls

Expand Down Expand Up @@ -442,7 +423,7 @@ Positions the HUD and toggles app mode based on where the user is looking
<a name="components/ui/icon-button"></a>
#### icon-button

A button with an image, tooltip, hover states and haptics.
A button with an image, tooltip, and hover states.

`src/components/icon-button.js`

Expand All @@ -458,7 +439,7 @@ HUD panel for muting, freezing, and space bubble controls.
<a name="components/ui/text-button"></a>
#### text-button

A button with text and haptics
A button with text

`src/components/text-button.js`

Expand Down
4 changes: 0 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
"react-router-dom": "^4.3.1",
"react-youtube": "^7.8.0",
"screenfull": "^4.0.1",
"super-hands": "github:mozillareality/aframe-super-hands-component#hubs/master",
"three": "github:mozillareality/three.js#hubs/master",
"three-mesh-bvh": "^0.1.0",
"three-pathfinding": "github:mozillareality/three-pathfinding#hubs/master",
Expand Down
4 changes: 2 additions & 2 deletions src/components/block-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ AFRAME.registerComponent("block-button", {
},

play() {
this.el.addEventListener("grab-start", this.onClick);
this.el.object3D.addEventListener("interact", this.onClick);
},

pause() {
this.el.removeEventListener("grab-start", this.onClick);
this.el.object3D.removeEventListener("interact", this.onClick);
},

block(clientId) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/camera-focus-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ AFRAME.registerComponent("camera-focus-button", {
},

play() {
this.el.addEventListener("grab-start", this.onClick);
this.el.object3D.addEventListener("interact", this.onClick);
},

pause() {
this.el.removeEventListener("grab-start", this.onClick);
this.el.object3D.removeEventListener("interact", this.onClick);
}
});
54 changes: 26 additions & 28 deletions src/components/camera-tool.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ AFRAME.registerComponent("camera-tool", {
},

init() {
this.stateAdded = this.stateAdded.bind(this);
this.onGrab = this.onGrab.bind(this);

this.lastUpdate = performance.now();
this.localSnapCount = 0; // Counter that is used to arrange photos

Expand Down Expand Up @@ -132,32 +129,18 @@ AFRAME.registerComponent("camera-tool", {
this.el.setAttribute("hover-menu__camera", { template: "#camera-hover-menu", dirs: ["forward", "back"] });
this.el.components["hover-menu__camera"].getHoverMenu().then(() => {
this.snapButton = this.el.querySelector(".snap-button");
this.snapButton.addEventListener("grab-start", () => (this.takeSnapshotNextTick = true));
this.snapButton.object3D.addEventListener("interact", () => {
this.takeSnapshotNextTick = true;
});
});
},

play() {
this.el.addEventListener("stateadded", this.stateAdded);
this.el.addEventListener("grab-start", this.onGrab);
},

pause() {
this.el.removeEventListener("stateadded", this.stateAdded);
this.el.removeEventListener("grab-start", this.onGrab);
},

remove() {
this.cameraSystem.deregister(this.el);
this.el.sceneEl.systems["camera-mirror"].unmirrorCameraAtEl(this.el);
this.el.sceneEl.emit("camera_removed");
},

stateAdded(evt) {
if (evt.detail === "activated") {
this.takeSnapshotNextTick = true;
}
},

focus(el, track) {
if (track) {
this.trackTarget = el;
Expand Down Expand Up @@ -185,19 +168,34 @@ AFRAME.registerComponent("camera-tool", {
this.el.sceneEl.systems["camera-mirror"].unmirrorCameraAtEl(this.el);
},

onGrab() {
this.localSnapCount = 0; // When camera is moved, reset photo arrangement algorithm
},

onAvatarUpdated() {
delete this.playerHead;
},

tick() {
const userinput = this.el.sceneEl.systems.userinput;
const grabber = this.el.components.grabbable.grabbers[0];
if (grabber && !!pathsMap[grabber.id]) {
const grabberPaths = pathsMap[grabber.id];
const interaction = AFRAME.scenes[0].systems.interaction;
const userinput = AFRAME.scenes[0].systems.userinput;
const heldLeftHand = interaction.state.leftHand.held === this.el;
const heldRightHand = interaction.state.rightHand.held === this.el;
const heldRightRemote = interaction.state.rightRemote.held === this.el;
if (
(heldLeftHand && userinput.get(interaction.options.leftHand.grabPath)) ||
(heldRightHand && userinput.get(interaction.options.rightHand.grabPath)) ||
(heldRightRemote && userinput.get(interaction.options.rightRemote.grabPath))
) {
this.localSnapCount = 0;
}

let grabberId;
if (heldRightHand) {
grabberId = "player-right-controller";
} else if (heldLeftHand) {
grabberId = "player-left-controller";
} else if (heldRightRemote) {
grabberId = "cursor";
}
if (grabberId) {
const grabberPaths = pathsMap[grabberId];
if (userinput.get(grabberPaths.takeSnapshot)) {
this.takeSnapshotNextTick = true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/clone-media-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ AFRAME.registerComponent("clone-media-button", {
},

play() {
this.el.addEventListener("grab-start", this.onClick);
this.el.object3D.addEventListener("interact", this.onClick);
},

pause() {
this.el.removeEventListener("grab-start", this.onClick);
this.el.object3D.removeEventListener("interact", this.onClick);
}
});
100 changes: 21 additions & 79 deletions src/components/cursor-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,13 @@ const HIGHLIGHT = new THREE.Color(23 / 255, 64 / 255, 118 / 255);
const NO_HIGHLIGHT = new THREE.Color(190 / 255, 190 / 255, 190 / 255);
const TRANSFORM_COLOR_1 = [150, 80, 150];
const TRANSFORM_COLOR_2 = [23, 64, 118];
/**
* Manages targeting and physical cursor location. Has the following responsibilities:
*
* - Tracking which entities in the scene can be targeted by the cursor (`objects`).
* - Performing a raycast per-frame or on-demand to identify which entity is being currently targeted.
* - Updating the visual presentation and position of the `cursor` entity and `line` component per frame.
* - Sending an event when an entity is targeted or un-targeted.
*/
AFRAME.registerComponent("cursor-controller", {
schema: {
cursor: { type: "selector" },
camera: { type: "selector" },
far: { default: 4 },
near: { default: 0.01 },
minDistance: { default: 0.18 },
objects: { default: "" }
minDistance: { default: 0.18 }
},

init: function() {
Expand All @@ -104,84 +95,37 @@ AFRAME.registerComponent("cursor-controller", {
{ once: true }
);

// raycaster state
this.setDirty = this.setDirty.bind(this);
this.targets = [];
this.raycaster = new THREE.Raycaster();
this.raycaster.firstHitOnly = true; // flag specific to three-mesh-bvh
this.dirty = true;
this.distance = this.data.far;
this.color = new THREE.Color(0, 0, 0);
this.transformColor = [0, 0, 0];
const lineMaterial = new THREE.LineBasicMaterial({
color: "white",
opacity: 0.2,
transparent: true,
visible: false
});

const lineGeometry = new THREE.BufferGeometry();
lineGeometry.addAttribute("position", new THREE.BufferAttribute(new Float32Array(2 * 3), 3));

this.line = new THREE.Line(lineGeometry, lineMaterial);
this.line = new THREE.Line(
lineGeometry,
new THREE.LineBasicMaterial({
color: "white",
opacity: 0.2,
transparent: true,
visible: false
})
);
this.el.setObject3D("line", this.line);
},

update: function() {
this.raycaster.far = this.data.far;
this.raycaster.near = this.data.near;
this.setDirty();
},

play: function() {
this.observer = new MutationObserver(this.setDirty);
this.observer.observe(this.el.sceneEl, { childList: true, attributes: true, subtree: true });
this.el.sceneEl.addEventListener("object3dset", this.setDirty);
this.el.sceneEl.addEventListener("object3dremove", this.setDirty);
},

pause: function() {
this.observer.disconnect();
this.el.sceneEl.removeEventListener("object3dset", this.setDirty);
this.el.sceneEl.removeEventListener("object3dremove", this.setDirty);
},

setDirty: function() {
this.dirty = true;
},

populateEntities: function(selector, target) {
target.length = 0;
const els = this.data.objects ? this.el.sceneEl.querySelectorAll(this.data.objects) : this.el.sceneEl.children;
for (let i = 0; i < els.length; i++) {
if (els[i].object3D) {
target.push(els[i].object3D);
}
}
},

emitIntersectionEvents: function(prevIntersection, currIntersection) {
// if we are now intersecting something, and previously we were intersecting nothing or something else
if (currIntersection && (!prevIntersection || currIntersection.object.el !== prevIntersection.object.el)) {
this.data.cursor.emit("raycaster-intersection", { el: currIntersection.object.el });
}
// if we were intersecting something, but now we are intersecting nothing or something else
if (prevIntersection && (!currIntersection || currIntersection.object.el !== prevIntersection.object.el)) {
this.data.cursor.emit("raycaster-intersection-cleared", { el: prevIntersection.object.el });
}
},

tick: (() => {
tick2: (() => {
const rawIntersections = [];
const cameraPos = new THREE.Vector3();

return function(t) {
if (this.dirty) {
// app aware devices cares about this.targets so we must update it even if cursor is not enabled
this.populateEntities(this.data.objects, this.targets);
this.dirty = false;
}

const userinput = AFRAME.scenes[0].systems.userinput;
const cursorPose = userinput.get(paths.actions.cursor.pose);
const rightHandPose = userinput.get(paths.actions.rightHand.pose);
Expand All @@ -193,16 +137,20 @@ AFRAME.registerComponent("cursor-controller", {
return;
}

const interaction = AFRAME.scenes[0].systems.interaction;
let intersection;
const isGrabbing = this.data.cursor.components["super-hands"].state.has("grab-start");
const isGrabbing = !!interaction.state.rightRemote.held;
if (!isGrabbing) {
rawIntersections.length = 0;
this.raycaster.ray.origin = cursorPose.position;
this.raycaster.ray.direction = cursorPose.direction;
this.raycaster.intersectObjects(this.targets, true, rawIntersections);
intersection = rawIntersections.find(x => x.object.el);
this.emitIntersectionEvents(this.prevIntersection, intersection);
this.prevIntersection = intersection;
this.raycaster.intersectObjects(
AFRAME.scenes[0].systems["hubs-systems"].cursorTargettingSystem.targets,
true,
rawIntersections
);
intersection = rawIntersections[0];
interaction.updateCursorIntersection(intersection);
this.distance = intersection ? intersection.distance : this.data.far;
}

Expand Down Expand Up @@ -235,7 +183,6 @@ AFRAME.registerComponent("cursor-controller", {
}

if (this.line.material.visible) {
// Reach into line component for better performance
const posePosition = cursorPose.position;
const cursorPosition = cursor.object3D.position;
const positionArray = this.line.geometry.attributes.position.array;
Expand All @@ -251,10 +198,5 @@ AFRAME.registerComponent("cursor-controller", {
this.line.geometry.computeBoundingSphere();
}
};
})(),

remove: function() {
this.emitIntersectionEvents(this.prevIntersection, null);
delete this.prevIntersection;
}
})()
});
Loading