@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
289 lines (243 loc) • 5.8 kB
JavaScript
import { AABB3 } from "../../../../../core/geom/3d/aabb/AABB3.js";
import { computeStringHash } from "../../../../../core/primitives/strings/computeStringHash.js";
import { entity_node_compute_bounding_box } from "../../../../ecs/parent/entity_node_compute_bounding_box.js";
import { ShadedGeometry } from "../ShadedGeometry.js";
export const SGMeshFlags = {
CastShadow: 1,
ReceiveShadow: 2,
Loaded: 4
};
/**
* @readonly
* @type {number}
*/
const DEFAULT_FLAGS = SGMeshFlags.CastShadow
| SGMeshFlags.ReceiveShadow
;
export class SGMesh {
/**
* Allows settings a new material to all parts of the mesh
* @type {Material|null}
*/
#material_override = null;
/**
*
* @type {number}
*/
flags = DEFAULT_FLAGS;
/**
*
* @type {string|null}
*/
__url = null;
/**
*
* @type {EntityNode|null}
* @private
*/
__node = null;
/**
*
* @type {AABB3}
* @private
*/
__initial_bounds = new AABB3();
/**
* Contents are generated by the system
* Do not modify contents unless you know exactly what you're doing
* @returns {EntityNode|null}
*/
get node() {
return this.__node;
}
/**
*
* @param {SGMesh} other
* @returns {boolean}
*/
equals(other) {
if (other === undefined || other === null) {
return false;
}
return this.__url === other.__url
&& this.flags === other.flags
&& this.materialOverride === other.materialOverride;
}
hash() {
return computeStringHash(this.__url);
}
/**
*
* @param {SGMesh} other
*/
copy(other) {
this.__url = other.__url;
this.__node = null;
this.__initial_bounds.copy(other.__initial_bounds);
this.#material_override = other.#material_override;
}
/**
*
* @returns {SGMesh}
*/
clone() {
const r = new SGMesh();
r.copy(this);
return r;
}
/**
*
* @param {Material} v
*/
set materialOverride(v) {
if (v === this.#material_override) {
return;
}
if (v === null) {
throw new Error(`Once material override is set it can not be cleared, create a new SGMesh instance if you would like to clear override`);
}
this.#material_override = v;
this.applyMaterialOverride();
}
get materialOverride() {
return this.#material_override;
}
applyMaterialOverride() {
if (this.__node === null) {
return;
}
this.__node.traverse(node => {
const sg = node.entity.getComponent(ShadedGeometry);
if (sg !== null) {
sg.material = this.#material_override;
}
});
}
/**
*
* @returns {string|null}
*/
get url() {
return this.__url;
}
/**
*
* @param {string|null} v
*/
set url(v) {
if (v === this.__url) {
// no change
return;
}
this.__url = v;
}
/**
*
* @param {AABB3} destination
* @returns {boolean}
*/
getBoundingBox(destination) {
if (this.__node === null) {
return false;
}
entity_node_compute_bounding_box(destination, this.__node);
return true;
}
/**
*
* @param {AABB3} destination
*/
getUntransformedBoundingBox(destination) {
destination.copy(this.__initial_bounds);
}
/**
*
* @param {number|SGMeshFlags} flag
* @returns {void}
*/
setFlag(flag) {
this.flags |= flag;
}
/**
*
* @param {number|SGMeshFlags} flag
* @returns {void}
*/
clearFlag(flag) {
this.flags &= ~flag;
}
/**
*
* @param {number|SGMeshFlags} flag
* @param {boolean} value
*/
writeFlag(flag, value) {
if (value) {
this.setFlag(flag);
} else {
this.clearFlag(flag);
}
}
/**
*
* @param {number|SGMeshFlags} flag
* @returns {boolean}
*/
getFlag(flag) {
return (this.flags & flag) === flag;
}
/**
*
* @return {boolean}
*/
get castShadow() {
return this.getFlag(SGMeshFlags.CastShadow);
}
/**
*
* @param {boolean} v
*/
set castShadow(v) {
this.writeFlag(SGMeshFlags.CastShadow, v);
}
/**
*
* @return {boolean}
*/
get receiveShadow() {
return this.getFlag(SGMeshFlags.ReceiveShadow);
}
/**
*
* @param {boolean} v
*/
set receiveShadow(v) {
this.writeFlag(SGMeshFlags.ReceiveShadow, v);
}
/**
*
* @param {string} url
* @returns {SGMesh}
*/
static fromURL(url) {
const r = new SGMesh();
r.url = url;
r.castShadow = true;
r.receiveShadow = true;
return r;
}
toJSON() {
return {
url: this.__url,
receiveShadow: this.receiveShadow,
castShadow: this.castShadow,
};
}
fromJSON({ url, receiveShadow = true, castShadow = true }) {
this.clearFlag(SGMeshFlags.Loaded);
this.__url = url;
this.receiveShadow = receiveShadow;
this.castShadow = castShadow;
}
}
SGMesh.typeName = "SGMesh";