111 lines
4.1 KiB
JavaScript
111 lines
4.1 KiB
JavaScript
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;
|
|
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} |