Spaces:
Sleeping
Sleeping
| import * as THREE from 'three'; | |
| import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js'; | |
| import { STATE } from '../core/State.js'; | |
| import { PALETTE_3D } from './palette.js'; | |
| export function initScene() { | |
| const scene = new THREE.Scene(); | |
| STATE.scene = scene; // Expose scene for visualizer helpers | |
| scene.background = new THREE.Color(PALETTE_3D.BACKGROUND); | |
| scene.fog = new THREE.FogExp2(PALETTE_3D.FOG, 0.02); | |
| const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000); | |
| camera.rotation.reorder('YXZ'); | |
| camera.position.set(0, 5, 20); | |
| const renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| document.querySelector('#app').innerHTML = ''; | |
| document.querySelector('#app').appendChild(renderer.domElement); | |
| const controls = new PointerLockControls(camera, document.body); | |
| // Patch requestPointerLock to pass { unadjustedMovement: true } with a fallback if unsupported/rejected | |
| const domEl = controls.domElement || document.body; | |
| const originalRequest = domEl.requestPointerLock || Element.prototype.requestPointerLock; | |
| if (originalRequest) { | |
| domEl.requestPointerLock = function(options) { | |
| try { | |
| const promise = originalRequest.call(this, { unadjustedMovement: true, ...options }); | |
| if (promise && typeof promise.catch === 'function') { | |
| promise.catch((err) => { | |
| console.warn("PointerLock with options rejected, falling back:", err); | |
| originalRequest.call(this); | |
| }); | |
| } | |
| return promise; | |
| } catch (e) { | |
| console.warn("PointerLock with options threw error, falling back:", e); | |
| try { | |
| return originalRequest.call(this); | |
| } catch (fallbackErr) { | |
| console.error("PointerLock fallback failed:", fallbackErr); | |
| } | |
| } | |
| }; | |
| } | |
| const gridHelper = new THREE.GridHelper(200, 200, PALETTE_3D.GRID_PRIMARY, PALETTE_3D.GRID_SECONDARY); | |
| gridHelper.position.y = -5; | |
| scene.add(gridHelper); | |
| window.addEventListener('resize', () => { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| }); | |
| return { scene, camera, renderer, controls }; | |
| } | |