the-world-engine
Version:
three.js based, unity like game engine for browser
169 lines (161 loc) • 5.68 kB
JavaScript
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);
}
}
}