phantasmal-world/src/rendering/Renderer.ts

90 lines
2.3 KiB
TypeScript
Raw Normal View History

import * as THREE from "three";
import {
2019-07-11 23:30:23 +08:00
Camera,
Color,
2019-07-11 23:30:23 +08:00
Group,
HemisphereLight,
MOUSE,
Scene,
2019-07-11 23:30:23 +08:00
Vector2,
Vector3,
WebGLRenderer,
} from "three";
import OrbitControlsCreator from "three-orbit-controls";
const OrbitControls = OrbitControlsCreator(THREE);
2019-07-11 23:30:23 +08:00
export class Renderer<C extends Camera> {
protected _debug = false;
get debug(): boolean {
return this._debug;
}
set debug(debug: boolean) {
this._debug = debug;
}
2019-07-18 01:37:48 +08:00
readonly camera: C;
readonly controls: any;
readonly scene = new Scene();
readonly light_holder = new Group();
private renderer = new WebGLRenderer({ antialias: true });
private render_scheduled = false;
private light = new HemisphereLight(0xffffff, 0x505050, 1.2);
2019-07-11 23:30:23 +08:00
constructor(camera: C) {
this.camera = camera;
2019-07-18 01:37:48 +08:00
this.controls = new OrbitControls(camera, this.dom_element);
this.controls.mouseButtons.ORBIT = MOUSE.RIGHT;
this.controls.mouseButtons.PAN = MOUSE.LEFT;
this.controls.addEventListener("change", this.schedule_render);
this.scene.background = new Color(0x181818);
this.light_holder.add(this.light);
this.scene.add(this.light_holder);
2019-07-18 01:37:48 +08:00
this.renderer.setPixelRatio(window.devicePixelRatio);
}
get dom_element(): HTMLElement {
return this.renderer.domElement;
}
2019-07-03 02:56:33 +08:00
set_size(width: number, height: number): void {
this.renderer.setSize(width, height);
2019-07-03 19:29:07 +08:00
this.schedule_render();
}
pointer_pos_to_device_coords(e: MouseEvent): Vector2 {
const coords = this.renderer.getSize(new Vector2());
2019-07-18 01:37:48 +08:00
coords.width = (e.offsetX / coords.width) * 2 - 1;
coords.height = (e.offsetY / coords.height) * -2 + 1;
return coords;
2019-07-18 01:37:48 +08:00
}
schedule_render = () => {
if (!this.render_scheduled) {
this.render_scheduled = true;
requestAnimationFrame(this.call_render);
}
};
2019-07-18 01:37:48 +08:00
reset_camera(position: Vector3, look_at: Vector3): void {
this.controls.reset();
this.camera.position.copy(position);
this.camera.lookAt(look_at);
}
2019-07-18 01:37:48 +08:00
protected render(): void {
this.renderer.render(this.scene, this.camera);
}
private call_render = () => {
this.render_scheduled = false;
this.render();
};
}