diff --git a/package.json b/package.json index 69b31a5a3854a7672fed750b1b0ecf0cbf6fa2d0..b3d4b301e5e9732b26a197efee373e863e722a7c 100644 --- a/package.json +++ b/package.json @@ -4,22 +4,19 @@ "main": "src/index.js", "license": "MPL-2.0", "scripts": { - "dev": "webpack-dev-server --https --open --config webpack.dev.js", + "dev": "webpack-dev-server --https --host 0.0.0.0 --useLocalIp --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js", - "prettier": "prettier --write src/**/*.js", - "deploy": "npm run build && now deploy --static ./public/" + "prettier": "prettier --write src/**/*.js" }, - "pre-commit": [ - "prettier" - ], "dependencies": { + "aframe-extras": "^3.12.4", "aframe": "0.7.0", - "aframe-input-mapping-component": "https://github.com/fernandojsg/aframe-input-mapping-component", + "aframe-input-mapping-component": "https://github.com/fernandojsg/aframe-input-mapping-component#6ebc38f", "aframe-teleport-controls": "https://github.com/netpro2k/aframe-teleport-controls#feature/teleport-origin", - "naf-janus-adapter": "^0.1.4", + "minijanus": "^0.1.6", + "naf-janus-adapter": "^0.1.5", "networked-aframe": "https://github.com/netpro2k/networked-aframe#bugfix/chrome/audio", "nipplejs": "^0.6.7", - "pleasejs": "^0.4.2", "query-string": "^5.0.1", "react": "^16.1.1", "react-dom": "^16.1.1" @@ -34,8 +31,6 @@ "eslint": "^4.10.0", "eslint-config-prettier": "^2.6.0", "eslint-plugin-prettier": "^2.3.1", - "now": "^8.3.11", - "pre-commit": "^1.2.2", "prettier": "^1.7.0", "style-loader": "^0.19.0", "webpack": "^3.6.0", diff --git a/public/assets/avatars/Bot_Body_Mesh.glb b/public/assets/avatars/Bot_Body_Mesh.glb new file mode 100644 index 0000000000000000000000000000000000000000..5b6ec544498ba30094dfb229de1fd4e93fff3da0 Binary files /dev/null and b/public/assets/avatars/Bot_Body_Mesh.glb differ diff --git a/public/assets/avatars/Bot_Head_Mesh.glb b/public/assets/avatars/Bot_Head_Mesh.glb new file mode 100644 index 0000000000000000000000000000000000000000..9d4ace94f63794cb1b54119c86d1632d139f2d9f Binary files /dev/null and b/public/assets/avatars/Bot_Head_Mesh.glb differ diff --git a/public/assets/avatars/Bot_LeftHand_Mesh.glb b/public/assets/avatars/Bot_LeftHand_Mesh.glb new file mode 100644 index 0000000000000000000000000000000000000000..1ba4463d4aba8054a20fee420d82962daf071178 Binary files /dev/null and b/public/assets/avatars/Bot_LeftHand_Mesh.glb differ diff --git a/public/assets/avatars/Bot_RightHand_Mesh.glb b/public/assets/avatars/Bot_RightHand_Mesh.glb new file mode 100644 index 0000000000000000000000000000000000000000..bb73909d7ed484a241737c116126e278cb58274c Binary files /dev/null and b/public/assets/avatars/Bot_RightHand_Mesh.glb differ diff --git a/public/room.html b/public/room.html index 2edb82aeb09039d5dc62f0001ee246001ecd336a..0b96981873dda6a51ecfb559275a31adbbc4a051 100644 --- a/public/room.html +++ b/public/room.html @@ -4,18 +4,18 @@ <title>Mozilla Mixed Reality Social Client</title> <script src="./app.bundle.js"></script> <style> - .a-enter-vr { - top: 90px; - bottom: auto; - } - #loader { - position: fixed; - width: 100vw; - height: 100vh; - z-index: 10001; - background: #eaeaea no-repeat url(assets/loading.gif) center center; - opacity: 0.9; - } + .a-enter-vr { + top: 90px; + bottom: auto; + } + #loader { + position: fixed; + width: 100vw; + height: 100vh; + z-index: 10001; + background: #eaeaea no-repeat url(assets/loading.gif) center center; + opacity: 0.9; + } </style> </head> @@ -33,7 +33,10 @@ <img id="grid" src="assets/grid.png" crossorigin="anonymous" /> <img id="sky" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg" crossorigin="anonymous" /> - <a-asset-item id="dodec-avatar-head" src="assets/avatars/dodec/DodecAvatarGLTF/DodecAvatar_Head.gltf"></a-asset-item> + <a-asset-item id="bot-head-mesh" src="assets/avatars/Bot_Head_Mesh.glb"></a-asset-item> + <a-asset-item id="bot-body-mesh" src="assets/avatars/Bot_Body_Mesh.glb"></a-asset-item> + <a-asset-item id="bot-left-hand-mesh" src="assets/avatars/Bot_LeftHand_Mesh.glb"></a-asset-item> + <a-asset-item id="bot-right-hand-mesh" src="assets/avatars/Bot_RightHand_Mesh.glb"></a-asset-item> <a-asset-item id="watch-model" src="assets/hud/watch.gltf"></a-asset-item> @@ -43,18 +46,46 @@ <script id="head-template" type="text/html"> <a-entity class="head" - gltf-model="#dodec-avatar-head" + gltf-model="#bot-head-mesh" networked-audio-source networked-audio-analyser - matcolor-audio-feedback="objectName: DodecAvatar_Head_0" + matcolor-audio-feedback="objectName: Head_Mesh" scale-audio-feedback - avatar-customization personal-space-invader + rotation="0 180 0" + animation-mixer ></a-entity> </script> - <script id="hand-template" type="text/html"> - <a-box class="hand" personal-space-invader scale="0.2 0.1 0.3"></a-box> + <script id="body-template" type="text/html"> + <a-entity + class="body" + gltf-model="#bot-body-mesh" + personal-space-invader + rotation="0 180 0" + position="0 -0.05 0" + ></a-entity> + </script> + + <script id="left-hand-template" type="text/html"> + <a-entity + class="hand" + gltf-model="#bot-left-hand-mesh" + animation-mixer + personal-space-invader + rotation="-90 90 0" + position="0 0 0.075" + ></a-entity> + </script> + + <script id="right-hand-template" type="text/html"> + <a-entity + class="hand" + gltf-model="#bot-right-hand-mesh" + personal-space-invader + rotation="-90 -90 0" + position="0 0 0.075" + ></a-entity> </script> <script id="video-template" type="text/html"> @@ -65,33 +96,86 @@ <a-entity class="nametag" nametag-transform="follow: .head" - text="side:double;align:center;color:#555" + text="side: double; align: center; color: #555" position="0 2.5 0" - scale="6 6 6"></a-entity> + scale="6 6 6" + ></a-entity> </script> </a-assets> - <a-entity id="player-rig" networked character-controller="pivot: #head"> + + <!-- Player Rig --> + <a-entity + id="player-rig" + networked + character-controller="pivot: #head" + > <a-sphere scale="0.1 0.1 0.1"></a-sphere> - <a-entity id="head" camera="userHeight: 1.6" personal-space-bubble look-controls networked="template:#head-template;showLocalTemplate:false;"></a-entity> - <a-entity id="nametag" networked="template:#nametag-template;showLocalTemplate:false;"></a-entity> - - <a-entity id="left-hand" split-axis-events hand-controls="left" hand-controls-visibility axis-dpad="centerZone: 1" networked="template:#hand-template;showLocalTemplate:false;"> - <a-entity id="watch" gltf-model="assets/hud/watch.gltf" position="0 0.0015 0.147" rotation="3.5 0 0"> - <a-circle mute-state-indicator scale-audio-feedback="analyserSrc: #head; minScale: 0.035; maxScale: 0.08;" position="0 0.023 0" - rotation="-90 0 0" scale="0.04 0.04 0.04" material="color:#d8eece;shader:flat"> - </a-circle> + + <a-entity + id="head" + camera="userHeight: 1.6" + personal-space-bubble + look-controls + networked="template: #head-template; showLocalTemplate: false;" + ></a-entity> + + <a-entity + id="body" + body-controller="eyeNeckOffset: 0 -0.11 0.09; neckHeight: 0.05" + networked="template: #body-template;" + ></a-entity> + + <a-entity + id="nametag" + networked="template: #nametag-template; showLocalTemplate: false;" + ></a-entity> + + <a-entity + id="left-hand" + split-axis-events + hand-controls2="left" + axis-dpad="centerZone: 1" + teleport-controls="cameraRig: #player-rig; teleportOrigin: #head; button: action_teleport_" + networked="template: #left-hand-template;" + > + <a-entity + id="watch" + gltf-model="assets/hud/watch.gltf" + position="0 0.0015 0.147" + rotation="3.5 0 0" + > + <a-circle + mute-state-indicator + scale-audio-feedback="analyserSrc: #head; minScale: 0.035; maxScale: 0.08;" + position="0 0.023 0" + rotation="-90 0 0" + scale="0.04 0.04 0.04" + material="color: #d8eece; shader: flat;" + ></a-circle> </a-entity> </a-entity> - <a-entity id="right-hand" hand-controls="right" hand-controls-child-visibility axis-dpad teleport-controls="cameraRig: #player-rig; teleportOrigin: #head; hitEntity: #telepor-indicator; button: action_teleport_;" - networked="template:#hand-template;showLocalTemplate:false;"> - </a-entity> + <a-entity + id="right-hand" + hand-controls2="right" + axis-dpad + teleport-controls="cameraRig: #player-rig; + teleportOrigin: #head; + hitEntity: #telepor-indicator; + button: action_teleport_;" + networked="template: #right-hand-template;" + ></a-entity> </a-entity> - <a-entity class="head" gltf-model="#rock-island" position="0 0 0"> + <!-- Environment --> + <a-entity + gltf-model="#rock-island" + position="0 0 0" + > <a-sky color="#DDFFD9"></a-sky> </a-entity> </a-scene> + <script> document.querySelector('a-scene').addEventListener('loaded', App.onSceneLoad) </script> diff --git a/src/components/avatar-customization.js b/src/components/avatar-customization.js deleted file mode 100644 index 8346b8e821ac904d8711dffe6563643f7628ba09..0000000000000000000000000000000000000000 --- a/src/components/avatar-customization.js +++ /dev/null @@ -1,49 +0,0 @@ -import Please from "pleasejs"; - -// @TODO this whole thing is a bit of a hack. This should probably just be setting some uniforms on a sharder. -// @TODO the palate should be indexed by alpha channel instead of the red channel. -// @TODO color should be multiplied with the texture value to allow for texture to provide surface detail. -// @TODO texture should be regenerated whenever headColor/LidColor values change to allow for networking, though arguably these will eventually be fetched from a users "profile" anywya, so might not be worth trying to network through NAF. -AFRAME.registerComponent("avatar-customization", { - schema: { - headColor: { type: "color", default: null }, - lidColor: { type: "color", default: null } - }, - - init: function() { - const colors = Please.make_color({ - format: "rgb-string", - colors_returned: 2 - }); - - this.colorMap = new Map(); - this.colorMap.set(128, this.data.headColor || new THREE.Color(colors[0])); - this.colorMap.set(115, this.data.lidColor || new THREE.Color(colors[1])); - - this.el.addEventListener("model-loaded", () => { - const map = this.el.object3D.getObjectByName("DodecAvatar_Head_0") - .material.map; - const img = map.image; - - const canvas = document.createElement("canvas"); - canvas.width = img.width; - canvas.height = img.height; - const ctx = canvas.getContext("2d"); - ctx.drawImage(img, 0, 0, img.width, img.height); - const imageData = ctx.getImageData(0, 0, img.width, img.height); - const pixelData = imageData.data; - - for (let i = 0; i < pixelData.length; i += 4) { - // @TODO check alpha channel and multiply colors to preserver surface detail - if (this.colorMap.has(pixelData[i])) { - const color = this.colorMap.get(pixelData[i]); - pixelData[i] = color.r * 255; - pixelData[i + 1] = color.g * 255; - pixelData[i + 2] = color.b * 255; - } - } - ctx.putImageData(imageData, 0, 0); - map.image = canvas; - }); - } -}); diff --git a/src/components/body-controller.js b/src/components/body-controller.js new file mode 100644 index 0000000000000000000000000000000000000000..05afec55951aff8ba8108bd6ee95e8212d9c8b95 --- /dev/null +++ b/src/components/body-controller.js @@ -0,0 +1,49 @@ +AFRAME.registerComponent("body-controller", { + schema: { + camera: { type: "selector", default: "[camera]" }, + rotationSpeed: { default: 0.07 }, + eyeNeckOffset: { type: "vec3" }, + neckHeight: { type: "number" } + }, + + init() { + this.targetAngleEuler = new THREE.Euler(); + this.targetAngle = new THREE.Quaternion(); + this.cameraPositionMatrix = new THREE.Matrix4(); + const offset = this.data.eyeNeckOffset; + this.eyeNeckTransformMatrix = new THREE.Matrix4().makeTranslation( + offset.x, + offset.y, + offset.z + ); + this.neckTransformMatrix = new THREE.Matrix4().makeTranslation( + 0, + this.data.neckHeight, + 0 + ); + this.bodyPositionMatrix = new THREE.Matrix4(); + this.bodyPositionVector = new THREE.Vector3(); + }, + + tick(time, dt) { + const object3D = this.el.object3D; + const cameraObject3D = this.data.camera.object3D; + + // Set Rotation + this.targetAngleEuler.set(0, cameraObject3D.rotation.y, 0); + this.targetAngle.setFromEuler(this.targetAngleEuler); + object3D.quaternion.slerp(this.targetAngle, this.data.rotationSpeed); + const object3DRotation = object3D.rotation; + this.el.setAttribute("rotation", { + x: object3DRotation.x * THREE.Math.RAD2DEG, + y: object3DRotation.y * THREE.Math.RAD2DEG, + z: object3DRotation.z * THREE.Math.RAD2DEG + }); + + //Set Position + this.bodyPositionMatrix.copy(cameraObject3D.matrix); + this.bodyPositionMatrix.multiply(this.eyeNeckTransformMatrix); + this.bodyPositionVector.setFromMatrixPosition(this.bodyPositionMatrix); + this.el.setAttribute("position", this.bodyPositionVector); + } +}); diff --git a/src/components/hand-controls-visibility.js b/src/components/hand-controls-visibility.js deleted file mode 100644 index 50d7514897b3974e3963c3fd636bea1a9e8d3aeb..0000000000000000000000000000000000000000 --- a/src/components/hand-controls-visibility.js +++ /dev/null @@ -1,21 +0,0 @@ -AFRAME.registerComponent("hand-controls-visibility", { - init() { - this.onControllerConnected = this.onControllerConnected.bind(this); - this.onControllerDisconnected = this.onControllerDisconnected.bind(this); - this.el.addEventListener("controllerconnected", this.onControllerConnected); - this.el.addEventListener( - "controllerdisconnected", - this.onControllerDisconnected - ); - - this.el.setAttribute("visible", false); - }, - - onControllerConnected() { - this.el.setAttribute("visible", true); - }, - - onControllerDisconnected() { - this.el.setAttribute("visible", false); - } -}); diff --git a/src/components/hand-controls2.js b/src/components/hand-controls2.js new file mode 100644 index 0000000000000000000000000000000000000000..80625759a8cba93b5d8e4f0da71037735823d971 --- /dev/null +++ b/src/components/hand-controls2.js @@ -0,0 +1,167 @@ +const GESTURES = { + open: "open", + // point: grip active, trackpad surface active, trigger inactive. + point: "point", + // pointThumb: grip active, trigger inactive, trackpad surface inactive. + pointThumb: "pointThumb", + // fist: grip active, trigger active, trackpad surface active. + fist: "fist", + // hold: trigger active, grip inactive. + hold: "hold", + // thumbUp: grip active, trigger active, trackpad surface inactive. + thumbUp: "thumbUp" +}; + +AFRAME.registerComponent("hand-controls2", { + schema: { default: "left" }, + + init() { + const el = this.el; + + this.gesture = GESTURES.open; + + this.fingersDown = { + thumb: false, + index: false, + middle: false, + ring: false, + pinky: false + }; + + this.onMiddleRingPinkyDown = this.updateGesture.bind(this, { + middle: true, + ring: true, + pinky: true + }); + + this.onMiddleRingPinkyUp = this.updateGesture.bind(this, { + middle: false, + ring: false, + pinky: false + }); + + this.onIndexDown = this.updateGesture.bind(this, { + index: true + }); + + this.onIndexUp = this.updateGesture.bind(this, { + index: false + }); + + this.onThumbDown = this.updateGesture.bind(this, { + thumb: true + }); + + this.onThumbUp = this.updateGesture.bind(this, { + thumb: false + }); + + this.onControllerConnected = this.onControllerConnected.bind(this); + this.onControllerDisconnected = this.onControllerDisconnected.bind(this); + + el.addEventListener("controllerconnected", this.onControllerConnected); + el.addEventListener( + "controllerdisconnected", + this.onControllerDisconnected + ); + + el.setAttribute("visible", false); + }, + + play() { + const el = this.el; + el.addEventListener("middle_ring_pinky_down", this.onMiddleRingPinkyDown); + el.addEventListener("middle_ring_pinky_up", this.onMiddleRingPinkyUp); + el.addEventListener("thumb_down", this.onThumbDown); + el.addEventListener("thumb_up", this.onThumbUp); + el.addEventListener("index_down", this.onIndexDown); + el.addEventListener("index_up", this.onIndexUp); + }, + + pause() { + const el = this.el; + el.removeEventListener( + "middle_ring_pinky_down", + this.onMiddleRingPinkyDown + ); + el.removeEventListener("middle_ring_pinky_up", this.onMiddleRingPinkyUp); + el.removeEventListener("thumb_down", this.onThumbDown); + el.removeEventListener("thumb_up", this.onThumbUp); + el.removeEventListener("index_down", this.onIndexDown); + el.removeEventListener("index_up", this.onIndexUp); + }, + + // Attach the platform specific tracked controllers. + update(prevData) { + const el = this.el; + const hand = this.data; + + const controlConfiguration = { + hand: hand, + model: false, + rotationOffset: 0 + }; + + if (hand !== prevData) { + el.setAttribute("vive-controls", controlConfiguration); + el.setAttribute("oculus-touch-controls", controlConfiguration); + el.setAttribute("windows-motion-controls", controlConfiguration); + } + }, + + remove() { + const el = this.el; + el.removeEventListener("controllerconnected", this.onControllerConnected); + el.removeEventListener( + "controllerdisconnected", + this.onControllerDisconnected + ); + }, + + updateGesture(nextFingersDown) { + Object.assign(this.fingersDown, nextFingersDown); + const gesture = this.determineGesture(); + + if (gesture !== this.gesture) { + this.gesture = gesture; + this.el.emit(this.last + "end"); + this.el.emit(this.gesture + "start"); + } + }, + + determineGesture() { + const { thumb, index, middle, ring, pinky } = this.fingersDown; + + if (!thumb && !index && !middle && !ring && !pinky) { + return GESTURES.open; + } else if (thumb && index && middle && ring && pinky) { + return GESTURES.fist; + } else if (!thumb && index && middle && ring && pinky) { + return GESTURES.thumbUp; + } else if (!thumb && !index && middle && ring && pinky) { + return GESTURES.pointThumb; + } else if (!thumb && index && !middle && !ring && !pinky) { + return GESTURES.hold; + } else if (thumb && !index && !middle && !ring && !pinky) { + return GESTURES.hold; + } else if (thumb && index && !middle && !ring && !pinky) { + return GESTURES.hold; + } else if (thumb && !index && middle && ring && pinky) { + return GESTURES.point; + } + + console.warn("Did not find matching gesture for ", this.fingersDown); + + return GESTURES.open; + }, + + // Show controller when connected + onControllerConnected() { + this.el.setAttribute("visible", true); + }, + + // Hide controller on disconnect + onControllerDisconnected() { + this.el.setAttribute("visible", false); + } +}); diff --git a/src/components/rig-selector.js b/src/components/rig-selector.js deleted file mode 100644 index f27a7bba4654c51d6b3b6b5a6c6c9c679068d2ba..0000000000000000000000000000000000000000 --- a/src/components/rig-selector.js +++ /dev/null @@ -1,59 +0,0 @@ -AFRAME.registerComponent("rig-selector", { - schema: { - vive: { default: "" }, - oculus: { default: "" }, - daydream: { default: "" }, - gearvr: { default: "" }, - mobile: { default: "" }, - desktop: { default: "" } - }, - init: function() { - var vrDevice = this.el.sceneEl.effect.getVRDisplay(); - var rigEl = document.createElement("a-entity"); - - if (vrDevice !== undefined) { - var displayName = vrDevice.displayName; - - if (displayName.indexOf("Oculus") !== -1) { - rigEl.setAttribute( - "template", - "src:" + this.data.oculus || this.data.desktop - ); - } else if (displayName.indexOf("OpenVR") !== -1) { - rigEl.setAttribute( - "template", - "src:" + this.data.vive || this.data.desktop - ); - } else if (displayName.indexOf("Daydream") !== -1) { - rigEl.setAttribute( - "template", - "src:" + this.data.daydream || this.data.mobile - ); - } else { - rigEl.setAttribute( - "template", - "src:" + this.data.desktop || this.data.mobile - ); - } - } else { - if (AFRAME.utils.device.isGearVR()) { - rigEl.setAttribute( - "template", - "src:" + this.data.gearvr || this.data.mobile - ); - } else if (AFRAME.utils.device.isMobile()) { - rigEl.setAttribute( - "template", - "src:" + this.data.mobile || this.data.desktop - ); - } else { - rigEl.setAttribute( - "template", - "src:" + this.data.desktop || this.data.mobile - ); - } - } - - this.el.appendChild(rigEl); - } -}); diff --git a/src/config.js b/src/config.js index 4eefb9bc77ce9a3f4796f933178f6b2f2bcb74b9..eed5c042fc564ebe1fdd872632de7ad835517e66 100644 --- a/src/config.js +++ b/src/config.js @@ -1,5 +1,4 @@ export default { - // janus_server_url: "wss://dev-janus.reticulum.io", janus_server_url: "wss://quander.me:8989", public_rooms: [1, 2, 3, 4, 5], default_room: 1 diff --git a/src/index.js b/src/index.js index 58b492b63ef9cba4bb8cede767bf5e64ddaeb6fa..c1b6368b509e5d66d3dc68698a3adb9225196f78 100644 --- a/src/index.js +++ b/src/index.js @@ -6,16 +6,19 @@ import "naf-janus-adapter"; import "aframe-teleport-controls"; import "aframe-input-mapping-component"; +import animationMixer from "aframe-extras/src/loaders/animation-mixer"; +AFRAME.registerComponent("animation-mixer", animationMixer); + import "./components/axis-dpad"; import "./components/mute-mic"; import "./components/audio-feedback"; import "./components/nametag-transform"; -import "./components/avatar-customization"; import "./components/mute-state-indicator"; -import "./components/hand-controls-visibility"; +import "./components/virtual-gamepad-controls"; +import "./components/body-controller"; +import "./components/hand-controls2"; import "./components/character-controller"; import "./components/split-axis-events"; -import "./components/virtual-gamepad-controls"; import "./systems/personal-space-bubble"; import registerNetworkScheams from "./network-schemas"; diff --git a/src/input-mappings.js b/src/input-mappings.js index 9035563b1ace79fea88b588f9863988d7404c8d6..d57ff6496b1d35bf0a435b06cfdb74dd807008e6 100644 --- a/src/input-mappings.js +++ b/src/input-mappings.js @@ -1,38 +1,46 @@ export default function registerInputMappings() { AFRAME.registerInputMappings({ - default: { - common: { - // @TODO these dpad events are emmited by an axis-dpad component. This should probalby move into either tracked-controller or input-mapping - dpadleftdown: "action_snap_rotate_left", - dpadrightdown: "action_snap_rotate_right", - dpadcenterdown: "action_teleport_down", // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_aim" - dpadcenterup: "action_teleport_up", // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_teleport" - touchpadpressedaxismovex: "translateX", - touchpadpressedaxismovey: "translateZ", - touchpadbuttonup: "stop_moving" - }, - "vive-controls": { - menudown: "action_mute" - }, - "oculus-touch-controls": { - xbuttondown: "action_mute" - }, - daydream: { - menudown: "action_mute" - }, - keyboard: { - m_press: "action_mute", - q_press: "action_snap_rotate_left", - e_press: "action_snap_rotate_right", - v_press: "action_share_screen", - w_down: "action_move_forward", - w_up: "action_dont_move_forward", - a_down: "action_move_left", - a_up: "action_dont_move_left", - s_down: "action_move_backward", - s_up: "action_dont_move_backward", - d_down: "action_move_right", - d_up: "action_dont_move_right" + mappings: { + default: { + common: { + // @TODO these dpad events are emmited by an axis-dpad component. This should probalby move into either tracked-controller or input-mapping + dpadleftdown: "action_snap_rotate_left", + dpadrightdown: "action_snap_rotate_right", + dpadcenterdown: "action_teleport_down", // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_aim" + dpadcenterup: "action_teleport_up", // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_teleport" + touchpadpressedaxismovex: "translateX", + touchpadpressedaxismovey: "translateZ", + touchpadbuttonup: "stop_moving" + }, + "vive-controls": { + menudown: "action_mute" + }, + "oculus-touch-controls": { + xbuttondown: "action_mute", + gripdown: "middle_ring_pinky_down", + gripup: "middle_ring_pinky_up", + thumbsticktouchstart: "thumb_down", + thumbsticktouchend: "thumb_up", + triggerdown: "index_down", + triggerup: "index_up" + }, + daydream: { + menudown: "action_mute" + }, + keyboard: { + m_press: "action_mute", + q_press: "action_snap_rotate_left", + e_press: "action_snap_rotate_right", + v_press: "action_share_screen", + w_down: "action_move_forward", + w_up: "action_dont_move_forward", + a_down: "action_move_left", + a_up: "action_dont_move_left", + s_down: "action_move_backward", + s_up: "action_dont_move_backward", + d_down: "action_move_right", + d_up: "action_dont_move_right" + } } } }); diff --git a/src/lobby.js b/src/lobby.js index 4ae9eeef7b5de88548969c1a16d6ddb6125366ae..61b3e35e814aa31763335a3a75076b5c534a1e4e 100644 --- a/src/lobby.js +++ b/src/lobby.js @@ -46,20 +46,12 @@ class Lobby extends React.Component { } fetchRooms() { - return Promise.all( - Config.public_rooms.map(room_id => { - return this.handle - .sendMessage({ - kind: "listusers", - room_id - }) - .then(signal => ({ - id: room_id, - limit: 12, - users: signal.plugindata.data.response.user_ids - })); - }) - ); + return this.handle + .sendMessage({ kind: "listusers" }) + .then(signal => { + const usersByRoom = signal.plugindata.data.response.users; + return Config.public_rooms.map(id => ({id, limit: 12, users: usersByRoom[id] || []})); + }); } onWebsocketMessage(event) { diff --git a/src/network-schemas.js b/src/network-schemas.js index 0f00706410b075fa3f4f7689ee8c22b6caa4e84d..d93c552cb6b90a68ee158c66cd93475338c60408 100644 --- a/src/network-schemas.js +++ b/src/network-schemas.js @@ -11,7 +11,12 @@ function registerNetworkSchemas() { }); NAF.schemas.add({ - template: "#hand-template", + template: "#right-hand-template", + components: ["position", "rotation", "visible"] + }); + + NAF.schemas.add({ + template: "#left-hand-template", components: ["position", "rotation", "visible"] }); diff --git a/yarn.lock b/yarn.lock index c60d2aea81572d59f6443c01eb9332a9f8670173..ef0c717dacd6ff8e82bed56f238917614cee86fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,9 +52,16 @@ acorn@^5.1.1: version "5.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" -"aframe-input-mapping-component@https://github.com/fernandojsg/aframe-input-mapping-component": - version "1.0.0" - resolved "https://github.com/fernandojsg/aframe-input-mapping-component#577cadad5a42e7216843dfeca9770fa8be465e09" +aframe-extras@^3.12.4: + version "3.12.4" + resolved "https://registry.yarnpkg.com/aframe-extras/-/aframe-extras-3.12.4.tgz#9276bde8b51a07a9822bbce1fc55f2eb8e6810dc" + dependencies: + aframe-physics-system "^1.4.3" + three-pathfinding "^0.2.2" + +"aframe-input-mapping-component@https://github.com/fernandojsg/aframe-input-mapping-component#6ebc38f": + version "0.1.1" + resolved "https://github.com/fernandojsg/aframe-input-mapping-component#6ebc38f0e871e8ab66673aef5cd11f6ce052076c" aframe-lerp-component@^1.1.0: version "1.1.0" @@ -62,6 +69,13 @@ aframe-lerp-component@^1.1.0: dependencies: almost-equal "^1.1.0" +aframe-physics-system@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/aframe-physics-system/-/aframe-physics-system-1.4.3.tgz#c6927e847081bfe546658314aa4c04958ef27934" + dependencies: + cannon "github:donmccurdy/cannon.js#v0.6.2-dev1" + three-to-cannon "^1.1.1" + "aframe-teleport-controls@https://github.com/netpro2k/aframe-teleport-controls#feature/teleport-origin": version "0.3.0" resolved "https://github.com/netpro2k/aframe-teleport-controls#41fe311d3123503ba44761acce69d0f0634139cc" @@ -1339,6 +1353,10 @@ caniuse-lite@^1.0.30000744: version "1.0.30000751" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000751.tgz#298ad34182ca4359757b4a93afc681b7b917e358" +"cannon@github:donmccurdy/cannon.js#v0.6.2-dev1": + version "0.6.2" + resolved "https://codeload.github.com/donmccurdy/cannon.js/tar.gz/022e8ba53fa83abf0ad8a0e4fd08623123838a17" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -1564,7 +1582,7 @@ concat-stream@1.4.x: readable-stream "~1.1.9" typedarray "~0.0.5" -concat-stream@^1.4.7, concat-stream@^1.6.0: +concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -3642,9 +3660,9 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minijanus@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/minijanus/-/minijanus-0.1.4.tgz#1a8294fa0735ce6a6c58a10dcff9a9ab0cfe8132" +minijanus@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/minijanus/-/minijanus-0.1.6.tgz#8aa08d5797239b3c54a998efa0ee25fa4a700689" minimalistic-assert@^1.0.0: version "1.0.0" @@ -3704,11 +3722,11 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -naf-janus-adapter@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/naf-janus-adapter/-/naf-janus-adapter-0.1.4.tgz#3e6e2022e8f6d5b7f6221fcec8b36a1e1e13be44" +naf-janus-adapter@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/naf-janus-adapter/-/naf-janus-adapter-0.1.5.tgz#f10c8cf390e226ddd62a0058c19f072547bd783a" dependencies: - minijanus "^0.1.4" + minijanus "^0.1.6" nan@^2.3.0: version "2.7.0" @@ -3840,10 +3858,6 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" -now@^8.3.11: - version "8.3.11" - resolved "https://registry.yarnpkg.com/now/-/now-8.3.11.tgz#bca2043bc4485b1b24ea656d652e448ae27fe0bb" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -3987,10 +4001,6 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-shim@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" - os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4179,10 +4189,6 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -pleasejs@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/pleasejs/-/pleasejs-0.4.2.tgz#aaaa1a5fa6902518de7e51e3c63b5f537f823164" - pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" @@ -4441,14 +4447,6 @@ postcss@^6.0.1: source-map "^0.6.1" supports-color "^4.4.0" -pre-commit@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.2.tgz#dbcee0ee9de7235e57f79c56d7ce94641a69eec6" - dependencies: - cross-spawn "^5.0.1" - spawn-sync "^1.0.15" - which "1.2.x" - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -5164,13 +5162,6 @@ source-map@~0.1.31: dependencies: amdefine ">=0.0.4" -spawn-sync@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" - dependencies: - concat-stream "^1.4.7" - os-shim "^0.1.2" - spdx-correct@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" @@ -5431,6 +5422,14 @@ three-buffer-vertex-data@^1.0.0: dependencies: flatten-vertex-data "^1.0.0" +three-pathfinding@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/three-pathfinding/-/three-pathfinding-0.2.3.tgz#469bb26fb6b331f536c9ec88fde78e9c9219f637" + +three-to-cannon@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/three-to-cannon/-/three-to-cannon-1.1.2.tgz#b0040b893b2fa5f0e8a0aedf58bc90fc07f137aa" + three@^0.87.0: version "0.87.1" resolved "https://registry.yarnpkg.com/three/-/three-0.87.1.tgz#466a34edc4543459ced9b9d7d276b65216fe2ba8" @@ -5796,12 +5795,6 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@1.2.x: - version "1.2.14" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" - dependencies: - isexe "^2.0.0" - which@^1.2.12, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"