babyeditor-tool 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/babyeditor.tool.cjs.js +1 -1
- package/dist/babyeditor.tool.cjs.js.map +1 -1
- package/dist/babyeditor.tool.es.js +49 -3
- package/dist/babyeditor.tool.es.js.map +1 -1
- package/dist/babyeditor.tool.umd.js +1 -1
- package/dist/babyeditor.tool.umd.js.map +1 -1
- package/package.json +1 -1
- package/types/CustomSystem.d.ts +8 -0
- package/types/CustomSystem.d.ts.map +1 -0
- package/types/CustomSystem.js +35 -0
- package/types/SceneLoader.d.ts +4 -0
- package/types/SceneLoader.d.ts.map +1 -1
- package/types/SceneLoader.js +6 -0
- package/types/interfaces/MetaData.interface.d.ts +43 -0
- package/types/interfaces/MetaData.interface.d.ts.map +1 -0
- package/types/interfaces/MetaData.interface.js +1 -0
- package/types/interfaces/SceneData.interface.d.ts +70 -0
- package/types/interfaces/SceneData.interface.d.ts.map +1 -0
- package/types/interfaces/SceneData.interface.js +1 -0
- package/types/tool/CustomSystem.d.ts +10 -0
- package/types/tool/CustomSystem.d.ts.map +1 -0
- package/types/tool/CustomSystem.js +42 -0
- package/types/tool/SceneLoader.d.ts +131 -0
- package/types/tool/SceneLoader.d.ts.map +1 -0
- package/types/tool/SceneLoader.js +165 -0
- package/types/tool/index.d.ts +2 -0
- package/types/tool/index.d.ts.map +1 -0
- package/types/tool/index.js +1 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@babylonjs/core");require("@babylonjs/materials"),require("@babylonjs/loaders"),require("@babylonjs/post-processes"),require("@babylonjs/procedural-textures");const s=require("@babylonjs/havok");
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@babylonjs/core");require("@babylonjs/materials"),require("@babylonjs/loaders"),require("@babylonjs/post-processes"),require("@babylonjs/procedural-textures");const s=require("@babylonjs/havok");class t{constructor(e,s=[]){this.scene=e,this.scriptInstanceList=s,this.load()}load(){const e=this.scene.transformNodes;for(let s=0;s<e.length;s++){const n=e[s];if(n.metadata){const e=n.metadata;"assetModel"===e.meshBuilderType&&e.assetModelBuilderOptions?.url&&t.LoadAssetModel(n,e.assetModelBuilderOptions.url,this.scene).then(()=>{const e=this.scriptInstanceList.find(e=>e.node===n);e&&"function"==typeof e.ready&&e.ready()})}}}static async LoadAssetModel(s,t,n){const i=t=>{t instanceof e.Node&&!t.parent&&(t.parent=s),t instanceof e.Mesh&&t.material&&(t.material.doNotSerialize=!0),t.doNotSerialize=!0},{meshes:a,transformNodes:c,lights:r,skeletons:o}=await e.ImportMeshAsync(t,n);a.forEach(e=>i(e)),c.forEach(e=>i(e)),r.forEach(e=>i(e)),o.forEach(e=>i(e))}}var n=Object.defineProperty,i=(e,s,t)=>((e,s,t)=>s in e?n(e,s,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[s]=t)(e,"symbol"!=typeof s?s+"":s,t);class a{constructor(s,t,n){i(this,"container"),i(this,"canvas"),i(this,"engine"),i(this,"scene"),i(this,"sceneData",""),i(this,"scriptsMap",{}),i(this,"scriptInstanceList",[]),this.container=s,this.canvas=document.createElement("canvas"),this.canvas.className="main-display-canvas",this.canvas.width=s.clientWidth,this.canvas.height=s.clientHeight,this.container.appendChild(this.canvas),this.engine=new e.Engine(this.canvas,!0),this.scene=new e.Scene(this.engine),this.load(t,n)}async load(n,i){this.scene&&this.scene.dispose(),i&&(this.scriptsMap=i),this.scene=new e.Scene(this.engine),this.sceneData=n,this.scriptInstanceList=[],this.scene.onBeforeRenderObservable.add(()=>{if(this.scriptInstanceList){const e=this.engine.getDeltaTime();for(let s=0;s<this.scriptInstanceList.length;s++){const t=this.scriptInstanceList[s];t.update&&t.update(e)}}});const a=await s();let c;this.scene.enablePhysics(new e.Vector3(0,-9.81,0),new e.HavokPlugin(!0,a)),await e.AppendSceneAsync("data:"+n,this.scene),c=0===this.scene.cameras.length?new e.FreeCamera("摄影机",new e.Vector3(50,50,50),this.scene,!0):this.scene.activeCamera||this.scene.cameras[0],c.attachControl(this.canvas),i&&this.initScripts(i),new t(this.scene,this.scriptInstanceList),this.render()}initScripts(e){if(!e)return;if(this.scene.metadata){const s=this.scene.metadata.scripts;s&&s.length>0&&this.runScript(this.scene,e,s)}const s=this.scene.getNodes();for(let t=0;t<s.length;t++){const n=s[t];n.metadata?.scripts&&n.metadata.scripts.length>0&&this.runScript(n,e,n.metadata.scripts)}}runScript(e,s,t){if(t)for(let n=0;n<t.length;n++){const i=t[n];for(const t in s)if(Object.prototype.hasOwnProperty.call(s,t)&&t===i.key&&!0!==i.disabled){let t=s[i.key];if(t instanceof Function){const s=new t(this.scene,e,i.values||{});if(s.start&&s.start(),s.dispose&&e.onDisposeObservable){const t=s.dispose;e.onDisposeObservable.addOnce(t.bind(s))}this.scriptInstanceList.push(s)}}}}render(){let e=this.scene;this.engine.runRenderLoop(()=>{e.render()})}resize(){this.engine.resize()}dispose(){this.scene.dispose(),this.engine.dispose()}static LoadCustomSystem(){}}exports.SceneLoader=a,exports.loadScene=function(e,s,t={}){return new a(e,s,t)};
|
|
2
2
|
//# sourceMappingURL=babyeditor.tool.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babyeditor.tool.cjs.js","sources":["../../src/tool/SceneLoader.ts"],"sourcesContent":["import { Engine, Scene, Nullable, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync, AbstractMesh, Camera, Node, TransformNode } from \"@babylonjs/core\";\r\nimport '@babylonjs/materials'\r\nimport '@babylonjs/loaders'\r\nimport '@babylonjs/post-processes'\r\nimport '@babylonjs/procedural-textures'\r\nimport HavokPhysics from \"@babylonjs/havok\";\r\n\r\n/**\r\n * 脚本接口\r\n */\r\nexport interface ScriptsMap {\r\n [index: string]: IScript | Function;\r\n}\r\n\r\n/**\r\n * 字符串字典\r\n */\r\nexport interface IStringDictionary<T> {\r\n [index: string]: T;\r\n}\r\n\r\n/**\r\n * 行为脚本接口\r\n */\r\nexport interface BehaviorScript {\r\n // 脚本类型\r\n type: 'script',\r\n // 是否启用脚本\r\n disabled: boolean,\r\n // 是否从资源中找不到对应的文件\r\n isLoss?: boolean,\r\n // 脚本标识key, 对应脚本资源的的请求路径\r\n key: string,\r\n // 脚本参数\r\n values: IStringDictionary<any>\r\n}\r\n\r\n/**\r\n * 运行场景加载的核心类\r\n * @description 在这里创建初始化场景所需要的一切的东西\r\n */\r\nexport class SceneLoader {\r\n /**\r\n * 场景容器\r\n */\r\n container: HTMLElement\r\n /**\r\n * 画布\r\n */\r\n canvas: HTMLCanvasElement\r\n /**\r\n * 引擎\r\n */\r\n engine: Engine\r\n /**\r\n * 场景\r\n */\r\n scene: Scene\r\n /**\r\n * 场景数据\r\n */\r\n sceneData: string = ''\r\n /**\r\n * 脚本代码列表\r\n */\r\n scritpsMap: ScriptsMap = {}\r\n /**\r\n * 脚本实例列表\r\n */\r\n private scriptInstanceList: IScript[] = []\r\n /**\r\n * 构造函数\r\n * @param container 容器\r\n * @param sceneData 场景数据\r\n * @param scriptsMap 脚本代码列表\r\n */\r\n constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap) {\r\n this.container = container\r\n this.canvas = document.createElement('canvas')\r\n this.canvas.className = 'main-display-canvas'\r\n this.canvas.width = container.clientWidth\r\n this.canvas.height = container.clientHeight\r\n this.container.appendChild(this.canvas)\r\n this.engine = new Engine(this.canvas, true)\r\n this.scene = new Scene(this.engine)\r\n\r\n this.load(sceneData, scriptsMap)\r\n }\r\n\r\n /**\r\n * 加载场景\r\n * @param sceneData 场景数据数据\r\n * @param scriptsMap 代码脚本地图\r\n */\r\n async load (sceneData: string, scriptsMap?: ScriptsMap) {\r\n if (this.scene) {\r\n this.scene.dispose()\r\n }\r\n if (scriptsMap) this.scritpsMap = scriptsMap\r\n this.scene = new Scene(this.engine)\r\n this.sceneData = sceneData\r\n this.scriptInstanceList = []\r\n\r\n // 执行更新代码\r\n this.scene.onBeforeRenderObservable.add(() => {\r\n if (this.scriptInstanceList) {\r\n const deltaTime = this.engine.getDeltaTime()\r\n for (let i = 0; i < this.scriptInstanceList.length; i++) {\r\n const script = this.scriptInstanceList[i];\r\n if (script.update) {\r\n script.update(deltaTime)\r\n }\r\n }\r\n }\r\n })\r\n\r\n const havokModule = await HavokPhysics()\r\n this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));\r\n\r\n await AppendSceneAsync('data:' + sceneData, this.scene)\r\n let camera\r\n if (this.scene.cameras.length === 0) {\r\n camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true)\r\n console.log('场景中无摄影机,自动创建摄影机')\r\n } else {\r\n camera = this.scene.activeCamera || this.scene.cameras[0]\r\n console.log('解析并使用场景摄影机')\r\n }\r\n camera.attachControl(this.canvas)\r\n\r\n if (scriptsMap) this.initScripts(scriptsMap)\r\n console.log('完成场景初始化')\r\n\r\n this.render()\r\n }\r\n\r\n /**\r\n * 初始化脚本\r\n */\r\n private initScripts(scriptsMap: ScriptsMap) {\r\n if (!scriptsMap) return\r\n\r\n if (this.scene.metadata) {\r\n const scriptList = this.scene.metadata.scripts as BehaviorScript[]\r\n if (scriptList && scriptList.length > 0) {\r\n this.runScript(this.scene, scriptsMap, scriptList)\r\n }\r\n }\r\n\r\n const nodes = this.scene.getNodes()\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n\r\n if (node.metadata?.scripts && node.metadata.scripts.length > 0) {\r\n this.runScript(node, scriptsMap, node.metadata.scripts)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 执行代码\r\n * @param node 代码绑定对象\r\n * @param scriptsMap 注入的全部脚本\r\n * @param scriptList 对象绑定的代码列表\r\n * @returns \r\n */\r\n private runScript (node: Scene | Node, scriptsMap: ScriptsMap, scriptList?: BehaviorScript[]) {\r\n if (!scriptList) return\r\n for (let i = 0; i < scriptList.length; i++) {\r\n const script: BehaviorScript = scriptList[i];\r\n\r\n for (const key in scriptsMap) {\r\n if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {\r\n if (key === script.key && script.disabled !== true) {\r\n let constructor: any = scriptsMap[script.key]\r\n\r\n if (constructor instanceof Function) {\r\n const instance = new (constructor)(this.scene, node, script.values || {})\r\n\r\n if (instance.start) instance.start()\r\n\r\n if (instance.dispose && node.onDisposeObservable) {\r\n const callback: any = instance.dispose\r\n node.onDisposeObservable.addOnce(callback.bind(instance))\r\n }\r\n\r\n this.scriptInstanceList.push(instance)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 开始渲染循环\r\n */\r\n private render() {\r\n let scene = this.scene\r\n this.engine.runRenderLoop(() => {\r\n scene.render()\r\n })\r\n }\r\n\r\n /**\r\n * 重置canvas变形后的系统尺寸\r\n */\r\n resize() {\r\n this.engine.resize()\r\n }\r\n\r\n dispose() {\r\n this.scene.dispose()\r\n this.engine.dispose()\r\n }\r\n}\r\n\r\nexport function loadScene (container: HTMLDivElement, sceneData: string, scriptsMap: ScriptsMap = {}) {\r\n const sceneLoader = new SceneLoader(container, sceneData, scriptsMap)\r\n\r\n return sceneLoader\r\n}\r\n\r\nexport type IScript = {\r\n start?: () => void,\r\n update?: (deltaTime: number) => void,\r\n dispose?: () => void,\r\n}\r\n"],"names":["SceneLoader","constructor","container","sceneData","scriptsMap","__publicField","this","canvas","document","createElement","className","width","clientWidth","height","clientHeight","appendChild","engine","Engine","scene","Scene","load","dispose","scritpsMap","scriptInstanceList","onBeforeRenderObservable","add","deltaTime","getDeltaTime","i","length","script","update","havokModule","HavokPhysics","camera","enablePhysics","Vector3","HavokPlugin","AppendSceneAsync","cameras","FreeCamera","activeCamera","attachControl","initScripts","render","metadata","scriptList","scripts","runScript","nodes","getNodes","node","key","Object","prototype","hasOwnProperty","call","disabled","Function","instance","values","start","onDisposeObservable","callback","addOnce","bind","push","runRenderLoop","resize"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"babyeditor.tool.cjs.js","sources":["../../src/tool/CustomSystem.ts","../../src/tool/SceneLoader.ts"],"sourcesContent":["import { MetaData } from \"../interfaces/MetaData.interface\";\r\nimport { ImportMeshAsync, Scene, TransformNode, Node, Skeleton, AnimationGroup, Mesh } from \"@babylonjs/core\";\r\nimport { IScript } from \"./SceneLoader\";\r\n\r\nexport class CustomSystem {\r\n constructor (public scene: Scene, private scriptInstanceList: IScript[] = []) {\r\n this.load()\r\n }\r\n\r\n load () {\r\n const transNodes = this.scene.transformNodes\r\n\r\n for (let i = 0; i < transNodes.length; i++) {\r\n const transNode = transNodes[i];\r\n if (transNode.metadata) {\r\n const metaData: MetaData = transNode.metadata\r\n // 当对象是外部资源模型时\r\n if (metaData.meshBuilderType === 'assetModel' && metaData.assetModelBuilderOptions?.url) {\r\n CustomSystem.LoadAssetModel(transNode, metaData.assetModelBuilderOptions.url, this.scene).then(() => {\r\n const findInstance = this.scriptInstanceList.find(instance => instance.node === transNode)\r\n if (findInstance && typeof findInstance.ready === 'function') {\r\n findInstance.ready()\r\n }\r\n })\r\n }\r\n }\r\n }\r\n }\r\n\r\n static async LoadAssetModel (parentNode: TransformNode, url: string, scene: Scene) {\r\n const applyMetaData = (node: Node | Skeleton) => {\r\n if (node instanceof Node && !node.parent) {\r\n node.parent = parentNode\r\n }\r\n if (node instanceof Mesh && node.material) {\r\n node.material.doNotSerialize = true\r\n }\r\n node.doNotSerialize = true\r\n }\r\n const { meshes, transformNodes, lights, skeletons } = await ImportMeshAsync(url, scene)\r\n meshes.forEach(node => applyMetaData(node))\r\n transformNodes.forEach(node => applyMetaData(node))\r\n lights.forEach(node => applyMetaData(node))\r\n skeletons.forEach(node => applyMetaData(node)) \r\n }\r\n}","import { Engine, Scene, Nullable, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync, AbstractMesh, Camera, Node, TransformNode } from \"@babylonjs/core\";\r\nimport '@babylonjs/materials'\r\nimport '@babylonjs/loaders'\r\nimport '@babylonjs/post-processes'\r\nimport '@babylonjs/procedural-textures'\r\nimport HavokPhysics from \"@babylonjs/havok\";\r\nimport { CustomSystem } from \"./CustomSystem\";\r\n\r\n/**\r\n * 脚本接口\r\n */\r\nexport interface ScriptsMap {\r\n [index: string]: IScript | Function;\r\n}\r\n\r\n/**\r\n * 字符串字典\r\n */\r\nexport interface IStringDictionary<T> {\r\n [index: string]: T;\r\n}\r\n\r\n/**\r\n * 行为脚本接口\r\n */\r\nexport interface BehaviorScript {\r\n // 脚本类型\r\n type: 'script',\r\n // 是否启用脚本\r\n disabled: boolean,\r\n // 是否从资源中找不到对应的文件\r\n isLoss?: boolean,\r\n // 脚本标识key, 对应脚本资源的的请求路径\r\n key: string,\r\n // 脚本参数\r\n values: IStringDictionary<any>\r\n}\r\n\r\n/**\r\n * 运行场景加载的核心类\r\n * @description 在这里创建初始化场景所需要的一切的东西\r\n */\r\nexport class SceneLoader {\r\n /**\r\n * 场景容器\r\n */\r\n container: HTMLElement\r\n /**\r\n * 画布\r\n */\r\n canvas: HTMLCanvasElement\r\n /**\r\n * 引擎\r\n */\r\n engine: Engine\r\n /**\r\n * 场景\r\n */\r\n scene: Scene\r\n /**\r\n * 场景数据\r\n */\r\n sceneData: string = ''\r\n /**\r\n * 脚本代码列表\r\n */\r\n scriptsMap: ScriptsMap = {}\r\n /**\r\n * 脚本实例列表\r\n */\r\n private scriptInstanceList: IScript[] = []\r\n /**\r\n * 构造函数\r\n * @param container 容器\r\n * @param sceneData 场景数据\r\n * @param scriptsMap 脚本代码列表\r\n */\r\n constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap) {\r\n this.container = container\r\n this.canvas = document.createElement('canvas')\r\n this.canvas.className = 'main-display-canvas'\r\n this.canvas.width = container.clientWidth\r\n this.canvas.height = container.clientHeight\r\n this.container.appendChild(this.canvas)\r\n this.engine = new Engine(this.canvas, true)\r\n this.scene = new Scene(this.engine)\r\n\r\n this.load(sceneData, scriptsMap)\r\n }\r\n\r\n /**\r\n * 加载场景\r\n * @param sceneData 场景数据数据\r\n * @param scriptsMap 代码脚本地图\r\n */\r\n async load (sceneData: string, scriptsMap?: ScriptsMap) {\r\n if (this.scene) {\r\n this.scene.dispose()\r\n }\r\n if (scriptsMap) this.scriptsMap = scriptsMap\r\n this.scene = new Scene(this.engine)\r\n this.sceneData = sceneData\r\n this.scriptInstanceList = []\r\n\r\n // 执行更新代码\r\n this.scene.onBeforeRenderObservable.add(() => {\r\n if (this.scriptInstanceList) {\r\n const deltaTime = this.engine.getDeltaTime()\r\n for (let i = 0; i < this.scriptInstanceList.length; i++) {\r\n const script = this.scriptInstanceList[i];\r\n if (script.update) {\r\n script.update(deltaTime)\r\n }\r\n }\r\n }\r\n })\r\n\r\n const havokModule = await HavokPhysics()\r\n this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));\r\n\r\n await AppendSceneAsync('data:' + sceneData, this.scene)\r\n let camera\r\n if (this.scene.cameras.length === 0) {\r\n camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true)\r\n console.log('场景中无摄影机,自动创建摄影机')\r\n } else {\r\n camera = this.scene.activeCamera || this.scene.cameras[0]\r\n console.log('解析并使用场景摄影机')\r\n }\r\n camera.attachControl(this.canvas)\r\n\r\n if (scriptsMap) this.initScripts(scriptsMap)\r\n console.log('完成场景初始化')\r\n\r\n new CustomSystem(this.scene, this.scriptInstanceList)\r\n\r\n this.render()\r\n }\r\n\r\n /**\r\n * 初始化脚本\r\n */\r\n private initScripts(scriptsMap: ScriptsMap) {\r\n if (!scriptsMap) return\r\n\r\n if (this.scene.metadata) {\r\n const scriptList = this.scene.metadata.scripts as BehaviorScript[]\r\n if (scriptList && scriptList.length > 0) {\r\n this.runScript(this.scene, scriptsMap, scriptList)\r\n }\r\n }\r\n\r\n const nodes = this.scene.getNodes()\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n\r\n if (node.metadata?.scripts && node.metadata.scripts.length > 0) {\r\n this.runScript(node, scriptsMap, node.metadata.scripts)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 执行代码\r\n * @param node 代码绑定对象\r\n * @param scriptsMap 注入的全部脚本\r\n * @param scriptList 对象绑定的代码列表\r\n * @returns \r\n */\r\n private runScript (node: Scene | Node, scriptsMap: ScriptsMap, scriptList?: BehaviorScript[]) {\r\n if (!scriptList) return\r\n for (let i = 0; i < scriptList.length; i++) {\r\n const script: BehaviorScript = scriptList[i];\r\n\r\n for (const key in scriptsMap) {\r\n if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {\r\n if (key === script.key && script.disabled !== true) {\r\n let constructor: any = scriptsMap[script.key]\r\n\r\n if (constructor instanceof Function) {\r\n const instance = new (constructor)(this.scene, node, script.values || {})\r\n\r\n if (instance.start) instance.start()\r\n\r\n if (instance.dispose && node.onDisposeObservable) {\r\n const callback: any = instance.dispose\r\n node.onDisposeObservable.addOnce(callback.bind(instance))\r\n }\r\n\r\n this.scriptInstanceList.push(instance)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 开始渲染循环\r\n */\r\n private render() {\r\n let scene = this.scene\r\n this.engine.runRenderLoop(() => {\r\n scene.render()\r\n })\r\n }\r\n\r\n /**\r\n * 重置canvas变形后的系统尺寸\r\n */\r\n resize() {\r\n this.engine.resize()\r\n }\r\n\r\n dispose() {\r\n this.scene.dispose()\r\n this.engine.dispose()\r\n }\r\n\r\n /**\r\n * 加载自定义组件系统。比如天气系统,模型系统\r\n */\r\n static LoadCustomSystem () {}\r\n}\r\n\r\nexport function loadScene (container: HTMLDivElement, sceneData: string, scriptsMap: ScriptsMap = {}) {\r\n const sceneLoader = new SceneLoader(container, sceneData, scriptsMap)\r\n\r\n return sceneLoader\r\n}\r\n\r\n/**\r\n * 脚本代码结构\r\n */\r\nexport type IScript = {\r\n /**\r\n * 脚执行时注入的场景对象\r\n */\r\n scene: Scene,\r\n /**\r\n * 当前实例化脚本绑定的对象\r\n */\r\n node: Node | Scene,\r\n /**\r\n * 脚本初始化执行的钩子函数\r\n */\r\n start?: () => void,\r\n /**\r\n * 当有异步动作初始化完成时的钩子函数\r\n */\r\n ready?: () => void,\r\n /**\r\n * 当没帧渲染是执行函数\r\n * @param deltaTime 间隔时间\r\n */\r\n update?: (deltaTime: number) => void,\r\n /**\r\n * 当对象被销毁时执行的函数\r\n */\r\n dispose?: () => void,\r\n}\r\n"],"names":["CustomSystem","constructor","scene","scriptInstanceList","this","load","transNodes","transformNodes","i","length","transNode","metadata","metaData","meshBuilderType","assetModelBuilderOptions","url","LoadAssetModel","then","findInstance","find","instance","node","ready","parentNode","applyMetaData","Node","parent","Mesh","material","doNotSerialize","meshes","lights","skeletons","ImportMeshAsync","forEach","SceneLoader","container","sceneData","scriptsMap","__publicField","canvas","document","createElement","className","width","clientWidth","height","clientHeight","appendChild","engine","Engine","Scene","dispose","onBeforeRenderObservable","add","deltaTime","getDeltaTime","script","update","havokModule","HavokPhysics","camera","enablePhysics","Vector3","HavokPlugin","AppendSceneAsync","cameras","FreeCamera","activeCamera","attachControl","initScripts","render","scriptList","scripts","runScript","nodes","getNodes","key","Object","prototype","hasOwnProperty","call","disabled","Function","values","start","onDisposeObservable","callback","addOnce","bind","push","runRenderLoop","resize","LoadCustomSystem"],"mappings":"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"}
|
|
@@ -1,9 +1,49 @@
|
|
|
1
|
-
import { Engine, Scene, Vector3, HavokPlugin, AppendSceneAsync, FreeCamera } from "@babylonjs/core";
|
|
1
|
+
import { ImportMeshAsync, Node, Mesh, Engine, Scene, Vector3, HavokPlugin, AppendSceneAsync, FreeCamera } from "@babylonjs/core";
|
|
2
2
|
import "@babylonjs/materials";
|
|
3
3
|
import "@babylonjs/loaders";
|
|
4
4
|
import "@babylonjs/post-processes";
|
|
5
5
|
import "@babylonjs/procedural-textures";
|
|
6
6
|
import HavokPhysics from "@babylonjs/havok";
|
|
7
|
+
class CustomSystem {
|
|
8
|
+
constructor(scene, scriptInstanceList = []) {
|
|
9
|
+
this.scene = scene;
|
|
10
|
+
this.scriptInstanceList = scriptInstanceList;
|
|
11
|
+
this.load();
|
|
12
|
+
}
|
|
13
|
+
load() {
|
|
14
|
+
const transNodes = this.scene.transformNodes;
|
|
15
|
+
for (let i = 0; i < transNodes.length; i++) {
|
|
16
|
+
const transNode = transNodes[i];
|
|
17
|
+
if (transNode.metadata) {
|
|
18
|
+
const metaData = transNode.metadata;
|
|
19
|
+
if (metaData.meshBuilderType === "assetModel" && metaData.assetModelBuilderOptions?.url) {
|
|
20
|
+
CustomSystem.LoadAssetModel(transNode, metaData.assetModelBuilderOptions.url, this.scene).then(() => {
|
|
21
|
+
const findInstance = this.scriptInstanceList.find((instance) => instance.node === transNode);
|
|
22
|
+
if (findInstance && typeof findInstance.ready === "function") {
|
|
23
|
+
findInstance.ready();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
static async LoadAssetModel(parentNode, url, scene) {
|
|
31
|
+
const applyMetaData = (node) => {
|
|
32
|
+
if (node instanceof Node && !node.parent) {
|
|
33
|
+
node.parent = parentNode;
|
|
34
|
+
}
|
|
35
|
+
if (node instanceof Mesh && node.material) {
|
|
36
|
+
node.material.doNotSerialize = true;
|
|
37
|
+
}
|
|
38
|
+
node.doNotSerialize = true;
|
|
39
|
+
};
|
|
40
|
+
const { meshes, transformNodes, lights, skeletons } = await ImportMeshAsync(url, scene);
|
|
41
|
+
meshes.forEach((node) => applyMetaData(node));
|
|
42
|
+
transformNodes.forEach((node) => applyMetaData(node));
|
|
43
|
+
lights.forEach((node) => applyMetaData(node));
|
|
44
|
+
skeletons.forEach((node) => applyMetaData(node));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
7
47
|
var __defProp = Object.defineProperty;
|
|
8
48
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
49
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -20,7 +60,7 @@ class SceneLoader {
|
|
|
20
60
|
__publicField(this, "engine");
|
|
21
61
|
__publicField(this, "scene");
|
|
22
62
|
__publicField(this, "sceneData", "");
|
|
23
|
-
__publicField(this, "
|
|
63
|
+
__publicField(this, "scriptsMap", {});
|
|
24
64
|
__publicField(this, "scriptInstanceList", []);
|
|
25
65
|
this.container = container;
|
|
26
66
|
this.canvas = document.createElement("canvas");
|
|
@@ -41,7 +81,7 @@ class SceneLoader {
|
|
|
41
81
|
if (this.scene) {
|
|
42
82
|
this.scene.dispose();
|
|
43
83
|
}
|
|
44
|
-
if (scriptsMap) this.
|
|
84
|
+
if (scriptsMap) this.scriptsMap = scriptsMap;
|
|
45
85
|
this.scene = new Scene(this.engine);
|
|
46
86
|
this.sceneData = sceneData;
|
|
47
87
|
this.scriptInstanceList = [];
|
|
@@ -67,6 +107,7 @@ class SceneLoader {
|
|
|
67
107
|
}
|
|
68
108
|
camera.attachControl(this.canvas);
|
|
69
109
|
if (scriptsMap) this.initScripts(scriptsMap);
|
|
110
|
+
new CustomSystem(this.scene, this.scriptInstanceList);
|
|
70
111
|
this.render();
|
|
71
112
|
}
|
|
72
113
|
/**
|
|
@@ -136,6 +177,11 @@ class SceneLoader {
|
|
|
136
177
|
this.scene.dispose();
|
|
137
178
|
this.engine.dispose();
|
|
138
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* 加载自定义组件系统。比如天气系统,模型系统
|
|
182
|
+
*/
|
|
183
|
+
static LoadCustomSystem() {
|
|
184
|
+
}
|
|
139
185
|
}
|
|
140
186
|
function loadScene(container, sceneData, scriptsMap = {}) {
|
|
141
187
|
const sceneLoader = new SceneLoader(container, sceneData, scriptsMap);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babyeditor.tool.es.js","sources":["../../src/tool/SceneLoader.ts"],"sourcesContent":["import { Engine, Scene, Nullable, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync, AbstractMesh, Camera, Node, TransformNode } from \"@babylonjs/core\";\r\nimport '@babylonjs/materials'\r\nimport '@babylonjs/loaders'\r\nimport '@babylonjs/post-processes'\r\nimport '@babylonjs/procedural-textures'\r\nimport HavokPhysics from \"@babylonjs/havok\";\r\n\r\n/**\r\n * 脚本接口\r\n */\r\nexport interface ScriptsMap {\r\n [index: string]: IScript | Function;\r\n}\r\n\r\n/**\r\n * 字符串字典\r\n */\r\nexport interface IStringDictionary<T> {\r\n [index: string]: T;\r\n}\r\n\r\n/**\r\n * 行为脚本接口\r\n */\r\nexport interface BehaviorScript {\r\n // 脚本类型\r\n type: 'script',\r\n // 是否启用脚本\r\n disabled: boolean,\r\n // 是否从资源中找不到对应的文件\r\n isLoss?: boolean,\r\n // 脚本标识key, 对应脚本资源的的请求路径\r\n key: string,\r\n // 脚本参数\r\n values: IStringDictionary<any>\r\n}\r\n\r\n/**\r\n * 运行场景加载的核心类\r\n * @description 在这里创建初始化场景所需要的一切的东西\r\n */\r\nexport class SceneLoader {\r\n /**\r\n * 场景容器\r\n */\r\n container: HTMLElement\r\n /**\r\n * 画布\r\n */\r\n canvas: HTMLCanvasElement\r\n /**\r\n * 引擎\r\n */\r\n engine: Engine\r\n /**\r\n * 场景\r\n */\r\n scene: Scene\r\n /**\r\n * 场景数据\r\n */\r\n sceneData: string = ''\r\n /**\r\n * 脚本代码列表\r\n */\r\n scritpsMap: ScriptsMap = {}\r\n /**\r\n * 脚本实例列表\r\n */\r\n private scriptInstanceList: IScript[] = []\r\n /**\r\n * 构造函数\r\n * @param container 容器\r\n * @param sceneData 场景数据\r\n * @param scriptsMap 脚本代码列表\r\n */\r\n constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap) {\r\n this.container = container\r\n this.canvas = document.createElement('canvas')\r\n this.canvas.className = 'main-display-canvas'\r\n this.canvas.width = container.clientWidth\r\n this.canvas.height = container.clientHeight\r\n this.container.appendChild(this.canvas)\r\n this.engine = new Engine(this.canvas, true)\r\n this.scene = new Scene(this.engine)\r\n\r\n this.load(sceneData, scriptsMap)\r\n }\r\n\r\n /**\r\n * 加载场景\r\n * @param sceneData 场景数据数据\r\n * @param scriptsMap 代码脚本地图\r\n */\r\n async load (sceneData: string, scriptsMap?: ScriptsMap) {\r\n if (this.scene) {\r\n this.scene.dispose()\r\n }\r\n if (scriptsMap) this.scritpsMap = scriptsMap\r\n this.scene = new Scene(this.engine)\r\n this.sceneData = sceneData\r\n this.scriptInstanceList = []\r\n\r\n // 执行更新代码\r\n this.scene.onBeforeRenderObservable.add(() => {\r\n if (this.scriptInstanceList) {\r\n const deltaTime = this.engine.getDeltaTime()\r\n for (let i = 0; i < this.scriptInstanceList.length; i++) {\r\n const script = this.scriptInstanceList[i];\r\n if (script.update) {\r\n script.update(deltaTime)\r\n }\r\n }\r\n }\r\n })\r\n\r\n const havokModule = await HavokPhysics()\r\n this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));\r\n\r\n await AppendSceneAsync('data:' + sceneData, this.scene)\r\n let camera\r\n if (this.scene.cameras.length === 0) {\r\n camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true)\r\n console.log('场景中无摄影机,自动创建摄影机')\r\n } else {\r\n camera = this.scene.activeCamera || this.scene.cameras[0]\r\n console.log('解析并使用场景摄影机')\r\n }\r\n camera.attachControl(this.canvas)\r\n\r\n if (scriptsMap) this.initScripts(scriptsMap)\r\n console.log('完成场景初始化')\r\n\r\n this.render()\r\n }\r\n\r\n /**\r\n * 初始化脚本\r\n */\r\n private initScripts(scriptsMap: ScriptsMap) {\r\n if (!scriptsMap) return\r\n\r\n if (this.scene.metadata) {\r\n const scriptList = this.scene.metadata.scripts as BehaviorScript[]\r\n if (scriptList && scriptList.length > 0) {\r\n this.runScript(this.scene, scriptsMap, scriptList)\r\n }\r\n }\r\n\r\n const nodes = this.scene.getNodes()\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n\r\n if (node.metadata?.scripts && node.metadata.scripts.length > 0) {\r\n this.runScript(node, scriptsMap, node.metadata.scripts)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 执行代码\r\n * @param node 代码绑定对象\r\n * @param scriptsMap 注入的全部脚本\r\n * @param scriptList 对象绑定的代码列表\r\n * @returns \r\n */\r\n private runScript (node: Scene | Node, scriptsMap: ScriptsMap, scriptList?: BehaviorScript[]) {\r\n if (!scriptList) return\r\n for (let i = 0; i < scriptList.length; i++) {\r\n const script: BehaviorScript = scriptList[i];\r\n\r\n for (const key in scriptsMap) {\r\n if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {\r\n if (key === script.key && script.disabled !== true) {\r\n let constructor: any = scriptsMap[script.key]\r\n\r\n if (constructor instanceof Function) {\r\n const instance = new (constructor)(this.scene, node, script.values || {})\r\n\r\n if (instance.start) instance.start()\r\n\r\n if (instance.dispose && node.onDisposeObservable) {\r\n const callback: any = instance.dispose\r\n node.onDisposeObservable.addOnce(callback.bind(instance))\r\n }\r\n\r\n this.scriptInstanceList.push(instance)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 开始渲染循环\r\n */\r\n private render() {\r\n let scene = this.scene\r\n this.engine.runRenderLoop(() => {\r\n scene.render()\r\n })\r\n }\r\n\r\n /**\r\n * 重置canvas变形后的系统尺寸\r\n */\r\n resize() {\r\n this.engine.resize()\r\n }\r\n\r\n dispose() {\r\n this.scene.dispose()\r\n this.engine.dispose()\r\n }\r\n}\r\n\r\nexport function loadScene (container: HTMLDivElement, sceneData: string, scriptsMap: ScriptsMap = {}) {\r\n const sceneLoader = new SceneLoader(container, sceneData, scriptsMap)\r\n\r\n return sceneLoader\r\n}\r\n\r\nexport type IScript = {\r\n start?: () => void,\r\n update?: (deltaTime: number) => void,\r\n dispose?: () => void,\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"babyeditor.tool.es.js","sources":["../../src/tool/CustomSystem.ts","../../src/tool/SceneLoader.ts"],"sourcesContent":["import { MetaData } from \"../interfaces/MetaData.interface\";\r\nimport { ImportMeshAsync, Scene, TransformNode, Node, Skeleton, AnimationGroup, Mesh } from \"@babylonjs/core\";\r\nimport { IScript } from \"./SceneLoader\";\r\n\r\nexport class CustomSystem {\r\n constructor (public scene: Scene, private scriptInstanceList: IScript[] = []) {\r\n this.load()\r\n }\r\n\r\n load () {\r\n const transNodes = this.scene.transformNodes\r\n\r\n for (let i = 0; i < transNodes.length; i++) {\r\n const transNode = transNodes[i];\r\n if (transNode.metadata) {\r\n const metaData: MetaData = transNode.metadata\r\n // 当对象是外部资源模型时\r\n if (metaData.meshBuilderType === 'assetModel' && metaData.assetModelBuilderOptions?.url) {\r\n CustomSystem.LoadAssetModel(transNode, metaData.assetModelBuilderOptions.url, this.scene).then(() => {\r\n const findInstance = this.scriptInstanceList.find(instance => instance.node === transNode)\r\n if (findInstance && typeof findInstance.ready === 'function') {\r\n findInstance.ready()\r\n }\r\n })\r\n }\r\n }\r\n }\r\n }\r\n\r\n static async LoadAssetModel (parentNode: TransformNode, url: string, scene: Scene) {\r\n const applyMetaData = (node: Node | Skeleton) => {\r\n if (node instanceof Node && !node.parent) {\r\n node.parent = parentNode\r\n }\r\n if (node instanceof Mesh && node.material) {\r\n node.material.doNotSerialize = true\r\n }\r\n node.doNotSerialize = true\r\n }\r\n const { meshes, transformNodes, lights, skeletons } = await ImportMeshAsync(url, scene)\r\n meshes.forEach(node => applyMetaData(node))\r\n transformNodes.forEach(node => applyMetaData(node))\r\n lights.forEach(node => applyMetaData(node))\r\n skeletons.forEach(node => applyMetaData(node)) \r\n }\r\n}","import { Engine, Scene, Nullable, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync, AbstractMesh, Camera, Node, TransformNode } from \"@babylonjs/core\";\r\nimport '@babylonjs/materials'\r\nimport '@babylonjs/loaders'\r\nimport '@babylonjs/post-processes'\r\nimport '@babylonjs/procedural-textures'\r\nimport HavokPhysics from \"@babylonjs/havok\";\r\nimport { CustomSystem } from \"./CustomSystem\";\r\n\r\n/**\r\n * 脚本接口\r\n */\r\nexport interface ScriptsMap {\r\n [index: string]: IScript | Function;\r\n}\r\n\r\n/**\r\n * 字符串字典\r\n */\r\nexport interface IStringDictionary<T> {\r\n [index: string]: T;\r\n}\r\n\r\n/**\r\n * 行为脚本接口\r\n */\r\nexport interface BehaviorScript {\r\n // 脚本类型\r\n type: 'script',\r\n // 是否启用脚本\r\n disabled: boolean,\r\n // 是否从资源中找不到对应的文件\r\n isLoss?: boolean,\r\n // 脚本标识key, 对应脚本资源的的请求路径\r\n key: string,\r\n // 脚本参数\r\n values: IStringDictionary<any>\r\n}\r\n\r\n/**\r\n * 运行场景加载的核心类\r\n * @description 在这里创建初始化场景所需要的一切的东西\r\n */\r\nexport class SceneLoader {\r\n /**\r\n * 场景容器\r\n */\r\n container: HTMLElement\r\n /**\r\n * 画布\r\n */\r\n canvas: HTMLCanvasElement\r\n /**\r\n * 引擎\r\n */\r\n engine: Engine\r\n /**\r\n * 场景\r\n */\r\n scene: Scene\r\n /**\r\n * 场景数据\r\n */\r\n sceneData: string = ''\r\n /**\r\n * 脚本代码列表\r\n */\r\n scriptsMap: ScriptsMap = {}\r\n /**\r\n * 脚本实例列表\r\n */\r\n private scriptInstanceList: IScript[] = []\r\n /**\r\n * 构造函数\r\n * @param container 容器\r\n * @param sceneData 场景数据\r\n * @param scriptsMap 脚本代码列表\r\n */\r\n constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap) {\r\n this.container = container\r\n this.canvas = document.createElement('canvas')\r\n this.canvas.className = 'main-display-canvas'\r\n this.canvas.width = container.clientWidth\r\n this.canvas.height = container.clientHeight\r\n this.container.appendChild(this.canvas)\r\n this.engine = new Engine(this.canvas, true)\r\n this.scene = new Scene(this.engine)\r\n\r\n this.load(sceneData, scriptsMap)\r\n }\r\n\r\n /**\r\n * 加载场景\r\n * @param sceneData 场景数据数据\r\n * @param scriptsMap 代码脚本地图\r\n */\r\n async load (sceneData: string, scriptsMap?: ScriptsMap) {\r\n if (this.scene) {\r\n this.scene.dispose()\r\n }\r\n if (scriptsMap) this.scriptsMap = scriptsMap\r\n this.scene = new Scene(this.engine)\r\n this.sceneData = sceneData\r\n this.scriptInstanceList = []\r\n\r\n // 执行更新代码\r\n this.scene.onBeforeRenderObservable.add(() => {\r\n if (this.scriptInstanceList) {\r\n const deltaTime = this.engine.getDeltaTime()\r\n for (let i = 0; i < this.scriptInstanceList.length; i++) {\r\n const script = this.scriptInstanceList[i];\r\n if (script.update) {\r\n script.update(deltaTime)\r\n }\r\n }\r\n }\r\n })\r\n\r\n const havokModule = await HavokPhysics()\r\n this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));\r\n\r\n await AppendSceneAsync('data:' + sceneData, this.scene)\r\n let camera\r\n if (this.scene.cameras.length === 0) {\r\n camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true)\r\n console.log('场景中无摄影机,自动创建摄影机')\r\n } else {\r\n camera = this.scene.activeCamera || this.scene.cameras[0]\r\n console.log('解析并使用场景摄影机')\r\n }\r\n camera.attachControl(this.canvas)\r\n\r\n if (scriptsMap) this.initScripts(scriptsMap)\r\n console.log('完成场景初始化')\r\n\r\n new CustomSystem(this.scene, this.scriptInstanceList)\r\n\r\n this.render()\r\n }\r\n\r\n /**\r\n * 初始化脚本\r\n */\r\n private initScripts(scriptsMap: ScriptsMap) {\r\n if (!scriptsMap) return\r\n\r\n if (this.scene.metadata) {\r\n const scriptList = this.scene.metadata.scripts as BehaviorScript[]\r\n if (scriptList && scriptList.length > 0) {\r\n this.runScript(this.scene, scriptsMap, scriptList)\r\n }\r\n }\r\n\r\n const nodes = this.scene.getNodes()\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n\r\n if (node.metadata?.scripts && node.metadata.scripts.length > 0) {\r\n this.runScript(node, scriptsMap, node.metadata.scripts)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 执行代码\r\n * @param node 代码绑定对象\r\n * @param scriptsMap 注入的全部脚本\r\n * @param scriptList 对象绑定的代码列表\r\n * @returns \r\n */\r\n private runScript (node: Scene | Node, scriptsMap: ScriptsMap, scriptList?: BehaviorScript[]) {\r\n if (!scriptList) return\r\n for (let i = 0; i < scriptList.length; i++) {\r\n const script: BehaviorScript = scriptList[i];\r\n\r\n for (const key in scriptsMap) {\r\n if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {\r\n if (key === script.key && script.disabled !== true) {\r\n let constructor: any = scriptsMap[script.key]\r\n\r\n if (constructor instanceof Function) {\r\n const instance = new (constructor)(this.scene, node, script.values || {})\r\n\r\n if (instance.start) instance.start()\r\n\r\n if (instance.dispose && node.onDisposeObservable) {\r\n const callback: any = instance.dispose\r\n node.onDisposeObservable.addOnce(callback.bind(instance))\r\n }\r\n\r\n this.scriptInstanceList.push(instance)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 开始渲染循环\r\n */\r\n private render() {\r\n let scene = this.scene\r\n this.engine.runRenderLoop(() => {\r\n scene.render()\r\n })\r\n }\r\n\r\n /**\r\n * 重置canvas变形后的系统尺寸\r\n */\r\n resize() {\r\n this.engine.resize()\r\n }\r\n\r\n dispose() {\r\n this.scene.dispose()\r\n this.engine.dispose()\r\n }\r\n\r\n /**\r\n * 加载自定义组件系统。比如天气系统,模型系统\r\n */\r\n static LoadCustomSystem () {}\r\n}\r\n\r\nexport function loadScene (container: HTMLDivElement, sceneData: string, scriptsMap: ScriptsMap = {}) {\r\n const sceneLoader = new SceneLoader(container, sceneData, scriptsMap)\r\n\r\n return sceneLoader\r\n}\r\n\r\n/**\r\n * 脚本代码结构\r\n */\r\nexport type IScript = {\r\n /**\r\n * 脚执行时注入的场景对象\r\n */\r\n scene: Scene,\r\n /**\r\n * 当前实例化脚本绑定的对象\r\n */\r\n node: Node | Scene,\r\n /**\r\n * 脚本初始化执行的钩子函数\r\n */\r\n start?: () => void,\r\n /**\r\n * 当有异步动作初始化完成时的钩子函数\r\n */\r\n ready?: () => void,\r\n /**\r\n * 当没帧渲染是执行函数\r\n * @param deltaTime 间隔时间\r\n */\r\n update?: (deltaTime: number) => void,\r\n /**\r\n * 当对象被销毁时执行的函数\r\n */\r\n dispose?: () => void,\r\n}\r\n"],"names":[],"mappings":";;;;;;AAIO,MAAM,aAAa;AAAA,EACxB,YAAoB,OAAsB,qBAAgC,IAAI;AAA1D,SAAA,QAAA;AAAsB,SAAA,qBAAA;AACxC,SAAK,KAAA;AAAA,EACP;AAAA,EAEA,OAAQ;AACN,UAAM,aAAa,KAAK,MAAM;AAE9B,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,YAAM,YAAY,WAAW,CAAC;AAC9B,UAAI,UAAU,UAAU;AACtB,cAAM,WAAqB,UAAU;AAErC,YAAI,SAAS,oBAAoB,gBAAgB,SAAS,0BAA0B,KAAK;AACvF,uBAAa,eAAe,WAAW,SAAS,yBAAyB,KAAK,KAAK,KAAK,EAAE,KAAK,MAAM;AACnG,kBAAM,eAAe,KAAK,mBAAmB,KAAK,CAAA,aAAY,SAAS,SAAS,SAAS;AACzF,gBAAI,gBAAgB,OAAO,aAAa,UAAU,YAAY;AAC5D,2BAAa,MAAA;AAAA,YACf;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAa,eAAgB,YAA2B,KAAa,OAAc;AACjF,UAAM,gBAAgB,CAAC,SAA0B;AAC/C,UAAI,gBAAgB,QAAQ,CAAC,KAAK,QAAQ;AACxC,aAAK,SAAS;AAAA,MAChB;AACA,UAAI,gBAAgB,QAAQ,KAAK,UAAU;AACzC,aAAK,SAAS,iBAAiB;AAAA,MACjC;AACA,WAAK,iBAAiB;AAAA,IACxB;AACA,UAAM,EAAE,QAAQ,gBAAgB,QAAQ,cAAc,MAAM,gBAAgB,KAAK,KAAK;AACtF,WAAO,QAAQ,CAAA,SAAQ,cAAc,IAAI,CAAC;AAC1C,mBAAe,QAAQ,CAAA,SAAQ,cAAc,IAAI,CAAC;AAClD,WAAO,QAAQ,CAAA,SAAQ,cAAc,IAAI,CAAC;AAC1C,cAAU,QAAQ,CAAA,SAAQ,cAAc,IAAI,CAAC;AAAA,EAC/C;AACF;;;;ACHO,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmCvB,YAAY,WAA2B,WAAmB,YAAyB;AA/BnF,kBAAA,MAAA,WAAA;AAIA,kBAAA,MAAA,QAAA;AAIA,kBAAA,MAAA,QAAA;AAIA,kBAAA,MAAA,OAAA;AAIA,kBAAA,MAAA,aAAoB,EAAA;AAIpB,kBAAA,MAAA,cAAyB,EAAC;AAI1B,kBAAA,MAAQ,sBAAgC,EAAC;AAQvC,SAAK,YAAY;AACjB,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,OAAO,YAAY;AACxB,SAAK,OAAO,QAAQ,UAAU;AAC9B,SAAK,OAAO,SAAS,UAAU;AAC/B,SAAK,UAAU,YAAY,KAAK,MAAM;AACtC,SAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI;AAC1C,SAAK,QAAQ,IAAI,MAAM,KAAK,MAAM;AAElC,SAAK,KAAK,WAAW,UAAU;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAM,WAAmB,YAAyB;AACtD,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,QAAA;AAAA,IACb;AACA,QAAI,iBAAiB,aAAa;AAClC,SAAK,QAAQ,IAAI,MAAM,KAAK,MAAM;AAClC,SAAK,YAAY;AACjB,SAAK,qBAAqB,CAAA;AAG1B,SAAK,MAAM,yBAAyB,IAAI,MAAM;AAC5C,UAAI,KAAK,oBAAoB;AAC3B,cAAM,YAAY,KAAK,OAAO,aAAA;AAC9B,iBAAS,IAAI,GAAG,IAAI,KAAK,mBAAmB,QAAQ,KAAK;AACvD,gBAAM,SAAS,KAAK,mBAAmB,CAAC;AACxC,cAAI,OAAO,QAAQ;AACjB,mBAAO,OAAO,SAAS;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,cAAc,MAAM,aAAA;AAC1B,SAAK,MAAM,cAAc,IAAI,QAAQ,GAAG,OAAO,CAAC,GAAG,IAAI,YAAY,MAAM,WAAW,CAAC;AAErF,UAAM,iBAAiB,UAAU,WAAW,KAAK,KAAK;AACtD,QAAI;AACJ,QAAI,KAAK,MAAM,QAAQ,WAAW,GAAG;AACnC,eAAS,IAAI,WAAW,OAAO,IAAI,QAAQ,IAAI,IAAI,EAAE,GAAG,KAAK,OAAO,IAAI;AAAA,IAE1E,OAAO;AACL,eAAS,KAAK,MAAM,gBAAgB,KAAK,MAAM,QAAQ,CAAC;AAAA,IAE1D;AACA,WAAO,cAAc,KAAK,MAAM;AAEhC,QAAI,WAAY,MAAK,YAAY,UAAU;AAG3C,QAAI,aAAa,KAAK,OAAO,KAAK,kBAAkB;AAEpD,SAAK,OAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,YAAwB;AAC1C,QAAI,CAAC,WAAY;AAEjB,QAAI,KAAK,MAAM,UAAU;AACvB,YAAM,aAAa,KAAK,MAAM,SAAS;AACvC,UAAI,cAAc,WAAW,SAAS,GAAG;AACvC,aAAK,UAAU,KAAK,OAAO,YAAY,UAAU;AAAA,MACnD;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK,MAAM,SAAA;AACzB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AAEpB,UAAI,KAAK,UAAU,WAAW,KAAK,SAAS,QAAQ,SAAS,GAAG;AAC9D,aAAK,UAAU,MAAM,YAAY,KAAK,SAAS,OAAO;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,UAAW,MAAoB,YAAwB,YAA+B;AAC5F,QAAI,CAAC,WAAY;AACjB,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,YAAM,SAAyB,WAAW,CAAC;AAE3C,iBAAW,OAAO,YAAY;AAC5B,YAAI,OAAO,UAAU,eAAe,KAAK,YAAY,GAAG,GAAG;AACzD,cAAI,QAAQ,OAAO,OAAO,OAAO,aAAa,MAAM;AAClD,gBAAI,cAAmB,WAAW,OAAO,GAAG;AAE5C,gBAAI,uBAAuB,UAAU;AACnC,oBAAM,WAAW,IAAK,YAAa,KAAK,OAAO,MAAM,OAAO,UAAU,EAAE;AAExE,kBAAI,SAAS,MAAO,UAAS,MAAA;AAE7B,kBAAI,SAAS,WAAW,KAAK,qBAAqB;AAChD,sBAAM,WAAgB,SAAS;AAC/B,qBAAK,oBAAoB,QAAQ,SAAS,KAAK,QAAQ,CAAC;AAAA,cAC1D;AAEA,mBAAK,mBAAmB,KAAK,QAAQ;AAAA,YACvC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS;AACf,QAAI,QAAQ,KAAK;AACjB,SAAK,OAAO,cAAc,MAAM;AAC9B,YAAM,OAAA;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AACP,SAAK,OAAO,OAAA;AAAA,EACd;AAAA,EAEA,UAAU;AACR,SAAK,MAAM,QAAA;AACX,SAAK,OAAO,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,mBAAoB;AAAA,EAAC;AAC9B;AAEO,SAAS,UAAW,WAA2B,WAAmB,aAAyB,CAAA,GAAI;AACpG,QAAM,cAAc,IAAI,YAAY,WAAW,WAAW,UAAU;AAEpE,SAAO;AACT;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports,require("@babylonjs/core"),require("@babylonjs/materials"),require("@babylonjs/loaders"),require("@babylonjs/post-processes"),require("@babylonjs/procedural-textures"),require("@babylonjs/havok")):"function"==typeof define&&define.amd?define(["exports","@babylonjs/core","@babylonjs/materials","@babylonjs/loaders","@babylonjs/post-processes","@babylonjs/procedural-textures","@babylonjs/havok"],s):s(((e="undefined"!=typeof globalThis?globalThis:e||self).BabyEditor=e.BabyEditor||{},e.BabyEditor.Tool={}),e.BABYLON,null,null,null,null,e.HavokPhysics)}(this,function(e,s,t,n,i,a,
|
|
1
|
+
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports,require("@babylonjs/core"),require("@babylonjs/materials"),require("@babylonjs/loaders"),require("@babylonjs/post-processes"),require("@babylonjs/procedural-textures"),require("@babylonjs/havok")):"function"==typeof define&&define.amd?define(["exports","@babylonjs/core","@babylonjs/materials","@babylonjs/loaders","@babylonjs/post-processes","@babylonjs/procedural-textures","@babylonjs/havok"],s):s(((e="undefined"!=typeof globalThis?globalThis:e||self).BabyEditor=e.BabyEditor||{},e.BabyEditor.Tool={}),e.BABYLON,null,null,null,null,e.HavokPhysics)}(this,function(e,s,t,n,i,a,o){"use strict";class c{constructor(e,s=[]){this.scene=e,this.scriptInstanceList=s,this.load()}load(){const e=this.scene.transformNodes;for(let s=0;s<e.length;s++){const t=e[s];if(t.metadata){const e=t.metadata;"assetModel"===e.meshBuilderType&&e.assetModelBuilderOptions?.url&&c.LoadAssetModel(t,e.assetModelBuilderOptions.url,this.scene).then(()=>{const e=this.scriptInstanceList.find(e=>e.node===t);e&&"function"==typeof e.ready&&e.ready()})}}}static async LoadAssetModel(e,t,n){const i=t=>{t instanceof s.Node&&!t.parent&&(t.parent=e),t instanceof s.Mesh&&t.material&&(t.material.doNotSerialize=!0),t.doNotSerialize=!0},{meshes:a,transformNodes:o,lights:c,skeletons:r}=await s.ImportMeshAsync(t,n);a.forEach(e=>i(e)),o.forEach(e=>i(e)),c.forEach(e=>i(e)),r.forEach(e=>i(e))}}var r=Object.defineProperty,l=(e,s,t)=>((e,s,t)=>s in e?r(e,s,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[s]=t)(e,"symbol"!=typeof s?s+"":s,t);class h{constructor(e,t,n){l(this,"container"),l(this,"canvas"),l(this,"engine"),l(this,"scene"),l(this,"sceneData",""),l(this,"scriptsMap",{}),l(this,"scriptInstanceList",[]),this.container=e,this.canvas=document.createElement("canvas"),this.canvas.className="main-display-canvas",this.canvas.width=e.clientWidth,this.canvas.height=e.clientHeight,this.container.appendChild(this.canvas),this.engine=new s.Engine(this.canvas,!0),this.scene=new s.Scene(this.engine),this.load(t,n)}async load(e,t){this.scene&&this.scene.dispose(),t&&(this.scriptsMap=t),this.scene=new s.Scene(this.engine),this.sceneData=e,this.scriptInstanceList=[],this.scene.onBeforeRenderObservable.add(()=>{if(this.scriptInstanceList){const e=this.engine.getDeltaTime();for(let s=0;s<this.scriptInstanceList.length;s++){const t=this.scriptInstanceList[s];t.update&&t.update(e)}}});const n=await o();let i;this.scene.enablePhysics(new s.Vector3(0,-9.81,0),new s.HavokPlugin(!0,n)),await s.AppendSceneAsync("data:"+e,this.scene),i=0===this.scene.cameras.length?new s.FreeCamera("摄影机",new s.Vector3(50,50,50),this.scene,!0):this.scene.activeCamera||this.scene.cameras[0],i.attachControl(this.canvas),t&&this.initScripts(t),new c(this.scene,this.scriptInstanceList),this.render()}initScripts(e){if(!e)return;if(this.scene.metadata){const s=this.scene.metadata.scripts;s&&s.length>0&&this.runScript(this.scene,e,s)}const s=this.scene.getNodes();for(let t=0;t<s.length;t++){const n=s[t];n.metadata?.scripts&&n.metadata.scripts.length>0&&this.runScript(n,e,n.metadata.scripts)}}runScript(e,s,t){if(t)for(let n=0;n<t.length;n++){const i=t[n];for(const t in s)if(Object.prototype.hasOwnProperty.call(s,t)&&t===i.key&&!0!==i.disabled){let t=s[i.key];if(t instanceof Function){const s=new t(this.scene,e,i.values||{});if(s.start&&s.start(),s.dispose&&e.onDisposeObservable){const t=s.dispose;e.onDisposeObservable.addOnce(t.bind(s))}this.scriptInstanceList.push(s)}}}}render(){let e=this.scene;this.engine.runRenderLoop(()=>{e.render()})}resize(){this.engine.resize()}dispose(){this.scene.dispose(),this.engine.dispose()}static LoadCustomSystem(){}}e.SceneLoader=h,e.loadScene=function(e,s,t={}){return new h(e,s,t)},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
|
|
2
2
|
//# sourceMappingURL=babyeditor.tool.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babyeditor.tool.umd.js","sources":["../../src/tool/SceneLoader.ts"],"sourcesContent":["import { Engine, Scene, Nullable, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync, AbstractMesh, Camera, Node, TransformNode } from \"@babylonjs/core\";\r\nimport '@babylonjs/materials'\r\nimport '@babylonjs/loaders'\r\nimport '@babylonjs/post-processes'\r\nimport '@babylonjs/procedural-textures'\r\nimport HavokPhysics from \"@babylonjs/havok\";\r\n\r\n/**\r\n * 脚本接口\r\n */\r\nexport interface ScriptsMap {\r\n [index: string]: IScript | Function;\r\n}\r\n\r\n/**\r\n * 字符串字典\r\n */\r\nexport interface IStringDictionary<T> {\r\n [index: string]: T;\r\n}\r\n\r\n/**\r\n * 行为脚本接口\r\n */\r\nexport interface BehaviorScript {\r\n // 脚本类型\r\n type: 'script',\r\n // 是否启用脚本\r\n disabled: boolean,\r\n // 是否从资源中找不到对应的文件\r\n isLoss?: boolean,\r\n // 脚本标识key, 对应脚本资源的的请求路径\r\n key: string,\r\n // 脚本参数\r\n values: IStringDictionary<any>\r\n}\r\n\r\n/**\r\n * 运行场景加载的核心类\r\n * @description 在这里创建初始化场景所需要的一切的东西\r\n */\r\nexport class SceneLoader {\r\n /**\r\n * 场景容器\r\n */\r\n container: HTMLElement\r\n /**\r\n * 画布\r\n */\r\n canvas: HTMLCanvasElement\r\n /**\r\n * 引擎\r\n */\r\n engine: Engine\r\n /**\r\n * 场景\r\n */\r\n scene: Scene\r\n /**\r\n * 场景数据\r\n */\r\n sceneData: string = ''\r\n /**\r\n * 脚本代码列表\r\n */\r\n scritpsMap: ScriptsMap = {}\r\n /**\r\n * 脚本实例列表\r\n */\r\n private scriptInstanceList: IScript[] = []\r\n /**\r\n * 构造函数\r\n * @param container 容器\r\n * @param sceneData 场景数据\r\n * @param scriptsMap 脚本代码列表\r\n */\r\n constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap) {\r\n this.container = container\r\n this.canvas = document.createElement('canvas')\r\n this.canvas.className = 'main-display-canvas'\r\n this.canvas.width = container.clientWidth\r\n this.canvas.height = container.clientHeight\r\n this.container.appendChild(this.canvas)\r\n this.engine = new Engine(this.canvas, true)\r\n this.scene = new Scene(this.engine)\r\n\r\n this.load(sceneData, scriptsMap)\r\n }\r\n\r\n /**\r\n * 加载场景\r\n * @param sceneData 场景数据数据\r\n * @param scriptsMap 代码脚本地图\r\n */\r\n async load (sceneData: string, scriptsMap?: ScriptsMap) {\r\n if (this.scene) {\r\n this.scene.dispose()\r\n }\r\n if (scriptsMap) this.scritpsMap = scriptsMap\r\n this.scene = new Scene(this.engine)\r\n this.sceneData = sceneData\r\n this.scriptInstanceList = []\r\n\r\n // 执行更新代码\r\n this.scene.onBeforeRenderObservable.add(() => {\r\n if (this.scriptInstanceList) {\r\n const deltaTime = this.engine.getDeltaTime()\r\n for (let i = 0; i < this.scriptInstanceList.length; i++) {\r\n const script = this.scriptInstanceList[i];\r\n if (script.update) {\r\n script.update(deltaTime)\r\n }\r\n }\r\n }\r\n })\r\n\r\n const havokModule = await HavokPhysics()\r\n this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));\r\n\r\n await AppendSceneAsync('data:' + sceneData, this.scene)\r\n let camera\r\n if (this.scene.cameras.length === 0) {\r\n camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true)\r\n console.log('场景中无摄影机,自动创建摄影机')\r\n } else {\r\n camera = this.scene.activeCamera || this.scene.cameras[0]\r\n console.log('解析并使用场景摄影机')\r\n }\r\n camera.attachControl(this.canvas)\r\n\r\n if (scriptsMap) this.initScripts(scriptsMap)\r\n console.log('完成场景初始化')\r\n\r\n this.render()\r\n }\r\n\r\n /**\r\n * 初始化脚本\r\n */\r\n private initScripts(scriptsMap: ScriptsMap) {\r\n if (!scriptsMap) return\r\n\r\n if (this.scene.metadata) {\r\n const scriptList = this.scene.metadata.scripts as BehaviorScript[]\r\n if (scriptList && scriptList.length > 0) {\r\n this.runScript(this.scene, scriptsMap, scriptList)\r\n }\r\n }\r\n\r\n const nodes = this.scene.getNodes()\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n\r\n if (node.metadata?.scripts && node.metadata.scripts.length > 0) {\r\n this.runScript(node, scriptsMap, node.metadata.scripts)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 执行代码\r\n * @param node 代码绑定对象\r\n * @param scriptsMap 注入的全部脚本\r\n * @param scriptList 对象绑定的代码列表\r\n * @returns \r\n */\r\n private runScript (node: Scene | Node, scriptsMap: ScriptsMap, scriptList?: BehaviorScript[]) {\r\n if (!scriptList) return\r\n for (let i = 0; i < scriptList.length; i++) {\r\n const script: BehaviorScript = scriptList[i];\r\n\r\n for (const key in scriptsMap) {\r\n if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {\r\n if (key === script.key && script.disabled !== true) {\r\n let constructor: any = scriptsMap[script.key]\r\n\r\n if (constructor instanceof Function) {\r\n const instance = new (constructor)(this.scene, node, script.values || {})\r\n\r\n if (instance.start) instance.start()\r\n\r\n if (instance.dispose && node.onDisposeObservable) {\r\n const callback: any = instance.dispose\r\n node.onDisposeObservable.addOnce(callback.bind(instance))\r\n }\r\n\r\n this.scriptInstanceList.push(instance)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 开始渲染循环\r\n */\r\n private render() {\r\n let scene = this.scene\r\n this.engine.runRenderLoop(() => {\r\n scene.render()\r\n })\r\n }\r\n\r\n /**\r\n * 重置canvas变形后的系统尺寸\r\n */\r\n resize() {\r\n this.engine.resize()\r\n }\r\n\r\n dispose() {\r\n this.scene.dispose()\r\n this.engine.dispose()\r\n }\r\n}\r\n\r\nexport function loadScene (container: HTMLDivElement, sceneData: string, scriptsMap: ScriptsMap = {}) {\r\n const sceneLoader = new SceneLoader(container, sceneData, scriptsMap)\r\n\r\n return sceneLoader\r\n}\r\n\r\nexport type IScript = {\r\n start?: () => void,\r\n update?: (deltaTime: number) => void,\r\n dispose?: () => void,\r\n}\r\n"],"names":["SceneLoader","constructor","container","sceneData","scriptsMap","__publicField","this","canvas","document","createElement","className","width","clientWidth","height","clientHeight","appendChild","engine","Engine","scene","Scene","load","dispose","scritpsMap","scriptInstanceList","onBeforeRenderObservable","add","deltaTime","getDeltaTime","i","length","script","update","havokModule","HavokPhysics","camera","enablePhysics","Vector3","HavokPlugin","AppendSceneAsync","cameras","FreeCamera","activeCamera","attachControl","initScripts","render","metadata","scriptList","scripts","runScript","nodes","getNodes","node","key","Object","prototype","hasOwnProperty","call","disabled","Function","instance","values","start","onDisposeObservable","callback","addOnce","bind","push","runRenderLoop","resize"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"babyeditor.tool.umd.js","sources":["../../src/tool/CustomSystem.ts","../../src/tool/SceneLoader.ts"],"sourcesContent":["import { MetaData } from \"../interfaces/MetaData.interface\";\r\nimport { ImportMeshAsync, Scene, TransformNode, Node, Skeleton, AnimationGroup, Mesh } from \"@babylonjs/core\";\r\nimport { IScript } from \"./SceneLoader\";\r\n\r\nexport class CustomSystem {\r\n constructor (public scene: Scene, private scriptInstanceList: IScript[] = []) {\r\n this.load()\r\n }\r\n\r\n load () {\r\n const transNodes = this.scene.transformNodes\r\n\r\n for (let i = 0; i < transNodes.length; i++) {\r\n const transNode = transNodes[i];\r\n if (transNode.metadata) {\r\n const metaData: MetaData = transNode.metadata\r\n // 当对象是外部资源模型时\r\n if (metaData.meshBuilderType === 'assetModel' && metaData.assetModelBuilderOptions?.url) {\r\n CustomSystem.LoadAssetModel(transNode, metaData.assetModelBuilderOptions.url, this.scene).then(() => {\r\n const findInstance = this.scriptInstanceList.find(instance => instance.node === transNode)\r\n if (findInstance && typeof findInstance.ready === 'function') {\r\n findInstance.ready()\r\n }\r\n })\r\n }\r\n }\r\n }\r\n }\r\n\r\n static async LoadAssetModel (parentNode: TransformNode, url: string, scene: Scene) {\r\n const applyMetaData = (node: Node | Skeleton) => {\r\n if (node instanceof Node && !node.parent) {\r\n node.parent = parentNode\r\n }\r\n if (node instanceof Mesh && node.material) {\r\n node.material.doNotSerialize = true\r\n }\r\n node.doNotSerialize = true\r\n }\r\n const { meshes, transformNodes, lights, skeletons } = await ImportMeshAsync(url, scene)\r\n meshes.forEach(node => applyMetaData(node))\r\n transformNodes.forEach(node => applyMetaData(node))\r\n lights.forEach(node => applyMetaData(node))\r\n skeletons.forEach(node => applyMetaData(node)) \r\n }\r\n}","import { Engine, Scene, Nullable, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync, AbstractMesh, Camera, Node, TransformNode } from \"@babylonjs/core\";\r\nimport '@babylonjs/materials'\r\nimport '@babylonjs/loaders'\r\nimport '@babylonjs/post-processes'\r\nimport '@babylonjs/procedural-textures'\r\nimport HavokPhysics from \"@babylonjs/havok\";\r\nimport { CustomSystem } from \"./CustomSystem\";\r\n\r\n/**\r\n * 脚本接口\r\n */\r\nexport interface ScriptsMap {\r\n [index: string]: IScript | Function;\r\n}\r\n\r\n/**\r\n * 字符串字典\r\n */\r\nexport interface IStringDictionary<T> {\r\n [index: string]: T;\r\n}\r\n\r\n/**\r\n * 行为脚本接口\r\n */\r\nexport interface BehaviorScript {\r\n // 脚本类型\r\n type: 'script',\r\n // 是否启用脚本\r\n disabled: boolean,\r\n // 是否从资源中找不到对应的文件\r\n isLoss?: boolean,\r\n // 脚本标识key, 对应脚本资源的的请求路径\r\n key: string,\r\n // 脚本参数\r\n values: IStringDictionary<any>\r\n}\r\n\r\n/**\r\n * 运行场景加载的核心类\r\n * @description 在这里创建初始化场景所需要的一切的东西\r\n */\r\nexport class SceneLoader {\r\n /**\r\n * 场景容器\r\n */\r\n container: HTMLElement\r\n /**\r\n * 画布\r\n */\r\n canvas: HTMLCanvasElement\r\n /**\r\n * 引擎\r\n */\r\n engine: Engine\r\n /**\r\n * 场景\r\n */\r\n scene: Scene\r\n /**\r\n * 场景数据\r\n */\r\n sceneData: string = ''\r\n /**\r\n * 脚本代码列表\r\n */\r\n scriptsMap: ScriptsMap = {}\r\n /**\r\n * 脚本实例列表\r\n */\r\n private scriptInstanceList: IScript[] = []\r\n /**\r\n * 构造函数\r\n * @param container 容器\r\n * @param sceneData 场景数据\r\n * @param scriptsMap 脚本代码列表\r\n */\r\n constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap) {\r\n this.container = container\r\n this.canvas = document.createElement('canvas')\r\n this.canvas.className = 'main-display-canvas'\r\n this.canvas.width = container.clientWidth\r\n this.canvas.height = container.clientHeight\r\n this.container.appendChild(this.canvas)\r\n this.engine = new Engine(this.canvas, true)\r\n this.scene = new Scene(this.engine)\r\n\r\n this.load(sceneData, scriptsMap)\r\n }\r\n\r\n /**\r\n * 加载场景\r\n * @param sceneData 场景数据数据\r\n * @param scriptsMap 代码脚本地图\r\n */\r\n async load (sceneData: string, scriptsMap?: ScriptsMap) {\r\n if (this.scene) {\r\n this.scene.dispose()\r\n }\r\n if (scriptsMap) this.scriptsMap = scriptsMap\r\n this.scene = new Scene(this.engine)\r\n this.sceneData = sceneData\r\n this.scriptInstanceList = []\r\n\r\n // 执行更新代码\r\n this.scene.onBeforeRenderObservable.add(() => {\r\n if (this.scriptInstanceList) {\r\n const deltaTime = this.engine.getDeltaTime()\r\n for (let i = 0; i < this.scriptInstanceList.length; i++) {\r\n const script = this.scriptInstanceList[i];\r\n if (script.update) {\r\n script.update(deltaTime)\r\n }\r\n }\r\n }\r\n })\r\n\r\n const havokModule = await HavokPhysics()\r\n this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));\r\n\r\n await AppendSceneAsync('data:' + sceneData, this.scene)\r\n let camera\r\n if (this.scene.cameras.length === 0) {\r\n camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true)\r\n console.log('场景中无摄影机,自动创建摄影机')\r\n } else {\r\n camera = this.scene.activeCamera || this.scene.cameras[0]\r\n console.log('解析并使用场景摄影机')\r\n }\r\n camera.attachControl(this.canvas)\r\n\r\n if (scriptsMap) this.initScripts(scriptsMap)\r\n console.log('完成场景初始化')\r\n\r\n new CustomSystem(this.scene, this.scriptInstanceList)\r\n\r\n this.render()\r\n }\r\n\r\n /**\r\n * 初始化脚本\r\n */\r\n private initScripts(scriptsMap: ScriptsMap) {\r\n if (!scriptsMap) return\r\n\r\n if (this.scene.metadata) {\r\n const scriptList = this.scene.metadata.scripts as BehaviorScript[]\r\n if (scriptList && scriptList.length > 0) {\r\n this.runScript(this.scene, scriptsMap, scriptList)\r\n }\r\n }\r\n\r\n const nodes = this.scene.getNodes()\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n\r\n if (node.metadata?.scripts && node.metadata.scripts.length > 0) {\r\n this.runScript(node, scriptsMap, node.metadata.scripts)\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 执行代码\r\n * @param node 代码绑定对象\r\n * @param scriptsMap 注入的全部脚本\r\n * @param scriptList 对象绑定的代码列表\r\n * @returns \r\n */\r\n private runScript (node: Scene | Node, scriptsMap: ScriptsMap, scriptList?: BehaviorScript[]) {\r\n if (!scriptList) return\r\n for (let i = 0; i < scriptList.length; i++) {\r\n const script: BehaviorScript = scriptList[i];\r\n\r\n for (const key in scriptsMap) {\r\n if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {\r\n if (key === script.key && script.disabled !== true) {\r\n let constructor: any = scriptsMap[script.key]\r\n\r\n if (constructor instanceof Function) {\r\n const instance = new (constructor)(this.scene, node, script.values || {})\r\n\r\n if (instance.start) instance.start()\r\n\r\n if (instance.dispose && node.onDisposeObservable) {\r\n const callback: any = instance.dispose\r\n node.onDisposeObservable.addOnce(callback.bind(instance))\r\n }\r\n\r\n this.scriptInstanceList.push(instance)\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 开始渲染循环\r\n */\r\n private render() {\r\n let scene = this.scene\r\n this.engine.runRenderLoop(() => {\r\n scene.render()\r\n })\r\n }\r\n\r\n /**\r\n * 重置canvas变形后的系统尺寸\r\n */\r\n resize() {\r\n this.engine.resize()\r\n }\r\n\r\n dispose() {\r\n this.scene.dispose()\r\n this.engine.dispose()\r\n }\r\n\r\n /**\r\n * 加载自定义组件系统。比如天气系统,模型系统\r\n */\r\n static LoadCustomSystem () {}\r\n}\r\n\r\nexport function loadScene (container: HTMLDivElement, sceneData: string, scriptsMap: ScriptsMap = {}) {\r\n const sceneLoader = new SceneLoader(container, sceneData, scriptsMap)\r\n\r\n return sceneLoader\r\n}\r\n\r\n/**\r\n * 脚本代码结构\r\n */\r\nexport type IScript = {\r\n /**\r\n * 脚执行时注入的场景对象\r\n */\r\n scene: Scene,\r\n /**\r\n * 当前实例化脚本绑定的对象\r\n */\r\n node: Node | Scene,\r\n /**\r\n * 脚本初始化执行的钩子函数\r\n */\r\n start?: () => void,\r\n /**\r\n * 当有异步动作初始化完成时的钩子函数\r\n */\r\n ready?: () => void,\r\n /**\r\n * 当没帧渲染是执行函数\r\n * @param deltaTime 间隔时间\r\n */\r\n update?: (deltaTime: number) => void,\r\n /**\r\n * 当对象被销毁时执行的函数\r\n */\r\n dispose?: () => void,\r\n}\r\n"],"names":["CustomSystem","constructor","scene","scriptInstanceList","this","load","transNodes","transformNodes","i","length","transNode","metadata","metaData","meshBuilderType","assetModelBuilderOptions","url","LoadAssetModel","then","findInstance","find","instance","node","ready","parentNode","applyMetaData","Node","parent","Mesh","material","doNotSerialize","meshes","lights","skeletons","ImportMeshAsync","forEach","SceneLoader","container","sceneData","scriptsMap","__publicField","canvas","document","createElement","className","width","clientWidth","height","clientHeight","appendChild","engine","Engine","Scene","dispose","onBeforeRenderObservable","add","deltaTime","getDeltaTime","script","update","havokModule","HavokPhysics","camera","enablePhysics","Vector3","HavokPlugin","AppendSceneAsync","cameras","FreeCamera","activeCamera","attachControl","initScripts","render","scriptList","scripts","runScript","nodes","getNodes","key","Object","prototype","hasOwnProperty","call","disabled","Function","values","start","onDisposeObservable","callback","addOnce","bind","push","runRenderLoop","resize","LoadCustomSystem"],"mappings":"iqBAIO,MAAMA,EACX,WAAAC,CAAoBC,EAAsBC,EAAgC,IAAtDC,KAAAF,MAAAA,EAAsBE,KAAAD,mBAAAA,EACxCC,KAAKC,MACP,CAEA,IAAAA,GACE,MAAMC,EAAaF,KAAKF,MAAMK,eAE9B,IAAA,IAASC,EAAI,EAAGA,EAAIF,EAAWG,OAAQD,IAAK,CAC1C,MAAME,EAAYJ,EAAWE,GAC7B,GAAIE,EAAUC,SAAU,CACtB,MAAMC,EAAqBF,EAAUC,SAEJ,eAA7BC,EAASC,iBAAoCD,EAASE,0BAA0BC,KAClFf,EAAagB,eAAeN,EAAWE,EAASE,yBAAyBC,IAAKX,KAAKF,OAAOe,KAAK,KAC7F,MAAMC,EAAed,KAAKD,mBAAmBgB,KAAKC,GAAYA,EAASC,OAASX,GAC5EQ,GAA8C,mBAAvBA,EAAaI,OACtCJ,EAAaI,SAIrB,CACF,CACF,CAEA,2BAAaN,CAAgBO,EAA2BR,EAAab,GACnE,MAAMsB,EAAiBH,IACjBA,aAAgBI,EAAAA,OAASJ,EAAKK,SAChCL,EAAKK,OAASH,GAEZF,aAAgBM,EAAAA,MAAQN,EAAKO,WAC/BP,EAAKO,SAASC,gBAAiB,GAEjCR,EAAKQ,gBAAiB,IAElBC,OAAEA,EAAAvB,eAAQA,EAAAwB,OAAgBA,EAAAC,UAAQA,SAAoBC,EAAAA,gBAAgBlB,EAAKb,GACjF4B,EAAOI,QAAQb,GAAQG,EAAcH,IACrCd,EAAe2B,QAAQb,GAAQG,EAAcH,IAC7CU,EAAOG,QAAQb,GAAQG,EAAcH,IACrCW,EAAUE,QAAQb,GAAQG,EAAcH,GAC1C,4JCFK,MAAMc,EAmCX,WAAAlC,CAAYmC,EAA2BC,EAAmBC,GA/B1DC,EAAAnC,KAAA,aAIAmC,EAAAnC,KAAA,UAIAmC,EAAAnC,KAAA,UAIAmC,EAAAnC,KAAA,SAIAmC,EAAAnC,KAAA,YAAoB,IAIpBmC,EAAAnC,KAAA,aAAyB,IAIzBmC,EAAAnC,KAAQ,qBAAgC,IAQtCA,KAAKgC,UAAYA,EACjBhC,KAAKoC,OAASC,SAASC,cAAc,UACrCtC,KAAKoC,OAAOG,UAAY,sBACxBvC,KAAKoC,OAAOI,MAAQR,EAAUS,YAC9BzC,KAAKoC,OAAOM,OAASV,EAAUW,aAC/B3C,KAAKgC,UAAUY,YAAY5C,KAAKoC,QAChCpC,KAAK6C,OAAS,IAAIC,EAAAA,OAAO9C,KAAKoC,QAAQ,GACtCpC,KAAKF,MAAQ,IAAIiD,QAAM/C,KAAK6C,QAE5B7C,KAAKC,KAAKgC,EAAWC,EACvB,CAOA,UAAMjC,CAAMgC,EAAmBC,GACzBlC,KAAKF,OACPE,KAAKF,MAAMkD,UAETd,SAAiBA,WAAaA,GAClClC,KAAKF,MAAQ,IAAIiD,QAAM/C,KAAK6C,QAC5B7C,KAAKiC,UAAYA,EACjBjC,KAAKD,mBAAqB,GAG1BC,KAAKF,MAAMmD,yBAAyBC,IAAI,KACtC,GAAIlD,KAAKD,mBAAoB,CAC3B,MAAMoD,EAAYnD,KAAK6C,OAAOO,eAC9B,IAAA,IAAShD,EAAI,EAAGA,EAAIJ,KAAKD,mBAAmBM,OAAQD,IAAK,CACvD,MAAMiD,EAASrD,KAAKD,mBAAmBK,GACnCiD,EAAOC,QACTD,EAAOC,OAAOH,EAElB,CACF,IAGF,MAAMI,QAAoBC,IAI1B,IAAIC,EAHJzD,KAAKF,MAAM4D,cAAc,IAAIC,EAAAA,QAAQ,GAAG,KAAO,GAAI,IAAIC,EAAAA,aAAY,EAAML,UAEnEM,EAAAA,iBAAiB,QAAU5B,EAAWjC,KAAKF,OAG/C2D,EADgC,IAA9BzD,KAAKF,MAAMgE,QAAQzD,OACZ,IAAI0D,EAAAA,WAAW,MAAO,IAAIJ,EAAAA,QAAQ,GAAI,GAAI,IAAK3D,KAAKF,OAAO,GAG3DE,KAAKF,MAAMkE,cAAgBhE,KAAKF,MAAMgE,QAAQ,GAGzDL,EAAOQ,cAAcjE,KAAKoC,QAEtBF,GAAYlC,KAAKkE,YAAYhC,GAGjC,IAAItC,EAAaI,KAAKF,MAAOE,KAAKD,oBAElCC,KAAKmE,QACP,CAKQ,WAAAD,CAAYhC,GAClB,IAAKA,EAAY,OAEjB,GAAIlC,KAAKF,MAAMS,SAAU,CACvB,MAAM6D,EAAapE,KAAKF,MAAMS,SAAS8D,QACnCD,GAAcA,EAAW/D,OAAS,GACpCL,KAAKsE,UAAUtE,KAAKF,MAAOoC,EAAYkC,EAE3C,CAEA,MAAMG,EAAQvE,KAAKF,MAAM0E,WACzB,IAAA,IAASpE,EAAI,EAAGA,EAAImE,EAAMlE,OAAQD,IAAK,CACrC,MAAMa,EAAOsD,EAAMnE,GAEfa,EAAKV,UAAU8D,SAAWpD,EAAKV,SAAS8D,QAAQhE,OAAS,GAC3DL,KAAKsE,UAAUrD,EAAMiB,EAAYjB,EAAKV,SAAS8D,QAEnD,CACF,CASQ,SAAAC,CAAWrD,EAAoBiB,EAAwBkC,GAC7D,GAAKA,EACL,IAAA,IAAShE,EAAI,EAAGA,EAAIgE,EAAW/D,OAAQD,IAAK,CAC1C,MAAMiD,EAAyBe,EAAWhE,GAE1C,IAAA,MAAWqE,KAAOvC,EAChB,GAAIwC,OAAOC,UAAUC,eAAeC,KAAK3C,EAAYuC,IAC/CA,IAAQpB,EAAOoB,MAA2B,IAApBpB,EAAOyB,SAAmB,CAClD,IAAIjF,EAAmBqC,EAAWmB,EAAOoB,KAEzC,GAAI5E,aAAuBkF,SAAU,CACnC,MAAM/D,EAAW,IAAKnB,EAAaG,KAAKF,MAAOmB,EAAMoC,EAAO2B,QAAU,IAItE,GAFIhE,EAASiE,OAAOjE,EAASiE,QAEzBjE,EAASgC,SAAW/B,EAAKiE,oBAAqB,CAChD,MAAMC,EAAgBnE,EAASgC,QAC/B/B,EAAKiE,oBAAoBE,QAAQD,EAASE,KAAKrE,GACjD,CAEAhB,KAAKD,mBAAmBuF,KAAKtE,EAC/B,CACF,CAGN,CACF,CAKQ,MAAAmD,GACN,IAAIrE,EAAQE,KAAKF,MACjBE,KAAK6C,OAAO0C,cAAc,KACxBzF,EAAMqE,UAEV,CAKA,MAAAqB,GACExF,KAAK6C,OAAO2C,QACd,CAEA,OAAAxC,GACEhD,KAAKF,MAAMkD,UACXhD,KAAK6C,OAAOG,SACd,CAKA,uBAAOyC,GAAqB,8BAGvB,SAAoBzD,EAA2BC,EAAmBC,EAAyB,CAAA,GAGhG,OAFoB,IAAIH,EAAYC,EAAWC,EAAWC,EAG5D"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Scene, TransformNode } from "@babylonjs/core";
|
|
2
|
+
export declare class CustomSystem {
|
|
3
|
+
scene: Scene;
|
|
4
|
+
constructor(scene: Scene);
|
|
5
|
+
load(): void;
|
|
6
|
+
static LoadAssetModel(parentNode: TransformNode, url: string, scene: Scene): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=CustomSystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CustomSystem.d.ts","sourceRoot":"","sources":["../../src/tool/CustomSystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,EAAE,aAAa,EAAwC,MAAM,iBAAiB,CAAC;AAE9G,qBAAa,YAAY;IACH,KAAK,EAAE,KAAK;gBAAZ,KAAK,EAAE,KAAK;IAIhC,IAAI;WAcS,cAAc,CAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAgBlF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ImportMeshAsync, Node, Mesh } from "@babylonjs/core";
|
|
2
|
+
export class CustomSystem {
|
|
3
|
+
constructor(scene) {
|
|
4
|
+
this.scene = scene;
|
|
5
|
+
this.load();
|
|
6
|
+
}
|
|
7
|
+
load() {
|
|
8
|
+
const transNodes = this.scene.transformNodes;
|
|
9
|
+
for (let i = 0; i < transNodes.length; i++) {
|
|
10
|
+
const transNode = transNodes[i];
|
|
11
|
+
if (transNode.metadata) {
|
|
12
|
+
const metaData = transNode.metadata;
|
|
13
|
+
if (metaData.meshBuilderType === 'assetModel' && metaData.assetModelBuilderOptions?.url) {
|
|
14
|
+
CustomSystem.LoadAssetModel(transNode, metaData.assetModelBuilderOptions.url, this.scene);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
static async LoadAssetModel(parentNode, url, scene) {
|
|
20
|
+
const applyMetaData = (node) => {
|
|
21
|
+
if (node instanceof Node && !node.parent) {
|
|
22
|
+
node.parent = parentNode;
|
|
23
|
+
}
|
|
24
|
+
if (node instanceof Mesh && node.material) {
|
|
25
|
+
node.material.doNotSerialize = true;
|
|
26
|
+
}
|
|
27
|
+
node.doNotSerialize = true;
|
|
28
|
+
};
|
|
29
|
+
const { meshes, transformNodes, lights, skeletons } = await ImportMeshAsync(url, scene);
|
|
30
|
+
meshes.forEach(node => applyMetaData(node));
|
|
31
|
+
transformNodes.forEach(node => applyMetaData(node));
|
|
32
|
+
lights.forEach(node => applyMetaData(node));
|
|
33
|
+
skeletons.forEach(node => applyMetaData(node));
|
|
34
|
+
}
|
|
35
|
+
}
|
package/types/SceneLoader.d.ts
CHANGED
|
@@ -92,6 +92,10 @@ export declare class SceneLoader {
|
|
|
92
92
|
*/
|
|
93
93
|
resize(): void;
|
|
94
94
|
dispose(): void;
|
|
95
|
+
/**
|
|
96
|
+
* 加载自定义组件系统。比如天气系统,模型系统
|
|
97
|
+
*/
|
|
98
|
+
static LoadCustomSystem(): void;
|
|
95
99
|
}
|
|
96
100
|
export declare function loadScene(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap): SceneLoader;
|
|
97
101
|
export type IScript = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneLoader.d.ts","sourceRoot":"","sources":["../../src/tool/SceneLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAA2G,MAAM,iBAAiB,CAAC;AACzJ,OAAO,sBAAsB,CAAA;AAC7B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,2BAA2B,CAAA;AAClC,OAAO,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"SceneLoader.d.ts","sourceRoot":"","sources":["../../src/tool/SceneLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAA2G,MAAM,iBAAiB,CAAC;AACzJ,OAAO,sBAAsB,CAAA;AAC7B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,2BAA2B,CAAA;AAClC,OAAO,gCAAgC,CAAA;AAIvC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAE7B,IAAI,EAAE,QAAQ,CAAC;IAEf,QAAQ,EAAE,OAAO,CAAC;IAElB,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAA;CAC/B;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB;;OAEG;IACH,SAAS,EAAE,WAAW,CAAA;IACtB;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAAA;IACzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IACZ;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;IACtB;;OAEG;IACH,UAAU,EAAE,UAAU,CAAK;IAC3B;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAgB;IAC1C;;;;;OAKG;gBACS,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU;IAajF;;;;OAIG;IACG,IAAI,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU;IA4CtD;;OAEG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA4BjB;;OAEG;IACH,OAAO,CAAC,MAAM;IAOd;;OAEG;IACH,MAAM;IAIN,OAAO;IAKP;;OAEG;IACH,MAAM,CAAC,gBAAgB;CACxB;AAED,wBAAgB,SAAS,CAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,UAAe,eAInG;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAA"}
|
package/types/SceneLoader.js
CHANGED
|
@@ -4,6 +4,7 @@ import '@babylonjs/loaders';
|
|
|
4
4
|
import '@babylonjs/post-processes';
|
|
5
5
|
import '@babylonjs/procedural-textures';
|
|
6
6
|
import HavokPhysics from "@babylonjs/havok";
|
|
7
|
+
import { CustomSystem } from "./CustomSystem";
|
|
7
8
|
/**
|
|
8
9
|
* 运行场景加载的核心类
|
|
9
10
|
* @description 在这里创建初始化场景所需要的一切的东西
|
|
@@ -77,6 +78,7 @@ export class SceneLoader {
|
|
|
77
78
|
console.log('解析并使用场景摄影机');
|
|
78
79
|
}
|
|
79
80
|
camera.attachControl(this.canvas);
|
|
81
|
+
new CustomSystem(this.scene);
|
|
80
82
|
if (scriptsMap)
|
|
81
83
|
this.initScripts(scriptsMap);
|
|
82
84
|
console.log('完成场景初始化');
|
|
@@ -152,6 +154,10 @@ export class SceneLoader {
|
|
|
152
154
|
this.scene.dispose();
|
|
153
155
|
this.engine.dispose();
|
|
154
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* 加载自定义组件系统。比如天气系统,模型系统
|
|
159
|
+
*/
|
|
160
|
+
static LoadCustomSystem() { }
|
|
155
161
|
}
|
|
156
162
|
export function loadScene(container, sceneData, scriptsMap = {}) {
|
|
157
163
|
const sceneLoader = new SceneLoader(container, sceneData, scriptsMap);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BehaviorScript } from "../tool/SceneLoader";
|
|
2
|
+
import { Vector3 } from "@babylonjs/core";
|
|
3
|
+
export interface MetaData {
|
|
4
|
+
type?: string;
|
|
5
|
+
scripts?: Array<BehaviorScript>;
|
|
6
|
+
noSerialize?: boolean;
|
|
7
|
+
editable?: boolean;
|
|
8
|
+
meshBuilderType?: string;
|
|
9
|
+
boxBuilderOptions?: {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
depth: number;
|
|
13
|
+
sideOrientation: number;
|
|
14
|
+
};
|
|
15
|
+
sphereBuilderOptions?: {
|
|
16
|
+
diameterX: number;
|
|
17
|
+
diameterY: number;
|
|
18
|
+
diameterZ: number;
|
|
19
|
+
slice: number;
|
|
20
|
+
segments: number;
|
|
21
|
+
arc: number;
|
|
22
|
+
sideOrientation: number;
|
|
23
|
+
};
|
|
24
|
+
cylinderBuilderOptions?: {
|
|
25
|
+
diameterTop: number;
|
|
26
|
+
diameterBottom: number;
|
|
27
|
+
height: number;
|
|
28
|
+
tessellation: number;
|
|
29
|
+
subdivisions: number;
|
|
30
|
+
arc: number;
|
|
31
|
+
sideOrientation: number;
|
|
32
|
+
};
|
|
33
|
+
extraPolygonBuilderOptions?: {
|
|
34
|
+
shape: Vector3[];
|
|
35
|
+
holes: Vector3[][];
|
|
36
|
+
depth: number;
|
|
37
|
+
sideOrientation: number;
|
|
38
|
+
};
|
|
39
|
+
assetModelBuilderOptions?: {
|
|
40
|
+
url: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=MetaData.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetaData.interface.d.ts","sourceRoot":"","sources":["../../../src/interfaces/MetaData.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC,MAAM,WAAW,QAAQ;IAEvB,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb,OAAO,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAA;IAE/B,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IAED,oBAAoB,CAAC,EAAE;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IAED,sBAAsB,CAAC,EAAE;QACvB,WAAW,EAAE,MAAM,CAAA;QACnB,cAAc,EAAE,MAAM,CAAA;QACtB,MAAM,EAAE,MAAM,CAAA;QACd,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,GAAG,EAAE,MAAM,CAAA;QACX,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IAED,0BAA0B,CAAC,EAAE;QAC3B,KAAK,EAAE,OAAO,EAAE,CAAC;QACjB,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,wBAAwB,CAAC,EAAE;QACzB,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { AssetsItem } from "@/servers/Assets.server";
|
|
2
|
+
import { BehaviorScript } from "@/tool";
|
|
3
|
+
import { Vector3 } from "@babylonjs/core";
|
|
4
|
+
export type SceneObjectType = 'transformNode' | 'mesh' | 'scene' | 'camera' | 'texture' | 'light' | 'sound' | 'soundTrack' | 'particleSystem' | 'skeleton' | "bone" | 'group' | 'material' | 'lensFlareSystem' | 'postProcess' | 'postProcessRenderPipeline' | 'spriteManager' | 'sprite';
|
|
5
|
+
export interface SceneTreeData {
|
|
6
|
+
uid: number;
|
|
7
|
+
id?: string;
|
|
8
|
+
name: string;
|
|
9
|
+
type: SceneObjectType;
|
|
10
|
+
visible?: boolean;
|
|
11
|
+
isNode?: boolean;
|
|
12
|
+
isEnabled?: boolean;
|
|
13
|
+
isFrozen?: boolean;
|
|
14
|
+
isSkeleton?: boolean;
|
|
15
|
+
icon?: string;
|
|
16
|
+
children?: SceneTreeData[];
|
|
17
|
+
}
|
|
18
|
+
export interface SceneObjectFindIndex {
|
|
19
|
+
type: SceneObjectType;
|
|
20
|
+
uid: number;
|
|
21
|
+
id?: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
isNode?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface DragingObjectType {
|
|
26
|
+
type: 'scene-object' | 'asset' | 'file' | 'none';
|
|
27
|
+
findIndex?: SceneObjectFindIndex;
|
|
28
|
+
assetsItem?: AssetsItem;
|
|
29
|
+
}
|
|
30
|
+
export interface MetaData {
|
|
31
|
+
type?: string;
|
|
32
|
+
scripts?: Array<BehaviorScript>;
|
|
33
|
+
noSerialize?: boolean;
|
|
34
|
+
editable?: boolean;
|
|
35
|
+
meshBuilderType?: string;
|
|
36
|
+
boxBuilderOptions?: {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
depth: number;
|
|
40
|
+
sideOrientation: number;
|
|
41
|
+
};
|
|
42
|
+
sphereBuilderOptions?: {
|
|
43
|
+
diameterX: number;
|
|
44
|
+
diameterY: number;
|
|
45
|
+
diameterZ: number;
|
|
46
|
+
slice: number;
|
|
47
|
+
segments: number;
|
|
48
|
+
arc: number;
|
|
49
|
+
sideOrientation: number;
|
|
50
|
+
};
|
|
51
|
+
cylinderBuilderOptions?: {
|
|
52
|
+
diameterTop: number;
|
|
53
|
+
diameterBottom: number;
|
|
54
|
+
height: number;
|
|
55
|
+
tessellation: number;
|
|
56
|
+
subdivisions: number;
|
|
57
|
+
arc: number;
|
|
58
|
+
sideOrientation: number;
|
|
59
|
+
};
|
|
60
|
+
extraPolygonBuilderOptions?: {
|
|
61
|
+
shape: Vector3[];
|
|
62
|
+
holes: Vector3[][];
|
|
63
|
+
depth: number;
|
|
64
|
+
sideOrientation: number;
|
|
65
|
+
};
|
|
66
|
+
assetModelBuilderOptions?: {
|
|
67
|
+
url: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=SceneData.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneData.interface.d.ts","sourceRoot":"","sources":["../../../src/interfaces/SceneData.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,gBAAgB,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,iBAAiB,GAAG,aAAa,GAAG,2BAA2B,GAAG,eAAe,GAAG,QAAQ,CAAA;AAEzR,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,eAAe,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,eAAe,CAAA;IACrB,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChD,SAAS,CAAC,EAAE,oBAAoB,CAAA;IAChC,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAGD,MAAM,WAAW,QAAQ;IAEvB,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb,OAAO,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAA;IAE/B,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IAED,oBAAoB,CAAC,EAAE;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IAED,sBAAsB,CAAC,EAAE;QACvB,WAAW,EAAE,MAAM,CAAA;QACnB,cAAc,EAAE,MAAM,CAAA;QACtB,MAAM,EAAE,MAAM,CAAA;QACd,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,GAAG,EAAE,MAAM,CAAA;QACX,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IAED,0BAA0B,CAAC,EAAE;QAC3B,KAAK,EAAE,OAAO,EAAE,CAAC;QACjB,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,wBAAwB,CAAC,EAAE;QACzB,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Scene, TransformNode } from "@babylonjs/core";
|
|
2
|
+
import { IScript } from "./SceneLoader";
|
|
3
|
+
export declare class CustomSystem {
|
|
4
|
+
scene: Scene;
|
|
5
|
+
private scriptInstanceList;
|
|
6
|
+
constructor(scene: Scene, scriptInstanceList?: IScript[]);
|
|
7
|
+
load(): void;
|
|
8
|
+
static LoadAssetModel(parentNode: TransformNode, url: string, scene: Scene): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=CustomSystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CustomSystem.d.ts","sourceRoot":"","sources":["../../../src/tool/CustomSystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,EAAE,aAAa,EAAwC,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,qBAAa,YAAY;IACH,KAAK,EAAE,KAAK;IAAE,OAAO,CAAC,kBAAkB;gBAAxC,KAAK,EAAE,KAAK,EAAU,kBAAkB,GAAE,OAAO,EAAO;IAI5E,IAAI;WAoBS,cAAc,CAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAgBlF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ImportMeshAsync, Node, Mesh } from "@babylonjs/core";
|
|
2
|
+
export class CustomSystem {
|
|
3
|
+
constructor(scene, scriptInstanceList = []) {
|
|
4
|
+
this.scene = scene;
|
|
5
|
+
this.scriptInstanceList = scriptInstanceList;
|
|
6
|
+
this.load();
|
|
7
|
+
}
|
|
8
|
+
load() {
|
|
9
|
+
const transNodes = this.scene.transformNodes;
|
|
10
|
+
for (let i = 0; i < transNodes.length; i++) {
|
|
11
|
+
const transNode = transNodes[i];
|
|
12
|
+
if (transNode.metadata) {
|
|
13
|
+
const metaData = transNode.metadata;
|
|
14
|
+
// 当对象是外部资源模型时
|
|
15
|
+
if (metaData.meshBuilderType === 'assetModel' && metaData.assetModelBuilderOptions?.url) {
|
|
16
|
+
CustomSystem.LoadAssetModel(transNode, metaData.assetModelBuilderOptions.url, this.scene).then(() => {
|
|
17
|
+
const findInstance = this.scriptInstanceList.find(instance => instance.node === transNode);
|
|
18
|
+
if (findInstance && typeof findInstance.ready === 'function') {
|
|
19
|
+
findInstance.ready();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
static async LoadAssetModel(parentNode, url, scene) {
|
|
27
|
+
const applyMetaData = (node) => {
|
|
28
|
+
if (node instanceof Node && !node.parent) {
|
|
29
|
+
node.parent = parentNode;
|
|
30
|
+
}
|
|
31
|
+
if (node instanceof Mesh && node.material) {
|
|
32
|
+
node.material.doNotSerialize = true;
|
|
33
|
+
}
|
|
34
|
+
node.doNotSerialize = true;
|
|
35
|
+
};
|
|
36
|
+
const { meshes, transformNodes, lights, skeletons } = await ImportMeshAsync(url, scene);
|
|
37
|
+
meshes.forEach(node => applyMetaData(node));
|
|
38
|
+
transformNodes.forEach(node => applyMetaData(node));
|
|
39
|
+
lights.forEach(node => applyMetaData(node));
|
|
40
|
+
skeletons.forEach(node => applyMetaData(node));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Engine, Scene, Node } from "@babylonjs/core";
|
|
2
|
+
import '@babylonjs/materials';
|
|
3
|
+
import '@babylonjs/loaders';
|
|
4
|
+
import '@babylonjs/post-processes';
|
|
5
|
+
import '@babylonjs/procedural-textures';
|
|
6
|
+
/**
|
|
7
|
+
* 脚本接口
|
|
8
|
+
*/
|
|
9
|
+
export interface ScriptsMap {
|
|
10
|
+
[index: string]: IScript | Function;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 字符串字典
|
|
14
|
+
*/
|
|
15
|
+
export interface IStringDictionary<T> {
|
|
16
|
+
[index: string]: T;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 行为脚本接口
|
|
20
|
+
*/
|
|
21
|
+
export interface BehaviorScript {
|
|
22
|
+
type: 'script';
|
|
23
|
+
disabled: boolean;
|
|
24
|
+
isLoss?: boolean;
|
|
25
|
+
key: string;
|
|
26
|
+
values: IStringDictionary<any>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 运行场景加载的核心类
|
|
30
|
+
* @description 在这里创建初始化场景所需要的一切的东西
|
|
31
|
+
*/
|
|
32
|
+
export declare class SceneLoader {
|
|
33
|
+
/**
|
|
34
|
+
* 场景容器
|
|
35
|
+
*/
|
|
36
|
+
container: HTMLElement;
|
|
37
|
+
/**
|
|
38
|
+
* 画布
|
|
39
|
+
*/
|
|
40
|
+
canvas: HTMLCanvasElement;
|
|
41
|
+
/**
|
|
42
|
+
* 引擎
|
|
43
|
+
*/
|
|
44
|
+
engine: Engine;
|
|
45
|
+
/**
|
|
46
|
+
* 场景
|
|
47
|
+
*/
|
|
48
|
+
scene: Scene;
|
|
49
|
+
/**
|
|
50
|
+
* 场景数据
|
|
51
|
+
*/
|
|
52
|
+
sceneData: string;
|
|
53
|
+
/**
|
|
54
|
+
* 脚本代码列表
|
|
55
|
+
*/
|
|
56
|
+
scriptsMap: ScriptsMap;
|
|
57
|
+
/**
|
|
58
|
+
* 脚本实例列表
|
|
59
|
+
*/
|
|
60
|
+
private scriptInstanceList;
|
|
61
|
+
/**
|
|
62
|
+
* 构造函数
|
|
63
|
+
* @param container 容器
|
|
64
|
+
* @param sceneData 场景数据
|
|
65
|
+
* @param scriptsMap 脚本代码列表
|
|
66
|
+
*/
|
|
67
|
+
constructor(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap);
|
|
68
|
+
/**
|
|
69
|
+
* 加载场景
|
|
70
|
+
* @param sceneData 场景数据数据
|
|
71
|
+
* @param scriptsMap 代码脚本地图
|
|
72
|
+
*/
|
|
73
|
+
load(sceneData: string, scriptsMap?: ScriptsMap): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* 初始化脚本
|
|
76
|
+
*/
|
|
77
|
+
private initScripts;
|
|
78
|
+
/**
|
|
79
|
+
* 执行代码
|
|
80
|
+
* @param node 代码绑定对象
|
|
81
|
+
* @param scriptsMap 注入的全部脚本
|
|
82
|
+
* @param scriptList 对象绑定的代码列表
|
|
83
|
+
* @returns
|
|
84
|
+
*/
|
|
85
|
+
private runScript;
|
|
86
|
+
/**
|
|
87
|
+
* 开始渲染循环
|
|
88
|
+
*/
|
|
89
|
+
private render;
|
|
90
|
+
/**
|
|
91
|
+
* 重置canvas变形后的系统尺寸
|
|
92
|
+
*/
|
|
93
|
+
resize(): void;
|
|
94
|
+
dispose(): void;
|
|
95
|
+
/**
|
|
96
|
+
* 加载自定义组件系统。比如天气系统,模型系统
|
|
97
|
+
*/
|
|
98
|
+
static LoadCustomSystem(): void;
|
|
99
|
+
}
|
|
100
|
+
export declare function loadScene(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap): SceneLoader;
|
|
101
|
+
/**
|
|
102
|
+
* 脚本代码结构
|
|
103
|
+
*/
|
|
104
|
+
export type IScript = {
|
|
105
|
+
/**
|
|
106
|
+
* 脚执行时注入的场景对象
|
|
107
|
+
*/
|
|
108
|
+
scene: Scene;
|
|
109
|
+
/**
|
|
110
|
+
* 当前实例化脚本绑定的对象
|
|
111
|
+
*/
|
|
112
|
+
node: Node | Scene;
|
|
113
|
+
/**
|
|
114
|
+
* 脚本初始化执行的钩子函数
|
|
115
|
+
*/
|
|
116
|
+
start?: () => void;
|
|
117
|
+
/**
|
|
118
|
+
* 当有异步动作初始化完成时的钩子函数
|
|
119
|
+
*/
|
|
120
|
+
ready?: () => void;
|
|
121
|
+
/**
|
|
122
|
+
* 当没帧渲染是执行函数
|
|
123
|
+
* @param deltaTime 间隔时间
|
|
124
|
+
*/
|
|
125
|
+
update?: (deltaTime: number) => void;
|
|
126
|
+
/**
|
|
127
|
+
* 当对象被销毁时执行的函数
|
|
128
|
+
*/
|
|
129
|
+
dispose?: () => void;
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=SceneLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneLoader.d.ts","sourceRoot":"","sources":["../../../src/tool/SceneLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAsF,IAAI,EAAiB,MAAM,iBAAiB,CAAC;AACzJ,OAAO,sBAAsB,CAAA;AAC7B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,2BAA2B,CAAA;AAClC,OAAO,gCAAgC,CAAA;AAIvC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAE7B,IAAI,EAAE,QAAQ,CAAC;IAEf,QAAQ,EAAE,OAAO,CAAC;IAElB,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAA;CAC/B;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB;;OAEG;IACH,SAAS,EAAE,WAAW,CAAA;IACtB;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAAA;IACzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IACZ;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;IACtB;;OAEG;IACH,UAAU,EAAE,UAAU,CAAK;IAC3B;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAgB;IAC1C;;;;;OAKG;gBACS,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU;IAajF;;;;OAIG;IACG,IAAI,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU;IA4CtD;;OAEG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA4BjB;;OAEG;IACH,OAAO,CAAC,MAAM;IAOd;;OAEG;IACH,MAAM;IAIN,OAAO;IAKP;;OAEG;IACH,MAAM,CAAC,gBAAgB;CACxB;AAED,wBAAgB,SAAS,CAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,UAAe,eAInG;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;IACb;;OAEG;IACH,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAA"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Engine, Scene, FreeCamera, Vector3, HavokPlugin, AppendSceneAsync } from "@babylonjs/core";
|
|
2
|
+
import '@babylonjs/materials';
|
|
3
|
+
import '@babylonjs/loaders';
|
|
4
|
+
import '@babylonjs/post-processes';
|
|
5
|
+
import '@babylonjs/procedural-textures';
|
|
6
|
+
import HavokPhysics from "@babylonjs/havok";
|
|
7
|
+
import { CustomSystem } from "./CustomSystem";
|
|
8
|
+
/**
|
|
9
|
+
* 运行场景加载的核心类
|
|
10
|
+
* @description 在这里创建初始化场景所需要的一切的东西
|
|
11
|
+
*/
|
|
12
|
+
export class SceneLoader {
|
|
13
|
+
/**
|
|
14
|
+
* 构造函数
|
|
15
|
+
* @param container 容器
|
|
16
|
+
* @param sceneData 场景数据
|
|
17
|
+
* @param scriptsMap 脚本代码列表
|
|
18
|
+
*/
|
|
19
|
+
constructor(container, sceneData, scriptsMap) {
|
|
20
|
+
/**
|
|
21
|
+
* 场景数据
|
|
22
|
+
*/
|
|
23
|
+
this.sceneData = '';
|
|
24
|
+
/**
|
|
25
|
+
* 脚本代码列表
|
|
26
|
+
*/
|
|
27
|
+
this.scriptsMap = {};
|
|
28
|
+
/**
|
|
29
|
+
* 脚本实例列表
|
|
30
|
+
*/
|
|
31
|
+
this.scriptInstanceList = [];
|
|
32
|
+
this.container = container;
|
|
33
|
+
this.canvas = document.createElement('canvas');
|
|
34
|
+
this.canvas.className = 'main-display-canvas';
|
|
35
|
+
this.canvas.width = container.clientWidth;
|
|
36
|
+
this.canvas.height = container.clientHeight;
|
|
37
|
+
this.container.appendChild(this.canvas);
|
|
38
|
+
this.engine = new Engine(this.canvas, true);
|
|
39
|
+
this.scene = new Scene(this.engine);
|
|
40
|
+
this.load(sceneData, scriptsMap);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 加载场景
|
|
44
|
+
* @param sceneData 场景数据数据
|
|
45
|
+
* @param scriptsMap 代码脚本地图
|
|
46
|
+
*/
|
|
47
|
+
async load(sceneData, scriptsMap) {
|
|
48
|
+
if (this.scene) {
|
|
49
|
+
this.scene.dispose();
|
|
50
|
+
}
|
|
51
|
+
if (scriptsMap)
|
|
52
|
+
this.scriptsMap = scriptsMap;
|
|
53
|
+
this.scene = new Scene(this.engine);
|
|
54
|
+
this.sceneData = sceneData;
|
|
55
|
+
this.scriptInstanceList = [];
|
|
56
|
+
// 执行更新代码
|
|
57
|
+
this.scene.onBeforeRenderObservable.add(() => {
|
|
58
|
+
if (this.scriptInstanceList) {
|
|
59
|
+
const deltaTime = this.engine.getDeltaTime();
|
|
60
|
+
for (let i = 0; i < this.scriptInstanceList.length; i++) {
|
|
61
|
+
const script = this.scriptInstanceList[i];
|
|
62
|
+
if (script.update) {
|
|
63
|
+
script.update(deltaTime);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const havokModule = await HavokPhysics();
|
|
69
|
+
this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));
|
|
70
|
+
await AppendSceneAsync('data:' + sceneData, this.scene);
|
|
71
|
+
let camera;
|
|
72
|
+
if (this.scene.cameras.length === 0) {
|
|
73
|
+
camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true);
|
|
74
|
+
console.log('场景中无摄影机,自动创建摄影机');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
camera = this.scene.activeCamera || this.scene.cameras[0];
|
|
78
|
+
console.log('解析并使用场景摄影机');
|
|
79
|
+
}
|
|
80
|
+
camera.attachControl(this.canvas);
|
|
81
|
+
if (scriptsMap)
|
|
82
|
+
this.initScripts(scriptsMap);
|
|
83
|
+
console.log('完成场景初始化');
|
|
84
|
+
new CustomSystem(this.scene, this.scriptInstanceList);
|
|
85
|
+
this.render();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 初始化脚本
|
|
89
|
+
*/
|
|
90
|
+
initScripts(scriptsMap) {
|
|
91
|
+
if (!scriptsMap)
|
|
92
|
+
return;
|
|
93
|
+
if (this.scene.metadata) {
|
|
94
|
+
const scriptList = this.scene.metadata.scripts;
|
|
95
|
+
if (scriptList && scriptList.length > 0) {
|
|
96
|
+
this.runScript(this.scene, scriptsMap, scriptList);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const nodes = this.scene.getNodes();
|
|
100
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
101
|
+
const node = nodes[i];
|
|
102
|
+
if (node.metadata?.scripts && node.metadata.scripts.length > 0) {
|
|
103
|
+
this.runScript(node, scriptsMap, node.metadata.scripts);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 执行代码
|
|
109
|
+
* @param node 代码绑定对象
|
|
110
|
+
* @param scriptsMap 注入的全部脚本
|
|
111
|
+
* @param scriptList 对象绑定的代码列表
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
runScript(node, scriptsMap, scriptList) {
|
|
115
|
+
if (!scriptList)
|
|
116
|
+
return;
|
|
117
|
+
for (let i = 0; i < scriptList.length; i++) {
|
|
118
|
+
const script = scriptList[i];
|
|
119
|
+
for (const key in scriptsMap) {
|
|
120
|
+
if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {
|
|
121
|
+
if (key === script.key && script.disabled !== true) {
|
|
122
|
+
let constructor = scriptsMap[script.key];
|
|
123
|
+
if (constructor instanceof Function) {
|
|
124
|
+
const instance = new (constructor)(this.scene, node, script.values || {});
|
|
125
|
+
if (instance.start)
|
|
126
|
+
instance.start();
|
|
127
|
+
if (instance.dispose && node.onDisposeObservable) {
|
|
128
|
+
const callback = instance.dispose;
|
|
129
|
+
node.onDisposeObservable.addOnce(callback.bind(instance));
|
|
130
|
+
}
|
|
131
|
+
this.scriptInstanceList.push(instance);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 开始渲染循环
|
|
140
|
+
*/
|
|
141
|
+
render() {
|
|
142
|
+
let scene = this.scene;
|
|
143
|
+
this.engine.runRenderLoop(() => {
|
|
144
|
+
scene.render();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 重置canvas变形后的系统尺寸
|
|
149
|
+
*/
|
|
150
|
+
resize() {
|
|
151
|
+
this.engine.resize();
|
|
152
|
+
}
|
|
153
|
+
dispose() {
|
|
154
|
+
this.scene.dispose();
|
|
155
|
+
this.engine.dispose();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 加载自定义组件系统。比如天气系统,模型系统
|
|
159
|
+
*/
|
|
160
|
+
static LoadCustomSystem() { }
|
|
161
|
+
}
|
|
162
|
+
export function loadScene(container, sceneData, scriptsMap = {}) {
|
|
163
|
+
const sceneLoader = new SceneLoader(container, sceneData, scriptsMap);
|
|
164
|
+
return sceneLoader;
|
|
165
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tool/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SceneLoader';
|