diff --git a/src/components/event-repeater.js b/src/components/event-repeater.js index d6f396766cd82cf42548d93f0808256a1e4891cd..e58c2f912d902329659bffc3e57083a82ceb754d 100644 --- a/src/components/event-repeater.js +++ b/src/components/event-repeater.js @@ -1,16 +1,15 @@ AFRAME.registerComponent("event-repeater", { schema: { - target: {type: "selector"}, - events: {type: "array"} + target: { type: "selector" }, + events: { type: "array" } }, init: function() { - let events = this.data.events; - for (let i = 0; i < events.length; i++) { - this.data.target.addEventListener(events[i], e => { - this.el.emit(events[i], e.details); - }); - } + const events = this.data.events; + for (let i = 0; i < events.length; i++) { + this.data.target.addEventListener(events[i], e => { + this.el.emit(events[i], e.details); + }); + } } - -}); \ No newline at end of file +}); diff --git a/src/components/networked-counter.js b/src/components/networked-counter.js index 9845bca6e9d644a5287a51fc864b9449b365b9e0..1a144561eb609814d86a948d3d7eee62a4c46942 100644 --- a/src/components/networked-counter.js +++ b/src/components/networked-counter.js @@ -1,7 +1,9 @@ AFRAME.registerComponent("networked-counter", { schema: { max: { default: 3 }, - ttl: { default: 120 } + ttl: { default: 120 }, + grab_event: { type: "string", default: "grab-start" }, + release_event: { type: "string", default: "grab-end" } }, init: function() { @@ -10,18 +12,6 @@ AFRAME.registerComponent("networked-counter", { this.timeouts = {}; }, - getCount: function() { - return queue.length; - }, - - getMax: function() { - return this.data.max; - }, - - getTtl: function() { - return this.data.ttl; - }, - register: function(networkedEl) { if (this.data.max <= 0) { return; @@ -42,8 +32,8 @@ AFRAME.registerComponent("networked-counter", { onReleaseHandler: onReleaseHandler }; - networkedEl.addEventListener("grab-start", onGrabHandler); - networkedEl.addEventListener("grab-end", onReleaseHandler); + networkedEl.addEventListener(this.data.grab_event, onGrabHandler); + networkedEl.addEventListener(this.data.release_event, onReleaseHandler); this.count++; @@ -51,15 +41,15 @@ AFRAME.registerComponent("networked-counter", { this._addTimeout(id); } - this._removeOldest(); + this._destroyOldest(); }, deregister: function(networkedEl) { const id = NAF.utils.getNetworkId(networkedEl); if (this.queue.hasOwnProperty(id)) { const item = this.queue[id]; - networkedEl.removeEventListener("grab-start", item.onGrabHandler); - networkedEl.removeEventListener("grab-end", item.onReleaseHandler); + networkedEl.removeEventListener(this.data.grab_event, item.onGrabHandler); + networkedEl.removeEventListener(this.data.release_event, item.onReleaseHandler); delete this.queue[id]; @@ -80,9 +70,10 @@ AFRAME.registerComponent("networked-counter", { this.queue[id].ts = Date.now(); }, - _removeOldest: function() { + _destroyOldest: function() { if (this.count > this.data.max) { - let oldest = null, ts = Number.MAX_VALUE; + let oldest = null, + ts = Number.MAX_VALUE; Object.keys(this.queue).forEach(function(id) { const expiration = this.queue[id].ts + this.data.ttl * 1000; if (this.queue[id].ts < ts && !this._isCurrentlyGrabbed(id)) { @@ -105,7 +96,6 @@ AFRAME.registerComponent("networked-counter", { _addTimeout: function(id) { const timeout = this.data.ttl * 1000; this.timeouts[id] = setTimeout(() => { - const el = this.queue[id].el; this.deregister(el); this._destroy(el); diff --git a/src/components/remote-dynamic-body.js b/src/components/remote-dynamic-body.js deleted file mode 100644 index 3d2a1dc7e525554e39430d140e931a29ef747427..0000000000000000000000000000000000000000 --- a/src/components/remote-dynamic-body.js +++ /dev/null @@ -1,50 +0,0 @@ -AFRAME.registerComponent("remote-dynamic-body", { - schema: { - mass: { default: 1 }, - counter: { type: "selector" }, - grabbable: {type: "boolean", default: true}, - stretchable: {type: "boolean", default: true} - }, - - init: function() { - this.counter = this.data.counter.components["networked-counter"]; - this.hand = null; - - NAF.utils.getNetworkedEntity(this.el).then(networkedEl => { - this.networkedEl = networkedEl; - if (!NAF.utils.isMine(networkedEl)) { - this.el.setAttribute("body", "type: dynamic; mass: 0"); - this.el.setAttribute("material", "color: white") - } else { - this.counter.register(networkedEl); - } - }); - - this.el.addEventListener("grab-start", e => { - this._onGrabStart(e); - }); - - this.el.addEventListener("ownership-lost", e => { - this.el.setAttribute("body", "mass: 0"); - this.el.emit("grab-end", {hand: this.hand}); - this.hand = null; - this.counter.deregister(this.el); - this.el.setAttribute("material", "color: white") - }); - }, - - _onGrabStart: function(e) { - this.hand = e.detail.hand; - if (this.networkedEl && !NAF.utils.isMine(this.networkedEl)) { - if (NAF.utils.takeOwnership(this.networkedEl)) { - this.el.setAttribute("body", `mass: ${this.data.mass};`); - this.counter.register(this.networkedEl); - this.el.setAttribute("material", "color: green") - } else { - this.el.emit("grab-end", {hand: this.hand}); - this.hand = null; - this.el.setAttribute("material", "color: red") - } - } - } -}); diff --git a/src/components/cursor-hand.js b/src/components/super-cursor.js similarity index 62% rename from src/components/cursor-hand.js rename to src/components/super-cursor.js index 758d5ac14d91c9256ee7406eab48a1905ddf74d1..47269cecea6c70adc1f9b161e76acf1b3c4bfe0e 100644 --- a/src/components/cursor-hand.js +++ b/src/components/super-cursor.js @@ -1,9 +1,9 @@ -AFRAME.registerComponent("cursor-hand", { - dependencies: ['raycaster'], +AFRAME.registerComponent("super-cursor", { + dependencies: ["raycaster"], schema: { - cursor: {type: "selector"}, - maxDistance: {type: "number", default: 3}, - minDistance: {type: "number", default: 0.5} + cursor: { type: "selector" }, + maxDistance: { type: "number", default: 3 }, + minDistance: { type: "number", default: 0.5 } }, init: function() { @@ -14,27 +14,26 @@ AFRAME.registerComponent("cursor-hand", { this.enabled = true; this.isGrabbing = false; - document.addEventListener("mousedown", (e) => { + document.addEventListener("mousedown", e => { this.data.cursor.emit("action_grab", {}); }); - document.addEventListener("mouseup", (e) => { + document.addEventListener("mouseup", e => { this.data.cursor.emit("action_release", {}); }); - document.addEventListener("wheel", (e) => { - if (this.isGrabbing) - this.currentDistanceMod += e.deltaY/10; + document.addEventListener("wheel", e => { + if (this.isGrabbing) this.currentDistanceMod += e.deltaY / 10; }); - window.addEventListener('enter-vr', e => { + window.addEventListener("enter-vr", e => { if (AFRAME.utils.device.checkHeadsetConnected() || AFRAME.utils.device.isMobile()) { this.enabled = false; this.data.cursor.setAttribute("visible", false); } }); - window.addEventListener('exit-vr', e => { + window.addEventListener("exit-vr", e => { this.enabled = true; this.data.cursor.setAttribute("visible", true); }); @@ -49,10 +48,10 @@ AFRAME.registerComponent("cursor-hand", { if (!this.isGrabbing) { const intersections = this.el.components.raycaster.intersections; - if(intersections.length > 0 && intersections[0].distance <= this.data.maxDistance) { + if (intersections.length > 0 && intersections[0].distance <= this.data.maxDistance) { isIntersecting = true; const point = intersections[0].point; - this.data.cursor.setAttribute('position', point); + this.data.cursor.setAttribute("position", point); this.currentDistance = intersections[0].distance; this.currentDistanceMod = 0; } else { @@ -63,19 +62,22 @@ AFRAME.registerComponent("cursor-hand", { if (this.isGrabbing || !isIntersecting) { const head = this.el.object3D; const origin = head.getWorldPosition(); - let direction = head.getWorldDirection(); - const distance = Math.min(Math.max(this.data.minDistance, this.currentDistance - this.currentDistanceMod), this.data.maxDistance); + const direction = head.getWorldDirection(); + const distance = Math.min( + Math.max(this.data.minDistance, this.currentDistance - this.currentDistanceMod), + this.data.maxDistance + ); this.currentDistanceMod = this.currentDistance - distance; direction.multiplyScalar(-distance); - let point = new THREE.Vector3(); + const point = new THREE.Vector3(); point.addVectors(origin, direction); - this.data.cursor.setAttribute("position", {x: point.x, y: point.y, z: point.z}); + this.data.cursor.setAttribute("position", { x: point.x, y: point.y, z: point.z }); } if ((this.isGrabbing || isIntersecting) && !this.wasIntersecting) { this.wasIntersecting = true; this.data.cursor.setAttribute("material", "color: #00FF00"); - } else if ((!this.isGrabbing && !isIntersecting) && this.wasIntersecting) { + } else if (!this.isGrabbing && !isIntersecting && this.wasIntersecting) { this.wasIntersecting = false; this.data.cursor.setAttribute("material", "color: #00EFFF"); } diff --git a/src/components/super-networked-interactable.js b/src/components/super-networked-interactable.js new file mode 100644 index 0000000000000000000000000000000000000000..c5546ec87e35d7aa4648d15536f20b9815dff14d --- /dev/null +++ b/src/components/super-networked-interactable.js @@ -0,0 +1,53 @@ +AFRAME.registerComponent("super-networked-interactable", { + schema: { + mass: { default: 1 }, + counter: { type: "selector" } + }, + + init: function() { + this.counter = this.data.counter.components["networked-counter"]; + this.hand = null; + + NAF.utils.getNetworkedEntity(this.el).then(networkedEl => { + this.networkedEl = networkedEl; + if (!NAF.utils.isMine(networkedEl)) { + this.el.setAttribute("body", "type: dynamic; mass: 0"); + } else { + this.counter.register(networkedEl); + } + }); + + this.grabStartListener = this._onGrabStart.bind(this); + this.ownershipLostListener = this._onOwnershipLost.bind(this); + this.el.addEventListener("grab-start", this.grabStartListener); + this.el.addEventListener("ownership-lost", this.ownershipLostListener); + }, + + remove: function() { + this.counter.deregister(this.el); + this.el.removeEventListener("grab-start", this.grabStartListener); + this.el.removeEventListener("ownership-lost", this.ownershipLostListener); + }, + + _onGrabStart: function(e) { + this.hand = e.detail.hand; + if (this.networkedEl && !NAF.utils.isMine(this.networkedEl)) { + if (NAF.utils.takeOwnership(this.networkedEl)) { + console.log("1"); + this.el.setAttribute("body", `mass: ${this.data.mass};`); + this.counter.register(this.networkedEl); + } else { + console.log("2"); + this.el.emit("grab-end", { hand: this.hand }); + this.hand = null; + } + } + }, + + _onOwnershipLost: function(e) { + this.el.setAttribute("body", "mass: 0"); + this.el.emit("grab-end", { hand: this.hand }); + this.hand = null; + this.counter.deregister(this.el); + } +}); diff --git a/src/components/super-spawner.js b/src/components/super-spawner.js index 0b8a0354dbede1113858b11eaeeac00869240d1a..efff5e9c871e458069466646bf5a2aacb762a68a 100644 --- a/src/components/super-spawner.js +++ b/src/components/super-spawner.js @@ -1,7 +1,7 @@ AFRAME.registerComponent("super-spawner", { schema: { - template: { default: '' }, - spawn_position: {type: "vec3"} + template: { default: "" }, + spawn_position: { type: "vec3" } }, init: function() { @@ -13,25 +13,25 @@ AFRAME.registerComponent("super-spawner", { _spawn: function(hand) { const entity = document.createElement("a-entity"); - entity.setAttribute('networked', 'template:' + this.data.template); + entity.setAttribute("networked", "template:" + this.data.template); const componentinitialized = new Promise((resolve, reject) => { - entity.addEventListener("componentinitialized", (e) => { - if(e.detail.name == "grabbable") { + entity.addEventListener("componentinitialized", e => { + if (e.detail.name == "grabbable") { resolve(); } }); }); const bodyloaded = new Promise((resolve, reject) => { - entity.addEventListener("body-loaded", (e) => { - resolve(); + entity.addEventListener("body-loaded", e => { + resolve(); }); }); Promise.all([componentinitialized, bodyloaded]).then(() => { - hand.emit("action_grab", {targetEntity: entity}); - entity.emit('grab-start', {hand: hand}); + hand.emit("action_grab", { targetEntity: entity }); + entity.emit("grab-start", { hand: hand }); }); entity.setAttribute("position", this.data.spawn_position || this.el.getAttribute("position")); diff --git a/src/room.html b/src/room.html index eef387bc25ea88f937d6e951d8b9e697de17567e..5826cfbf9a781f06f2fbd16078927426fab7673d 100644 --- a/src/room.html +++ b/src/room.html @@ -92,7 +92,7 @@ gltf-model="#interactable-duck" scale="2 2 2" class="collidable" - remote-dynamic-body="counter: #counter; mass: 5;" + super-networked-interactable="counter: #counter; mass: 5;" body="type: dynamic; mass: 5; shape: box;" grabbable stretchable @@ -105,7 +105,7 @@ colliderEndEvent: collisions; colliderEndEventProperty: clearedEls; grabStartButtons: action_grab; grabEndButtons: action_release; stretchStartButtons: action_grab; stretchEndButtons: action_release; - dargDropStartButtons: action_grab; dragDropEndButtons: action_release; + dragDropStartButtons: action_grab; dragDropEndButtons: action_release; " collision-filter="collisionForces: false" physics-collider @@ -152,8 +152,8 @@ look-controls="pointerLockEnabled: true;" > <a-entity - id="cursor-hand" - cursor-hand="cursor: #3d-cursor" + id="super-cursor" + super-cursor="cursor: #3d-cursor" position="0 0 0" raycaster="objects: .collidable; direction: 0 0 -1;" ></a-entity> diff --git a/src/room.js b/src/room.js index 4e6a569b1aaaf1df73c4f3b7d2b2197c71d63fff..dea6a536fd6c49c312a20a4262dd9b6e3f2c80df 100644 --- a/src/room.js +++ b/src/room.js @@ -46,10 +46,10 @@ import "./elements/a-gltf-entity"; import "aframe-physics-system"; import "aframe-physics-extras"; import "super-hands"; -import "./components/remote-dynamic-body"; +import "./components/super-networked-interactable"; import "./components/networked-counter"; import "./components/super-spawner"; -import "./components/cursor-hand"; +import "./components/super-cursor"; import "./components/event-repeater"; import { promptForName, getCookie, parseJwt } from "./utils/identity";