diff --git a/src/components/image-plus.js b/src/components/image-plus.js index f23be48bb966c5f4c3f53939674fde54a52dd509..942f022812b261858b5d2326632a8f80959f6986 100644 --- a/src/components/image-plus.js +++ b/src/components/image-plus.js @@ -4,8 +4,6 @@ AFRAME.registerComponent("image-plus", { schema: { src: { type: "string" }, - freezeSpeedLimit: { default: 1 }, - initialOffset: { default: { x: 0, y: 0, z: -1.5 } }, reorientOnGrab: { default: false } }, @@ -45,19 +43,9 @@ AFRAME.registerComponent("image-plus", { } }, - _sleepIfStill(e) { - if ( - e.target === this.el && - this.el.body.velocity.lengthSquared() < this.data.freezeSpeedLimit * this.data.freezeSpeedLimit - ) { - this.el.body.sleep(); - } - }, - _onGrab: (function() { const q = new THREE.Quaternion(); return function() { - this.el.body.wakeUp(); if (this.data.reorientOnGrab) { this.billboardTarget.getWorldQuaternion(q); this.el.body.quaternion.copy(q); @@ -67,20 +55,14 @@ AFRAME.registerComponent("image-plus", { init() { this._onMaterialLoaded = this._onMaterialLoaded.bind(this); - this._sleepIfStill = this._sleepIfStill.bind(this); this._onGrab = this._onGrab.bind(this); - this.billboardTarget = document.querySelector("#player-camera").object3D; - - const el = this.el; - el.addEventListener("materialtextureloaded", this._onMaterialLoaded); - el.addEventListener("materialvideoloadeddata", this._onMaterialLoaded); - - el.addEventListener("grab-start", this._onGrab); - el.addEventListener("grab-end", this._sleepIfStill); - el.addEventListener("body-loaded", this._sleepIfStill); + this.el.addEventListener("materialtextureloaded", this._onMaterialLoaded); + this.el.addEventListener("materialvideoloadeddata", this._onMaterialLoaded); + this.el.addEventListener("grab-start", this._onGrab); const worldPos = new THREE.Vector3().copy(this.data.initialOffset); + this.billboardTarget = document.querySelector("#player-camera").object3D; this.billboardTarget.localToWorld(worldPos); this.el.object3D.position.copy(worldPos); this.billboardTarget.getWorldQuaternion(this.el.object3D.quaternion); diff --git a/src/components/networked-counter.js b/src/components/networked-counter.js index be9725cf6a50efb822370ab5d4b7196a6bcce3c4..9b9b5f8be954d3099dad4259e9d5372e4260c367 100644 --- a/src/components/networked-counter.js +++ b/src/components/networked-counter.js @@ -6,7 +6,7 @@ AFRAME.registerComponent("networked-counter", { schema: { max: { default: 3 }, - ttl: { default: 120 }, + ttl: { default: 0 }, grab_event: { type: "string", default: "grab-start" }, release_event: { type: "string", default: "grab-end" } }, @@ -115,6 +115,7 @@ AFRAME.registerComponent("networked-counter", { }, _addTimeout: function(id) { + if (!this.data.ttl) return; const timeout = this.data.ttl * 1000; this.timeouts[id] = setTimeout(() => { const el = this.queue[id].el; diff --git a/src/components/sticky-object.js b/src/components/sticky-object.js new file mode 100644 index 0000000000000000000000000000000000000000..d24bf02774e9e808ce6869aec65d385e7d58c0d9 --- /dev/null +++ b/src/components/sticky-object.js @@ -0,0 +1,67 @@ +AFRAME.registerComponent("sticky-object", { + dependencies: ["body"], + + schema: { + autoLockOnLoad: { default: false }, + autoLockOnRelease: { default: false }, + autoLockSpeedLimit: { default: 1 } + }, + + init() { + this._onGrab = this._onGrab.bind(this); + this._onRelease = this._onRelease.bind(this); + this._onBodyLoaded = this._onBodyLoaded.bind(this); + this.el.addEventListener("grab-start", this._onGrab); + this.el.addEventListener("grab-end", this._onRelease); + this.el.addEventListener("body-loaded", this._onBodyLoaded); + }, + + setLocked(locked) { + this.locked = locked; + this.el.body.type = locked ? window.CANNON.Body.STATIC : window.CANNON.Body.DYNAMIC; + this.el.setAttribute("body", { + mass: locked ? 0 : this.bodyMass + }); + }, + + _onBodyLoaded() { + this.bodyMass = this.el.body.mass; + if (this.data.autoLockOnLoad) { + this.setLocked(true); + } + }, + + _onRelease() { + if ( + this.data.autoLockOnRelease && + this.el.body.velocity.lengthSquared() < this.data.autoLockSpeedLimit * this.data.autoLockSpeedLimit + ) { + this.setLocked(true); + } + }, + + _onGrab() { + this.setLocked(false); + } +}); + +AFRAME.registerComponent("sticky-object-zone", { + dependencies: ["physics"], + init() { + const q = new THREE.Quaternion(); + const p = new THREE.Vector3(); + this.el.object3D.getWorldQuaternion(q); + this.el.object3D.getWorldPosition(p); + this.el.addEventListener("collisions", e => { + console.log("collisions", e.detail.els, e.detail.clearedEls); + e.detail.els.forEach(el => { + const stickyObject = el.components["sticky-object"]; + if (!stickyObject) return; + + stickyObject.setLocked(true); + el.object3D.position.copy(p); + el.object3D.quaternion.copy(q); + }); + }); + } +}); diff --git a/src/hub.html b/src/hub.html index 1206d99c1e289386559a37fb82bb93add7461e0c..c7d4a75626f4d27f2f29e60ee644d1b65430c66c 100644 --- a/src/hub.html +++ b/src/hub.html @@ -36,7 +36,7 @@ <a-scene renderer="antialias: true" networked-scene="adapter: janus; audio: true; debug: true; connectOnLoad: false;" - physics="gravity: -6;" + physics="gravity: -6; debug: true;" mute-mic="eventSrc: a-scene; toggleEvents: action_mute" freeze-controller="toggleEvent: action_freeze" personal-space-bubble="debug: false;" @@ -190,6 +190,7 @@ stretchable="useWorldPosition: true;" hoverable duck + sticky-object ></a-entity> </template> @@ -198,12 +199,13 @@ class="interactable" super-networked-interactable="counter: #media-counter; mass: 1;" body="type: dynamic; shape: none; mass: 1;" - grabbable="uusePhysics: never;" + grabbable stretchable="useWorldPosition: true;" hoverable geometry="primitive: plane" material="side: double;" image-plus + sticky-object="autoLockOnLoad: true; autoLockOnRelease: true;" > </a-entity> </template> @@ -222,7 +224,7 @@ <!-- Interactables --> <a-entity id="counter" networked-counter="max: 3; ttl: 120"></a-entity> - <a-entity id="media-counter" networked-counter="max: 3; ttl: 120"></a-entity> + <a-entity id="media-counter" networked-counter="max: 3;"></a-entity> <a-entity id="cursor-controller" @@ -387,6 +389,40 @@ nav-mesh-helper static-body="shape: none;" ></a-entity> + + <a-entity + geometry="primitive: box;" + static-body="shape: box;" + collision-filter="collisionForces: false;" + physics-collider + sticky-object-zone + position="1.25 2 -5.9" + visible="false" + scale="1 1 0.5" + > + </a-entity> + <a-entity + geometry="primitive: box;" + static-body="shape: box;" + collision-filter="collisionForces: false;" + physics-collider + sticky-object-zone + position="0 2 -5.9" + visible="false" + scale="1 1 0.5" + > + </a-entity> + <a-entity + geometry="primitive: box;" + static-body="shape: box;" + collision-filter="collisionForces: false;" + physics-collider + sticky-object-zone + position="-1.25 2 -5.9" + visible="false" + scale="1 1 0.5" + > + </a-entity> </a-scene> <div id="ui-root"></div> diff --git a/src/hub.js b/src/hub.js index 53b98c7c4c491fc8a467512c33dd2044e8a52b0a..ed9f861b9b399ba60f83e88aa46f1fa325762e22 100644 --- a/src/hub.js +++ b/src/hub.js @@ -68,6 +68,7 @@ import "./components/pinch-to-move"; import "./components/look-on-mobile"; import "./components/pitch-yaw-rotator"; import "./components/input-configurator"; +import "./components/sticky-object"; import ReactDOM from "react-dom"; import React from "react";