import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/Addons.js'; import { OrbitControls } from 'three/examples/jsm/Addons.js'; import { MapControls } from 'three/addons/controls/MapControls.js'; import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; import { TransformControls } from 'three/addons/controls/TransformControls.js'; class GameEngine { async init(domNode) { const width = 1200, height = 800; const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10000); camera.position.set(1, 0, 1); const scene = new THREE.Scene(); // this.light = new THREE.AmbientLight( 0x404040, 0 ); // soft white light // scene.add( this.light ); function animate(time) { let delta = clock.getDelta(); mixer.update(delta); renderer.render(scene, camera); controls.update(); } const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: true }); renderer.setPixelRatio( window.devicePixelRatio ); // renderer.toneMapping = THREE.CineonToneMapping; // renderer.toneMappingExposure = 1.2; // renderer.shadowMap.enabled = true; // renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap renderer.outputEncoding = THREE.sRGBEncoding; const controls = new OrbitControls( camera, renderer.domElement ); //controls.enableZoom = true; //const controls = new MapControls( camera, renderer.domElement ); this.transformControls = new TransformControls( camera, renderer.domElement ); this.transformControls.addEventListener( 'dragging-changed', function ( event ) { controls.enabled = ! event.value; } ); // controls.enableDamping = true; // controls.screenSpacePanning = true; renderer.setSize(width, height); renderer.setAnimationLoop(animate); const mixer = new THREE.AnimationMixer(this.scene); const clock = new THREE.Clock(); this.clock = clock; this.renderer = renderer; this.scene = scene; this.loader = new GLTFLoader(); this.camera = camera; this.controls = controls; this.mixer = mixer; domNode.appendChild(renderer.domElement); let texture = await this.loadTexture('/static/textures/bck.webp'); // let bck = await this.loadTexture('/static/textures/bck.webp'); // bck.premultiplyAlpha = true; texture.mapping = THREE.EquirectangularReflectionMapping; // scene.background = bck; //new THREE.Color(0.7,0.7,0.7); scene.environment = texture; scene.background = new THREE.Color(1,1,1); console.log('GameEngine started') renderer.domElement.addEventListener('wheel', (event)=>{ camera.zoom -= event.deltaY / 1000; camera.zoom = Math.max(camera.zoom, .4); controls.rotateSpeed = 1 / camera.zoom; camera.updateProjectionMatrix(); }) } $ = THREE; async load(url, progress){ return new Promise((resolve, reject)=>{ this.loader.load(url, resolve, progress, reject) }) } async loadTexture(url, progress){ return new Promise((resolve, reject)=>{ new THREE.TextureLoader().load(url, texture=>{ //texture.encoding = THREE.sRGBEncoding; texture.colorSpace = THREE.SRGBColorSpace; resolve(texture) }, progress, reject) }) } async captureScreenshot(type = 'image/webp', quality = 80){ return new Promise((resolve, reject)=>{ this.renderer.domElement.toBlob(resolve, type, quality) }) } playAnimation(object, clip, play = true){ let action = this.mixer.clipAction(clip, object); if (play) action.play(); else action.stop(); } stop(){ this.renderer.setAnimationLoop(null); } } export {GameEngine}