From 3028e1f86410d05a13a41c29fb922197ffc1602c Mon Sep 17 00:00:00 2001 From: Byongho96 Date: Mon, 9 Dec 2024 05:32:10 +0000 Subject: [PATCH] deploy: 0bdcae4ac61f5f769e29bdbb0577b9d7a1764453 --- public/examples/shoot-vr/index.html | 91 +++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/public/examples/shoot-vr/index.html b/public/examples/shoot-vr/index.html index c1a9ee5..5a2cf97 100644 --- a/public/examples/shoot-vr/index.html +++ b/public/examples/shoot-vr/index.html @@ -27,7 +27,7 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { FirstPersonKeyboardControls } from 'physics-character-controls'; + import { PhysicsControls } from 'physics-character-controls'; import { Monster, MonsterFactory } from './monster.js'; @@ -74,27 +74,47 @@ world.receiveShadow = true; scene.add(world); - controls = new FirstPersonKeyboardControls({ - object: camera, - domElement: renderer.domElement, - worldObject: world, - physicsOptions: { - jumpForce: 0, - groundMoveSpeed: 0, - floatMoveSpeed: 0, - }, + controls = new PhysicsControls(cameraGrandParent, renderer.domElement, world, { + colliderHeight: 1.6, + colliderRadius: 0.5, }); + controls.enabled = false; }); + // Renderer + const renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.setAnimationLoop(animate); + renderer.xr.enabled = true; + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + renderer.toneMapping = THREE.ACESFilmicToneMapping; + container.appendChild(renderer.domElement); + // Scene const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Camera + const cameraGrandParent = new THREE.Object3D(); + cameraGrandParent.position.set(0, 2, 0); + scene.add(cameraGrandParent); + + const cameraParent = new THREE.Object3D(); + cameraParent.lookAt(0, 0, 1); + cameraGrandParent.add(cameraParent); + const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000); camera.rotation.order = 'YXZ'; - camera.position.set(0, 2, 0); - scene.add(camera); + cameraParent.add(camera); + + renderer.xr.addEventListener('sessionstart', () => { + const xrCamera = renderer.xr.getCamera(); + cameraParent.add(xrCamera); + + controls.enabled = true; + }); // Light const spotLight = new THREE.SpotLight(0xffbb55, 50, 100, Math.PI / 5, 0.5); @@ -103,17 +123,6 @@ spotLight.target = camera; camera.add(spotLight); - // Renderer - const renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - // Audio const listener = new THREE.AudioListener(); camera.add(listener); @@ -149,9 +158,11 @@ const monsterFactory = new MonsterFactory(listener); monsterFactory.loadGLTF().then(() => { monsterInterval = setInterval(() => { + if (!renderer.xr.isPresenting) return; + if (monsters.length > 20) return; - const monster = monsterFactory.createMonster(camera); + const monster = monsterFactory.createMonster(cameraGrandParent); if (!monster) return; monster.object.position.set(Math.random() * 20 - 10, 0, Math.random() * 20 - 10); @@ -200,9 +211,12 @@ }, 1000); } + let gamepad1, gamepad2; + const controller1 = renderer.xr.getController(0); controller1.addEventListener('selectstart', onSelectStart); controller1.addEventListener('connected', function (event) { + gamepad1 = event.data.gamepad; this.add(buildController(event.data)); }); controller1.addEventListener('disconnected', function () { @@ -213,6 +227,7 @@ const controller2 = renderer.xr.getController(1); controller2.addEventListener('selectstart', onSelectStart); controller2.addEventListener('connected', function (event) { + gamepad2 = event.data.gamepad; this.add(buildController(event.data)); }); controller2.addEventListener('disconnected', function () { @@ -264,6 +279,34 @@ monster.update(delta); }); + if (renderer.xr.isPresenting) { + // move by left joystick + const speed = 100; + + const x = gamepad2.axes[2]; + const y = gamepad2.axes[3]; + + const accumulatedDirection = new THREE.Vector3(); + + const forwardDirection = new THREE.Vector3(); + renderer.xr.getCamera().getWorldDirection(forwardDirection); + forwardDirection.y = 0; + forwardDirection.normalize(); + forwardDirection.multiplyScalar(-1 * y * speed * delta); + + const sideDirection = new THREE.Vector3(); + renderer.xr.getCamera().getWorldDirection(sideDirection); + sideDirection.y = 0; + sideDirection.cross(renderer.xr.getCamera().up); + sideDirection.normalize(); + sideDirection.multiplyScalar(x * speed * delta); + + accumulatedDirection.add(forwardDirection).add(sideDirection); + + controls.velocity.x = accumulatedDirection.x; + controls.velocity.z = accumulatedDirection.z; + } + renderer.render(scene, camera); stats.update();