@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
123 lines (93 loc) • 3.32 kB
JavaScript
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;