diff --git a/README.md b/README.md
index f71424e..4ffc577 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Essential game components for [A-Frame](https://aframe.io/)!
-
+
diff --git a/dist/a-game.js b/dist/a-game.js
index 727c117..7e47182 100644
--- a/dist/a-game.js
+++ b/dist/a-game.js
@@ -2,7 +2,7 @@
module.exports={
"name": "a-game",
"title": "A-Game",
- "version": "0.16.0",
+ "version": "0.17.0",
"description": "game components for A-Frame",
"homepage": "https://github.com/poeticAndroid/a-game/blob/master/README.md",
"main": "index.js",
@@ -89,6 +89,7 @@ AFRAME.registerComponent("grabbing", {
this._btnPress = {}
this._btnFlex = {}
this._keysDown = {}
+ this._grabCount = 0
this._hands = ["head", "left", "right"]
this._head = {}
@@ -401,6 +402,7 @@ AFRAME.registerComponent("grabbing", {
// if (this[_hand].glove.getAttribute("body"))
this[_hand].glove.setAttribute("body", "collidesWith", 0)
this.emit("grab", this[_hand].glove, this[_hand].grabbed, { intersection: hit })
+ this._grabCount = Math.min(2, this._grabCount + 1)
this.el.addState("grabbing")
this[_hand].grabbed.addState("grabbed")
this.sticky = true
@@ -426,9 +428,11 @@ AFRAME.registerComponent("grabbing", {
// if (this[_hand].glove.getAttribute("body"))
this[_hand].glove.setAttribute("body", "collidesWith", 1)
}, 1024)
- this.emit("drop", this[_hand].glove, this[_hand].grabbed)
- this.el.removeState("grabbing")
if (this[_hand].grabbed) {
+ this.emit("drop", this[_hand].glove, this[_hand].grabbed)
+ this._grabCount = Math.max(0, this._grabCount - 1)
+ if (!this._grabCount)
+ this.el.removeState("grabbing")
this._flexFinger(hand, 5, 0)
this[_hand].grabbed.removeState("grabbed")
this[_hand].grabbed = null
@@ -606,12 +610,14 @@ AFRAME.registerComponent("grabbing", {
this.useDown("head", btn ? ((btn % 2) ? btn + 1 : btn - 1) : btn)
},
_onWheel(e) {
- if (this._keysDown["KeyR"] && e.deltaY > 0) return this.moveHeadHand(0, 0, 0, -0.125)
- if (this._keysDown["KeyR"] && e.deltaY < 0) return this.moveHeadHand(0, 0, 0, 0.125)
- if (this._keysDown["KeyY"] && e.deltaY > 0) return this.moveHeadHand(0, 0, -0.125)
- if (this._keysDown["KeyY"] && e.deltaY < 0) return this.moveHeadHand(0, 0, 0.125)
- if (this._keysDown["KeyT"] && e.deltaY > 0) return this.moveHeadHand(0, 0.125)
- if (this._keysDown["KeyT"] && e.deltaY < 0) return this.moveHeadHand(0, -0.125)
+ let x = 0, y = 0, z = 0
+ if (this._keysDown["Digit3"] && e.deltaY > 0) z += -0.125
+ if (this._keysDown["Digit3"] && e.deltaY < 0) z += 0.125
+ if (this._keysDown["Digit2"] && e.deltaY > 0) y += -0.125
+ if (this._keysDown["Digit2"] && e.deltaY < 0) y += 0.125
+ if (this._keysDown["Digit1"] && e.deltaY > 0) x += 0.125
+ if (this._keysDown["Digit1"] && e.deltaY < 0) x += -0.125
+ if (x || y || z) return this.moveHeadHand(0, x, y, z)
if (e.deltaY > 0) return this.moveHeadHand(0.125)
if (e.deltaY < 0) return this.moveHeadHand(-0.125)
},
@@ -689,17 +695,18 @@ AFRAME.registerComponent("climbable", {
init() {
this.el.setAttribute("grabbable", "physics:false; kinematicGrab:false;")
- this._player = this.el.sceneEl.querySelector("[locomotion")
- this._quat = new THREE.Quaternion()
- this._lpos = new THREE.Vector3()
- this._wpos = new THREE.Vector3()
- this._handpos = new THREE.Vector3()
+ this._player = this.el.sceneEl.querySelector("[locomotion]")
this._onBump = this._onBump.bind(this)
this._onBumpThis = this._onBumpThis.bind(this)
this._autoGrab = true
setTimeout(() => {
+ this._quat = new THREE.Quaternion()
+ this._lpos = new THREE.Vector3()
+ this._wpos = new THREE.Vector3()
+ this._handpos = new THREE.Vector3()
+
this._quat.copy(this.el.object3D.quaternion)
this._lpos.copy(this.el.object3D.position)
this.el.object3D.getWorldPosition(this._wpos)
@@ -714,9 +721,14 @@ AFRAME.registerComponent("climbable", {
pause() {
this._player.removeEventListener("bump", this._onBump)
this.el.removeEventListener("bump", this._onBumpThis)
+ this._climbing = false
},
tick() {
+ if (!this._lpos) return
+ this.el.object3D.quaternion.copy(this._quat)
+ this.el.object3D.position.copy(this._lpos)
+
if (!this._climbing) return
let delta = THREE.Vector3.temp()
this._hand.object3D.getWorldPosition(delta)
@@ -729,9 +741,6 @@ AFRAME.registerComponent("climbable", {
this._player.components.locomotion.stopFall()
this._player.components.locomotion.move(delta)
if (this._handpos.y - this._wpos.y > this._top) this._player.components.grabbing.dropObject(this.el)
-
- this.el.object3D.quaternion.copy(this._quat)
- this.el.object3D.position.copy(this._lpos)
},
events: {
@@ -848,6 +857,7 @@ AFRAME.registerComponent("receptacle", {
schema: {
objects: { type: "string", default: "[grabbable]" },
radius: { type: "number", default: 0.125 },
+ onlyGrabbed: { type: "boolean", default: false },
},
init() {
@@ -892,6 +902,7 @@ AFRAME.registerComponent("receptacle", {
})
}
this._hover = false
+ this._grabbed = false
} else if (delta.length() > this.data.radius) {
if (this.el.is("filled")) {
this._anchor.removeAttribute("joint__put")
@@ -915,6 +926,7 @@ AFRAME.registerComponent("receptacle", {
})
}
this._hover = false
+ this._grabbed = false
} else if (this.nearest.is("grabbed") || !this._hover) {
if (!this._hover) {
this.el.emit("hover", {
@@ -928,7 +940,9 @@ AFRAME.registerComponent("receptacle", {
this._anchor.removeAttribute("animation__rot")
this._anchor.copyWorldPosRot(this.nearest)
this._hover = true
- } else {
+ if (this.nearest.is("grabbed"))
+ this._grabbed = true
+ } else if (this._grabbed || !this.data.onlyGrabbed) {
if (!this.el.is("filled")) {
this._anchor.copyWorldPosRot(this.nearest)
this._anchor.components.body.commit()
@@ -2458,10 +2472,11 @@ AFRAME.registerComponent("trigger", {
trigger: this.el,
object: obj,
}
- this.el.removeState("triggered")
this.el.emit("untrigger", d)
obj.emit("untrigger", d)
this.triggered.splice(this.triggered.indexOf(obj), 1)
+ if (!this.triggered.length)
+ this.el.removeState("triggered")
}
}
},
diff --git a/dist/a-game.min.js b/dist/a-game.min.js
index 2ef1d77..46f88d2 100644
--- a/dist/a-game.min.js
+++ b/dist/a-game.min.js
@@ -1 +1 @@
-!function t(e,s,i){function o(a,r){if(!s[a]){if(!e[a]){var h="function"==typeof require&&require;if(!r&&h)return h(a,!0);if(n)return n(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=s[a]={exports:{}};e[a][0].call(c.exports,(function(t){return o(e[a][1][t]||t)}),c,c.exports,t,e,s,i)}return s[a].exports}for(var n="function"==typeof require&&require,a=0;a dist/#{name}.min.js"',bump:"npm version minor --no-git-tag-version",gitadd:"git add package*.json dist/*.js"},"pre-commit":["bump","build","gitadd"],keywords:["aframe","webvr","webxr","gamedev"],author:"poeticAndroid",license:"MIT",devDependencies:{browserify:"^17.0.0","foreach-cli":"^1.8.1",minify:"^7.0.1","pre-commit":"^1.2.2",watchify:"^4.0.0"}}},{}],2:[function(t,e,s){t("./libs/pools"),t("./libs/copyWorldPosRot"),t("./libs/ensureElement"),t("./libs/touchGestures"),t("./libs/betterRaycaster"),setTimeout((()=>{document.body.addEventListener("swipeup",(t=>{document.body.requestFullscreen()}))})),t("./components/grabbing"),t("./components/include"),t("./components/injectplayer"),t("./components/locomotion"),t("./components/onevent"),t("./components/onstate"),t("./components/physics"),t("./components/script"),t("./components/trigger"),t("./primitives/a-hand"),t("./primitives/a-main"),t("./primitives/a-player");const i=t("../package");console.log(`${i.title} Version ${i.version} by ${i.author}\n(${i.homepage})`)},{"../package":1,"./components/grabbing":3,"./components/include":9,"./components/injectplayer":10,"./components/locomotion":11,"./components/onevent":15,"./components/onstate":16,"./components/physics":17,"./components/script":21,"./components/trigger":22,"./libs/betterRaycaster":23,"./libs/copyWorldPosRot":25,"./libs/ensureElement":26,"./libs/pools":27,"./libs/touchGestures":28,"./primitives/a-hand":29,"./primitives/a-main":30,"./primitives/a-player":31}],3:[function(t,e,s){AFRAME.registerComponent("grabbing",{schema:{hideOnGrab:{type:"boolean",default:!0},grabDistance:{type:"number",default:1}},init(){this._enableHands=this._enableHands.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onMouseDown=this._onMouseDown.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onWheel=this._onWheel.bind(this),this._onButtonChanged=this._onButtonChanged.bind(this),this._onTouchTap=this._onTouchTap.bind(this),this._onTouchHold=this._onTouchHold.bind(this),this._btnPress={},this._btnFlex={},this._keysDown={},this._hands=["head","left","right"],this._head={},this._left={},this._right={},this._head.hand=this.el.querySelector("a-camera"),this._left.hand=this.el.querySelector('a-hand[side="left"]'),this._right.hand=this.el.querySelector('a-hand[side="right"]'),this._head.glove=this._head.hand.ensure(".hitbox","a-sphere",{class:"hitbox",body:"type:kinematic;",radius:.25}),this._left.glove=this._ensureGlove(this._left.hand),this._right.glove=this._ensureGlove(this._right.hand),this._left.glove.setAttribute("visible",!1),this._right.glove.setAttribute("visible",!1);for(let t of this._hands){this["_"+t].hand.addEventListener("buttonchanged",this._enableHands)}this._head.ray=this._head.hand.ensure(".grabbing-ray","a-entity",{class:"grabbing-ray",position:"0 -0.125 0",raycaster:{objects:"[wall], [grabbable]",autoRefresh:!1}}),this._head.buttonRay=this._head.hand.ensure(".button.ray","a-entity",{class:"button ray",position:"0 -0.125 0",raycaster:{objects:"[wall], [button]",far:1,autoRefresh:!1}}),this._head.reticle=this._head.ray.ensure(".reticle","a-sphere",{class:"reticle",radius:.015625,position:"0 0 -1"},''),this._head.buttonReticle=this._head.buttonRay.ensure(".reticle","a-sphere",{class:"reticle",radius:.015625,color:"black",position:"0 0 -1"},''),this._head.anchor=this._head.ray.ensure(".grabbing.anchor","a-entity",{class:"grabbing anchor",visible:!1,body:"type:kinematic;autoShape:false;"})},update(t){for(let t of this._hands){let e="_"+t;this[e].ray&&this[e].ray.setAttribute("raycaster","far",this.data.grabDistance+("head"===t?1:.1875))}},play(){document.addEventListener("keydown",this._onKeyDown),document.addEventListener("keyup",this._onKeyUp),this.el.sceneEl.canvas.addEventListener("mousedown",this._onMouseDown),this.el.sceneEl.canvas.addEventListener("mouseup",this._onMouseUp),this.el.sceneEl.canvas.addEventListener("wheel",this._onWheel);for(let t of[this._left.hand,this._right.hand])t.addEventListener("buttonchanged",this._onButtonChanged);this.el.sceneEl.canvas.addEventListener("tap",this._onTouchTap),this.el.sceneEl.canvas.addEventListener("hold",this._onTouchHold)},pause(){document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("keyup",this._onKeyUp),this.el.sceneEl.canvas.removeEventListener("mousedown",this._onMouseDown),this.el.sceneEl.canvas.removeEventListener("mouseup",this._onMouseUp),this.el.sceneEl.canvas.removeEventListener("wheel",this._onWheel);for(let t of[this._left.hand,this._right.hand])t.removeEventListener("buttonchanged",this._onButtonChanged);this.el.sceneEl.canvas.removeEventListener("tap",this._onTouchTap),this.el.sceneEl.canvas.removeEventListener("hold",this._onTouchHold)},remove(){for(let t of this._hands){let e="_"+t;this.drop(t),this[e].glove.copyWorldPosRot(this[e].hand);let s=.25;for(let i=0;i<5;i++)this.emit("fingerflex",this[e].glove,this[e].grabbed,{hand:t,finger:i,flex:s})}},tick(t,e){for(i=0,len=navigator.getGamepads().length;i{this.sticky=!1,this._flexFinger(t,5,.5)}),256)}},drop(t="head"){let e="_"+t;this.sticky||(this[e].anchor.removeAttribute("animation__rot"),this[e].anchor.removeAttribute("animation__pos"),this[e].glove.setAttribute("visible",!0),setTimeout((()=>{this[e].anchor.removeAttribute("joint__grab"),this[e].anchor.setAttribute("position","0 0 0"),this[e].anchor.setAttribute("rotation","0 0 0")}),32),setTimeout((()=>{this[e].glove.setAttribute("body","collidesWith",1)}),1024),this.emit("drop",this[e].glove,this[e].grabbed),this.el.removeState("grabbing"),this[e].grabbed&&(this._flexFinger(t,5,0),this[e].grabbed.removeState("grabbed"),this[e].grabbed=null))},dropObject(t){for(let e of this._hands){this["_"+e].grabbed===t&&this.drop(e)}},use(t="head",e=0){this.useDown(t,e),setTimeout((()=>{this.useUp(t,e)}),32)},useDown(t="head",e=0){let s="_"+t;this[s].grabbed?this.emit("usedown",this[s].glove,this[s].grabbed,{button:e}):this[s]._lastButton&&(this[s]._lastClick=this[s]._lastButton,this.emit("press",this[s].glove,this[s]._lastClick,{button:e}),this[s]._lastClick.addState("pressed"))},useUp(t="head",e=0){let s="_"+t;this[s].grabbed?this.emit("useup",this[s].glove,this[s].grabbed,{button:e}):this[s]._lastClick&&(this.emit("unpress",this[s].glove,this[s]._lastClick),this[s]._lastClick.removeState("pressed"),this[s]._lastClick=null)},moveHeadHand(t=0,e=0,s=0,i=0){this._head.anchor.object3D.position.z=Math.min(Math.max(-1.5,this._head.anchor.object3D.position.z+t),-.125);let o=THREE.Quaternion.temp().set(e,s,i,1).normalize();this._head.anchor.object3D.quaternion.premultiply(o)},emit(t,e,s,i={}){i.grabbing=this.el,i.grabbedElement=s,i.gloveElement=e;for(let t of this._hands)this["_"+t].glove===e&&(i.hand=t);e.emit(t,i),s&&s.emit(t,i)},_enableHands(){for(let t of this._hands){let e="_"+t;this[e].hand.removeEventListener("buttonchanged",this._enableHands);let s=.0625;if(this[e].glove.ensure(".hitbox","a-box",{class:"hitbox",visible:!1,position:"0 0 0.03125",width:s/2,height:s,depth:2*s}),this[e].glove.setAttribute("body","type:kinematic;"),"head"===t)continue;this[e]._occlusionRay=this.el.sceneEl.ensure(".occlusion-ray."+t,"a-entity",{class:"occlusion-ray "+t,raycaster:{objects:"[wall]",autoRefresh:!1}});let i=this[e].glove.querySelector(".palm")||this[e].glove;this[e].ray=i.ensure(".grabbing.ray","a-entity",{class:"grabbing ray",position:"left"===t?"-0.0625 0 0.0625":"0.0625 0 0.0625",rotation:"left"===t?"0 -45 0":"0 45 0",raycaster:{objects:"[wall], [grabbable]",autoRefresh:!1}}),this[e].buttonRay=i.ensure(".button.ray","a-entity",{class:"button ray",position:"0 0.03125 0",rotation:"left"===t?"0 -8 0":"0 8 0",raycaster:{objects:"[wall], [button]",far:.5,autoRefresh:!1}}),this[e].anchor=this[e].ray.ensure(".grabbing.anchor","a-entity",{class:"grabbing anchor",visible:"false",body:"type:kinematic;autoShape:false;"}),this[e].glove.setAttribute("visible",!0)}this._head.ray=null,this._head.buttonRay=null,this.update()},_ensureGlove(t){let e=t.getAttribute("side"),s=t.getAttribute("color")||"lightblue";return t.ensure(".glove","a-entity",{class:"glove",fingerflex:{min:"left"===e?-10:10,max:"left"===e?-90:90}},`\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n `)},_flexFinger(t,e,s){let i="_"+t;if(e<5)this.emit("fingerflex",this[i].glove,this[i].grabbed,{hand:t,finger:e,flex:s});else for(e-=5;e<5;e++)this.emit("fingerflex",this[i].glove,this[i].grabbed,{hand:t,finger:e,flex:s})},_onKeyDown(t){this._keysDown[t.code]=!0,"e"===t.key&&this.toggleGrab()},_onKeyUp(t){this._keysDown[t.code]=!1},_onMouseDown(t){let e=t.button;this.useDown("head",e?e%2?e+1:e-1:e)},_onWheel(t){return this._keysDown.KeyR&&t.deltaY>0?this.moveHeadHand(0,0,0,-.125):this._keysDown.KeyR&&t.deltaY<0?this.moveHeadHand(0,0,0,.125):this._keysDown.KeyY&&t.deltaY>0?this.moveHeadHand(0,0,-.125):this._keysDown.KeyY&&t.deltaY<0?this.moveHeadHand(0,0,.125):this._keysDown.KeyT&&t.deltaY>0?this.moveHeadHand(0,.125):this._keysDown.KeyT&&t.deltaY<0?this.moveHeadHand(0,-.125):t.deltaY>0?this.moveHeadHand(.125):t.deltaY<0?this.moveHeadHand(-.125):void 0},_onMouseUp(t){let e=t.button;this.useUp("head",e?e%2?e+1:e-1:e)},_onTouchTap(t){this.use()},_onTouchHold(t){this.toggleGrab()},_onButtonChanged(t){let e=t.srcElement.getAttribute("tracked-controls").hand,s="_"+e,i=-1,o=0;switch(t.detail.state.touched&&(o=.5),t.detail.state.pressed&&(o=1),t.detail.state.value&&(o=.5+t.detail.state.value/2),this._btnFlex[e+t.detail.id]=o,t.detail.id){case 0:i=1,t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.useDown(e),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.useUp(e);break;case 1:i=7,t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.grab(e),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.drop(e);break;case 3:i=0,o=Math.max(this._btnFlex[e+3]||0,this._btnFlex[e+4]||0,this._btnFlex[e+5]||0);break;case 4:i=0,o=Math.max(this._btnFlex[e+3]||0,this._btnFlex[e+4]||0,this._btnFlex[e+5]||0),t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.useDown(e,1),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.useUp(e,1);break;case 5:i=0,o=Math.max(this._btnFlex[e+3]||0,this._btnFlex[e+4]||0,this._btnFlex[e+5]||0),t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.useDown(e,2),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.useUp(e,2)}this._btnPress[e+t.detail.id]=t.detail.state.pressed,(this.sticky||this[s]._lastButton)&&0!==i||this._flexFinger(e,i,o)}}),t("./grabbing/button"),t("./grabbing/climbable"),t("./grabbing/fingerflex"),t("./grabbing/grabbable"),t("./grabbing/receptacle")},{"./grabbing/button":4,"./grabbing/climbable":5,"./grabbing/fingerflex":6,"./grabbing/grabbable":7,"./grabbing/receptacle":8}],4:[function(t,e,s){AFRAME.registerComponent("button",{schema:{}})},{}],5:[function(t,e,s){AFRAME.registerComponent("climbable",{dependencies:["wall"],schema:{},init(){this.el.setAttribute("grabbable","physics:false; kinematicGrab:false;"),this._player=this.el.sceneEl.querySelector("[locomotion"),this._quat=new THREE.Quaternion,this._lpos=new THREE.Vector3,this._wpos=new THREE.Vector3,this._handpos=new THREE.Vector3,this._onBump=this._onBump.bind(this),this._onBumpThis=this._onBumpThis.bind(this),this._autoGrab=!0,setTimeout((()=>{this._quat.copy(this.el.object3D.quaternion),this._lpos.copy(this.el.object3D.position),this.el.object3D.getWorldPosition(this._wpos),this._top=parseFloat(this.el.getAttribute("height")||1)/2+2}),256)},play(){this._player.addEventListener("bump",this._onBump),this.el.addEventListener("bump",this._onBumpThis)},pause(){this._player.removeEventListener("bump",this._onBump),this.el.removeEventListener("bump",this._onBumpThis)},tick(){if(!this._climbing)return;let t=THREE.Vector3.temp();this._hand.object3D.getWorldPosition(t),t.sub(this._handpos).multiplyScalar(-1),"head"===this._handName&&(t.y=0,t.y=t.length(),this._handpos.y+=t.y),this._player.components.locomotion.stopFall(),this._player.components.locomotion.move(t),this._handpos.y-this._wpos.y>this._top&&this._player.components.grabbing.dropObject(this.el),this.el.object3D.quaternion.copy(this._quat),this.el.object3D.position.copy(this._lpos)},events:{grab(t){this._climbing=!0,this._handName=t.detail.hand,this._hand=t.detail.gloveElement.parentNode,this._hand.object3D.getWorldPosition(this._handpos),t.detail.intersection.distance>("head"===this._handName?.5:.25)?setTimeout(this._onBump,260):this._player.components.locomotion.jump(),clearTimeout(this._autoCrouchTO),this._autoCrouchTO=setTimeout((()=>{this.el.sceneEl.querySelector(".legs")?.object3D.position.copy(this._player.components.locomotion.headPos)}),1024)},drop(t){this._climbing=!1,clearTimeout(this._autoCrouchTO),this._autoCrouchTO=setTimeout((()=>{this._player.components.locomotion.toggleCrouch(!0),this._autoCrouchTO=setTimeout((()=>{this.el.sceneEl.querySelector(".legs")?.object3D.position.add(this._player.components.locomotion.centerPos).sub(this._player.components.locomotion.feetPos)}),512)}),256)}},_onBump(t){this._autoGrab||(this._player.components.grabbing.dropObject(this.el),clearTimeout(this._autoGrabTO),this._autoGrabTO=setTimeout((()=>{this._autoGrab=!0}),4096))},_onBumpThis(t){this._autoGrab&&(this._player.components.grabbing.grab(),this._autoGrab=!1)}})},{}],6:[function(t,e,s){AFRAME.registerComponent("fingerflex",{schema:{min:{type:"number",default:10},max:{type:"number",default:90}},init(){this._fingers=["thumb","index","middle","ring","little"],this._currentFlex=[0,0,0,0,0],this._targetFlex=[0,0,0,0,0]},tick(t,e){for(let t=0;t<5;t++){let e=this._fingers[t],s=this._currentFlex[t],i=this._targetFlex[t];s+=Math.random()*Math.random()*(i-s);let o=this.data.min+s*(this.data.max-this.data.min),n=this.el.querySelector(".bend."+e);for(;n;){let t=n.getAttribute("rotation");t.y=o,n.setAttribute("rotation",t),n=n.querySelector(".bend")}this._currentFlex[t]=s}},events:{fingerflex(t){this._targetFlex[t.detail.finger]=t.detail.flex}}})},{}],7:[function(t,e,s){AFRAME.registerComponent("grabbable",{schema:{physics:{type:"boolean",default:!0},kinematicGrab:{type:"boolean",default:!0},fixed:{type:"boolean",default:!1},fixedPosition:{type:"vec3",default:{x:0,y:0,z:0}}},init(){this.data.physics&&!this.el.getAttribute("body")&&this.el.setAttribute("body","type:dynamic;")},events:{grab(){this.data.kinematicGrab&&this.el.setAttribute("body","type","kinematic")},drop(){this.data.physics&&this.el.setAttribute("body","type","dynamic")}}})},{}],8:[function(t,e,s){AFRAME.registerComponent("receptacle",{schema:{objects:{type:"string",default:"[grabbable]"},radius:{type:"number",default:.125}},init(){this._anchor=this.el.ensure(".receptacle.anchor","a-entity",{class:"receptacle anchor",body:"type:kinematic;autoShape:false;"}),this._refreshTO=setInterval(this.refreshObjects.bind(this),1024)},remove(){clearInterval(this._refreshTO)},tick(){if(!this.nearest)return this.refreshObjects();let t=THREE.Vector3.temp(),e=THREE.Vector3.temp();this.el.object3D.localToWorld(t.set(0,0,0)),this.nearest.object3D.localToWorld(e.set(0,0,0)),e.sub(t),this._lastNearest&&this._lastNearest!==this.nearest?(this.el.is("filled")&&(this._anchor.removeAttribute("joint__put"),this._anchor.removeAttribute("animation__pos"),this._anchor.removeAttribute("animation__rot"),this.el.removeState("filled"),this._lastNearest.removeState("put"),this.el.emit("take",{grabbable:this._lastNearest}),this._lastNearest.emit("take",{receptacle:this.el})),this._hover&&(this.el.emit("unhover",{grabbable:this._lastNearest}),this._lastNearest.emit("unhover",{receptacle:this.el})),this._hover=!1):e.length()>this.data.radius?(this.el.is("filled")&&(this._anchor.removeAttribute("joint__put"),this._anchor.removeAttribute("animation__pos"),this._anchor.removeAttribute("animation__rot"),this.el.removeState("filled"),this.nearest.removeState("put"),this.el.emit("take",{grabbable:this.nearest}),this.nearest.emit("take",{receptacle:this.el})),this._hover&&(this.el.emit("unhover",{grabbable:this.nearest}),this.nearest.emit("unhover",{receptacle:this.el})),this._hover=!1):this.nearest.is("grabbed")||!this._hover?(this._hover||(this.el.emit("hover",{grabbable:this.nearest}),this.nearest.emit("hover",{receptacle:this.el})),this._anchor.removeAttribute("animation__pos"),this._anchor.removeAttribute("animation__rot"),this._anchor.copyWorldPosRot(this.nearest),this._hover=!0):(this.el.is("filled")||(this._anchor.copyWorldPosRot(this.nearest),this._anchor.components.body.commit(),this.nearest.components.body&&this._anchor.setAttribute("joint__put",{body2:this.nearest,type:"lock"}),this.el.addState("filled"),this.nearest.addState("put"),this.el.emit("put",{grabbable:this.nearest}),this.nearest.emit("put",{receptacle:this.el})),this._anchor.getAttribute("animation__pos")||(this._anchor.setAttribute("animation__pos",{property:"position",to:{x:0,y:0,z:0},dur:256}),this._anchor.setAttribute("animation__rot",{property:"rotation",to:{x:0,y:0,z:0},dur:256})),this.nearest.copyWorldPosRot(this._anchor),this._hover=!0),this._lastNearest=this.nearest},refreshObjects(){let t=1/0,e=THREE.Vector3.temp(),s=THREE.Vector3.temp(),i=THREE.Vector3.temp(),o=this.el.sceneEl.querySelectorAll(this.data.objects);this.nearest=null,o&&(this.el.object3D.localToWorld(e.set(0,0,0)),o.forEach((o=>{o.object3D.localToWorld(s.set(0,0,0)),i.copy(s).sub(e),t>i.length()&&(t=i.length(),this.nearest=o)})))}})},{}],9:[function(t,e,s){AFRAME.registerComponent("include",{schema:{type:"string"},async init(){if(this.data&&!this.el.sceneEl._including_){this.el.sceneEl._including_=!0;let t=this.el.outerHTML,e=t.indexOf(" "),s=t.indexOf(" include="),i=t.substr(e,s-e);e=t.indexOf('"',s+10)+1,s=t.indexOf(">"),i+=t.substr(e,s-e);let o=await fetch(this.data);o.status>=200&&o.status<300?this.el.outerHTML=await(await o.text()).replace(">"," >").replace(" "," "+i+" "):this.el.removeAttribute("include"),this.el.sceneEl._including_=!1;let n=this.el.sceneEl.querySelector("[include]");n&&n.components&&n.components.include&&n.components.include.init()}}})},{}],10:[function(t,e,s){AFRAME.registerComponent("injectplayer",{init(){this.el.ensure("a-camera","a-camera",{"look-controls":{pointerLockEnabled:!0,touchEnabled:!1},"wasd-controls":{enabled:!1}}),this.el.ensure('a-hand[side="left"]',"a-hand",{side:"left"}),this.el.ensure('a-hand[side="right"]',"a-hand",{side:"right"})}})},{}],11:[function(t,e,s){AFRAME.registerComponent("locomotion",{dependencies:["position","injectplayer"],schema:{speed:{type:"number",default:4},stepLength:{type:"number",default:1},rotationSpeed:{type:"number",default:1},teleportDistance:{type:"number",default:5},jumpForce:{type:"number",default:4},gravity:{type:"number",default:10},godMode:{type:"boolean",default:!1}},init(){this._onKeyDown=this._onKeyDown.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onAxisMove=this._onAxisMove.bind(this),this._onButtonChanged=this._onButtonChanged.bind(this),this._onTouchStart=this._onTouchStart.bind(this),this._onTouchMove=this._onTouchMove.bind(this),this._onTouchEnd=this._onTouchEnd.bind(this),this._onEnterVR=this._onEnterVR.bind(this),this._onExitVR=this._onExitVR.bind(this),this._keysDown={},this._kbStick=new THREE.Vector2,this._axes=[0,0,0,0],this._leftTouchCenter=new THREE.Vector2,this._leftTouchDir=new THREE.Vector2,this._rightTouchCenter=new THREE.Vector2,this._rightTouchDir=new THREE.Vector2,this._teleporting=!0,this._bumpOverload=0,this._vertVelocity=1,this.currentFloorPosition=new THREE.Vector3,this.centerPos=new THREE.Vector3,this.headPos=new THREE.Vector3,this.headDir=new THREE.Vector3,this.feetPos=new THREE.Vector3,this.lastStep=new THREE.Vector3,this._config={quantizeMovement:!1,quantizeRotation:!1,quantizeMovementVR:!!this.el.sceneEl.isMobile,quantizeRotationVR:!0},this.el.sceneEl.is("vr-mode")?this._onEnterVR():this._onExitVR(),this._camera=this.el.querySelector("a-camera"),this._leftHand=this.el.querySelector('a-hand[side="left"]'),this._rightHand=this.el.querySelector('a-hand[side="right"]'),this._legs=this.el.sceneEl.ensure(".legs","a-entity",{class:"legs",position:"0 0.5 0",raycaster:{autoRefresh:!1,objects:"[floor]",direction:"0 -1 0",far:.625}}),this._legBumper=this.el.sceneEl.ensure(".leg-bumper","a-entity",{class:"leg-bumper",position:"0 0.5 0",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._headBumper=this.el.sceneEl.ensure(".head-bumper","a-entity",{class:"head-bumper",position:"0 0.5 0",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._teleportBeam=this._camera.ensure(".teleport-ray","a-entity",{class:"teleport-ray",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._teleportCursor=this.el.ensure(".teleport-cursor","a-cylinder",{class:"teleport-cursor",radius:.5,height:.0625,material:"opacity:0.5;"}),this._teleportCursor.setAttribute("visible",!1)},update(t){this._godMode=this.data.godMode},play(){document.addEventListener("keydown",this._onKeyDown),document.addEventListener("keyup",this._onKeyUp),this._leftHand.addEventListener("axismove",this._onAxisMove),this._rightHand.addEventListener("axismove",this._onAxisMove),this._leftHand.addEventListener("buttonchanged",this._onButtonChanged),this._rightHand.addEventListener("buttonchanged",this._onButtonChanged),this.el.sceneEl.canvas.addEventListener("touchstart",this._onTouchStart),this.el.sceneEl.canvas.addEventListener("touchmove",this._onTouchMove),this.el.sceneEl.canvas.addEventListener("touchend",this._onTouchEnd),this.el.sceneEl.addEventListener("enter-vr",this._onEnterVR),this.el.sceneEl.addEventListener("exit-vr",this._onExitVR)},pause(){document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("keyup",this._onKeyUp),this._leftHand.removeEventListener("axismove",this._onAxisMove),this._rightHand.removeEventListener("axismove",this._onAxisMove),this._leftHand.removeEventListener("buttonchanged",this._onButtonChanged),this._rightHand.removeEventListener("buttonchanged",this._onButtonChanged),this.el.sceneEl.canvas.removeEventListener("touchstart",this._onTouchStart),this.el.sceneEl.canvas.removeEventListener("touchmove",this._onTouchMove),this.el.sceneEl.canvas.removeEventListener("touchend",this._onTouchEnd),this.el.sceneEl.removeEventListener("enter-vr",this._onEnterVR),this.el.sceneEl.removeEventListener("exit-vr",this._onExitVR)},remove(){this.el.sceneEl.removeChild(this._legs),this.el.sceneEl.removeChild(this._legBumper),this.el.sceneEl.removeChild(this._headBumper)},tick(t,e){e/=1e3,this.el.object3D.localToWorld(this.centerPos.set(0,0,0)),this.headPos.copy(this._camera.object3D.position),this._camera.object3D.parent.localToWorld(this.headPos),this.headDir.set(0,0,-1).applyQuaternion(this._camera.object3D.quaternion).applyQuaternion(this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp())),this._legs.object3D.localToWorld(this.feetPos.set(0,0,0)),this.feetPos.y-=.5,this._applyButtons(e),this._applyMoveStick(e),this._applyAuxStick(e);let s=THREE.Vector3.temp().copy(this.headPos).sub(this.feetPos);if(s.y=0,(s.length()>.5||!this.currentFloor)&&(this.currentFloor&&s.multiplyScalar(.1),this._legs.object3D.position.add(s),this.feetPos.add(s)),!this._godMode&&!this._caution){let t=this._legs.components.raycaster;t.refreshObjects();let s=t.intersections[0];if(s&&this._vertVelocity<=0){if(this._vertVelocity=0,this.currentFloor===s.el){let t=THREE.Vector3.temp();t.copy(this.currentFloor.object3D.position).sub(this.currentFloorPosition),this.move(t),this.lastStep.add(t),t.y=0,this._legs.object3D.position.add(t)}else this.currentFloor&&this.currentFloor.emit("leave"),s.el.emit("enter");this.move(THREE.Vector3.temp().set(0,.5-s.distance,0)),this.currentFloor=s.el,this.currentFloorPosition.copy(this.currentFloor.object3D.position)}else this.currentFloor&&this.currentFloor.emit("leave"),this._vertVelocity-=this.data.gravity*e,this.move(THREE.Vector3.temp().set(0,Math.max(-.5,this._vertVelocity*e),0)),this.currentFloor=null}if(this._godMode)this._legBumper.object3D.position.copy(this._legs.object3D.position),this._headBumper.object3D.position.copy(this._legs.object3D.position);else if(this._bumpOverload>4||Math.abs(this.headPos.y-this.feetPos.y)>3)this.feetPos.y=this.centerPos.y,this._legs.object3D.position.y=this.feetPos.y+.5,this.teleport(this._legBumper.object3D.position,!0),this._bumpOverload&&this._bumpOverload--;else{let t=THREE.Vector3.temp();t.copy(this.feetPos).y+=.5,this._bump(t,this._legBumper),t.copy(this.headPos),this._bump(t,this._headBumper)}let i=THREE.Vector3.temp();if(i.copy(this.feetPos).sub(this.lastStep),i.length()>this.data.stepLength)for(this.currentFloor&&(this.el.emit("step"),this.currentFloor.emit("step"));i.length()>this.data.stepLength;)i.multiplyScalar(this.data.stepLength/i.length()),this.lastStep.add(i),i.copy(this.feetPos).sub(this.lastStep)},teleport(t,e){let s=THREE.Vector3.temp();s.copy(t).sub(this.feetPos),this.move(s),this._legs.object3D.position.x=this.feetPos.x=this.headPos.x,this._legs.object3D.position.z=this.feetPos.z=this.headPos.z,this._caution=8,e&&(this._legBumper.object3D.position.copy(this._legs.object3D.position),this._headBumper.object3D.position.copy(this._legs.object3D.position))},jump(){this.currentFloor&&(this._vertVelocity=this.data.jumpForce)},stopFall(){this._legs.object3D.position.x=this.feetPos.x=this.headPos.x,this._legs.object3D.position.z=this.feetPos.z=this.headPos.z,this._vertVelocity=Math.max(this._vertVelocity,0)},toggleCrouch(t){let e,s=this.headPos.y-this.feetPos.y;clearTimeout(this._crouchResetTO),this._crouchResetTO=null,Math.abs(this.centerPos.y-this.feetPos.y)>.03125?e=this.feetPos.y-this.centerPos.y:t||(e=s>1?-1:1),this.el.removeAttribute("animation"),e&&this.el.setAttribute("animation",{property:"object3D.position.y",to:this.el.object3D.position.y+e,dur:256})},move(t){this.el.object3D.position.add(t),this.centerPos.add(t),this.headPos.add(t),this._legs.object3D.position.y+=t.y,this.feetPos.y+=t.y},_bump(t,e){let s=THREE.Matrix3.temp(),i=THREE.Vector3.temp();i.copy(t),i.sub(e.object3D.position);let o=i.length();if(o){e.setAttribute("raycaster","far",o+.125),e.setAttribute("raycaster","direction",`${i.x} ${i.y} ${i.z}`);let n=e.components.raycaster;n.refreshObjects();let a=n.intersections[0];if(a){this.el.removeAttribute("animation"),s.getNormalMatrix(a.el.object3D.matrixWorld),i.copy(a.face.normal).applyMatrix3(s).normalize().multiplyScalar(o+.125);let t=this._legs.object3D.position.y;this.move(i),e.object3D.position.add(i),this._legs.object3D.position.y!==t&&(e===this._headBumper&&this._headBumper.object3D.position.copy(this._legBumper.object3D.position),clearTimeout(this._crouchResetTO),this._crouchResetTO=setTimeout((()=>{this.toggleCrouch(!0)}),4096)),this._legs.object3D.position.add(i),this._legs.object3D.position.y=Math.max(t,this.headPos.y-1.5),this._caution=4,this._bumpOverload++,this._vertVelocity=Math.min(0,this._vertVelocity);let n={player:this.el,object:a.el};this.el.emit("bump",n),a.el.emit("bump",n)}else this._caution?this._caution--:(this._bumpOverload&&this._bumpOverload--,e.object3D.position.lerp(t,.25))}},_callMoveStick(){let t=THREE.Vector2.temp().set(0,0),e=THREE.Vector2.temp();for(e.set(0,0),this._keysDown.KeyA&&e.x--,this._keysDown.KeyD&&e.x++,(this._keysDown.KeyW||this._keysDown.ArrowUp)&&e.y--,(this._keysDown.KeyS||this._keysDown.ArrowDown)&&e.y++,this._kbStick.length()>.1?this._kbStick.multiplyScalar((this._kbStick.length()-.1)/this._kbStick.length()):this._kbStick.set(0,0),this._kbStick.add(e.multiplyScalar(.2)),this._kbStick.length()>1&&this._kbStick.normalize(),this._kbStick.length()>t.length()&&t.copy(this._kbStick),this._deadZone(e.set(this._axes[0],this._axes[1])),e.length()>t.length()&&t.copy(e),e.copy(this._leftTouchDir),e.length()>t.length()&&t.copy(e),i=0,len=navigator.getGamepads().length;it.length()&&t.copy(e));return t.length()>1&&t.normalize(),(this._keysDown.ShiftLeft||this._keysDown.ShiftRight)&&t.multiplyScalar(.25),t},_applyMoveStick(t){let e=this._callMoveStick();e.multiplyScalar(this.data.speed),e.multiplyScalar(t);let s=THREE.Vector2.temp().set(this.headDir.z,-this.headDir.x).angle()-Math.PI,i=Math.cos(s)*e.x-Math.sin(s)*e.y,o=Math.sin(s)*e.x+Math.cos(s)*e.y,n=THREE.Vector3.temp().set(i,0,o);this.quantizeMovement&&(this._quantTime=this._quantTime||0,this._quantDelta=this._quantDelta||new THREE.Vector3,this._quantTime+=t,this._quantDelta.add(n),this._quantTime>.25?(this._quantTime-=.25,n.copy(this._quantDelta),this._quantDelta.set(0,0,0)):n.set(0,0,0)),this.move(n)},_callAuxStick(){let t=THREE.Vector2.temp().set(0,0),e=THREE.Vector2.temp();for(e.set(0,0),this._keysDown.ArrowLeft&&e.x--,this._keysDown.ArrowRight&&e.x++,this._keysDown.KeyQ&&e.y--,this._keysDown.KeyC&&e.y++,e.length()>t.length()&&t.copy(e),this._fourWay(this._deadZone(e.set(this._axes[2],this._axes[3]))),e.length()>t.length()&&t.copy(e),this._fourWay(e.copy(this._rightTouchDir)),e.length()>t.length()&&t.copy(e),i=0,len=navigator.getGamepads().length;it.length()&&t.copy(e));return t.length()>1&&t.normalize(),(this._keysDown.ShiftLeft||this._keysDown.ShiftRight)&&t.multiplyScalar(.25),t},_applyAuxStick(t){let e=this._callAuxStick(),s=0;if(this.quantizeRotation?Math.round(e.x)?this._rotating||(this._rotating=!0,s=-Math.round(e.x)*Math.PI/4):this._rotating=!1:s=-e.x*this.data.rotationSpeed*t,s){let t=THREE.Vector2.temp(),e=THREE.Vector2.temp(),i=THREE.Vector3.temp();t.set(this.feetPos.x,this.feetPos.z),e.set(this.centerPos.x,this.centerPos.z),t.rotateAround(e,-s),i.set(this.feetPos.x-t.x,0,this.feetPos.z-t.y),this.el.object3D.rotateY(s),this.el.object3D.position.add(i),this.centerPos.add(i)}if(this._godMode)this.el.object3D.position.y+=-e.y*this.data.speed*t,this._legs.object3D.position.y+=-e.y*this.data.speed*t;else if(Math.round(e.y)>0?this._crouching||(this._crouching=!0,this.toggleCrouch()):this._crouching=!1,Math.round(e.y)<0){!this._teleporting&&this.data.teleportDistance&&(this._teleportCursor.setAttribute("visible",!0),this._teleporting=!0);let t=THREE.Quaternion.temp();if(this._teleportCursor.object3D.getWorldQuaternion(t),this._teleportCursor.object3D.quaternion.multiply(t.conjugate().normalize()).multiply(t.copy(this.el.object3D.quaternion).multiply(this._camera.object3D.quaternion)),this._teleportCursor.object3D.quaternion.x=0,this._teleportCursor.object3D.quaternion.z=0,this._teleportCursor.object3D.quaternion.normalize(),ray=this._teleportBeam.components.raycaster,ray.refreshObjects(),hit=ray.intersections[0],hit&&null!=hit.el.getAttribute("floor")){let e=THREE.Vector3.temp(),s=THREE.Vector3.temp(),i=THREE.Matrix3.temp();s.copy(hit.point).sub(this.feetPos),s.y>1.5&&s.multiplyScalar(0),s.length()>this.data.teleportDistance&&s.normalize().multiplyScalar(this.data.teleportDistance),s.add(this.feetPos),this._teleportCursor.object3D.position.copy(s),this._teleportCursor.object3D.parent.worldToLocal(this._teleportCursor.object3D.position),i.getNormalMatrix(hit.el.object3D.matrixWorld),s.copy(hit.face.normal).applyMatrix3(i).normalize(),s.applyQuaternion(t.copy(this.el.object3D.quaternion).conjugate()),e.set(0,1,0),t.setFromUnitVectors(e,s),this._teleportCursor.object3D.quaternion.premultiply(t)}else this._teleportCursor.object3D.position.copy(this.feetPos),this._teleportCursor.object3D.parent.worldToLocal(this._teleportCursor.object3D.position)}else if(this._teleporting){let t=THREE.Vector3.temp();this._teleportCursor.object3D.localToWorld(t.set(0,0,0)),this.teleport(t),this._teleportCursor.setAttribute("visible",!1),this._teleportCursor.setAttribute("position","0 0 0"),this._teleporting=!1}},_callButtons(){let t=0;for(this._keysDown.Space&&(t|=1),this._keysDown.KeyG&&(t|=2),this._vrRightClick&&(t|=1),this._vrLeftClick&&(t|=2),i=0,len=navigator.getGamepads().length;i(t.length()>e?t.multiplyScalar((t.length()-e)/(1-e)/t.length()):t.set(0,0),t),_fourWay(t){let e=t.length();return Math.abs(t.x)>Math.abs(t.y)?t.y=0:t.x=0,t.multiplyScalar(e/t.length()),t},_onKeyDown(t){this._keysDown[t.code]=!0},_onKeyUp(t){this._keysDown[t.code]=!1},_onAxisMove(t){"left"===t.srcElement.getAttribute("tracked-controls").hand?(this._axes[0]=t.detail.axis[2],this._axes[1]=t.detail.axis[3]):(this._axes[2]=t.detail.axis[2],this._axes[3]=t.detail.axis[3]),this._handEnabled||(this._teleportBeam.parentElement.removeChild(this._teleportBeam),this._teleportBeam=this._rightHand.ensure(".teleportBeam","a-entity",{class:"teleportBeam",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._handEnabled=!0)},_onButtonChanged(t){"left"===t.srcElement.getAttribute("tracked-controls").hand?3==t.detail.id&&(this._vrLeftClick=t.detail.state.pressed):3==t.detail.id&&(this._vrRightClick=t.detail.state.pressed)},_onTouchStart(t){let e=this.el.sceneEl.canvas.clientWidth;for(let s=0;se/2&&(this._rightTouchId=i.identifier,this._rightTouchCenter.set(i.clientX,i.clientY))}t.preventDefault()},_onTouchMove(t){for(let e=0;e32&&(o.multiplyScalar((o.length()-32)/o.length()),i.add(o),o.multiplyScalar(32/o.length())),o.divideScalar(32))}t.preventDefault()},_onTouchEnd(t){for(let e=0;e{this.init()}),256);let e=new THREE.Vector3;setTimeout((()=>{this.el.object3D.localToWorld(e.set(0,0,0)),t.teleport(e,!0),setTimeout((()=>{t.toggleCrouch(!0)}),256)}),256)}})},{}],14:[function(t,e,s){AFRAME.registerComponent("wall",{schema:{physics:{type:"boolean",default:!0}},update(){this.data.physics&&!this.el.getAttribute("body")&&this.el.setAttribute("body","type:static")}})},{}],15:[function(t,e,s){AFRAME.registerComponent("onevent",{multiple:!0,schema:{event:{type:"string"},entity:{type:"selector"},property:{type:"string"},value:{type:"string"}},init(){this.trigger=this.trigger.bind(this)},update(t){this.pause(),this._event=this.data.event||this.id||"",this._entity=this.data.entity||this.el,this._property=this.data.property||"",this._value=this.data.value||"",this.el.isPlaying&&this.play()},play(){this._event&&this.el.addEventListener(this._event,this.trigger)},pause(){this._event&&this.el.removeEventListener(this._event,this.trigger)},trigger(t){let e=this._property.split(".");e.push(this._value),this._entity.setAttribute(...e)}})},{}],16:[function(t,e,s){AFRAME.registerComponent("onstate",{multiple:!0,schema:{state:{type:"string"},entity:{type:"selector"},property:{type:"string"},on:{type:"string"},off:{type:"string"}},init(){this.trigger=this.trigger.bind(this)},update(t){this._state=this.data.state||this.id||"",this._entity=this.data.entity||this.el,this._property=this.data.property||"",this._on=this.data.on||"",this._off=this.data.off||""},play(){this.trigger(),this.el.addEventListener("stateadded",this.trigger),this.el.addEventListener("stateremoved",this.trigger)},pause(){this.el.removeEventListener("stateadded",this.trigger),this.el.removeEventListener("stateremoved",this.trigger)},trigger(t){if(t&&t.detail!==this._state)return;let e=this._property.split(".");e.push(this.el.is(this._state)?this._on:this._off),this._entity.setAttribute(...e)}})},{}],17:[function(t,e,s){const i=t("../libs/cmdCodec"),o=t("../../package");AFRAME.registerSystem("physics",{schema:{workerUrl:{type:"string",default:`https://cdn.jsdelivr.net/gh/poeticAndroid/a-game@v${o.version}/dist/cannonWorker.min.js`},gravity:{type:"vec3",default:{x:0,y:-10,z:0}},debug:{type:"boolean",default:!1}},update(){if(this.data.workerUrl){if(!this.worker){if(this.data.workerUrl.includes("//")){let t=`importScripts(${JSON.stringify(this.data.workerUrl)})`;this.worker=new Worker(`data:text/javascript;base64,${btoa(t)}`)}else this.worker=new Worker(this.data.workerUrl);this.worker.postMessage("log "+i.stringifyParam("Physics worker ready!")),this.worker.addEventListener("message",this.onMessage.bind(this))}this.bodies=this.bodies||[],this.movingBodies=this.movingBodies||[],this.joints=this.joints||[],this.buffers=[new Float64Array(8),new Float64Array(8)],this.worker.postMessage("world gravity = "+i.stringifyParam(this.data.gravity)),this._debug=this.data.debug}else this.remove()},remove(){this.worker&&this.worker.terminate(),this.worker=null,this.bodies=[],this.movingBodies=[]},tick(t,e){if(!this.worker)return;if(this.buffers.length<2)return;let s=this.buffers.shift();if(s.length<8*this.movingBodies.length){let t=s.length;for(;t<8*this.movingBodies.length;)t*=2;let e=this.movingBodies;s=new Float64Array(t),s.fill(NaN);let i=THREE.Vector3.temp(),o=THREE.Quaternion.temp();for(let t=0;t2;)this.buffers.shift()},command(t){switch("number"==typeof t[0]&&t.shift(),t.shift()){case"body":let e=t.shift(),s=this.bodies[e];s&&s.components.body.command(t)}},eval(t){this.worker.postMessage("world eval "+i.stringifyParam(t))}}),t("./physics/body"),t("./physics/shape"),t("./physics/joint")},{"../../package":1,"../libs/cmdCodec":24,"./physics/body":18,"./physics/joint":19,"./physics/shape":20}],18:[function(t,e,s){const i=t("../../libs/cmdCodec");AFRAME.registerComponent("body",{dependencies:["position","rotation","scale"],schema:{type:{type:"string",default:"dynamic"},mass:{type:"number",default:1},friction:{type:"number",default:.3},restitution:{type:"number",default:.3},belongsTo:{type:"int",default:1},collidesWith:{type:"int",default:1},emitsWith:{type:"int",default:0},sleeping:{type:"boolean",default:!1},autoShape:{type:"boolean",default:!0}},init(){let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.bodies,s=this.el.sceneEl.systems.physics.movingBodies,o=this.el.sceneEl.systems.physics.buffers[0];if(!t)return;this.id=e.indexOf(null),this.id<0&&(this.id=e.length),e[this.id]=this.el,"static"!==this.data.type?(this.mid=s.indexOf(null),this.mid<0&&(this.mid=s.length),s[this.mid]=this.el):this.mid=null;let n={mid:this.mid};if(n.type=this.data.type,n.position=this.el.object3D.localToWorld(THREE.Vector3.temp().set(0,0,0)),n.quaternion=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp()),null!==this.mid){let t=8*this.mid;o[t++]=n.position.x,o[t++]=n.position.y,o[t++]=n.position.z,o[t++]=this.data.sleeping,o[t++]=n.quaternion.x,o[t++]=n.quaternion.y,o[t++]=n.quaternion.z,o[t++]=n.quaternion.w}if(this.shapes=[],this.sleeping=!0,t.postMessage("world body "+this.id+" create "+i.stringifyParam(n)),setTimeout((()=>{n.position=this.el.object3D.localToWorld(THREE.Vector3.temp().set(0,0,0)),n.quaternion=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp()),t.postMessage("world body "+this.id+" position = "+i.stringifyParam(n.position)),t.postMessage("world body "+this.id+" quaternion = "+i.stringifyParam(n.quaternion)),this.el.components.shape&&this.el.components.shape.play();let e=this.el.querySelectorAll("[shape]");e&&e.forEach((t=>{t.components.shape&&t.components.shape.play()})),this.el.components.joint&&this.el.components.joint.play();for(let t in this.el.components)"joint__"===t.substr(0,7)&&this.el.components[t].play()})),this.data.autoShape&&!this.el.getAttribute("shape"))if(this.el.firstElementChild){let t=this.el.querySelectorAll("a-box, a-sphere, a-cylinder");t&&t.forEach((t=>{t.getAttribute("shape")||t.setAttribute("shape",!0)}))}else this.el.setAttribute("shape",!0);this._initiated=!0},play(){this._initiated||(this.init(),this.update({}))},update(t){let e=this.el.sceneEl.systems.physics.worker;e&&(this.data.type!==t.type&&e.postMessage("world body "+this.id+" type = "+i.stringifyParam(this.data.type)),this.data.mass!==t.mass&&e.postMessage("world body "+this.id+" mass = "+i.stringifyParam(this.data.mass)),this.data.friction!==t.friction&&e.postMessage("world body "+this.id+" friction = "+i.stringifyParam(this.data.friction)),this.data.restitution!==t.restitution&&e.postMessage("world body "+this.id+" restitution = "+i.stringifyParam(this.data.restitution)),this.data.belongsTo!==t.belongsTo&&e.postMessage("world body "+this.id+" belongsTo = "+i.stringifyParam(this.data.belongsTo)),this.data.collidesWith!==t.collidesWith&&e.postMessage("world body "+this.id+" collidesWith = "+i.stringifyParam(this.data.collidesWith)),this.data.emitsWith!==t.emitsWith&&e.postMessage("world body "+this.id+" emitsWith = "+i.stringifyParam(this.data.emitsWith)),setTimeout((()=>{e.postMessage("world body "+this.id+" sleeping = "+!!this.data.sleeping)})))},sleep(){let t=this.el.sceneEl.systems.physics.worker;t&&(t.postMessage("world body "+this.id+" sleeping = true"),this.sleeping=!0)},pause(){let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.bodies,s=this.el.sceneEl.systems.physics.movingBodies;if(!t)return;this.el.components.joint&&this.el.components.joint.pause();for(let t in this.el.components)"joint__"===t.substr(0,7)&&this.el.components[t].pause();let i=this.el.querySelectorAll("[shape]");i&&i.forEach((t=>{t.components.shape&&t.components.shape.pause()})),this.el.components.shape&&this.el.components.shape.pause(),e[this.id]=null,null!==this.mid&&(s[this.mid]=null),t.postMessage("world body "+this.id+" remove"),this._initiated=!1},tick(){let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.buffers[0];if(t&&null!==this.mid){let t=8*this.mid;if(e.length<=t)return;if("kinematic"===this.data.type){let s=this.el.object3D.localToWorld(THREE.Vector3.temp().set(0,0,0));e[t++]=s.x,e[t++]=s.y,e[t++]=s.z,this.sleeping=!!e[t++];let i=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp());e[t++]=i.x,e[t++]=i.y,e[t++]=i.z,e[t++]=i.w}else if(e[t+1]){let s=THREE.Quaternion.temp();this.el.object3D.position.set(e[t++],e[t++],e[t++]),this.el.object3D.parent.worldToLocal(this.el.object3D.position),this.sleeping=!!e[t++],this.el.object3D.getWorldQuaternion(s),this.el.object3D.quaternion.multiply(s.conjugate().normalize()),s.set(e[t++],e[t++],e[t++],e[t++]),this.el.object3D.quaternion.multiply(s.normalize())}}},command(t){switch(t.shift()){case"emits":let e=t.shift();switch(e.event){case"collision":let t=this.el.sceneEl.systems.physics.bodies;if(e.body1=t[e.body1],e.body2=t[e.body2],!e.body1||!e.body2)return;e.shape1=e.body1.components.body.shapes[e.shape1],e.shape2=e.body2.components.body.shapes[e.shape2]}this.el.emit(e.event,e)}},eval(t){this.el.sceneEl.systems.physics.worker.postMessage("world body "+this.id+" eval "+i.stringifyParam(t))},commit(){let t=this.el.sceneEl.systems.physics.worker,e=THREE.Vector3.temp(),s=THREE.Quaternion.temp();this.el.object3D.localToWorld(e.set(0,0,0)),t.postMessage("world body "+this.id+" position "+i.stringifyParam(e)),this.el.object3D.getWorldQuaternion(s),t.postMessage("world body "+this.id+" quaternion "+i.stringifyParam(s))}})},{"../../libs/cmdCodec":24}],19:[function(t,e,s){const i=t("../../libs/cmdCodec");AFRAME.registerComponent("joint",{multiple:!0,schema:{type:{type:"string",default:"ball"},body1:{type:"selector"},body2:{type:"selector"},pivot1:{type:"vec3",default:{x:0,y:0,z:0}},pivot2:{type:"vec3",default:{x:0,y:0,z:0}},axis1:{type:"vec3",default:{x:0,y:1,z:0}},axis2:{type:"vec3",default:{x:0,y:1,z:0}},min:{type:"number",default:0},max:{type:"number",default:1},collision:{type:"boolean",default:!0}},play(){if(null!=this._id)return;let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.joints;if(!t)return;if(!this.data.body1.components.body)return this._retry=setTimeout((()=>{this.play()}),256);if(!this.data.body2.components.body)return this._retry=setTimeout((()=>{this.play()}),256);this._id=e.indexOf(null),this._id<0&&(this._id=e.length),e[this._id]=this.el;let s={};s.type=this.data.type,s.body1=this.data.body1?this.data.body1.components.body.id:this.el.components.body.id,s.body2=this.data.body2.components.body.id,s.pivot1=THREE.Vector3.temp().copy(this.data.pivot1),s.pivot2=THREE.Vector3.temp().copy(this.data.pivot2),s.axis1=this.data.axis1,s.axis2=this.data.axis2,s.min=this.data.min,s.max=this.data.max,s.collision=this.data.collision;let o=this.el.object3D.getWorldScale(THREE.Vector3.temp());s.pivot1.multiply(o),s.pivot2.multiply(o),t.postMessage("world joint "+this._id+" create "+i.stringifyParam(s))},update(t){this.el.sceneEl.systems.physics.worker&&(this.data.body1=this.data.body1||this.el)},pause(){clearTimeout(this._retry);let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.joints;t&&(e[this._id]=null,t.postMessage("world joint "+this._id+" remove"),this._id=null)},eval(t){this.el.sceneEl.systems.physics.worker.postMessage("world joint "+this._id+" eval "+i.stringifyParam(t))}})},{"../../libs/cmdCodec":24}],20:[function(t,e,s){const i=t("../../libs/cmdCodec");AFRAME.registerComponent("shape",{schema:{},play(){if(null!=this.id)return;let t=this.el.sceneEl.systems.physics.worker;if(!t)return;for(this.body=this.el;this.body&&!this.body.matches("[body]");)this.body=this.body.parentElement;if(!this.body)return this._retry=setTimeout((()=>{this.play()}),256);this.bodyId=this.body.components.body.id;let e=this.body.components.body.shapes;this.id=e.indexOf(null),this.id<0&&(this.id=e.length),e[this.id]=this.el;let s={};s.position=this.el.object3D.getWorldPosition(THREE.Vector3.temp()),this.body.object3D.worldToLocal(s.position),s.quaternion=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp());let o=this.body.object3D.getWorldQuaternion(THREE.Quaternion.temp());switch(s.quaternion.multiply(o.conjugate().normalize()).normalize(),s.size=THREE.Vector3.temp().set(1,1,1),this.el.tagName.toLowerCase()){case"a-sphere":s.type="sphere",s.size.multiplyScalar(2*parseFloat(this.el.getAttribute("radius")||1));break;case"a-cylinder":s.type="cylinder",s.size.multiplyScalar(2*parseFloat(this.el.getAttribute("radius")||1)).y=parseFloat(this.el.getAttribute("height")||1);break;case"a-box":s.type="box",s.size.set(parseFloat(this.el.getAttribute("width")||1),parseFloat(this.el.getAttribute("height")||1),parseFloat(this.el.getAttribute("depth")||1))}let n=this.el.object3D.getWorldScale(THREE.Vector3.temp());s.size.multiply(n),s.position.multiply(n),t.postMessage("world body "+this.bodyId+" shape "+this.id+" create "+i.stringifyParam(s))},pause(){if(clearTimeout(this._retry),!this.body)return;let t=this.el.sceneEl.systems.physics.worker;if(!t)return;let e=this.body.components.body.shapes;t.postMessage("world body "+this.bodyId+" shape "+this.id+" remove"),e[this.id]=null,this.id=null},eval(t){this.el.sceneEl.systems.physics.worker.postMessage("world body "+this.bodyId+" shape "+this.id+" eval "+i.stringifyParam(t))}})},{"../../libs/cmdCodec":24}],21:[function(require,module,exports){AFRAME.registerComponent("script",{schema:{src:{type:"string"},call:{type:"string"},args:{type:"array"}},async update(oldData){if(this.data.src!==oldData.src){this.script&&(this.el.isPlaying&&this.script.pause?.(),this.script.remove?.()),this.script=null;let response=await fetch(this.data.src);if(response.status>=200&&response.status<300){if(this.script=eval(await await response.text()),this.script.el=this.el,this.script.events)for(let t in this.script.events)this.script.events[t]=this.script.events[t].bind(this.script)}else console.error("Could not load",this.data.src);this.script.init?.(),this.el.isPlaying&&this.script.play?.()}this.script&&this.data.call?.trim()&&(this.script[this.data.call.trim()](...this.data.args),this.el.setAttribute("script","call",""))},remove(){this.script&&this.script.remove?.(...arguments)},tick(){this.script&&this.script.tick?.(...arguments)},tock(){this.script&&this.script.tock?.(...arguments)},play(){if(this.script){if(this.script.events)for(let t in this.script.events)this.el.addEventListener(t,this.script.events[t]);this.script.play?.(...arguments)}},pause(){if(this.script){if(this.script.events)for(let t in this.script.events)this.el.removeEventListener(t,this.script.events[t]);this.script.pause?.(...arguments)}}})},{}],22:[function(t,e,s){AFRAME.registerComponent("trigger",{schema:{objects:{type:"string",default:"[camera]"}},init(){this._refreshTO=setInterval(this.refreshObjects.bind(this),1024)},remove(){clearInterval(this._refreshTO)},tick(){this.objects||this.refreshObjects();let t,e=THREE.Vector3.temp(),s=parseFloat(this.el.getAttribute("width")||1),i=parseFloat(this.el.getAttribute("height")||1),o=parseFloat(this.el.getAttribute("depth")||1),n=parseFloat(this.el.getAttribute("radius")||1);for(let a of this.objects){switch(a.object3D.localToWorld(e.set(0,0,0)),this.el.object3D.worldToLocal(e),this.el.tagName.toLowerCase()){case"a-sphere":t=e.length()=0){let t={trigger:this.el,object:a};this.el.removeState("triggered"),this.el.emit("untrigger",t),a.emit("untrigger",t),this.triggered.splice(this.triggered.indexOf(a),1)}}},refreshObjects(){this.objects=this.objects||[],this.triggered=this.triggered||[],this.objects.splice(0,this.objects.length);let t=this.el.sceneEl.querySelectorAll(this.data.objects);if(t){t.forEach((t=>{this.objects.push(t)}));for(let t=0;t=0)return t;return(t+", ").replaceAll(","," *,")+t}AFRAME.components.raycaster.Component.prototype.update=function(){return this._matchSelector=this.data.objects,this.data.objects=n(this.data.objects),i.apply(this,arguments)},AFRAME.components.raycaster.Component.prototype.refreshObjects=function(){let t=o.apply(this,arguments),e=this.intersections;for(let t of e)for(t.el=t.object.el;t.el&&!t.el.matches(this._matchSelector);)t.el=t.el.parentNode;return t}},{}],24:[function(t,e,s){e.exports={parse(t){let e=t.split(" "),s=[];for(let t of e)if(t)try{s.push(JSON.parse(t))}catch(e){"="!==t&&s.push(t)}return s},stringifyParam:t=>JSON.stringify(t).replaceAll(" ","\\u0020").replaceAll('"_','"')}},{}],25:[function(t,e,s){AFRAME.AEntity.prototype.copyWorldPosRot=function(t){let e=THREE.Quaternion.temp(),s=t.object3D,i=this.object3D;s&&i&&i.parent&&(s.localToWorld(i.position.set(0,0,0)),i.parent.worldToLocal(i.position),i.getWorldQuaternion(e),i.quaternion.multiply(e.conjugate().normalize()),s.getWorldQuaternion(e),i.quaternion.multiply(e.normalize()))}},{}],26:[function(t,e,s){Element.prototype.ensure=function(t,e=t,s={},i=""){let o,n,a;if(o=this.querySelector(t),!o){for(n in o=document.createElement(e),this.appendChild(o),s)a=s[n],o.setAttribute(n,a);o.innerHTML=i}return o}},{}],27:[function(t,e,s){function i(t){t._pool=[],t._inUse=[],t.temp=function(){let e=t._pool.pop()||new t;return t._inUse.push(e),t._gc||(t._gc=setTimeout(t._recycle)),e},t._recycle=function(){for(;t._inUse.length;)t._pool.push(t._inUse.pop());t._gc=!1}}i(THREE.Vector2),i(THREE.Vector3),i(THREE.Quaternion),i(THREE.Matrix3),i(THREE.Matrix4)},{}],28:[function(t,e,s){let i=Element.prototype.addEventListener,o=Element.prototype.removeEventListener,n=t=>{if(t._tgest)return t._tgest;let e,s,i,o;t._tgest={handlers:{swipeup:[],swipedown:[],swipeleft:[],swiperight:[],tap:[],hold:[]}};let n=(e,s)=>{if(t._tgest.handlers[e])for(let i of t._tgest.handlers[e])i(s);else console.log(e,t._tgest.handlers[e])};return t.addEventListener("touchstart",(t=>{e=t.changedTouches[0].screenX,s=t.changedTouches[0].screenY,o=!1,i=setTimeout((()=>{o=!0,n("hold",t)}),512)})),t.addEventListener("touchmove",(t=>{let a=t.changedTouches[0].screenX,r=t.changedTouches[0].screenY;if(Math.sqrt(Math.pow(e-a,2)+Math.pow(s-r,2))>32){if(clearTimeout(i),o)return;Math.abs(e-a)>Math.abs(s-r)?n(a{clearTimeout(i);let a=t.changedTouches[0].screenX,r=t.changedTouches[0].screenY;if(Math.sqrt(Math.pow(e-a,2)+Math.pow(s-r,2))<32){if(o)return;n("tap",t)}})),t._tgest};Element.prototype.addEventListener=function(t,e){switch(t){case"swipeup":case"swipedown":case"swipeleft":case"swiperight":case"tap":case"hold":n(this).handlers[t].push(e);break;default:return i.call(this,t,e)}},Element.prototype.removeEventListener=function(t,e){switch(t){case"swipeup":case"swipedown":case"swipeleft":case"swiperight":case"tap":case"hold":let s=n(this),i=s.handlers[t].indexOf(e);i>=0&&s.handlers[t].splice(i,1);break;default:return o.call(this,t,e)}}},{}],29:[function(t,e,s){AFRAME.registerPrimitive("a-hand",{mappings:{side:"tracked-controls.hand"}})},{}],30:[function(t,e,s){AFRAME.registerPrimitive("a-main",{})},{}],31:[function(t,e,s){AFRAME.registerPrimitive("a-player",{defaultComponents:{injectplayer:{}}})},{}]},{},[2]);
+!function t(e,s,i){function o(a,r){if(!s[a]){if(!e[a]){var h="function"==typeof require&&require;if(!r&&h)return h(a,!0);if(n)return n(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=s[a]={exports:{}};e[a][0].call(c.exports,(function(t){return o(e[a][1][t]||t)}),c,c.exports,t,e,s,i)}return s[a].exports}for(var n="function"==typeof require&&require,a=0;a dist/#{name}.min.js"',bump:"npm version minor --no-git-tag-version",gitadd:"git add package*.json dist/*.js"},"pre-commit":["bump","build","gitadd"],keywords:["aframe","webvr","webxr","gamedev"],author:"poeticAndroid",license:"MIT",devDependencies:{browserify:"^17.0.0","foreach-cli":"^1.8.1",minify:"^7.0.1","pre-commit":"^1.2.2",watchify:"^4.0.0"}}},{}],2:[function(t,e,s){t("./libs/pools"),t("./libs/copyWorldPosRot"),t("./libs/ensureElement"),t("./libs/touchGestures"),t("./libs/betterRaycaster"),setTimeout((()=>{document.body.addEventListener("swipeup",(t=>{document.body.requestFullscreen()}))})),t("./components/grabbing"),t("./components/include"),t("./components/injectplayer"),t("./components/locomotion"),t("./components/onevent"),t("./components/onstate"),t("./components/physics"),t("./components/script"),t("./components/trigger"),t("./primitives/a-hand"),t("./primitives/a-main"),t("./primitives/a-player");const i=t("../package");console.log(`${i.title} Version ${i.version} by ${i.author}\n(${i.homepage})`)},{"../package":1,"./components/grabbing":3,"./components/include":9,"./components/injectplayer":10,"./components/locomotion":11,"./components/onevent":15,"./components/onstate":16,"./components/physics":17,"./components/script":21,"./components/trigger":22,"./libs/betterRaycaster":23,"./libs/copyWorldPosRot":25,"./libs/ensureElement":26,"./libs/pools":27,"./libs/touchGestures":28,"./primitives/a-hand":29,"./primitives/a-main":30,"./primitives/a-player":31}],3:[function(t,e,s){AFRAME.registerComponent("grabbing",{schema:{hideOnGrab:{type:"boolean",default:!0},grabDistance:{type:"number",default:1}},init(){this._enableHands=this._enableHands.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onMouseDown=this._onMouseDown.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onWheel=this._onWheel.bind(this),this._onButtonChanged=this._onButtonChanged.bind(this),this._onTouchTap=this._onTouchTap.bind(this),this._onTouchHold=this._onTouchHold.bind(this),this._btnPress={},this._btnFlex={},this._keysDown={},this._grabCount=0,this._hands=["head","left","right"],this._head={},this._left={},this._right={},this._head.hand=this.el.querySelector("a-camera"),this._left.hand=this.el.querySelector('a-hand[side="left"]'),this._right.hand=this.el.querySelector('a-hand[side="right"]'),this._head.glove=this._head.hand.ensure(".hitbox","a-sphere",{class:"hitbox",body:"type:kinematic;",radius:.25}),this._left.glove=this._ensureGlove(this._left.hand),this._right.glove=this._ensureGlove(this._right.hand),this._left.glove.setAttribute("visible",!1),this._right.glove.setAttribute("visible",!1);for(let t of this._hands){this["_"+t].hand.addEventListener("buttonchanged",this._enableHands)}this._head.ray=this._head.hand.ensure(".grabbing-ray","a-entity",{class:"grabbing-ray",position:"0 -0.125 0",raycaster:{objects:"[wall], [grabbable]",autoRefresh:!1}}),this._head.buttonRay=this._head.hand.ensure(".button.ray","a-entity",{class:"button ray",position:"0 -0.125 0",raycaster:{objects:"[wall], [button]",far:1,autoRefresh:!1}}),this._head.reticle=this._head.ray.ensure(".reticle","a-sphere",{class:"reticle",radius:.015625,position:"0 0 -1"},''),this._head.buttonReticle=this._head.buttonRay.ensure(".reticle","a-sphere",{class:"reticle",radius:.015625,color:"black",position:"0 0 -1"},''),this._head.anchor=this._head.ray.ensure(".grabbing.anchor","a-entity",{class:"grabbing anchor",visible:!1,body:"type:kinematic;autoShape:false;"})},update(t){for(let t of this._hands){let e="_"+t;this[e].ray&&this[e].ray.setAttribute("raycaster","far",this.data.grabDistance+("head"===t?1:.1875))}},play(){document.addEventListener("keydown",this._onKeyDown),document.addEventListener("keyup",this._onKeyUp),this.el.sceneEl.canvas.addEventListener("mousedown",this._onMouseDown),this.el.sceneEl.canvas.addEventListener("mouseup",this._onMouseUp),this.el.sceneEl.canvas.addEventListener("wheel",this._onWheel);for(let t of[this._left.hand,this._right.hand])t.addEventListener("buttonchanged",this._onButtonChanged);this.el.sceneEl.canvas.addEventListener("tap",this._onTouchTap),this.el.sceneEl.canvas.addEventListener("hold",this._onTouchHold)},pause(){document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("keyup",this._onKeyUp),this.el.sceneEl.canvas.removeEventListener("mousedown",this._onMouseDown),this.el.sceneEl.canvas.removeEventListener("mouseup",this._onMouseUp),this.el.sceneEl.canvas.removeEventListener("wheel",this._onWheel);for(let t of[this._left.hand,this._right.hand])t.removeEventListener("buttonchanged",this._onButtonChanged);this.el.sceneEl.canvas.removeEventListener("tap",this._onTouchTap),this.el.sceneEl.canvas.removeEventListener("hold",this._onTouchHold)},remove(){for(let t of this._hands){let e="_"+t;this.drop(t),this[e].glove.copyWorldPosRot(this[e].hand);let s=.25;for(let i=0;i<5;i++)this.emit("fingerflex",this[e].glove,this[e].grabbed,{hand:t,finger:i,flex:s})}},tick(t,e){for(i=0,len=navigator.getGamepads().length;i{this.sticky=!1,this._flexFinger(t,5,.5)}),256)}},drop(t="head"){let e="_"+t;this.sticky||(this[e].anchor.removeAttribute("animation__rot"),this[e].anchor.removeAttribute("animation__pos"),this[e].glove.setAttribute("visible",!0),setTimeout((()=>{this[e].anchor.removeAttribute("joint__grab"),this[e].anchor.setAttribute("position","0 0 0"),this[e].anchor.setAttribute("rotation","0 0 0")}),32),setTimeout((()=>{this[e].glove.setAttribute("body","collidesWith",1)}),1024),this[e].grabbed&&(this.emit("drop",this[e].glove,this[e].grabbed),this._grabCount=Math.max(0,this._grabCount-1),this._grabCount||this.el.removeState("grabbing"),this._flexFinger(t,5,0),this[e].grabbed.removeState("grabbed"),this[e].grabbed=null))},dropObject(t){for(let e of this._hands){this["_"+e].grabbed===t&&this.drop(e)}},use(t="head",e=0){this.useDown(t,e),setTimeout((()=>{this.useUp(t,e)}),32)},useDown(t="head",e=0){let s="_"+t;this[s].grabbed?this.emit("usedown",this[s].glove,this[s].grabbed,{button:e}):this[s]._lastButton&&(this[s]._lastClick=this[s]._lastButton,this.emit("press",this[s].glove,this[s]._lastClick,{button:e}),this[s]._lastClick.addState("pressed"))},useUp(t="head",e=0){let s="_"+t;this[s].grabbed?this.emit("useup",this[s].glove,this[s].grabbed,{button:e}):this[s]._lastClick&&(this.emit("unpress",this[s].glove,this[s]._lastClick),this[s]._lastClick.removeState("pressed"),this[s]._lastClick=null)},moveHeadHand(t=0,e=0,s=0,i=0){this._head.anchor.object3D.position.z=Math.min(Math.max(-1.5,this._head.anchor.object3D.position.z+t),-.125);let o=THREE.Quaternion.temp().set(e,s,i,1).normalize();this._head.anchor.object3D.quaternion.premultiply(o)},emit(t,e,s,i={}){i.grabbing=this.el,i.grabbedElement=s,i.gloveElement=e;for(let t of this._hands)this["_"+t].glove===e&&(i.hand=t);e.emit(t,i),s&&s.emit(t,i)},_enableHands(){for(let t of this._hands){let e="_"+t;this[e].hand.removeEventListener("buttonchanged",this._enableHands);let s=.0625;if(this[e].glove.ensure(".hitbox","a-box",{class:"hitbox",visible:!1,position:"0 0 0.03125",width:s/2,height:s,depth:2*s}),this[e].glove.setAttribute("body","type:kinematic;"),"head"===t)continue;this[e]._occlusionRay=this.el.sceneEl.ensure(".occlusion-ray."+t,"a-entity",{class:"occlusion-ray "+t,raycaster:{objects:"[wall]",autoRefresh:!1}});let i=this[e].glove.querySelector(".palm")||this[e].glove;this[e].ray=i.ensure(".grabbing.ray","a-entity",{class:"grabbing ray",position:"left"===t?"-0.0625 0 0.0625":"0.0625 0 0.0625",rotation:"left"===t?"0 -45 0":"0 45 0",raycaster:{objects:"[wall], [grabbable]",autoRefresh:!1}}),this[e].buttonRay=i.ensure(".button.ray","a-entity",{class:"button ray",position:"0 0.03125 0",rotation:"left"===t?"0 -8 0":"0 8 0",raycaster:{objects:"[wall], [button]",far:.5,autoRefresh:!1}}),this[e].anchor=this[e].ray.ensure(".grabbing.anchor","a-entity",{class:"grabbing anchor",visible:"false",body:"type:kinematic;autoShape:false;"}),this[e].glove.setAttribute("visible",!0)}this._head.ray=null,this._head.buttonRay=null,this.update()},_ensureGlove(t){let e=t.getAttribute("side"),s=t.getAttribute("color")||"lightblue";return t.ensure(".glove","a-entity",{class:"glove",fingerflex:{min:"left"===e?-10:10,max:"left"===e?-90:90}},`\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n `)},_flexFinger(t,e,s){let i="_"+t;if(e<5)this.emit("fingerflex",this[i].glove,this[i].grabbed,{hand:t,finger:e,flex:s});else for(e-=5;e<5;e++)this.emit("fingerflex",this[i].glove,this[i].grabbed,{hand:t,finger:e,flex:s})},_onKeyDown(t){this._keysDown[t.code]=!0,"e"===t.key&&this.toggleGrab()},_onKeyUp(t){this._keysDown[t.code]=!1},_onMouseDown(t){let e=t.button;this.useDown("head",e?e%2?e+1:e-1:e)},_onWheel(t){let e=0,s=0,i=0;return this._keysDown.Digit3&&t.deltaY>0&&(i+=-.125),this._keysDown.Digit3&&t.deltaY<0&&(i+=.125),this._keysDown.Digit2&&t.deltaY>0&&(s+=-.125),this._keysDown.Digit2&&t.deltaY<0&&(s+=.125),this._keysDown.Digit1&&t.deltaY>0&&(e+=.125),this._keysDown.Digit1&&t.deltaY<0&&(e+=-.125),e||s||i?this.moveHeadHand(0,e,s,i):t.deltaY>0?this.moveHeadHand(.125):t.deltaY<0?this.moveHeadHand(-.125):void 0},_onMouseUp(t){let e=t.button;this.useUp("head",e?e%2?e+1:e-1:e)},_onTouchTap(t){this.use()},_onTouchHold(t){this.toggleGrab()},_onButtonChanged(t){let e=t.srcElement.getAttribute("tracked-controls").hand,s="_"+e,i=-1,o=0;switch(t.detail.state.touched&&(o=.5),t.detail.state.pressed&&(o=1),t.detail.state.value&&(o=.5+t.detail.state.value/2),this._btnFlex[e+t.detail.id]=o,t.detail.id){case 0:i=1,t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.useDown(e),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.useUp(e);break;case 1:i=7,t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.grab(e),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.drop(e);break;case 3:i=0,o=Math.max(this._btnFlex[e+3]||0,this._btnFlex[e+4]||0,this._btnFlex[e+5]||0);break;case 4:i=0,o=Math.max(this._btnFlex[e+3]||0,this._btnFlex[e+4]||0,this._btnFlex[e+5]||0),t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.useDown(e,1),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.useUp(e,1);break;case 5:i=0,o=Math.max(this._btnFlex[e+3]||0,this._btnFlex[e+4]||0,this._btnFlex[e+5]||0),t.detail.state.pressed&&!this._btnPress[e+t.detail.id]&&this.useDown(e,2),!t.detail.state.pressed&&this._btnPress[e+t.detail.id]&&this.useUp(e,2)}this._btnPress[e+t.detail.id]=t.detail.state.pressed,(this.sticky||this[s]._lastButton)&&0!==i||this._flexFinger(e,i,o)}}),t("./grabbing/button"),t("./grabbing/climbable"),t("./grabbing/fingerflex"),t("./grabbing/grabbable"),t("./grabbing/receptacle")},{"./grabbing/button":4,"./grabbing/climbable":5,"./grabbing/fingerflex":6,"./grabbing/grabbable":7,"./grabbing/receptacle":8}],4:[function(t,e,s){AFRAME.registerComponent("button",{schema:{}})},{}],5:[function(t,e,s){AFRAME.registerComponent("climbable",{dependencies:["wall"],schema:{},init(){this.el.setAttribute("grabbable","physics:false; kinematicGrab:false;"),this._player=this.el.sceneEl.querySelector("[locomotion]"),this._onBump=this._onBump.bind(this),this._onBumpThis=this._onBumpThis.bind(this),this._autoGrab=!0,setTimeout((()=>{this._quat=new THREE.Quaternion,this._lpos=new THREE.Vector3,this._wpos=new THREE.Vector3,this._handpos=new THREE.Vector3,this._quat.copy(this.el.object3D.quaternion),this._lpos.copy(this.el.object3D.position),this.el.object3D.getWorldPosition(this._wpos),this._top=parseFloat(this.el.getAttribute("height")||1)/2+2}),256)},play(){this._player.addEventListener("bump",this._onBump),this.el.addEventListener("bump",this._onBumpThis)},pause(){this._player.removeEventListener("bump",this._onBump),this.el.removeEventListener("bump",this._onBumpThis),this._climbing=!1},tick(){if(!this._lpos)return;if(this.el.object3D.quaternion.copy(this._quat),this.el.object3D.position.copy(this._lpos),!this._climbing)return;let t=THREE.Vector3.temp();this._hand.object3D.getWorldPosition(t),t.sub(this._handpos).multiplyScalar(-1),"head"===this._handName&&(t.y=0,t.y=t.length(),this._handpos.y+=t.y),this._player.components.locomotion.stopFall(),this._player.components.locomotion.move(t),this._handpos.y-this._wpos.y>this._top&&this._player.components.grabbing.dropObject(this.el)},events:{grab(t){this._climbing=!0,this._handName=t.detail.hand,this._hand=t.detail.gloveElement.parentNode,this._hand.object3D.getWorldPosition(this._handpos),t.detail.intersection.distance>("head"===this._handName?.5:.25)?setTimeout(this._onBump,260):this._player.components.locomotion.jump(),clearTimeout(this._autoCrouchTO),this._autoCrouchTO=setTimeout((()=>{this.el.sceneEl.querySelector(".legs")?.object3D.position.copy(this._player.components.locomotion.headPos)}),1024)},drop(t){this._climbing=!1,clearTimeout(this._autoCrouchTO),this._autoCrouchTO=setTimeout((()=>{this._player.components.locomotion.toggleCrouch(!0),this._autoCrouchTO=setTimeout((()=>{this.el.sceneEl.querySelector(".legs")?.object3D.position.add(this._player.components.locomotion.centerPos).sub(this._player.components.locomotion.feetPos)}),512)}),256)}},_onBump(t){this._autoGrab||(this._player.components.grabbing.dropObject(this.el),clearTimeout(this._autoGrabTO),this._autoGrabTO=setTimeout((()=>{this._autoGrab=!0}),4096))},_onBumpThis(t){this._autoGrab&&(this._player.components.grabbing.grab(),this._autoGrab=!1)}})},{}],6:[function(t,e,s){AFRAME.registerComponent("fingerflex",{schema:{min:{type:"number",default:10},max:{type:"number",default:90}},init(){this._fingers=["thumb","index","middle","ring","little"],this._currentFlex=[0,0,0,0,0],this._targetFlex=[0,0,0,0,0]},tick(t,e){for(let t=0;t<5;t++){let e=this._fingers[t],s=this._currentFlex[t],i=this._targetFlex[t];s+=Math.random()*Math.random()*(i-s);let o=this.data.min+s*(this.data.max-this.data.min),n=this.el.querySelector(".bend."+e);for(;n;){let t=n.getAttribute("rotation");t.y=o,n.setAttribute("rotation",t),n=n.querySelector(".bend")}this._currentFlex[t]=s}},events:{fingerflex(t){this._targetFlex[t.detail.finger]=t.detail.flex}}})},{}],7:[function(t,e,s){AFRAME.registerComponent("grabbable",{schema:{physics:{type:"boolean",default:!0},kinematicGrab:{type:"boolean",default:!0},fixed:{type:"boolean",default:!1},fixedPosition:{type:"vec3",default:{x:0,y:0,z:0}}},init(){this.data.physics&&!this.el.getAttribute("body")&&this.el.setAttribute("body","type:dynamic;")},events:{grab(){this.data.kinematicGrab&&this.el.setAttribute("body","type","kinematic")},drop(){this.data.physics&&this.el.setAttribute("body","type","dynamic")}}})},{}],8:[function(t,e,s){AFRAME.registerComponent("receptacle",{schema:{objects:{type:"string",default:"[grabbable]"},radius:{type:"number",default:.125},onlyGrabbed:{type:"boolean",default:!1}},init(){this._anchor=this.el.ensure(".receptacle.anchor","a-entity",{class:"receptacle anchor",body:"type:kinematic;autoShape:false;"}),this._refreshTO=setInterval(this.refreshObjects.bind(this),1024)},remove(){clearInterval(this._refreshTO)},tick(){if(!this.nearest)return this.refreshObjects();let t=THREE.Vector3.temp(),e=THREE.Vector3.temp();this.el.object3D.localToWorld(t.set(0,0,0)),this.nearest.object3D.localToWorld(e.set(0,0,0)),e.sub(t),this._lastNearest&&this._lastNearest!==this.nearest?(this.el.is("filled")&&(this._anchor.removeAttribute("joint__put"),this._anchor.removeAttribute("animation__pos"),this._anchor.removeAttribute("animation__rot"),this.el.removeState("filled"),this._lastNearest.removeState("put"),this.el.emit("take",{grabbable:this._lastNearest}),this._lastNearest.emit("take",{receptacle:this.el})),this._hover&&(this.el.emit("unhover",{grabbable:this._lastNearest}),this._lastNearest.emit("unhover",{receptacle:this.el})),this._hover=!1,this._grabbed=!1):e.length()>this.data.radius?(this.el.is("filled")&&(this._anchor.removeAttribute("joint__put"),this._anchor.removeAttribute("animation__pos"),this._anchor.removeAttribute("animation__rot"),this.el.removeState("filled"),this.nearest.removeState("put"),this.el.emit("take",{grabbable:this.nearest}),this.nearest.emit("take",{receptacle:this.el})),this._hover&&(this.el.emit("unhover",{grabbable:this.nearest}),this.nearest.emit("unhover",{receptacle:this.el})),this._hover=!1,this._grabbed=!1):this.nearest.is("grabbed")||!this._hover?(this._hover||(this.el.emit("hover",{grabbable:this.nearest}),this.nearest.emit("hover",{receptacle:this.el})),this._anchor.removeAttribute("animation__pos"),this._anchor.removeAttribute("animation__rot"),this._anchor.copyWorldPosRot(this.nearest),this._hover=!0,this.nearest.is("grabbed")&&(this._grabbed=!0)):!this._grabbed&&this.data.onlyGrabbed||(this.el.is("filled")||(this._anchor.copyWorldPosRot(this.nearest),this._anchor.components.body.commit(),this.nearest.components.body&&this._anchor.setAttribute("joint__put",{body2:this.nearest,type:"lock"}),this.el.addState("filled"),this.nearest.addState("put"),this.el.emit("put",{grabbable:this.nearest}),this.nearest.emit("put",{receptacle:this.el})),this._anchor.getAttribute("animation__pos")||(this._anchor.setAttribute("animation__pos",{property:"position",to:{x:0,y:0,z:0},dur:256}),this._anchor.setAttribute("animation__rot",{property:"rotation",to:{x:0,y:0,z:0},dur:256})),this.nearest.copyWorldPosRot(this._anchor),this._hover=!0),this._lastNearest=this.nearest},refreshObjects(){let t=1/0,e=THREE.Vector3.temp(),s=THREE.Vector3.temp(),i=THREE.Vector3.temp(),o=this.el.sceneEl.querySelectorAll(this.data.objects);this.nearest=null,o&&(this.el.object3D.localToWorld(e.set(0,0,0)),o.forEach((o=>{o.object3D.localToWorld(s.set(0,0,0)),i.copy(s).sub(e),t>i.length()&&(t=i.length(),this.nearest=o)})))}})},{}],9:[function(t,e,s){AFRAME.registerComponent("include",{schema:{type:"string"},async init(){if(this.data&&!this.el.sceneEl._including_){this.el.sceneEl._including_=!0;let t=this.el.outerHTML,e=t.indexOf(" "),s=t.indexOf(" include="),i=t.substr(e,s-e);e=t.indexOf('"',s+10)+1,s=t.indexOf(">"),i+=t.substr(e,s-e);let o=await fetch(this.data);o.status>=200&&o.status<300?this.el.outerHTML=await(await o.text()).replace(">"," >").replace(" "," "+i+" "):this.el.removeAttribute("include"),this.el.sceneEl._including_=!1;let n=this.el.sceneEl.querySelector("[include]");n&&n.components&&n.components.include&&n.components.include.init()}}})},{}],10:[function(t,e,s){AFRAME.registerComponent("injectplayer",{init(){this.el.ensure("a-camera","a-camera",{"look-controls":{pointerLockEnabled:!0,touchEnabled:!1},"wasd-controls":{enabled:!1}}),this.el.ensure('a-hand[side="left"]',"a-hand",{side:"left"}),this.el.ensure('a-hand[side="right"]',"a-hand",{side:"right"})}})},{}],11:[function(t,e,s){AFRAME.registerComponent("locomotion",{dependencies:["position","injectplayer"],schema:{speed:{type:"number",default:4},stepLength:{type:"number",default:1},rotationSpeed:{type:"number",default:1},teleportDistance:{type:"number",default:5},jumpForce:{type:"number",default:4},gravity:{type:"number",default:10},godMode:{type:"boolean",default:!1}},init(){this._onKeyDown=this._onKeyDown.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onAxisMove=this._onAxisMove.bind(this),this._onButtonChanged=this._onButtonChanged.bind(this),this._onTouchStart=this._onTouchStart.bind(this),this._onTouchMove=this._onTouchMove.bind(this),this._onTouchEnd=this._onTouchEnd.bind(this),this._onEnterVR=this._onEnterVR.bind(this),this._onExitVR=this._onExitVR.bind(this),this._keysDown={},this._kbStick=new THREE.Vector2,this._axes=[0,0,0,0],this._leftTouchCenter=new THREE.Vector2,this._leftTouchDir=new THREE.Vector2,this._rightTouchCenter=new THREE.Vector2,this._rightTouchDir=new THREE.Vector2,this._teleporting=!0,this._bumpOverload=0,this._vertVelocity=1,this.currentFloorPosition=new THREE.Vector3,this.centerPos=new THREE.Vector3,this.headPos=new THREE.Vector3,this.headDir=new THREE.Vector3,this.feetPos=new THREE.Vector3,this.lastStep=new THREE.Vector3,this._config={quantizeMovement:!1,quantizeRotation:!1,quantizeMovementVR:!!this.el.sceneEl.isMobile,quantizeRotationVR:!0},this.el.sceneEl.is("vr-mode")?this._onEnterVR():this._onExitVR(),this._camera=this.el.querySelector("a-camera"),this._leftHand=this.el.querySelector('a-hand[side="left"]'),this._rightHand=this.el.querySelector('a-hand[side="right"]'),this._legs=this.el.sceneEl.ensure(".legs","a-entity",{class:"legs",position:"0 0.5 0",raycaster:{autoRefresh:!1,objects:"[floor]",direction:"0 -1 0",far:.625}}),this._legBumper=this.el.sceneEl.ensure(".leg-bumper","a-entity",{class:"leg-bumper",position:"0 0.5 0",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._headBumper=this.el.sceneEl.ensure(".head-bumper","a-entity",{class:"head-bumper",position:"0 0.5 0",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._teleportBeam=this._camera.ensure(".teleport-ray","a-entity",{class:"teleport-ray",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._teleportCursor=this.el.ensure(".teleport-cursor","a-cylinder",{class:"teleport-cursor",radius:.5,height:.0625,material:"opacity:0.5;"}),this._teleportCursor.setAttribute("visible",!1)},update(t){this._godMode=this.data.godMode},play(){document.addEventListener("keydown",this._onKeyDown),document.addEventListener("keyup",this._onKeyUp),this._leftHand.addEventListener("axismove",this._onAxisMove),this._rightHand.addEventListener("axismove",this._onAxisMove),this._leftHand.addEventListener("buttonchanged",this._onButtonChanged),this._rightHand.addEventListener("buttonchanged",this._onButtonChanged),this.el.sceneEl.canvas.addEventListener("touchstart",this._onTouchStart),this.el.sceneEl.canvas.addEventListener("touchmove",this._onTouchMove),this.el.sceneEl.canvas.addEventListener("touchend",this._onTouchEnd),this.el.sceneEl.addEventListener("enter-vr",this._onEnterVR),this.el.sceneEl.addEventListener("exit-vr",this._onExitVR)},pause(){document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("keyup",this._onKeyUp),this._leftHand.removeEventListener("axismove",this._onAxisMove),this._rightHand.removeEventListener("axismove",this._onAxisMove),this._leftHand.removeEventListener("buttonchanged",this._onButtonChanged),this._rightHand.removeEventListener("buttonchanged",this._onButtonChanged),this.el.sceneEl.canvas.removeEventListener("touchstart",this._onTouchStart),this.el.sceneEl.canvas.removeEventListener("touchmove",this._onTouchMove),this.el.sceneEl.canvas.removeEventListener("touchend",this._onTouchEnd),this.el.sceneEl.removeEventListener("enter-vr",this._onEnterVR),this.el.sceneEl.removeEventListener("exit-vr",this._onExitVR)},remove(){this.el.sceneEl.removeChild(this._legs),this.el.sceneEl.removeChild(this._legBumper),this.el.sceneEl.removeChild(this._headBumper)},tick(t,e){e/=1e3,this.el.object3D.localToWorld(this.centerPos.set(0,0,0)),this.headPos.copy(this._camera.object3D.position),this._camera.object3D.parent.localToWorld(this.headPos),this.headDir.set(0,0,-1).applyQuaternion(this._camera.object3D.quaternion).applyQuaternion(this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp())),this._legs.object3D.localToWorld(this.feetPos.set(0,0,0)),this.feetPos.y-=.5,this._applyButtons(e),this._applyMoveStick(e),this._applyAuxStick(e);let s=THREE.Vector3.temp().copy(this.headPos).sub(this.feetPos);if(s.y=0,(s.length()>.5||!this.currentFloor)&&(this.currentFloor&&s.multiplyScalar(.1),this._legs.object3D.position.add(s),this.feetPos.add(s)),!this._godMode&&!this._caution){let t=this._legs.components.raycaster;t.refreshObjects();let s=t.intersections[0];if(s&&this._vertVelocity<=0){if(this._vertVelocity=0,this.currentFloor===s.el){let t=THREE.Vector3.temp();t.copy(this.currentFloor.object3D.position).sub(this.currentFloorPosition),this.move(t),this.lastStep.add(t),t.y=0,this._legs.object3D.position.add(t)}else this.currentFloor&&this.currentFloor.emit("leave"),s.el.emit("enter");this.move(THREE.Vector3.temp().set(0,.5-s.distance,0)),this.currentFloor=s.el,this.currentFloorPosition.copy(this.currentFloor.object3D.position)}else this.currentFloor&&this.currentFloor.emit("leave"),this._vertVelocity-=this.data.gravity*e,this.move(THREE.Vector3.temp().set(0,Math.max(-.5,this._vertVelocity*e),0)),this.currentFloor=null}if(this._godMode)this._legBumper.object3D.position.copy(this._legs.object3D.position),this._headBumper.object3D.position.copy(this._legs.object3D.position);else if(this._bumpOverload>4||Math.abs(this.headPos.y-this.feetPos.y)>3)this.feetPos.y=this.centerPos.y,this._legs.object3D.position.y=this.feetPos.y+.5,this.teleport(this._legBumper.object3D.position,!0),this._bumpOverload&&this._bumpOverload--;else{let t=THREE.Vector3.temp();t.copy(this.feetPos).y+=.5,this._bump(t,this._legBumper),t.copy(this.headPos),this._bump(t,this._headBumper)}let i=THREE.Vector3.temp();if(i.copy(this.feetPos).sub(this.lastStep),i.length()>this.data.stepLength)for(this.currentFloor&&(this.el.emit("step"),this.currentFloor.emit("step"));i.length()>this.data.stepLength;)i.multiplyScalar(this.data.stepLength/i.length()),this.lastStep.add(i),i.copy(this.feetPos).sub(this.lastStep)},teleport(t,e){let s=THREE.Vector3.temp();s.copy(t).sub(this.feetPos),this.move(s),this._legs.object3D.position.x=this.feetPos.x=this.headPos.x,this._legs.object3D.position.z=this.feetPos.z=this.headPos.z,this._caution=8,e&&(this._legBumper.object3D.position.copy(this._legs.object3D.position),this._headBumper.object3D.position.copy(this._legs.object3D.position))},jump(){this.currentFloor&&(this._vertVelocity=this.data.jumpForce)},stopFall(){this._legs.object3D.position.x=this.feetPos.x=this.headPos.x,this._legs.object3D.position.z=this.feetPos.z=this.headPos.z,this._vertVelocity=Math.max(this._vertVelocity,0)},toggleCrouch(t){let e,s=this.headPos.y-this.feetPos.y;clearTimeout(this._crouchResetTO),this._crouchResetTO=null,Math.abs(this.centerPos.y-this.feetPos.y)>.03125?e=this.feetPos.y-this.centerPos.y:t||(e=s>1?-1:1),this.el.removeAttribute("animation"),e&&this.el.setAttribute("animation",{property:"object3D.position.y",to:this.el.object3D.position.y+e,dur:256})},move(t){this.el.object3D.position.add(t),this.centerPos.add(t),this.headPos.add(t),this._legs.object3D.position.y+=t.y,this.feetPos.y+=t.y},_bump(t,e){let s=THREE.Matrix3.temp(),i=THREE.Vector3.temp();i.copy(t),i.sub(e.object3D.position);let o=i.length();if(o){e.setAttribute("raycaster","far",o+.125),e.setAttribute("raycaster","direction",`${i.x} ${i.y} ${i.z}`);let n=e.components.raycaster;n.refreshObjects();let a=n.intersections[0];if(a){this.el.removeAttribute("animation"),s.getNormalMatrix(a.el.object3D.matrixWorld),i.copy(a.face.normal).applyMatrix3(s).normalize().multiplyScalar(o+.125);let t=this._legs.object3D.position.y;this.move(i),e.object3D.position.add(i),this._legs.object3D.position.y!==t&&(e===this._headBumper&&this._headBumper.object3D.position.copy(this._legBumper.object3D.position),clearTimeout(this._crouchResetTO),this._crouchResetTO=setTimeout((()=>{this.toggleCrouch(!0)}),4096)),this._legs.object3D.position.add(i),this._legs.object3D.position.y=Math.max(t,this.headPos.y-1.5),this._caution=4,this._bumpOverload++,this._vertVelocity=Math.min(0,this._vertVelocity);let n={player:this.el,object:a.el};this.el.emit("bump",n),a.el.emit("bump",n)}else this._caution?this._caution--:(this._bumpOverload&&this._bumpOverload--,e.object3D.position.lerp(t,.25))}},_callMoveStick(){let t=THREE.Vector2.temp().set(0,0),e=THREE.Vector2.temp();for(e.set(0,0),this._keysDown.KeyA&&e.x--,this._keysDown.KeyD&&e.x++,(this._keysDown.KeyW||this._keysDown.ArrowUp)&&e.y--,(this._keysDown.KeyS||this._keysDown.ArrowDown)&&e.y++,this._kbStick.length()>.1?this._kbStick.multiplyScalar((this._kbStick.length()-.1)/this._kbStick.length()):this._kbStick.set(0,0),this._kbStick.add(e.multiplyScalar(.2)),this._kbStick.length()>1&&this._kbStick.normalize(),this._kbStick.length()>t.length()&&t.copy(this._kbStick),this._deadZone(e.set(this._axes[0],this._axes[1])),e.length()>t.length()&&t.copy(e),e.copy(this._leftTouchDir),e.length()>t.length()&&t.copy(e),i=0,len=navigator.getGamepads().length;it.length()&&t.copy(e));return t.length()>1&&t.normalize(),(this._keysDown.ShiftLeft||this._keysDown.ShiftRight)&&t.multiplyScalar(.25),t},_applyMoveStick(t){let e=this._callMoveStick();e.multiplyScalar(this.data.speed),e.multiplyScalar(t);let s=THREE.Vector2.temp().set(this.headDir.z,-this.headDir.x).angle()-Math.PI,i=Math.cos(s)*e.x-Math.sin(s)*e.y,o=Math.sin(s)*e.x+Math.cos(s)*e.y,n=THREE.Vector3.temp().set(i,0,o);this.quantizeMovement&&(this._quantTime=this._quantTime||0,this._quantDelta=this._quantDelta||new THREE.Vector3,this._quantTime+=t,this._quantDelta.add(n),this._quantTime>.25?(this._quantTime-=.25,n.copy(this._quantDelta),this._quantDelta.set(0,0,0)):n.set(0,0,0)),this.move(n)},_callAuxStick(){let t=THREE.Vector2.temp().set(0,0),e=THREE.Vector2.temp();for(e.set(0,0),this._keysDown.ArrowLeft&&e.x--,this._keysDown.ArrowRight&&e.x++,this._keysDown.KeyQ&&e.y--,this._keysDown.KeyC&&e.y++,e.length()>t.length()&&t.copy(e),this._fourWay(this._deadZone(e.set(this._axes[2],this._axes[3]))),e.length()>t.length()&&t.copy(e),this._fourWay(e.copy(this._rightTouchDir)),e.length()>t.length()&&t.copy(e),i=0,len=navigator.getGamepads().length;it.length()&&t.copy(e));return t.length()>1&&t.normalize(),(this._keysDown.ShiftLeft||this._keysDown.ShiftRight)&&t.multiplyScalar(.25),t},_applyAuxStick(t){let e=this._callAuxStick(),s=0;if(this.quantizeRotation?Math.round(e.x)?this._rotating||(this._rotating=!0,s=-Math.round(e.x)*Math.PI/4):this._rotating=!1:s=-e.x*this.data.rotationSpeed*t,s){let t=THREE.Vector2.temp(),e=THREE.Vector2.temp(),i=THREE.Vector3.temp();t.set(this.feetPos.x,this.feetPos.z),e.set(this.centerPos.x,this.centerPos.z),t.rotateAround(e,-s),i.set(this.feetPos.x-t.x,0,this.feetPos.z-t.y),this.el.object3D.rotateY(s),this.el.object3D.position.add(i),this.centerPos.add(i)}if(this._godMode)this.el.object3D.position.y+=-e.y*this.data.speed*t,this._legs.object3D.position.y+=-e.y*this.data.speed*t;else if(Math.round(e.y)>0?this._crouching||(this._crouching=!0,this.toggleCrouch()):this._crouching=!1,Math.round(e.y)<0){!this._teleporting&&this.data.teleportDistance&&(this._teleportCursor.setAttribute("visible",!0),this._teleporting=!0);let t=THREE.Quaternion.temp();if(this._teleportCursor.object3D.getWorldQuaternion(t),this._teleportCursor.object3D.quaternion.multiply(t.conjugate().normalize()).multiply(t.copy(this.el.object3D.quaternion).multiply(this._camera.object3D.quaternion)),this._teleportCursor.object3D.quaternion.x=0,this._teleportCursor.object3D.quaternion.z=0,this._teleportCursor.object3D.quaternion.normalize(),ray=this._teleportBeam.components.raycaster,ray.refreshObjects(),hit=ray.intersections[0],hit&&null!=hit.el.getAttribute("floor")){let e=THREE.Vector3.temp(),s=THREE.Vector3.temp(),i=THREE.Matrix3.temp();s.copy(hit.point).sub(this.feetPos),s.y>1.5&&s.multiplyScalar(0),s.length()>this.data.teleportDistance&&s.normalize().multiplyScalar(this.data.teleportDistance),s.add(this.feetPos),this._teleportCursor.object3D.position.copy(s),this._teleportCursor.object3D.parent.worldToLocal(this._teleportCursor.object3D.position),i.getNormalMatrix(hit.el.object3D.matrixWorld),s.copy(hit.face.normal).applyMatrix3(i).normalize(),s.applyQuaternion(t.copy(this.el.object3D.quaternion).conjugate()),e.set(0,1,0),t.setFromUnitVectors(e,s),this._teleportCursor.object3D.quaternion.premultiply(t)}else this._teleportCursor.object3D.position.copy(this.feetPos),this._teleportCursor.object3D.parent.worldToLocal(this._teleportCursor.object3D.position)}else if(this._teleporting){let t=THREE.Vector3.temp();this._teleportCursor.object3D.localToWorld(t.set(0,0,0)),this.teleport(t),this._teleportCursor.setAttribute("visible",!1),this._teleportCursor.setAttribute("position","0 0 0"),this._teleporting=!1}},_callButtons(){let t=0;for(this._keysDown.Space&&(t|=1),this._keysDown.KeyG&&(t|=2),this._vrRightClick&&(t|=1),this._vrLeftClick&&(t|=2),i=0,len=navigator.getGamepads().length;i(t.length()>e?t.multiplyScalar((t.length()-e)/(1-e)/t.length()):t.set(0,0),t),_fourWay(t){let e=t.length();return Math.abs(t.x)>Math.abs(t.y)?t.y=0:t.x=0,t.multiplyScalar(e/t.length()),t},_onKeyDown(t){this._keysDown[t.code]=!0},_onKeyUp(t){this._keysDown[t.code]=!1},_onAxisMove(t){"left"===t.srcElement.getAttribute("tracked-controls").hand?(this._axes[0]=t.detail.axis[2],this._axes[1]=t.detail.axis[3]):(this._axes[2]=t.detail.axis[2],this._axes[3]=t.detail.axis[3]),this._handEnabled||(this._teleportBeam.parentElement.removeChild(this._teleportBeam),this._teleportBeam=this._rightHand.ensure(".teleportBeam","a-entity",{class:"teleportBeam",raycaster:{autoRefresh:!1,objects:"[wall]"}}),this._handEnabled=!0)},_onButtonChanged(t){"left"===t.srcElement.getAttribute("tracked-controls").hand?3==t.detail.id&&(this._vrLeftClick=t.detail.state.pressed):3==t.detail.id&&(this._vrRightClick=t.detail.state.pressed)},_onTouchStart(t){let e=this.el.sceneEl.canvas.clientWidth;for(let s=0;se/2&&(this._rightTouchId=i.identifier,this._rightTouchCenter.set(i.clientX,i.clientY))}t.preventDefault()},_onTouchMove(t){for(let e=0;e32&&(o.multiplyScalar((o.length()-32)/o.length()),i.add(o),o.multiplyScalar(32/o.length())),o.divideScalar(32))}t.preventDefault()},_onTouchEnd(t){for(let e=0;e{this.init()}),256);let e=new THREE.Vector3;setTimeout((()=>{this.el.object3D.localToWorld(e.set(0,0,0)),t.teleport(e,!0),setTimeout((()=>{t.toggleCrouch(!0)}),256)}),256)}})},{}],14:[function(t,e,s){AFRAME.registerComponent("wall",{schema:{physics:{type:"boolean",default:!0}},update(){this.data.physics&&!this.el.getAttribute("body")&&this.el.setAttribute("body","type:static")}})},{}],15:[function(t,e,s){AFRAME.registerComponent("onevent",{multiple:!0,schema:{event:{type:"string"},entity:{type:"selector"},property:{type:"string"},value:{type:"string"}},init(){this.trigger=this.trigger.bind(this)},update(t){this.pause(),this._event=this.data.event||this.id||"",this._entity=this.data.entity||this.el,this._property=this.data.property||"",this._value=this.data.value||"",this.el.isPlaying&&this.play()},play(){this._event&&this.el.addEventListener(this._event,this.trigger)},pause(){this._event&&this.el.removeEventListener(this._event,this.trigger)},trigger(t){let e=this._property.split(".");e.push(this._value),this._entity.setAttribute(...e)}})},{}],16:[function(t,e,s){AFRAME.registerComponent("onstate",{multiple:!0,schema:{state:{type:"string"},entity:{type:"selector"},property:{type:"string"},on:{type:"string"},off:{type:"string"}},init(){this.trigger=this.trigger.bind(this)},update(t){this._state=this.data.state||this.id||"",this._entity=this.data.entity||this.el,this._property=this.data.property||"",this._on=this.data.on||"",this._off=this.data.off||""},play(){this.trigger(),this.el.addEventListener("stateadded",this.trigger),this.el.addEventListener("stateremoved",this.trigger)},pause(){this.el.removeEventListener("stateadded",this.trigger),this.el.removeEventListener("stateremoved",this.trigger)},trigger(t){if(t&&t.detail!==this._state)return;let e=this._property.split(".");e.push(this.el.is(this._state)?this._on:this._off),this._entity.setAttribute(...e)}})},{}],17:[function(t,e,s){const i=t("../libs/cmdCodec"),o=t("../../package");AFRAME.registerSystem("physics",{schema:{workerUrl:{type:"string",default:`https://cdn.jsdelivr.net/gh/poeticAndroid/a-game@v${o.version}/dist/cannonWorker.min.js`},gravity:{type:"vec3",default:{x:0,y:-10,z:0}},debug:{type:"boolean",default:!1}},update(){if(this.data.workerUrl){if(!this.worker){if(this.data.workerUrl.includes("//")){let t=`importScripts(${JSON.stringify(this.data.workerUrl)})`;this.worker=new Worker(`data:text/javascript;base64,${btoa(t)}`)}else this.worker=new Worker(this.data.workerUrl);this.worker.postMessage("log "+i.stringifyParam("Physics worker ready!")),this.worker.addEventListener("message",this.onMessage.bind(this))}this.bodies=this.bodies||[],this.movingBodies=this.movingBodies||[],this.joints=this.joints||[],this.buffers=[new Float64Array(8),new Float64Array(8)],this.worker.postMessage("world gravity = "+i.stringifyParam(this.data.gravity)),this._debug=this.data.debug}else this.remove()},remove(){this.worker&&this.worker.terminate(),this.worker=null,this.bodies=[],this.movingBodies=[]},tick(t,e){if(!this.worker)return;if(this.buffers.length<2)return;let s=this.buffers.shift();if(s.length<8*this.movingBodies.length){let t=s.length;for(;t<8*this.movingBodies.length;)t*=2;let e=this.movingBodies;s=new Float64Array(t),s.fill(NaN);let i=THREE.Vector3.temp(),o=THREE.Quaternion.temp();for(let t=0;t2;)this.buffers.shift()},command(t){switch("number"==typeof t[0]&&t.shift(),t.shift()){case"body":let e=t.shift(),s=this.bodies[e];s&&s.components.body.command(t)}},eval(t){this.worker.postMessage("world eval "+i.stringifyParam(t))}}),t("./physics/body"),t("./physics/shape"),t("./physics/joint")},{"../../package":1,"../libs/cmdCodec":24,"./physics/body":18,"./physics/joint":19,"./physics/shape":20}],18:[function(t,e,s){const i=t("../../libs/cmdCodec");AFRAME.registerComponent("body",{dependencies:["position","rotation","scale"],schema:{type:{type:"string",default:"dynamic"},mass:{type:"number",default:1},friction:{type:"number",default:.3},restitution:{type:"number",default:.3},belongsTo:{type:"int",default:1},collidesWith:{type:"int",default:1},emitsWith:{type:"int",default:0},sleeping:{type:"boolean",default:!1},autoShape:{type:"boolean",default:!0}},init(){let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.bodies,s=this.el.sceneEl.systems.physics.movingBodies,o=this.el.sceneEl.systems.physics.buffers[0];if(!t)return;this.id=e.indexOf(null),this.id<0&&(this.id=e.length),e[this.id]=this.el,"static"!==this.data.type?(this.mid=s.indexOf(null),this.mid<0&&(this.mid=s.length),s[this.mid]=this.el):this.mid=null;let n={mid:this.mid};if(n.type=this.data.type,n.position=this.el.object3D.localToWorld(THREE.Vector3.temp().set(0,0,0)),n.quaternion=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp()),null!==this.mid){let t=8*this.mid;o[t++]=n.position.x,o[t++]=n.position.y,o[t++]=n.position.z,o[t++]=this.data.sleeping,o[t++]=n.quaternion.x,o[t++]=n.quaternion.y,o[t++]=n.quaternion.z,o[t++]=n.quaternion.w}if(this.shapes=[],this.sleeping=!0,t.postMessage("world body "+this.id+" create "+i.stringifyParam(n)),setTimeout((()=>{n.position=this.el.object3D.localToWorld(THREE.Vector3.temp().set(0,0,0)),n.quaternion=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp()),t.postMessage("world body "+this.id+" position = "+i.stringifyParam(n.position)),t.postMessage("world body "+this.id+" quaternion = "+i.stringifyParam(n.quaternion)),this.el.components.shape&&this.el.components.shape.play();let e=this.el.querySelectorAll("[shape]");e&&e.forEach((t=>{t.components.shape&&t.components.shape.play()})),this.el.components.joint&&this.el.components.joint.play();for(let t in this.el.components)"joint__"===t.substr(0,7)&&this.el.components[t].play()})),this.data.autoShape&&!this.el.getAttribute("shape"))if(this.el.firstElementChild){let t=this.el.querySelectorAll("a-box, a-sphere, a-cylinder");t&&t.forEach((t=>{t.getAttribute("shape")||t.setAttribute("shape",!0)}))}else this.el.setAttribute("shape",!0);this._initiated=!0},play(){this._initiated||(this.init(),this.update({}))},update(t){let e=this.el.sceneEl.systems.physics.worker;e&&(this.data.type!==t.type&&e.postMessage("world body "+this.id+" type = "+i.stringifyParam(this.data.type)),this.data.mass!==t.mass&&e.postMessage("world body "+this.id+" mass = "+i.stringifyParam(this.data.mass)),this.data.friction!==t.friction&&e.postMessage("world body "+this.id+" friction = "+i.stringifyParam(this.data.friction)),this.data.restitution!==t.restitution&&e.postMessage("world body "+this.id+" restitution = "+i.stringifyParam(this.data.restitution)),this.data.belongsTo!==t.belongsTo&&e.postMessage("world body "+this.id+" belongsTo = "+i.stringifyParam(this.data.belongsTo)),this.data.collidesWith!==t.collidesWith&&e.postMessage("world body "+this.id+" collidesWith = "+i.stringifyParam(this.data.collidesWith)),this.data.emitsWith!==t.emitsWith&&e.postMessage("world body "+this.id+" emitsWith = "+i.stringifyParam(this.data.emitsWith)),setTimeout((()=>{e.postMessage("world body "+this.id+" sleeping = "+!!this.data.sleeping)})))},sleep(){let t=this.el.sceneEl.systems.physics.worker;t&&(t.postMessage("world body "+this.id+" sleeping = true"),this.sleeping=!0)},pause(){let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.bodies,s=this.el.sceneEl.systems.physics.movingBodies;if(!t)return;this.el.components.joint&&this.el.components.joint.pause();for(let t in this.el.components)"joint__"===t.substr(0,7)&&this.el.components[t].pause();let i=this.el.querySelectorAll("[shape]");i&&i.forEach((t=>{t.components.shape&&t.components.shape.pause()})),this.el.components.shape&&this.el.components.shape.pause(),e[this.id]=null,null!==this.mid&&(s[this.mid]=null),t.postMessage("world body "+this.id+" remove"),this._initiated=!1},tick(){let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.buffers[0];if(t&&null!==this.mid){let t=8*this.mid;if(e.length<=t)return;if("kinematic"===this.data.type){let s=this.el.object3D.localToWorld(THREE.Vector3.temp().set(0,0,0));e[t++]=s.x,e[t++]=s.y,e[t++]=s.z,this.sleeping=!!e[t++];let i=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp());e[t++]=i.x,e[t++]=i.y,e[t++]=i.z,e[t++]=i.w}else if(e[t+1]){let s=THREE.Quaternion.temp();this.el.object3D.position.set(e[t++],e[t++],e[t++]),this.el.object3D.parent.worldToLocal(this.el.object3D.position),this.sleeping=!!e[t++],this.el.object3D.getWorldQuaternion(s),this.el.object3D.quaternion.multiply(s.conjugate().normalize()),s.set(e[t++],e[t++],e[t++],e[t++]),this.el.object3D.quaternion.multiply(s.normalize())}}},command(t){switch(t.shift()){case"emits":let e=t.shift();switch(e.event){case"collision":let t=this.el.sceneEl.systems.physics.bodies;if(e.body1=t[e.body1],e.body2=t[e.body2],!e.body1||!e.body2)return;e.shape1=e.body1.components.body.shapes[e.shape1],e.shape2=e.body2.components.body.shapes[e.shape2]}this.el.emit(e.event,e)}},eval(t){this.el.sceneEl.systems.physics.worker.postMessage("world body "+this.id+" eval "+i.stringifyParam(t))},commit(){let t=this.el.sceneEl.systems.physics.worker,e=THREE.Vector3.temp(),s=THREE.Quaternion.temp();this.el.object3D.localToWorld(e.set(0,0,0)),t.postMessage("world body "+this.id+" position "+i.stringifyParam(e)),this.el.object3D.getWorldQuaternion(s),t.postMessage("world body "+this.id+" quaternion "+i.stringifyParam(s))}})},{"../../libs/cmdCodec":24}],19:[function(t,e,s){const i=t("../../libs/cmdCodec");AFRAME.registerComponent("joint",{multiple:!0,schema:{type:{type:"string",default:"ball"},body1:{type:"selector"},body2:{type:"selector"},pivot1:{type:"vec3",default:{x:0,y:0,z:0}},pivot2:{type:"vec3",default:{x:0,y:0,z:0}},axis1:{type:"vec3",default:{x:0,y:1,z:0}},axis2:{type:"vec3",default:{x:0,y:1,z:0}},min:{type:"number",default:0},max:{type:"number",default:1},collision:{type:"boolean",default:!0}},play(){if(null!=this._id)return;let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.joints;if(!t)return;if(!this.data.body1.components.body)return this._retry=setTimeout((()=>{this.play()}),256);if(!this.data.body2.components.body)return this._retry=setTimeout((()=>{this.play()}),256);this._id=e.indexOf(null),this._id<0&&(this._id=e.length),e[this._id]=this.el;let s={};s.type=this.data.type,s.body1=this.data.body1?this.data.body1.components.body.id:this.el.components.body.id,s.body2=this.data.body2.components.body.id,s.pivot1=THREE.Vector3.temp().copy(this.data.pivot1),s.pivot2=THREE.Vector3.temp().copy(this.data.pivot2),s.axis1=this.data.axis1,s.axis2=this.data.axis2,s.min=this.data.min,s.max=this.data.max,s.collision=this.data.collision;let o=this.el.object3D.getWorldScale(THREE.Vector3.temp());s.pivot1.multiply(o),s.pivot2.multiply(o),t.postMessage("world joint "+this._id+" create "+i.stringifyParam(s))},update(t){this.el.sceneEl.systems.physics.worker&&(this.data.body1=this.data.body1||this.el)},pause(){clearTimeout(this._retry);let t=this.el.sceneEl.systems.physics.worker,e=this.el.sceneEl.systems.physics.joints;t&&(e[this._id]=null,t.postMessage("world joint "+this._id+" remove"),this._id=null)},eval(t){this.el.sceneEl.systems.physics.worker.postMessage("world joint "+this._id+" eval "+i.stringifyParam(t))}})},{"../../libs/cmdCodec":24}],20:[function(t,e,s){const i=t("../../libs/cmdCodec");AFRAME.registerComponent("shape",{schema:{},play(){if(null!=this.id)return;let t=this.el.sceneEl.systems.physics.worker;if(!t)return;for(this.body=this.el;this.body&&!this.body.matches("[body]");)this.body=this.body.parentElement;if(!this.body)return this._retry=setTimeout((()=>{this.play()}),256);this.bodyId=this.body.components.body.id;let e=this.body.components.body.shapes;this.id=e.indexOf(null),this.id<0&&(this.id=e.length),e[this.id]=this.el;let s={};s.position=this.el.object3D.getWorldPosition(THREE.Vector3.temp()),this.body.object3D.worldToLocal(s.position),s.quaternion=this.el.object3D.getWorldQuaternion(THREE.Quaternion.temp());let o=this.body.object3D.getWorldQuaternion(THREE.Quaternion.temp());switch(s.quaternion.multiply(o.conjugate().normalize()).normalize(),s.size=THREE.Vector3.temp().set(1,1,1),this.el.tagName.toLowerCase()){case"a-sphere":s.type="sphere",s.size.multiplyScalar(2*parseFloat(this.el.getAttribute("radius")||1));break;case"a-cylinder":s.type="cylinder",s.size.multiplyScalar(2*parseFloat(this.el.getAttribute("radius")||1)).y=parseFloat(this.el.getAttribute("height")||1);break;case"a-box":s.type="box",s.size.set(parseFloat(this.el.getAttribute("width")||1),parseFloat(this.el.getAttribute("height")||1),parseFloat(this.el.getAttribute("depth")||1))}let n=this.el.object3D.getWorldScale(THREE.Vector3.temp());s.size.multiply(n),s.position.multiply(n),t.postMessage("world body "+this.bodyId+" shape "+this.id+" create "+i.stringifyParam(s))},pause(){if(clearTimeout(this._retry),!this.body)return;let t=this.el.sceneEl.systems.physics.worker;if(!t)return;let e=this.body.components.body.shapes;t.postMessage("world body "+this.bodyId+" shape "+this.id+" remove"),e[this.id]=null,this.id=null},eval(t){this.el.sceneEl.systems.physics.worker.postMessage("world body "+this.bodyId+" shape "+this.id+" eval "+i.stringifyParam(t))}})},{"../../libs/cmdCodec":24}],21:[function(require,module,exports){AFRAME.registerComponent("script",{schema:{src:{type:"string"},call:{type:"string"},args:{type:"array"}},async update(oldData){if(this.data.src!==oldData.src){this.script&&(this.el.isPlaying&&this.script.pause?.(),this.script.remove?.()),this.script=null;let response=await fetch(this.data.src);if(response.status>=200&&response.status<300){if(this.script=eval(await await response.text()),this.script.el=this.el,this.script.events)for(let t in this.script.events)this.script.events[t]=this.script.events[t].bind(this.script)}else console.error("Could not load",this.data.src);this.script.init?.(),this.el.isPlaying&&this.script.play?.()}this.script&&this.data.call?.trim()&&(this.script[this.data.call.trim()](...this.data.args),this.el.setAttribute("script","call",""))},remove(){this.script&&this.script.remove?.(...arguments)},tick(){this.script&&this.script.tick?.(...arguments)},tock(){this.script&&this.script.tock?.(...arguments)},play(){if(this.script){if(this.script.events)for(let t in this.script.events)this.el.addEventListener(t,this.script.events[t]);this.script.play?.(...arguments)}},pause(){if(this.script){if(this.script.events)for(let t in this.script.events)this.el.removeEventListener(t,this.script.events[t]);this.script.pause?.(...arguments)}}})},{}],22:[function(t,e,s){AFRAME.registerComponent("trigger",{schema:{objects:{type:"string",default:"[camera]"}},init(){this._refreshTO=setInterval(this.refreshObjects.bind(this),1024)},remove(){clearInterval(this._refreshTO)},tick(){this.objects||this.refreshObjects();let t,e=THREE.Vector3.temp(),s=parseFloat(this.el.getAttribute("width")||1),i=parseFloat(this.el.getAttribute("height")||1),o=parseFloat(this.el.getAttribute("depth")||1),n=parseFloat(this.el.getAttribute("radius")||1);for(let a of this.objects){switch(a.object3D.localToWorld(e.set(0,0,0)),this.el.object3D.worldToLocal(e),this.el.tagName.toLowerCase()){case"a-sphere":t=e.length()=0){let t={trigger:this.el,object:a};this.el.emit("untrigger",t),a.emit("untrigger",t),this.triggered.splice(this.triggered.indexOf(a),1),this.triggered.length||this.el.removeState("triggered")}}},refreshObjects(){this.objects=this.objects||[],this.triggered=this.triggered||[],this.objects.splice(0,this.objects.length);let t=this.el.sceneEl.querySelectorAll(this.data.objects);if(t){t.forEach((t=>{this.objects.push(t)}));for(let t=0;t=0)return t;return(t+", ").replaceAll(","," *,")+t}AFRAME.components.raycaster.Component.prototype.update=function(){return this._matchSelector=this.data.objects,this.data.objects=n(this.data.objects),i.apply(this,arguments)},AFRAME.components.raycaster.Component.prototype.refreshObjects=function(){let t=o.apply(this,arguments),e=this.intersections;for(let t of e)for(t.el=t.object.el;t.el&&!t.el.matches(this._matchSelector);)t.el=t.el.parentNode;return t}},{}],24:[function(t,e,s){e.exports={parse(t){let e=t.split(" "),s=[];for(let t of e)if(t)try{s.push(JSON.parse(t))}catch(e){"="!==t&&s.push(t)}return s},stringifyParam:t=>JSON.stringify(t).replaceAll(" ","\\u0020").replaceAll('"_','"')}},{}],25:[function(t,e,s){AFRAME.AEntity.prototype.copyWorldPosRot=function(t){let e=THREE.Quaternion.temp(),s=t.object3D,i=this.object3D;s&&i&&i.parent&&(s.localToWorld(i.position.set(0,0,0)),i.parent.worldToLocal(i.position),i.getWorldQuaternion(e),i.quaternion.multiply(e.conjugate().normalize()),s.getWorldQuaternion(e),i.quaternion.multiply(e.normalize()))}},{}],26:[function(t,e,s){Element.prototype.ensure=function(t,e=t,s={},i=""){let o,n,a;if(o=this.querySelector(t),!o){for(n in o=document.createElement(e),this.appendChild(o),s)a=s[n],o.setAttribute(n,a);o.innerHTML=i}return o}},{}],27:[function(t,e,s){function i(t){t._pool=[],t._inUse=[],t.temp=function(){let e=t._pool.pop()||new t;return t._inUse.push(e),t._gc||(t._gc=setTimeout(t._recycle)),e},t._recycle=function(){for(;t._inUse.length;)t._pool.push(t._inUse.pop());t._gc=!1}}i(THREE.Vector2),i(THREE.Vector3),i(THREE.Quaternion),i(THREE.Matrix3),i(THREE.Matrix4)},{}],28:[function(t,e,s){let i=Element.prototype.addEventListener,o=Element.prototype.removeEventListener,n=t=>{if(t._tgest)return t._tgest;let e,s,i,o;t._tgest={handlers:{swipeup:[],swipedown:[],swipeleft:[],swiperight:[],tap:[],hold:[]}};let n=(e,s)=>{if(t._tgest.handlers[e])for(let i of t._tgest.handlers[e])i(s);else console.log(e,t._tgest.handlers[e])};return t.addEventListener("touchstart",(t=>{e=t.changedTouches[0].screenX,s=t.changedTouches[0].screenY,o=!1,i=setTimeout((()=>{o=!0,n("hold",t)}),512)})),t.addEventListener("touchmove",(t=>{let a=t.changedTouches[0].screenX,r=t.changedTouches[0].screenY;if(Math.sqrt(Math.pow(e-a,2)+Math.pow(s-r,2))>32){if(clearTimeout(i),o)return;Math.abs(e-a)>Math.abs(s-r)?n(a{clearTimeout(i);let a=t.changedTouches[0].screenX,r=t.changedTouches[0].screenY;if(Math.sqrt(Math.pow(e-a,2)+Math.pow(s-r,2))<32){if(o)return;n("tap",t)}})),t._tgest};Element.prototype.addEventListener=function(t,e){switch(t){case"swipeup":case"swipedown":case"swipeleft":case"swiperight":case"tap":case"hold":n(this).handlers[t].push(e);break;default:return i.call(this,t,e)}},Element.prototype.removeEventListener=function(t,e){switch(t){case"swipeup":case"swipedown":case"swipeleft":case"swiperight":case"tap":case"hold":let s=n(this),i=s.handlers[t].indexOf(e);i>=0&&s.handlers[t].splice(i,1);break;default:return o.call(this,t,e)}}},{}],29:[function(t,e,s){AFRAME.registerPrimitive("a-hand",{mappings:{side:"tracked-controls.hand"}})},{}],30:[function(t,e,s){AFRAME.registerPrimitive("a-main",{})},{}],31:[function(t,e,s){AFRAME.registerPrimitive("a-player",{defaultComponents:{injectplayer:{}}})},{}]},{},[2]);
diff --git a/dist/index.html b/dist/index.html
index 5cee931..27eaf65 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -15,7 +15,7 @@
-
+
diff --git a/dist/scenes/demo.html b/dist/scenes/demo.html
index ba29fdf..75a5342 100644
--- a/dist/scenes/demo.html
+++ b/dist/scenes/demo.html
@@ -52,7 +52,7 @@
-
+
diff --git a/package-lock.json b/package-lock.json
index 7717ad5..14e0021 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "a-game",
- "version": "0.16.0",
+ "version": "0.17.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 96e5d8e..e615733 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "a-game",
"title": "A-Game",
- "version": "0.16.0",
+ "version": "0.17.0",
"description": "game components for A-Frame",
"homepage": "https://github.com/poeticAndroid/a-game/blob/master/README.md",
"main": "index.js",
diff --git a/src/components/grabbing.js b/src/components/grabbing.js
index 0d6ac0d..662949c 100644
--- a/src/components/grabbing.js
+++ b/src/components/grabbing.js
@@ -20,6 +20,7 @@ AFRAME.registerComponent("grabbing", {
this._btnPress = {}
this._btnFlex = {}
this._keysDown = {}
+ this._grabCount = 0
this._hands = ["head", "left", "right"]
this._head = {}
@@ -332,6 +333,7 @@ AFRAME.registerComponent("grabbing", {
// if (this[_hand].glove.getAttribute("body"))
this[_hand].glove.setAttribute("body", "collidesWith", 0)
this.emit("grab", this[_hand].glove, this[_hand].grabbed, { intersection: hit })
+ this._grabCount = Math.min(2, this._grabCount + 1)
this.el.addState("grabbing")
this[_hand].grabbed.addState("grabbed")
this.sticky = true
@@ -357,9 +359,11 @@ AFRAME.registerComponent("grabbing", {
// if (this[_hand].glove.getAttribute("body"))
this[_hand].glove.setAttribute("body", "collidesWith", 1)
}, 1024)
- this.emit("drop", this[_hand].glove, this[_hand].grabbed)
- this.el.removeState("grabbing")
if (this[_hand].grabbed) {
+ this.emit("drop", this[_hand].glove, this[_hand].grabbed)
+ this._grabCount = Math.max(0, this._grabCount - 1)
+ if (!this._grabCount)
+ this.el.removeState("grabbing")
this._flexFinger(hand, 5, 0)
this[_hand].grabbed.removeState("grabbed")
this[_hand].grabbed = null
@@ -537,12 +541,14 @@ AFRAME.registerComponent("grabbing", {
this.useDown("head", btn ? ((btn % 2) ? btn + 1 : btn - 1) : btn)
},
_onWheel(e) {
- if (this._keysDown["KeyR"] && e.deltaY > 0) return this.moveHeadHand(0, 0, 0, -0.125)
- if (this._keysDown["KeyR"] && e.deltaY < 0) return this.moveHeadHand(0, 0, 0, 0.125)
- if (this._keysDown["KeyY"] && e.deltaY > 0) return this.moveHeadHand(0, 0, -0.125)
- if (this._keysDown["KeyY"] && e.deltaY < 0) return this.moveHeadHand(0, 0, 0.125)
- if (this._keysDown["KeyT"] && e.deltaY > 0) return this.moveHeadHand(0, 0.125)
- if (this._keysDown["KeyT"] && e.deltaY < 0) return this.moveHeadHand(0, -0.125)
+ let x = 0, y = 0, z = 0
+ if (this._keysDown["Digit3"] && e.deltaY > 0) z += -0.125
+ if (this._keysDown["Digit3"] && e.deltaY < 0) z += 0.125
+ if (this._keysDown["Digit2"] && e.deltaY > 0) y += -0.125
+ if (this._keysDown["Digit2"] && e.deltaY < 0) y += 0.125
+ if (this._keysDown["Digit1"] && e.deltaY > 0) x += 0.125
+ if (this._keysDown["Digit1"] && e.deltaY < 0) x += -0.125
+ if (x || y || z) return this.moveHeadHand(0, x, y, z)
if (e.deltaY > 0) return this.moveHeadHand(0.125)
if (e.deltaY < 0) return this.moveHeadHand(-0.125)
},
diff --git a/src/components/grabbing.md b/src/components/grabbing.md
index cbf2025..36bfca6 100644
--- a/src/components/grabbing.md
+++ b/src/components/grabbing.md
@@ -16,7 +16,7 @@ This makes it possible to grab and use grabbable objects using the following con
| Primary use | Trigger | Left click | Tap |
| Secondary | A | Right click |
| Tertiary | B | Middle click |
-| Move hand | X + D-pad | R/T/Y + scroll wheel |
+| Move hand | X + D-pad | 1/2/3 + scroll wheel |
## Properties
@@ -63,6 +63,13 @@ These events are emitted by both the glove and the `grabbable` that it's grabbin
| unhover | button no longer pointed at |
+## States
+
+| State | Description |
+| -------- | ---------------------------- |
+| grabbing | currently grabbing something |
+
+
## Related components
- [button](./grabbing/button.md)
diff --git a/src/components/grabbing/button.md b/src/components/grabbing/button.md
index e602404..fe7c108 100644
--- a/src/components/grabbing/button.md
+++ b/src/components/grabbing/button.md
@@ -15,3 +15,10 @@ Add the `button` component to any object you want the player to be able to press
| press | button got pressed |
| unpress | button no longer pressed |
| unhover | button no longer pointed at |
+
+
+## States
+
+| State | Description |
+| ------- | ----------------------- |
+| pressed | currently being pressed |
diff --git a/src/components/grabbing/climbable.js b/src/components/grabbing/climbable.js
index be38757..37b5d73 100644
--- a/src/components/grabbing/climbable.js
+++ b/src/components/grabbing/climbable.js
@@ -7,17 +7,18 @@ AFRAME.registerComponent("climbable", {
init() {
this.el.setAttribute("grabbable", "physics:false; kinematicGrab:false;")
- this._player = this.el.sceneEl.querySelector("[locomotion")
- this._quat = new THREE.Quaternion()
- this._lpos = new THREE.Vector3()
- this._wpos = new THREE.Vector3()
- this._handpos = new THREE.Vector3()
+ this._player = this.el.sceneEl.querySelector("[locomotion]")
this._onBump = this._onBump.bind(this)
this._onBumpThis = this._onBumpThis.bind(this)
this._autoGrab = true
setTimeout(() => {
+ this._quat = new THREE.Quaternion()
+ this._lpos = new THREE.Vector3()
+ this._wpos = new THREE.Vector3()
+ this._handpos = new THREE.Vector3()
+
this._quat.copy(this.el.object3D.quaternion)
this._lpos.copy(this.el.object3D.position)
this.el.object3D.getWorldPosition(this._wpos)
@@ -32,9 +33,14 @@ AFRAME.registerComponent("climbable", {
pause() {
this._player.removeEventListener("bump", this._onBump)
this.el.removeEventListener("bump", this._onBumpThis)
+ this._climbing = false
},
tick() {
+ if (!this._lpos) return
+ this.el.object3D.quaternion.copy(this._quat)
+ this.el.object3D.position.copy(this._lpos)
+
if (!this._climbing) return
let delta = THREE.Vector3.temp()
this._hand.object3D.getWorldPosition(delta)
@@ -47,9 +53,6 @@ AFRAME.registerComponent("climbable", {
this._player.components.locomotion.stopFall()
this._player.components.locomotion.move(delta)
if (this._handpos.y - this._wpos.y > this._top) this._player.components.grabbing.dropObject(this.el)
-
- this.el.object3D.quaternion.copy(this._quat)
- this.el.object3D.position.copy(this._lpos)
},
events: {
diff --git a/src/components/grabbing/grabbable.md b/src/components/grabbing/grabbable.md
index 43ed792..02d69a6 100644
--- a/src/components/grabbing/grabbable.md
+++ b/src/components/grabbing/grabbable.md
@@ -28,3 +28,11 @@ Add the `grabbable` component to any object you want the player to be able to pi
| useup | use-button is released. |
| drop | dropping. |
| fingerflex | a finger is flexing. |
+
+
+## States
+
+| State | Description |
+| ------- | --------------------------- |
+| grabbed | currently being grabbed |
+| put | currently in a `receptacle` |
diff --git a/src/components/grabbing/receptacle.js b/src/components/grabbing/receptacle.js
index ab32272..4d0e083 100644
--- a/src/components/grabbing/receptacle.js
+++ b/src/components/grabbing/receptacle.js
@@ -4,6 +4,7 @@ AFRAME.registerComponent("receptacle", {
schema: {
objects: { type: "string", default: "[grabbable]" },
radius: { type: "number", default: 0.125 },
+ onlyGrabbed: { type: "boolean", default: false },
},
init() {
@@ -48,6 +49,7 @@ AFRAME.registerComponent("receptacle", {
})
}
this._hover = false
+ this._grabbed = false
} else if (delta.length() > this.data.radius) {
if (this.el.is("filled")) {
this._anchor.removeAttribute("joint__put")
@@ -71,6 +73,7 @@ AFRAME.registerComponent("receptacle", {
})
}
this._hover = false
+ this._grabbed = false
} else if (this.nearest.is("grabbed") || !this._hover) {
if (!this._hover) {
this.el.emit("hover", {
@@ -84,7 +87,9 @@ AFRAME.registerComponent("receptacle", {
this._anchor.removeAttribute("animation__rot")
this._anchor.copyWorldPosRot(this.nearest)
this._hover = true
- } else {
+ if (this.nearest.is("grabbed"))
+ this._grabbed = true
+ } else if (this._grabbed || !this.data.onlyGrabbed) {
if (!this.el.is("filled")) {
this._anchor.copyWorldPosRot(this.nearest)
this._anchor.components.body.commit()
diff --git a/src/components/grabbing/receptacle.md b/src/components/grabbing/receptacle.md
index deaef77..dc1625d 100644
--- a/src/components/grabbing/receptacle.md
+++ b/src/components/grabbing/receptacle.md
@@ -1,6 +1,6 @@
# receptacle
-Add the `receptacle` component to any object you want the player to be able to pick up.
+Add the `receptacle` component to any object you want to attract and hold another object within a given radius.
```html
@@ -9,10 +9,11 @@ Add the `receptacle` component to any object you want the player to be able to p
## Properties
-| Property | Description | Default |
-| -------- | --------------------------------------------------------- | ------------- |
-| objects | Selector for the type of objects this receptacle attracts | `[grabbable]` |
-| radius | Radius of attraction | 0.125 |
+| Property | Description | Default |
+| ----------- | --------------------------------------------------------- | ------------- |
+| objects | Selector for the type of objects this receptacle attracts | `[grabbable]` |
+| radius | Radius of attraction | 0.125 |
+| onlyGrabbed | Only accept grabbed objects | false |
## Events
@@ -25,3 +26,10 @@ These event are emitted on the receptacle as well as the object it attracts.
| take | object is taken out of the receptacle |
| hover | attractive object is within radius |
| unhover | attractive object is out of radius |
+
+
+## States
+
+| Event | Description |
+| ------ | --------------------------- |
+| filled | currently holding something |
diff --git a/src/components/trigger.js b/src/components/trigger.js
index 72234e0..2d05bd4 100644
--- a/src/components/trigger.js
+++ b/src/components/trigger.js
@@ -54,10 +54,11 @@ AFRAME.registerComponent("trigger", {
trigger: this.el,
object: obj,
}
- this.el.removeState("triggered")
this.el.emit("untrigger", d)
obj.emit("untrigger", d)
this.triggered.splice(this.triggered.indexOf(obj), 1)
+ if (!this.triggered.length)
+ this.el.removeState("triggered")
}
}
},
diff --git a/src/components/trigger.md b/src/components/trigger.md
index 887b080..3229426 100644
--- a/src/components/trigger.md
+++ b/src/components/trigger.md
@@ -23,3 +23,10 @@ These events are emitted by both the triggered and the triggering object.
| --------- | ------------------ |
| trigger | object has entered |
| untrigger | object has left |
+
+
+## States
+
+| State | Description |
+| --------- | ----------------------------------------- |
+| triggered | at least one object is inside the trigger |