diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js index 5940a22..792e093 100644 --- a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js +++ b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js @@ -71,7 +71,7 @@ class MazeQuizGame extends EventManager { //engine.hero.model.rotation.y += Math.PI; engine.motionQueue.add({ o: engine.hero, - a:{cameraDelta: k=>k*Math.PI*6 }, + a:{cameraDelta: k=>k*Math.PI*4 }, t: 12 }); this.dispatchEvent({type:'finish'}) diff --git a/src/lib/GameEngine.js b/src/lib/GameEngine.js index 534d296..00851d8 100644 --- a/src/lib/GameEngine.js +++ b/src/lib/GameEngine.js @@ -252,17 +252,13 @@ class GameEngine extends EventManager{ if (gameEngine.hero){ if (!gameEngine.pointerControls.isLocked){ gameEngine.hero.cameraZ += event.deltaY / 100; - }else{ - gameEngine.camera.fov += event.deltaY / 100; - gameEngine.camera.fov = Math.min(Math.max(gameEngine.camera.fov, 0.01), 90); - gameEngine.camera.updateProjectionMatrix(); } }else{ gameEngine.camera.zoom -= event.deltaY / (1000 / gameEngine.camera.zoom); gameEngine.camera.zoom = Math.max(gameEngine.camera.zoom, .01); //controls.rotateSpeed = 1 / Math.sqrt(gameEngine.camera.zoom); - gameEngine.orbitControls.panSpeed = 1 / gameEngine.camera.zoom; gameEngine.camera.updateProjectionMatrix(); + gameEngine.orbitControls.panSpeed = 1 / gameEngine.camera.zoom; } }) @@ -689,6 +685,7 @@ class GameEngine extends EventManager{ clearScene(){ this.hero?.dispose(); this.dashboard?.reset(); + this.pointerControls.dispose(); //this.activeObjects.clear(); this.physics.stop(); this.physics.clear(); diff --git a/src/lib/Hero.js b/src/lib/Hero.js index 66d5c03..0718861 100644 --- a/src/lib/Hero.js +++ b/src/lib/Hero.js @@ -16,11 +16,23 @@ class Hero{ set cameraZ(v){ this.#cameraZ = Math.min(Math.max(v, 1), 12); if (this.#cameraZ == 1){ - this.engine.pointerControls.lock(true).then(()=>{ + if (this.engine.renderer.xr.isPresenting){ this.#cameraZ = 0; - }).catch(err=>{ - console.log(err); - }) + this.fpv = true; + this.camera.rotation.set(0,0,0); + }else{ + this.engine.pointerControls.lock(true).then(()=>{ + this.#cameraZ = 0; + this.fpv = true; + this.engine.pointerControls.once('unlock', ()=>{ + this.fpv = false; + }) + }).catch(err=>{ + console.log(err); + }) + } + }else if(this.fpv){ + this.fpv = false; } } @@ -87,13 +99,16 @@ class Hero{ this.actionStart = 0; this.cameraDelta = 0; this.cameraIdleDelta = 0; + this.fpv = false; this.ready = true; + this.camera.rotation.reorder('YZX'); + this.engine.camera.rotation.reorder('YZX'); } update(delta){ if (this.ready && this.engine.physics.started && !this.disableInput) { this.updateCharacterControls(delta) - if (this.engine.renderer.xr.isPresenting){ + if (this.engine.renderer.xr.isPresenting && !this.fpv){ this.cameraMode = 'fixed' this.engine.cameraRig.position.y = -this.engine.camera.position.y; this.engine.dashboard.object.position.y = this.engine.camera.position.y; @@ -119,11 +134,10 @@ class Hero{ updateCharacterControls(delta) { let pc = this.engine.pointerControls; - if (pc.isLocked && this.model.visible){ + if (this.fpv && this.model.visible){ this.model.visible = false; - this.camera.rotation.reorder('YZX'); } - if (!pc.isLocked && !this.model.visible){ + if (!this.fpv && !this.model.visible){ this.model.visible = true; this.#cameraZ = 4 this.engine.camera.fov = 45; @@ -168,7 +182,7 @@ class Hero{ this.fadeDuration = 1; } - if (this.currentAction.startsWith('idle') && play != 'idle' && !pc.isLocked && !this.engine.renderer.xr.isPresenting){ + if (this.currentAction.startsWith('idle') && play != 'idle' && !this.fpv && !this.engine.renderer.xr.isPresenting){ this.cameraIdleDelta += delta * 0.33; }else { this.cameraIdleDelta = 0; @@ -206,13 +220,19 @@ class Hero{ } if (pc.motion){ - if (!pc.isLocked){ + if (!this.fpv){ //this.directionVelocity = this.directionVelocity * 2.5 * Math.abs(input[0]) this.direction += input[0] * delta * 2.5 //this.directionVelocity; this.walkDirection.set(0, 0, input[1]) this.walkDirection.applyAxisAngle(this.rotateAngle, this.direction) }else{ - this.direction = this.camera.rotation.y; + if (this.engine.renderer.xr.isPresenting){ + this.direction = this.engine.camera.rotation.y; + }else{ + this.direction = this.camera.rotation.y; + + } + this.walkDirection.set(input[0], 0, input[1]) this.walkDirection.applyAxisAngle(this.rotateAngle, this.direction) //console.log(this.camera.rotation.y * 180/Math.PI); @@ -258,7 +278,7 @@ class Hero{ if (this.cameraMode == 'rotate'){ cameraDesiredPosition = new Vector3( this.model.position.x + this.#cameraZ* Math.sin(this.model.rotation.y + Math.PI + this.cameraDelta + this.cameraIdleDelta), - this.model.position.y + (pc.isLocked? this.size.y*0.9 : this.cameraY), + this.model.position.y + (this.fpv? this.size.y*0.9 : this.cameraY), this.model.position.z + this.#cameraZ* Math.cos(this.model.rotation.y + Math.PI + this.cameraDelta + this.cameraIdleDelta) ) } else { @@ -269,14 +289,14 @@ class Hero{ // ) cameraDesiredPosition = new Vector3( this.model.position.x + this.#cameraZ* Math.sin(0+ Math.PI + this.cameraDelta + this.cameraIdleDelta), - this.model.position.y + (pc.isLocked? this.size.y*0.9 : this.cameraY), + this.model.position.y + (this.fpv? this.size.y*0.9 : this.cameraY), this.model.position.z + this.#cameraZ* Math.cos(0+ Math.PI + this.cameraDelta + this.cameraIdleDelta) ) } cameraPosition.lerp(cameraDesiredPosition, this.cameraMode == 'fixed' ? delta*2 : delta*2) this.camera.position.copy(cameraPosition) - if (!pc.isLocked){ + if (!this.fpv){ this.camera.lookAt( this.model.position.x, this.cameraY -this.size.y * 0.5 + this.model.position.y, diff --git a/src/lib/PointerControls.js b/src/lib/PointerControls.js index ea37070..1933986 100644 --- a/src/lib/PointerControls.js +++ b/src/lib/PointerControls.js @@ -1,12 +1,13 @@ -import { Vector3, Vector2, Controls, Euler } from 'three'; +import { Vector3, Euler } from 'three'; +import { EventManager } from './EventManager'; const _MOUSE_SENSITIVITY = 0.002; const _euler = new Euler( 0, 0, 0, 'YXZ' ); -class PointerControls extends Controls { +class PointerControls extends EventManager { constructor(engine) { - super( engine.cameraWorld, engine.renderer.domElement ); + super(); this.kb = {}; this.dom = engine.renderer.domElement; @@ -26,6 +27,7 @@ class PointerControls extends Controls { this.pointerSpeed = 1.0; this._onMouseMove = onMouseMove.bind( this ); + this._onMouseWheel = onMouseWheel.bind( this ); this._onPointerlockChange = onPointerlockChange.bind( this ); this._onPointerlockError = onPointerlockError.bind( this ); @@ -43,8 +45,8 @@ class PointerControls extends Controls { this.kb[event.code] = false; }; - document.addEventListener('keydown', onKeyDown); - document.addEventListener('keyup', onKeyUp); + this.dom.ownerDocument.addEventListener('keydown', onKeyDown); + this.dom.ownerDocument.addEventListener('keyup', onKeyUp); this.dom.addEventListener('click', () => { this.isLocked && this.clicked && this.clicked(); @@ -64,24 +66,20 @@ class PointerControls extends Controls { this.update = () => { }; - this.connect(this.dom); - } - - connect( element ) { - super.connect( element ); + this.object = engine.cameraWorld; + this.dom.ownerDocument.addEventListener( 'wheel', this._onMouseWheel ); this.dom.ownerDocument.addEventListener( 'mousemove', this._onMouseMove ); this.dom.ownerDocument.addEventListener( 'pointerlockchange', this._onPointerlockChange ); this.dom.ownerDocument.addEventListener( 'pointerlockerror', this._onPointerlockError ); - } + } - disconnect() { + dispose() { + this.dom.ownerDocument.removeEventListener( 'wheel', this._onMouseWheel ); this.dom.ownerDocument.removeEventListener( 'mousemove', this._onMouseMove ); this.dom.ownerDocument.removeEventListener( 'pointerlockchange', this._onPointerlockChange ); this.dom.ownerDocument.removeEventListener( 'pointerlockerror', this._onPointerlockError ); - } - - dispose() { - this.disconnect(); + this.dom.ownerDocument.removeEventListener( 'keydown', this.onKeyDown ); + this.dom.ownerDocument.removeEventListener( 'keyup', this.onKeyUp ); } get moveForward(){ @@ -195,13 +193,24 @@ function onMouseMove( event ) { this.dispatchEvent( { type: 'change' } ); } +function onMouseWheel( event ){ + if (this.isLocked){ + this.engine.camera.fov += event.deltaY / 100; + this.engine.camera.fov = Math.min(Math.max(this.engine.camera.fov, 0.01), 45); + this.engine.camera.updateProjectionMatrix(); + if (this.engine.camera.fov >= 45){ + this.unlock(); + } + } +} + function onPointerlockChange() { if ( this.dom.ownerDocument.pointerLockElement === this.dom ) { - this.dispatchEvent( { type: 'lock' } ); this.isLocked = true; + this.dispatchEvent( { type: 'lock' } ); } else { - this.dispatchEvent( { type: 'unlock' } ); this.isLocked = false; + this.dispatchEvent( { type: 'unlock' } ); } //this.engine.cameraRig.rotation.y = this.isLocked ? 0 : Math.PI; }