UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

169 lines (161 loc) 5.68 kB
import { Matrix4, Object3D, Quaternion, Vector3 } from "three/src/Three"; export class CSS3DObject extends Object3D { isCSS3DObject=true; element; constructor(t = document.createElement("div")) { super(); this.element = t; this.element.style.position = "absolute"; this.element.style.pointerEvents = "auto"; this.element.style.userSelect = "none"; this.element.setAttribute("draggable", "false"); this.addEventListener("removed", (() => { this.traverse((t => { if (t instanceof CSS3DObject) { if (t.element instanceof Element && t.element.parentNode !== null) { t.element.parentNode.removeChild(t.element); } } })); })); } copy(t, e) { super.copy(t, e); this.element = t.element.cloneNode(true); return this; } } export class CSS3DSprite extends CSS3DObject { isCSS3DSprite=true; rotation2D; constructor(t) { super(t); this.rotation2D = 0; } copy(t, e) { super.copy(t, e); this.rotation2D = t.rotation2D; return this; } } const tempPosition = new Vector3; const tempQuaternion = new Quaternion; const tempScale = new Vector3; const tempMatrix = new Matrix4; const tempMatrix2 = new Matrix4; export class CSS3DRenderer { domElement; Qe=0; Ve=0; ze=0; Re=0; Ze={ camera: { fov: 0, style: "" }, objects: new WeakMap }; Ae; constructor() { const t = document.createElement("div"); t.style.overflow = "hidden"; this.domElement = t; this.Ae = document.createElement("div"); this.Ae.style.transformStyle = "preserve-3d"; this.Ae.style.pointerEvents = "none"; this.domElement.appendChild(this.Ae); } getSize() { return { width: this.Qe, height: this.Ve }; } render(t, e) { const i = e.projectionMatrix.elements[5] * this.Re; if (this.Ze.camera.fov !== i) { this.domElement.style.perspective = e.isPerspectiveCamera ? i + "px" : ""; this.Ze.camera.fov = i; } if (t.matrixAutoUpdate === true) t.updateMatrixWorld(); if (e.parent === null) e.updateMatrixWorld(); let s, r; if (e.isOrthographicCamera) { s = -(e.right + e.left) / 2; r = (e.top + e.bottom) / 2; } else { s = 1; r = 1; } const n = e.isOrthographicCamera ? "scale(" + i + ")" + "translate(" + this.Be(s) + "px," + this.Be(r) + "px)" + this.Ge(e.matrixWorldInverse) : "translateZ(" + i + "px)" + this.Ge(e.matrixWorldInverse); const a = n + "translate(" + this.ze + "px," + this.Re + "px)"; if (this.Ze.camera.style !== a) { this.Ae.style.transform = a; this.Ze.camera.style = a; } this.Je(t, t, e, n); } setSize(t, e) { this.Qe = t; this.Ve = e; this.ze = this.Qe / 2; this.Re = this.Ve / 2; this.domElement.style.width = t + "px"; this.domElement.style.height = e + "px"; this.Ae.style.width = t + "px"; this.Ae.style.height = e + "px"; } Be(t) { return Math.abs(t) < 1e-10 ? 0 : t; } Ge(t) { const e = t.elements; const i = this.Be; return "matrix3d(" + i(e[0]) + "," + i(-e[1]) + "," + i(e[2]) + "," + i(e[3]) + "," + i(e[4]) + "," + i(-e[5]) + "," + i(e[6]) + "," + i(e[7]) + "," + i(e[8]) + "," + i(-e[9]) + "," + i(e[10]) + "," + i(e[11]) + "," + i(e[12]) + "," + i(-e[13]) + "," + i(e[14]) + "," + i(e[15]) + ")"; } Ne(t) { const e = t.elements; const i = this.Be; const s = "matrix3d(" + i(e[0]) + "," + i(e[1]) + "," + i(e[2]) + "," + i(e[3]) + "," + i(-e[4]) + "," + i(-e[5]) + "," + i(-e[6]) + "," + i(-e[7]) + "," + i(e[8]) + "," + i(e[9]) + "," + i(e[10]) + "," + i(e[11]) + "," + i(e[12]) + "," + i(e[13]) + "," + i(e[14]) + "," + i(e[15]) + ")"; return "translate(-50%,-50%)" + s; } Je(t, e, i, s) { if (t.isCSS3DObject) { t.onBeforeRender(this, e, i); let s; if (t.isCSS3DSprite) { tempMatrix.copy(i.matrixWorldInverse); tempMatrix.transpose(); if (t.rotation2D !== 0) tempMatrix.multiply(tempMatrix2.makeRotationZ(t.rotation2D)); t.matrixWorld.decompose(tempPosition, tempQuaternion, tempScale); tempMatrix.setPosition(tempPosition); tempMatrix.scale(tempScale); tempMatrix.elements[3] = 0; tempMatrix.elements[7] = 0; tempMatrix.elements[11] = 0; tempMatrix.elements[15] = 1; s = this.Ne(tempMatrix); } else { s = this.Ne(t.matrixWorld); } const r = t.element; const n = this.Ze.objects.get(t); if (n === undefined || n.style !== s) { r.style.transform = s; const e = { style: s }; this.Ze.objects.set(t, e); } r.style.display = t.visible ? "" : "none"; if (r.parentNode !== this.Ae) { this.Ae.appendChild(r); } t.onAfterRender(this, e, i); } for (let r = 0, n = t.children.length; r < n; ++r) { this.Je(t.children[r], e, i, s); } } }