diff --git a/src/components/character-controller.js b/src/components/character-controller.js index 80260e0fcfbf258492e536fa1ab930811cfef1eb..910123ba8bb2f5e54e64037ac478a1ac2e57e577 100644 --- a/src/components/character-controller.js +++ b/src/components/character-controller.js @@ -105,6 +105,7 @@ AFRAME.registerComponent("character-controller", { const startScale = new THREE.Vector3(); return function(t, dt) { + if (!this.el.sceneEl.is("entered")) return; const deltaSeconds = dt / 1000; const root = this.el.object3D; const pivot = this.data.pivot.object3D; diff --git a/src/components/gltf-model-plus.js b/src/components/gltf-model-plus.js index 912490b97e552d7c4aff1b6b69c519c29a66869d..b4d25bb3989aea9619a3ebc2d4f6b3bc8e5de9cf 100644 --- a/src/components/gltf-model-plus.js +++ b/src/components/gltf-model-plus.js @@ -1,5 +1,6 @@ import nextTick from "../utils/next-tick"; import SketchfabZipWorker from "../workers/sketchfab-zip.worker.js"; +import MobileStandardMaterial from "../materials/MobileStandardMaterial"; import cubeMapPosX from "../assets/images/cubemap/posx.jpg"; import cubeMapNegX from "../assets/images/cubemap/negx.jpg"; import cubeMapPosY from "../assets/images/cubemap/posy.jpg"; @@ -255,8 +256,12 @@ async function loadGLTF(src, contentType, preferredTechnique, onProgress) { gltf.scene.traverse(object => { if (object.material && object.material.type === "MeshStandardMaterial") { - object.material.envMap = envMap; - object.material.needsUpdate = true; + if (preferredTechnique === "KHR_materials_unlit") { + object.material = MobileStandardMaterial.fromStandardMaterial(object.material); + } else { + object.material.envMap = envMap; + object.material.needsUpdate = true; + } } }); diff --git a/src/components/hand-controls2.js b/src/components/hand-controls2.js index 4e50b1a500034affe300603340c5af0b8efb925b..534f796c45c304097768d5e486cac12db4d76664 100644 --- a/src/components/hand-controls2.js +++ b/src/components/hand-controls2.js @@ -50,6 +50,13 @@ AFRAME.registerComponent("hand-controls2", { init() { this.pose = POSES.open; this.el.setAttribute("visible", false); + + this.connectedController = null; + + this.onControllerConnected = this.onControllerConnected.bind(this); + this.onControllerDisconnected = this.onControllerDisconnected.bind(this); + this.el.addEventListener("controllerconnected", this.onControllerConnected); + this.el.addEventListener("controllerdisconnected", this.onControllerDisconnected); }, update(prevData) { @@ -109,5 +116,17 @@ AFRAME.registerComponent("hand-controls2", { this.pose = pose; } this.el.setAttribute("visible", hasPose); + }, + + // Show controller when connected + onControllerConnected(e) { + this.connectedController = e.detail.name; + this.el.setAttribute("visible", true); + }, + + // Hide controller on disconnect + onControllerDisconnected() { + this.connectedController = null; + this.el.setAttribute("visible", false); } }); diff --git a/src/components/tools/pen.js b/src/components/tools/pen.js index 7e4b097b0d36ea65f4a39b1040b16828bd566b6d..dd52ca4ab14030ddf064a9d5ae9f0ef9a7d4456a 100644 --- a/src/components/tools/pen.js +++ b/src/components/tools/pen.js @@ -140,6 +140,10 @@ AFRAME.registerComponent("pen", { this.timeSinceLastDraw = time % this.data.drawFrequency; } + + if (this.currentDrawing && !grabber) { + this._endDraw(); + } }, //helper function to get normal of direction of drawing cross direction to camera diff --git a/src/hub.html b/src/hub.html index b32855a0cda3e9a31fdd2215251c004f62adc5b8..9627bdf36cf679a3207c569968299bf3a29fc7e0 100644 --- a/src/hub.html +++ b/src/hub.html @@ -31,6 +31,7 @@ personal-space-bubble="debug: false;" vr-mode-ui="enabled: false" stats-plus="false" + action-to-event__mute="path: /actions/muteMic; event: action_mute;" > <a-assets> diff --git a/src/materials/MobileStandardMaterial.js b/src/materials/MobileStandardMaterial.js new file mode 100644 index 0000000000000000000000000000000000000000..aa9e10de101be73807c0259e1eb75f222e4d974d --- /dev/null +++ b/src/materials/MobileStandardMaterial.js @@ -0,0 +1,110 @@ +const VERTEX_SHADER = ` +#include <common> +#include <uv_pars_vertex> +#include <uv2_pars_vertex> +#include <color_pars_vertex> +#include <fog_pars_vertex> +#include <morphtarget_pars_vertex> +#include <skinning_pars_vertex> +#include <logdepthbuf_pars_vertex> +#include <clipping_planes_pars_vertex> + +void main() { + #include <uv_vertex> + #include <uv2_vertex> + #include <color_vertex> + #include <skinbase_vertex> + + #include <begin_vertex> + #include <morphtarget_vertex> + #include <skinning_vertex> + #include <project_vertex> + #include <logdepthbuf_vertex> + + #include <worldpos_vertex> + #include <clipping_planes_vertex> + #include <fog_vertex> +} +`; + +const FRAGMENT_SHADER = ` +uniform vec3 diffuse; +uniform vec3 emissive; +uniform float opacity; + +#include <common> +#include <color_pars_fragment> +#include <uv_pars_fragment> +#include <uv2_pars_fragment> +#include <map_pars_fragment> +#include <aomap_pars_fragment> +#include <emissivemap_pars_fragment> +#include <fog_pars_fragment> +#include <logdepthbuf_pars_fragment> +#include <clipping_planes_pars_fragment> + +void main() { + #include <clipping_planes_fragment> + + vec4 diffuseColor = vec4(diffuse, opacity); + ReflectedLight reflectedLight = ReflectedLight(vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); + vec3 totalEmissiveRadiance = emissive; + + #include <logdepthbuf_fragment> + #include <map_fragment> + #include <color_fragment> + #include <alphatest_fragment> + #include <emissivemap_fragment> + + reflectedLight.indirectDiffuse += vec3(1.0); + + #include <aomap_fragment> + + reflectedLight.indirectDiffuse *= diffuseColor.rgb; + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; + + gl_FragColor = vec4(outgoingLight, diffuseColor.a); + + #include <premultiplied_alpha_fragment> + #include <tonemapping_fragment> + #include <encodings_fragment> + #include <fog_fragment> +} +`; + +export default class MobileStandardMaterial extends THREE.ShaderMaterial { + static fromStandardMaterial(material) { + const parameters = { + vertexShader: VERTEX_SHADER, + fragmentShader: FRAGMENT_SHADER, + uniforms: { + uvTransform: { value: new THREE.Matrix3() }, + diffuse: { value: material.color }, + opacity: { value: material.opacity }, + map: { value: material.map }, + aoMapIntensity: { value: material.aoMapIntensity }, + aoMap: { value: material.aoMap }, + emissive: { value: material.emissive }, + emissiveMap: { value: material.emissiveMap } + }, + fog: true, + lights: false, + opacity: material.opacity, + transparent: material.transparent, + skinning: material.skinning, + morphTargets: material.morphTargets + }; + + const mobileMaterial = new MobileStandardMaterial(parameters); + + mobileMaterial.color = material.color; + mobileMaterial.map = material.map; + mobileMaterial.aoMap = material.aoMap; + mobileMaterial.aoMapIntensity = material.aoMapIntensity; + mobileMaterial.emissive = material.emissive; + mobileMaterial.emissiveMap = material.emissiveMap; + + return mobileMaterial; + } +} diff --git a/src/scene-entry-manager.js b/src/scene-entry-manager.js index ffa5021d8c8db5a326f05c6d2bb92d06ad57b6ce..789bde3192259a19ca9fc0877805addc527f0a45 100644 --- a/src/scene-entry-manager.js +++ b/src/scene-entry-manager.js @@ -94,6 +94,8 @@ export default class SceneEntryManager { this.store.update({ activity: { lastEnteredAt: new Date().toISOString() } }); }); })(); + + this.scene.addState("entered"); }; whenSceneLoaded = callback => { diff --git a/src/systems/userinput/bindings/keyboard-mouse-user.js b/src/systems/userinput/bindings/keyboard-mouse-user.js index cd610085e64a1ce33a96f91e5bfe58c41983cab9..d38fb69f82063ba778924edd82eac1aadd0a6730 100644 --- a/src/systems/userinput/bindings/keyboard-mouse-user.js +++ b/src/systems/userinput/bindings/keyboard-mouse-user.js @@ -109,6 +109,15 @@ export const keyboardMouseUserBindings = { dest: { value: paths.actions.cameraDelta }, xform: xforms.compose_vec2 }, + { + src: { + value: paths.device.keyboard.key("m") + }, + dest: { + value: paths.actions.muteMic + }, + xform: xforms.rising + }, { src: { value: paths.device.keyboard.key("l") diff --git a/src/systems/userinput/paths.js b/src/systems/userinput/paths.js index cca20e88d5bff76fcedfb61320725cd156800860..75f655055b4578c0ce38f7781a561955f3ba5100 100644 --- a/src/systems/userinput/paths.js +++ b/src/systems/userinput/paths.js @@ -14,6 +14,7 @@ paths.actions.stopGazeTeleport = "/actions/stopTeleport"; paths.actions.spawnPen = "/actions/spawnPen"; paths.actions.ensureFrozen = "/actions/ensureFrozen"; paths.actions.thaw = "/actions/thaw"; +paths.actions.muteMic = "/actions/muteMic"; paths.actions.cursor = {}; paths.actions.cursor.pose = "/actions/cursorPose"; paths.actions.cursor.grab = "/actions/cursorGrab"; diff --git a/src/systems/userinput/userinput.js b/src/systems/userinput/userinput.js index eb5b16ef0bf666d70d9d400bb3e312c2810c8432..2ffbdca79db0e2d07d464f32ea320fc8cb31c329 100644 --- a/src/systems/userinput/userinput.js +++ b/src/systems/userinput/userinput.js @@ -75,8 +75,6 @@ AFRAME.registerSystem("userinput", { this.registeredMappings = new Set([keyboardDebuggingBindings]); this.xformStates = new Map(); - this.gamepads = []; - const appAwareTouchscreenDevice = new AppAwareTouchscreenDevice(); const updateBindingsForVRMode = () => { const inVRMode = this.el.sceneEl.is("vr-mode"); @@ -103,17 +101,16 @@ AFRAME.registerSystem("userinput", { window.addEventListener( "gamepadconnected", e => { - console.log(e.gamepad); let gamepadDevice; - if (e.gamepad.id === "OpenVR Gamepad") { - for (let i = 0; i < this.activeDevices.length; i++) { - const activeDevice = this.activeDevices[i]; - if (activeDevice.gamepad && activeDevice.gamepad === e.gamepad) { - console.warn("ignoring gamepad"); - return; // multiple connect events without a disconnect event - } + for (let i = 0; i < this.activeDevices.length; i++) { + const activeDevice = this.activeDevices[i]; + if (activeDevice.gamepad && activeDevice.gamepad === e.gamepad) { + console.warn("ignoring gamepad", e.gamepad); + return; // multiple connect events without a disconnect event } - if (this.activeDevices) gamepadDevice = new ViveControllerDevice(e.gamepad); + } + if (e.gamepad.id === "OpenVR Gamepad") { + gamepadDevice = new ViveControllerDevice(e.gamepad); this.registeredMappings.add(viveUserBindings); } else if (e.gamepad.id.startsWith("Oculus Touch")) { gamepadDevice = new OculusTouchControllerDevice(e.gamepad); @@ -132,16 +129,17 @@ AFRAME.registerSystem("userinput", { this.registeredMappings.add(gamepadBindings); } this.activeDevices.add(gamepadDevice); - this.gamepads[e.gamepad.index] = gamepadDevice; }, false ); window.addEventListener( "gamepaddisconnected", e => { - if (this.gamepads[e.gamepad.index]) { - this.activeDevices.delete(this.gamepads[e.gamepad.index]); - delete this.gamepads[e.gamepad.index]; + for (const device of this.activeDevices) { + if (device.gamepad === e.gamepad) { + this.activeDevices.delete(device); + return; + } } }, false