diff --git a/.eslintrc.js b/.eslintrc.js index 1cadfd103fd1910f79fb0e7928b0663b9e6a248a..fcd01630f75612e9262f216b79101005e14e7d5d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -14,6 +14,7 @@ module.exports = { rules: { "prettier/prettier": "error", "prefer-const": "error", + "no-use-before-define": "error", "no-var": "error", "no-throw-literal": "error", // Light console usage is useful but remove debug logs before merging to master. diff --git a/package.json b/package.json index 7ee4cd06bf14b02983d687d954184761a1d60bf2..70702a53f8890c2952a2d3d9f4de22eabb61e092 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ "@fortawesome/fontawesome-free-solid": "^5.0.9", "@fortawesome/react-fontawesome": "^0.0.18", "aframe-billboard-component": "^1.0.0", - "aframe-extras": "^3.12.4", + "aframe-extras": "^4.0.0", "aframe-input-mapping-component": "https://github.com/johnshaughnessy/aframe-input-mapping-component#feature/map-to-array", "aframe-physics-extras": "https://github.com/infinitelee/aframe-physics-extras#fix/physics-collider-crash", "aframe-physics-system": "https://github.com/infinitelee/aframe-physics-system#feature/shape-component", - "aframe-teleport-controls": "https://github.com/netpro2k/aframe-teleport-controls#feature/pauseable", + "aframe-teleport-controls": "^0.3.1", "aframe-xr": "github:brianpeiris/aframe-xr#3162aed", "classnames": "^2.2.5", "detect-browser": "^2.1.0", diff --git a/src/components/character-controller.js b/src/components/character-controller.js index 1249dff3b0fbb3231bb52bd373e6cd91b7f3a544..8da41b1a2e4bf4f3928a8f74b6a521679b11759a 100644 --- a/src/components/character-controller.js +++ b/src/components/character-controller.js @@ -1,5 +1,6 @@ const CLAMP_VELOCITY = 0.01; const MAX_DELTA = 0.2; +const EPS = 10e-6; // Does not have any type of collisions yet. AFRAME.registerComponent("character-controller", { @@ -79,6 +80,8 @@ AFRAME.registerComponent("character-controller", { const rotationInvMatrix = new THREE.Matrix4(); const pivotRotationMatrix = new THREE.Matrix4(); const pivotRotationInvMatrix = new THREE.Matrix4(); + const start = new THREE.Vector3(); + let navGroup, navNode; return function(t, dt) { const deltaSeconds = dt / 1000; @@ -87,6 +90,8 @@ AFRAME.registerComponent("character-controller", { const distance = this.data.groundAcc * deltaSeconds; const rotationDelta = this.data.rotationSpeed * this.angularVelocity * deltaSeconds; + start.copy(root.position); + // Other aframe components like teleport-controls set position/rotation/scale, not the matrix, so we need to make sure to compose them back into the matrix root.updateMatrix(); @@ -128,9 +133,19 @@ AFRAME.registerComponent("character-controller", { z: root.rotation.z * THREE.Math.RAD2DEG }); - this.el.setAttribute("position", root.position); - this.pendingSnapRotationMatrix.identity(); // Revert to identity + + //copied from aframe-extras movement-controls + const nav = this.el.sceneEl.systems.nav; + if (nav.navMesh && this.velocity.lengthSq() > EPS) { + if (!navGroup) { + navGroup = nav.getGroup(start); + } + navNode = navNode || nav.getNode(start, navGroup); + navNode = nav.clampStep(start, root.position, navGroup, navNode, root.position); + } else { + this.el.setAttribute("position", root.position); + } }; })(), diff --git a/src/components/gltf-bundle.js b/src/components/gltf-bundle.js index 38120d8f369389995839c5eb9836e6682fc4b98f..ba6f7b3dc6d78aa08646352e49b6e3f91031056a 100644 --- a/src/components/gltf-bundle.js +++ b/src/components/gltf-bundle.js @@ -23,7 +23,7 @@ AFRAME.registerComponent("gltf-bundle", { const src = new URL(asset.src, this.baseURL).href; const gltfEl = document.createElement("a-entity"); - gltfEl.setAttribute("gltf-model-plus", { src }); + gltfEl.setAttribute("gltf-model-plus", { src, inflate: true }); loaded.push(new Promise(resolve => gltfEl.addEventListener("model-loaded", resolve))); this.el.appendChild(gltfEl); } diff --git a/src/components/gltf-model-plus.js b/src/components/gltf-model-plus.js index 3864f9327c92ce63deddf8f08766a9316cf4a3da..d9ff8d8ff722388d3b0a63f4731d5541e91bde5e 100644 --- a/src/components/gltf-model-plus.js +++ b/src/components/gltf-model-plus.js @@ -127,7 +127,7 @@ const inflateEntities = function(parentEl, node) { const entityComponents = node.userData.components; if (entityComponents) { for (const prop in entityComponents) { - if (entityComponents.hasOwnProperty(prop)) { + if (entityComponents.hasOwnProperty(prop) && AFRAME.GLTFModelPlus.components.hasOwnProperty(prop)) { const { inflator, componentName } = AFRAME.GLTFModelPlus.components[prop]; if (inflator) { diff --git a/src/components/super-cursor.js b/src/components/super-cursor.js index 691b76ae73813b7c52ca5b4e10730aa051878bea..c93bf8da15234ed38ab1eba7b55712f59adea20f 100644 --- a/src/components/super-cursor.js +++ b/src/components/super-cursor.js @@ -118,7 +118,7 @@ AFRAME.registerComponent("super-cursor", { _handleMouseDown: function() { if (this.isInteractable) { const lookControls = this.data.camera.components["look-controls"]; - lookControls.pause(); + if (lookControls) lookControls.pause(); } this.data.cursor.emit("action_grab", {}); }, @@ -129,7 +129,7 @@ AFRAME.registerComponent("super-cursor", { _handleMouseUp: function() { const lookControls = this.data.camera.components["look-controls"]; - lookControls.play(); + if (lookControls) lookControls.play(); this.data.cursor.emit("action_release", {}); }, diff --git a/src/gltf-component-mappings.js b/src/gltf-component-mappings.js index d1f9d87b0adc70e470af1ce3218008b4929a53a9..2166e7a62a186c9caa1ce3da8f39b5cafa4fff31 100644 --- a/src/gltf-component-mappings.js +++ b/src/gltf-component-mappings.js @@ -3,6 +3,5 @@ import "./components/gltf-model-plus"; AFRAME.GLTFModelPlus.registerComponent("scale-audio-feedback", "scale-audio-feedback"); AFRAME.GLTFModelPlus.registerComponent("loop-animation", "loop-animation"); AFRAME.GLTFModelPlus.registerComponent("shape", "shape"); -AFRAME.GLTFModelPlus.registerComponent("box-shape", "box-shape"); -AFRAME.GLTFModelPlus.registerComponent("sphere-shape", "sphere-shape"); -AFRAME.GLTFModelPlus.registerComponent("cylinder-shape", "cylinder-shape"); +AFRAME.GLTFModelPlus.registerComponent("visible", "visible"); +AFRAME.GLTFModelPlus.registerComponent("nav-mesh", "nav-mesh"); diff --git a/src/hub.html b/src/hub.html index d6ab08e28441a2081f12c092f53085bad23544b3..d032444c9b1c41d29726a8982c9331dab3bbffb4 100644 --- a/src/hub.html +++ b/src/hub.html @@ -19,7 +19,7 @@ <a-scene networked-scene="adapter: janus; audio: true; debug: true; connectOnLoad: false;" - physics + physics="debug: true" mute-mic="eventSrc: a-scene; toggleEvents: action_mute" personal-space-bubble="debug: false;" @@ -135,10 +135,10 @@ scale="2 2 2" class="interactable" super-spawner="template: #interactable-template;" - position="2.5 1.2 0" + position="2.9 1.2 0" body="mass: 0; type: static; shape: box;" ></a-entity> - + <a-entity id="super-cursor" super-cursor="cursor: #3d-cursor; camera: #player-camera;" @@ -187,7 +187,6 @@ camera position="0 1.6 0" personal-space-bubble="radius: 0.4" - look-controls ></a-entity> <a-entity @@ -195,7 +194,11 @@ class="left-controller" hand-controls2="left" tracked-controls - teleport-controls="cameraRig: #player-rig; teleportOrigin: #player-camera; button: action_teleport_" + teleport-controls=" + cameraRig: #player-rig; + teleportOrigin: #player-camera; + button: action_teleport_; + collisionEntities: [nav-mesh]" app-mode-toggle-playing__teleport-controls="mode: hud; invert: true;" haptic-feedback ></a-entity> @@ -205,7 +208,11 @@ class="right-controller" hand-controls2="right" tracked-controls - teleport-controls="cameraRig: #player-rig; teleportOrigin: #player-camera; button: action_teleport_" + teleport-controls=" + cameraRig: #player-rig; + teleportOrigin: #player-camera; + button: action_teleport_; + collisionEntities: [nav-mesh]" haptic-feedback raycaster="objects:.hud; showLine: true; far: 2;" cursor="fuse: false; downEvents: action_ui_select_down; upEvents: action_ui_select_up;" @@ -237,14 +244,6 @@ <template data-selector=".LeftHand"> <a-entity bone-visibility> - <a-entity - id="watch" - gltf-model-plus="src: #watch-model" - bone-mute-state-indicator - scale="1.5 1.5 1.5" - rotation="0 -90 90" - position="0 -0.04 0" - ></a--entity> <a-entity event-repeater="events: action_grab, action_release; eventSource: #player-left-controller" static-body="shape: sphere; sphereRadius: 0.02" diff --git a/src/hub.js b/src/hub.js index 0b34551cea7e804f2e0ab48d729dbcc1972d58f6..fc843649946ff6630563dfa1c1efd78e1d2b00d1 100644 --- a/src/hub.js +++ b/src/hub.js @@ -69,6 +69,7 @@ if (qs.quality) { import "aframe-physics-system"; import "aframe-physics-extras"; +import "aframe-extras/src/pathfinding"; import "super-hands"; import "./components/super-networked-interactable"; import "./components/networked-counter"; @@ -126,6 +127,7 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) { const scene = document.querySelector("a-scene"); const playerRig = document.querySelector("#player-rig"); document.querySelector("a-scene canvas").classList.remove("blurred"); + scene.render(); if (enterInVR) { scene.enterVR(); @@ -133,7 +135,7 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) { AFRAME.registerInputActions(inGameActions, "default"); - document.querySelector("#player-camera").setAttribute("look-controls"); + document.querySelector("#player-camera").setAttribute("look-controls", ""); scene.setAttribute("networked-scene", { room: janusRoomId, @@ -179,11 +181,7 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) { screenEntity.setAttribute("visible", sharingScreen); }); - if (qsTruthy("offline")) { - onConnect(); - } else { - document.body.addEventListener("connected", onConnect); - + if (!qsTruthy("offline")) { scene.components["networked-scene"].connect(); if (mediaStream) { @@ -207,8 +205,6 @@ async function enterScene(mediaStream, enterInVR, janusRoomId) { } } -function onConnect() {} - function mountUI(scene) { const disableAutoExitOnConcurrentLoad = qsTruthy("allow_multi"); const forcedVREntryType = qs.vr_entry_type || null; @@ -255,7 +251,11 @@ const onReady = async () => { const environmentRoot = document.querySelector("#environment-root"); const initialEnvironmentEl = document.createElement("a-entity"); - initialEnvironmentEl.addEventListener("bundleloaded", () => uiRoot.setState({ initialEnvironmentLoaded: true })); + initialEnvironmentEl.addEventListener("bundleloaded", () => { + uiRoot.setState({ initialEnvironmentLoaded: true }); + // Wait a tick so that the environments actually render. + setTimeout(() => scene.renderer.animate(null)); + }); environmentRoot.appendChild(initialEnvironmentEl); if (qs.room) { diff --git a/src/vendor/GLTFLoader.js b/src/vendor/GLTFLoader.js index 25e397ce98c7ebc2be929195c6863338154c01bc..7610044b41b6dd9956b2d84984e46671de46e494 100644 --- a/src/vendor/GLTFLoader.js +++ b/src/vendor/GLTFLoader.js @@ -29,6 +29,8 @@ THREE.GLTFLoader = ( function () { var scope = this; + scope.url = url; + var path = this.path !== undefined ? this.path : THREE.LoaderUtils.extractUrlBase( url ); var loader = new THREE.FileLoader( scope.manager ); @@ -82,6 +84,7 @@ THREE.GLTFLoader = ( function () { parse: function ( data, path, onLoad, onError ) { + var scope = this; var content; var extensions = {}; @@ -159,7 +162,7 @@ THREE.GLTFLoader = ( function () { } - console.time( 'GLTFLoader' ); + console.time( `GLTFLoader - ${scope.url}` ); var parser = new GLTFParser( json, extensions, { @@ -171,7 +174,7 @@ THREE.GLTFLoader = ( function () { parser.parse( function ( scene, scenes, cameras, animations, asset ) { - console.timeEnd( 'GLTFLoader' ); + console.timeEnd( `GLTFLoader - ${scope.url}` ); var glTF = { scene: scene, diff --git a/yarn.lock b/yarn.lock index c89c01a87f233fd07aeabbd529dc7e7729636de2..e5a3f201925ccf10aff81f04c80d3bdc520e34bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -160,12 +160,11 @@ aframe-billboard-component@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/aframe-billboard-component/-/aframe-billboard-component-1.0.0.tgz#10ce2482729eef7386c5844d65917581a62d3adc" -aframe-extras@^3.12.4: - version "3.13.1" - resolved "https://registry.yarnpkg.com/aframe-extras/-/aframe-extras-3.13.1.tgz#f8b6ef18c29e92538d05d94913640942a307c46c" +aframe-extras@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/aframe-extras/-/aframe-extras-4.0.0.tgz#fc851e2a1312c30a4d4addc3e0fa2dbf3e723ead" dependencies: - aframe-physics-system "^1.4.3" - three-pathfinding "^0.2.2" + three-pathfinding "^0.5.5" "aframe-input-mapping-component@https://github.com/johnshaughnessy/aframe-input-mapping-component#feature/map-to-array": version "0.1.2" @@ -181,13 +180,6 @@ aframe-lerp-component@^1.1.0: version "0.1.2" resolved "https://github.com/infinitelee/aframe-physics-extras#49b2d5d3c0caac905783aee51d9e89dbdf7199b8" -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-physics-system@https://github.com/infinitelee/aframe-physics-system#feature/shape-component": version "3.0.2" resolved "https://github.com/infinitelee/aframe-physics-system#c8add507adcb6d67ecb7613924662e413a811454" @@ -198,9 +190,9 @@ aframe-physics-system@^1.4.3: three-to-cannon "^1.2.0" webworkify "^1.4.0" -"aframe-teleport-controls@https://github.com/netpro2k/aframe-teleport-controls#feature/pauseable": - version "0.3.2" - resolved "https://github.com/netpro2k/aframe-teleport-controls#7f67003dd3bd1348357fbf89aaeed916ef2d4016" +aframe-teleport-controls@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/aframe-teleport-controls/-/aframe-teleport-controls-0.3.1.tgz#7d7ef206f483ea92425a6333b0f8fb26c9596d1c" "aframe-xr@github:brianpeiris/aframe-xr#3162aed": version "0.0.9" @@ -7622,11 +7614,11 @@ textextensions@2: version "2.2.0" resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286" -three-pathfinding@^0.2.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/three-pathfinding/-/three-pathfinding-0.2.3.tgz#469bb26fb6b331f536c9ec88fde78e9c9219f637" +three-pathfinding@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/three-pathfinding/-/three-pathfinding-0.5.5.tgz#ff05a8f8cfba343b3b07c05c25d11b0d161911f8" -three-to-cannon@^1.1.1, three-to-cannon@^1.2.0: +three-to-cannon@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/three-to-cannon/-/three-to-cannon-1.2.0.tgz#92b9a756a270851aa98c3058c51ef15891507c01"