UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

123 lines (93 loc) 3.32 kB
import { AbstractLight } from "./AbstractLight.js"; import { aabb3_matrix4_project_by_corners } from "../../../../../core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js"; import { aabb3_build_corners } from "../../../../../core/geom/3d/aabb/aabb3_build_corners.js"; import { array_copy } from "../../../../../core/collection/array/array_copy.js"; import { mat4 } from "gl-matrix"; import Signal from "../../../../../core/events/signal/Signal.js"; const corners = []; export class Decal extends AbstractLight { constructor() { super(); /** * Transform matrix, initial volume is a unit cube * @type {number[]|Float32Array|mat4[]} */ this.transform = new Float32Array(16); this.transform_inverse = new Float32Array(16); this.uv = new Float32Array(4); this.color = new Float32Array(4); // initialize color to full white this.color.fill(1); /** * * @type {Sampler2D} */ this.texture_diffuse = null; /** * Order in which decal should be applied, higher priority decals will be drawn first * NOTE: not implemented yet * @type {number} */ this.draw_priority = 0; this.__signal_transfom_changed = new Signal(); } /** * * @param {number[]|Float32Array|ArrayLike<number>} m */ setTransform(m) { mat4.copy(this.transform, m); mat4.invert(this.transform_inverse, this.transform); this.__signal_transfom_changed.send0(); } handleUvPositionChange(x, y) { this.uv[0] = x; this.uv[1] = y; } handleUvSizeChange(x, y) { this.uv[2] = x; this.uv[3] = y; } compare(other) { if (other.isDecal) { const dDraw = this.draw_priority - other.draw_priority; if (dDraw !== 0) { return dDraw; } } return super.compare(other); } onDimensionChanged(f, thisArg) { this.__signal_transfom_changed.add(f, thisArg); } offDimensionChanged(f, thisArg) { this.__signal_transfom_changed.remove(f, thisArg); } getCenter(result) { // extract translation portion of the matrix result[0] = this.transform[12]; result[1] = this.transform[13]; result[2] = this.transform[14]; } getAABB(result) { aabb3_build_corners(corners, 0, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5); aabb3_matrix4_project_by_corners(result, corners, this.transform); } toArray(destination, address) { array_copy(this.transform_inverse, 0, destination, address, 16); // array_copy(this.transform , 0, destination, address, 16); array_copy(this.uv, 0, destination, address + 16, 4); // required for sorting // destination[address + 20] = this.draw_priority; // destination[address + 21] = this.id; // color array_copy(this.color, 0, destination, address + 20, 4); return 24; } } /** * @readonly * @type {boolean} */ Decal.prototype.isDecal = true; Decal.prototype.ENCODED_SLOT_COUNT = 24;