UNPKG

@megavr/ecsy-babylon

Version:

babylon.js ecsy binding and helpers

82 lines (73 loc) 3.56 kB
import * as BABYLON from "@babylonjs/core"; import { Entity, System } from "ecsy"; import { Mesh, MeshTypes } from "../components/index"; import { getScene, getAssetManager } from "../utils/gameUtils"; import { updateObjectsTransform, updateObjectValue } from "../utils/objectUtils"; import { disposeObject } from "../utils/objectUtils"; /** System for Mesh component */ export class MeshSystem extends System { /** @hidden */ static queries = { mesh: { components: [Mesh], listen: { added: true, removed: true, changed: [Mesh] } }, }; /** @hidden */ queries: any; /** @hidden */ execute() { this.queries.mesh.added.forEach((entity: Entity) => { this._updateMesh(entity, entity.getComponent(Mesh)); }); this.queries.mesh.changed.forEach((entity: Entity) => { disposeObject(entity.getComponent(Mesh)); this._updateMesh(entity, entity.getComponent(Mesh)); }); this.queries.mesh.removed.forEach((entity: Entity) => { disposeObject(entity.getComponent(Mesh)); }); } private _updateMesh(entity: Entity, mesh: Mesh) { switch (mesh.type) { case MeshTypes.Url: mesh.url && BABYLON.SceneLoader.IsPluginForExtensionAvailable(this._fileExt(mesh.url)) ? this._loadUrlMesh(entity, mesh, mesh.url) : this._unsupportedMesh(entity, mesh); break; default: mesh.object = (BABYLON.MeshBuilder as any)[`Create${mesh.type!}`].call(this, mesh.type!, mesh.options ? mesh.options : {}, getScene(this, mesh.scene)); this._updateMeshValue(mesh); updateObjectsTransform(entity); break; } } private _fileExt(url: String): string { return url.substring(url.lastIndexOf("."), url.length); } private _loadUrlMesh(entity: Entity, mesh: Mesh, url: String) { let assetManager = getAssetManager(this, mesh.scene); let filenameIndex = url.lastIndexOf("/") + 1; let task = assetManager.addMeshTask(mesh.type!, "", url.substring(0, filenameIndex), url.substring(filenameIndex, url.length)); task.onSuccess = (task) => { mesh.object = task.loadedMeshes[0] as BABYLON.Mesh; this._updateMeshValue(mesh); updateObjectsTransform(entity); } task.onError = () => { this._unsupportedMesh(entity, mesh); } assetManager.load(); assetManager.reset(); } private _updateMeshValue(mesh: Mesh) { for (let prop in mesh) { updateObjectValue(mesh, prop); } } private _unsupportedMesh(entity: Entity, mesh: Mesh) { let scene = getScene(this, mesh.scene); mesh.object = BABYLON.MeshBuilder.CreatePlane("", {}, scene); let material = new BABYLON.StandardMaterial("", scene); const errorData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAgMAAADXB5lNAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURSgoKCgoKCgoKO88OVVpm6AAAAACdFJOU/LlgHlY8AAAAP9JREFUOMvN1MFtwzAMBVB3nU7RcQsSKDcI96EPvrPAZ0nZkRUZKXKMb36xPr+UxMvX8nB9LDRdy+fj/ff7gES4bKYUBPYDdLOQcEgDY1cx6AqIjUADQFYvUNohkAFBEbFP+Y1MRAPboU1JOKdUj8rgp1BLWo+jaQutQUdotDuqMS+eRxblzM8F3kHDkIAD8kNxcBbukCuidmADaILcITOheST/g2wDVIYEX+Gckj2q7NkjmyYMTRlU4K/+HJQNEWttGDtIwZZffgcH8rkJgtFBC2h44oYCHeCWoRztUBugQP0E15pCP32JyzT2AiZT0zyL2gvd4T3+YpeXwfy6+ANZO9QlB5svlAAAAABJRU5ErkJggg=="; // BABYLON.Texture.BILINEAR_SAMPLINGMODE = 2 material.diffuseTexture = new BABYLON.Texture("data:errorData", scene, false, false, 2, null, null, errorData, true); mesh.object.material = material; updateObjectsTransform(entity); } }