118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
import * as Three from 'three';
|
|
import { RESOLUTION_X, RESOLUTION_Y } from '../consts';
|
|
import Stats from 'stats.js';
|
|
import { Point } from '../physics/common';
|
|
import Selector from './selector.class';
|
|
import Asset from '../assets/asset.class';
|
|
|
|
export enum CursorType
|
|
{
|
|
default = "default",
|
|
pointer = "pointer",
|
|
move = "move",
|
|
updown = "ns-resize",
|
|
leftright = "ew-resize",
|
|
nesw = "nesw-resize",
|
|
nwse = "nwse-resize",
|
|
//rotate = "url(public/rotate.png)"
|
|
rotate = "crosshair" //tmp
|
|
}
|
|
export default class Renderer
|
|
{
|
|
static scene: Three.Scene;
|
|
static aspect: number;
|
|
|
|
static renderer: Three.WebGLRenderer;
|
|
static camera: Three.OrthographicCamera;
|
|
|
|
static #zoom: number;
|
|
static #pos: Point = { x: 0, y: 0 };
|
|
|
|
static #stats: Stats;
|
|
static init(): Boolean
|
|
{
|
|
try {
|
|
this.renderer = new Three.WebGLRenderer({ antialias: true });
|
|
this.renderer.setPixelRatio( window.devicePixelRatio );
|
|
document.body.appendChild(this.renderer.domElement);
|
|
|
|
this.scene = new Three.Scene();
|
|
this.camera = new Three.OrthographicCamera();
|
|
this.camera.position.z = 500;
|
|
|
|
this.#zoom = 5;
|
|
|
|
const stats = this.#stats = new Stats();
|
|
stats.showPanel(0);
|
|
document.body.appendChild(stats.dom);
|
|
|
|
this.#resize();
|
|
window.addEventListener("resize", this.#resize.bind(this));
|
|
|
|
return true;
|
|
}
|
|
catch(e)
|
|
{
|
|
console.error(e);
|
|
return false;
|
|
}
|
|
}
|
|
static get canvas(): HTMLCanvasElement
|
|
{
|
|
return this.renderer.domElement;
|
|
}
|
|
static get zoom(): number
|
|
{
|
|
return this.#zoom;
|
|
}
|
|
static set zoom(v: number)
|
|
{
|
|
this.#zoom = v;
|
|
this.#resize();
|
|
}
|
|
static move(x: number, y: number): void
|
|
{
|
|
this.#pos.x += x;
|
|
this.#pos.y += y;
|
|
|
|
this.camera.position.x += x;
|
|
this.camera.position.y += y;
|
|
}
|
|
static screenSpaceToCameraSpace(x: number, y: number, omit: boolean = false): Point {
|
|
return { x: ((x / window.innerWidth - 0.5) * RESOLUTION_X * this.aspect) / this.#zoom + (omit ? 0 : this.#pos.x), y: (- (y / window.innerHeight - 0.5) * RESOLUTION_Y) / this.zoom + (omit ? 0 : this.#pos.y) };
|
|
}
|
|
static #resize(): void
|
|
{
|
|
const aspect = this.aspect = window.innerWidth / window.innerHeight;
|
|
this.renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
this.camera.left = RESOLUTION_X * aspect / - 2 / this.#zoom;
|
|
this.camera.right = RESOLUTION_X * aspect / 2 / this.#zoom;
|
|
this.camera.top = RESOLUTION_Y / 2 / this.#zoom;
|
|
this.camera.bottom = RESOLUTION_Y / - 2 / this.#zoom;
|
|
|
|
this.camera.updateProjectionMatrix();
|
|
|
|
this.render();
|
|
}
|
|
static render(delta?: number): void
|
|
{
|
|
this.#stats.begin();
|
|
Selector.update();
|
|
this.renderer.render(this.scene, this.camera);
|
|
Asset.quadtree.cleanup();
|
|
this.#stats.end();
|
|
}
|
|
static startRendering(): void
|
|
{
|
|
this.renderer.setAnimationLoop(Renderer.render.bind(Renderer));
|
|
}
|
|
static stopRendering(): void
|
|
{
|
|
this.renderer.setAnimationLoop(null);
|
|
}
|
|
static cursor(type?: CursorType): void
|
|
{
|
|
Renderer.canvas.style.setProperty("cursor", type ?? CursorType.default);
|
|
}
|
|
} |