UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

289 lines (243 loc) • 5.8 kB
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";