fix: normal mode was unplayable when webxr was available
fix: in vr mode performance was degraded since every frame was rendered twice fix: enter vr is now displayed propertly on mobile devices
This commit is contained in:
parent
df6ed989d0
commit
2bd3307199
4 changed files with 23 additions and 16 deletions
|
|
@ -20,6 +20,7 @@ export class Viewer {
|
|||
playerHeight: number
|
||||
isSneaking: boolean
|
||||
version: string
|
||||
cameraObjectOverride?: THREE.Object3D // for xr
|
||||
|
||||
constructor (public renderer: THREE.WebGLRenderer, numWorkers?: number) {
|
||||
this.scene = new THREE.Scene()
|
||||
|
|
@ -81,12 +82,13 @@ export class Viewer {
|
|||
}
|
||||
|
||||
setFirstPersonCamera (pos: Vec3 | null, yaw: number, pitch: number, roll = 0) {
|
||||
const cam = this.cameraObjectOverride || this.camera
|
||||
if (pos) {
|
||||
let y = pos.y + this.playerHeight
|
||||
if (this.isSneaking) y -= 0.3
|
||||
new tweenJs.Tween(this.camera.position).to({ x: pos.x, y, z: pos.z }, 50).start()
|
||||
new tweenJs.Tween(cam.position).to({ x: pos.x, y, z: pos.z }, 50).start()
|
||||
}
|
||||
this.camera.rotation.set(pitch, yaw, roll, 'ZYX')
|
||||
cam.rotation.set(pitch, yaw, roll, 'ZYX')
|
||||
}
|
||||
|
||||
// todo type
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ let previousWindowHeight = window.innerHeight
|
|||
const renderFrame = (time: DOMHighResTimeStamp) => {
|
||||
if (window.stopLoop) return
|
||||
window.requestAnimationFrame(renderFrame)
|
||||
if (window.stopRender) return
|
||||
if (window.stopRender || renderer.xr.isPresenting) return
|
||||
if (renderInterval) {
|
||||
delta += time - lastTime
|
||||
lastTime = time
|
||||
|
|
@ -540,7 +540,7 @@ async function connect (connectOptions: {
|
|||
|
||||
window.debugMenu = debugMenu
|
||||
|
||||
void initVR(bot, renderer, viewer)
|
||||
void initVR()
|
||||
|
||||
postRenderFrameFn = () => {
|
||||
viewer.setFirstPersonCamera(null, bot.entity.yaw, bot.entity.pitch)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,12 @@ body {
|
|||
text-shadow: 1px 1px #222;
|
||||
}
|
||||
|
||||
#VRButton {
|
||||
background: rgba(0, 0, 0, 0.3) !important;
|
||||
opacity: 0.7 !important;
|
||||
position: fixed !important;
|
||||
}
|
||||
|
||||
.dirt-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
|||
23
src/vr.js
23
src/vr.js
|
|
@ -1,13 +1,11 @@
|
|||
/* global THREE */
|
||||
|
||||
const { VRButton } = require('three/examples/jsm/webxr/VRButton.js')
|
||||
const { GLTFLoader } = require('three/examples/jsm/loaders/GLTFLoader.js')
|
||||
const { XRControllerModelFactory } = require('three/examples/jsm/webxr/XRControllerModelFactory.js')
|
||||
const TWEEN = require('@tweenjs/tween.js')
|
||||
|
||||
async function initVR (bot, renderer, viewer) {
|
||||
async function initVR () {
|
||||
const { renderer } = viewer
|
||||
if (!('xr' in navigator)) return
|
||||
const isSupported = await navigator.xr.isSessionSupported('immersive-vr')
|
||||
const isSupported = await navigator.xr.isSessionSupported('immersive-vr') && !!XRSession.prototype.updateRenderState // e.g. android webview doesn't support updateRenderState
|
||||
if (!isSupported) return
|
||||
|
||||
// VR
|
||||
|
|
@ -34,14 +32,10 @@ async function initVR (bot, renderer, viewer) {
|
|||
})
|
||||
controller2.add(hand2)
|
||||
|
||||
viewer.setFirstPersonCamera = function (pos, yaw, pitch) {
|
||||
if (pos) new TWEEN.Tween(user.position).to({ x: pos.x, y: pos.y, z: pos.z }, 50).start()
|
||||
user.rotation.set(pitch, yaw, 0, 'ZYX')
|
||||
}
|
||||
|
||||
let rotSnapReset = true
|
||||
let yawOffset = 0
|
||||
renderer.setAnimationLoop(() => {
|
||||
if (!renderer.xr.isPresenting) return
|
||||
if (hand1.xrInputSource && hand2.xrInputSource) {
|
||||
hand1.xAxis = hand1.xrInputSource.gamepad.axes[2]
|
||||
hand1.yAxis = hand1.xrInputSource.gamepad.axes[3]
|
||||
|
|
@ -76,9 +70,14 @@ async function initVR (bot, renderer, viewer) {
|
|||
bot.setControlState('right', hand2.xAxis < -0.5)
|
||||
bot.setControlState('left', hand2.xAxis > 0.5)
|
||||
|
||||
TWEEN.update()
|
||||
viewer.update()
|
||||
renderer.render(viewer.scene, viewer.camera)
|
||||
viewer.render()
|
||||
})
|
||||
renderer.xr.addEventListener('sessionstart', () => {
|
||||
viewer.cameraObjectOverride = user
|
||||
})
|
||||
renderer.xr.addEventListener('sessionend', () => {
|
||||
viewer.cameraObjectOverride = undefined
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue