diff --git a/public/index.html b/public/index.html index af26298af6c5e9330193231d96d2c7b3fa93bc8e..cd036c297c139c8ac3e078a502b39cde4b00aae1 100644 --- a/public/index.html +++ b/public/index.html @@ -40,7 +40,7 @@ </script> </a-assets> - <a-entity id="player-rig" networked wasd-controls snap-rotation="leftEventSrc: #right-hand; rightEventSrc: #right-hand"> + <a-entity id="player-rig" networked wasd-controls snap-rotation="leftEventSrc: #right-hand; rightEventSrc: #right-hand; pivotSrc: #head"> <a-entity id="head" camera="userHeight: 1.6" @@ -74,6 +74,7 @@ geometry="primitive: plane; width: 100; height: 100;" rotation="-90 0 0" material="shader: flat; src: #grid; repeat: 100 100;"></a-entity> <a-sky src="#sky" rotation="0 -90 0"></a-sky> + <a-box></a-box> </a-scene> <script> document.querySelector('a-scene').addEventListener('loaded', onSceneLoad) diff --git a/src/components/snap-rotation.js b/src/components/snap-rotation.js index d0de335a4cdf57c54d78dac288a740f1c09d3c6d..d80ef742f37bb2602a893272cad08d026699aa90 100644 --- a/src/components/snap-rotation.js +++ b/src/components/snap-rotation.js @@ -17,13 +17,23 @@ AFRAME.registerComponent("snap-rotation", { rightKey: { default: "e" }, rightEvent: { default: "dpadrightdown" }, - rightEventSrc: { type: "selector" } + rightEventSrc: { type: "selector" }, + + pivotSrc: { type: "selector" } }, init: function() { this.onButtonPressed = this.onButtonPressed.bind(this); }, + update: function() { + const {rotationAxis, rotationDegres} = this.data; + + const angle = rotationDegres * THREE.Math.DEG2RAD; + this.lRotMat = new THREE.Matrix4().makeRotationAxis(rotationAxis, angle); + this.rRotMat = new THREE.Matrix4().makeRotationAxis(rotationAxis, -angle); + }, + play: function() { const { leftEventSrc, leftEvent, rightEventSrc, rightEvent } = this.data; window.addEventListener("keypress", this.onButtonPressed); @@ -42,28 +52,49 @@ AFRAME.registerComponent("snap-rotation", { leftEventSrc.removeEventListener(leftEvent, this.onButtonPressed); }, - onButtonPressed: function(e) { - const { - rotationAxis, - rotationDegres, - leftKey, - leftEvent, - rightKey, - rightEvent - } = this.data; - const obj = this.el.object3D; + onButtonPressed: (function() { + const trans = new THREE.Matrix4(); + const transInv = new THREE.Matrix4(); + const pivotPos = new THREE.Vector3(); + + return function(e) { + const { + rotationAxis, + rotationDegres, + leftKey, + leftEvent, + rightKey, + rightEvent, + pivotSrc + } = this.data; + + var rot; + if (e.type === leftEvent || (leftKey && e.key === leftKey)) { + rot = this.lRotMat; + } else if (e.type === rightEvent || (rightKey && e.key === rightKey)) { + rot = this.rRotMat; + } else { + return; + } + + const obj = this.el.object3D; + const pivot = pivotSrc.object3D; - if (e.type === leftEvent || (leftKey && e.key === leftKey)) { - obj.rotateOnAxis(rotationAxis, rotationDegres * THREE.Math.DEG2RAD); - } else if (e.type === rightEvent || (rightKey && e.key === rightKey)) { - obj.rotateOnAxis(rotationAxis, -rotationDegres * THREE.Math.DEG2RAD); - } + pivotPos.copy(pivot.position); + pivotPos.applyMatrix4(obj.matrix); + trans.setPosition(pivotPos); + transInv.makeTranslation(-pivotPos.x, -pivotPos.y, -pivotPos.z); + obj.applyMatrix(transInv); + obj.applyMatrix(rot); + obj.applyMatrix(trans); - // @TODO this is really ugly, can't just set the rotation directly or it wont network - this.el.setAttribute("rotation", { - x: obj.rotation.x * THREE.Math.RAD2DEG, - y: obj.rotation.y * THREE.Math.RAD2DEG, - z: obj.rotation.z * THREE.Math.RAD2DEG - }); - } + // @TODO this is really ugly, can't just set the position/rotation directly or they wont network + this.el.setAttribute("rotation", { + x: obj.rotation.x * THREE.Math.RAD2DEG, + y: obj.rotation.y * THREE.Math.RAD2DEG, + z: obj.rotation.z * THREE.Math.RAD2DEG + }); + this.el.setAttribute("position", obj.position); + }; + })() });