babyeditor-tool 0.0.5

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/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # babyeditor-tool
2
+
3
+ 三维场景编辑器 BabyEditor 的官方场景工具库,基于 Babylon.js,适用于 WebGL/WebGPU 项目,支持场景加载、导出、编辑等功能。
4
+
5
+ ## 特性
6
+ - 支持 Babylon.js 场景文件的加载与导出
7
+ - 适用于现代 WebGL/WebGPU 应用
8
+ - 体积小,易于集成
9
+ - TypeScript 类型支持
10
+
11
+ ## 安装
12
+
13
+ ```bash
14
+ npm install babyeditor-tool
15
+ # 或者
16
+ yarn add babyeditor-tool
17
+ ```
18
+
19
+ ## 使用示例
20
+
21
+ ```js
22
+ import { loadScene } from 'babyeditor-tool';
23
+ import SceneScript from './scene.script'
24
+
25
+ const scriptMap = {
26
+ 'mapkey': SceneScript
27
+ }
28
+
29
+ // 加载场景
30
+ const sceneLoader = loadScene(div, sceneData, scriptMap);
31
+ ```
32
+
33
+ ## API 文档
34
+ 详见 [类型定义文件](./types/index.d.ts) 或源码注释。
35
+
36
+ ## 依赖
37
+ - [babylonjs](https://www.npmjs.com/package/babylonjs) >= 8.0.0
38
+
@@ -0,0 +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");var t=Object.defineProperty,n=(e,s,n)=>((e,s,n)=>s in e?t(e,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[s]=n)(e,"symbol"!=typeof s?s+"":s,n);class i{constructor(s,t,i){n(this,"container"),n(this,"canvas"),n(this,"engine"),n(this,"scene"),n(this,"sceneData",""),n(this,"scritpsMap",{}),n(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,i)}async load(t,n){this.scene&&this.scene.dispose(),n&&(this.scritpsMap=n),this.scene=new e.Scene(this.engine),this.sceneData=t,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 i=await s();let a;this.scene.enablePhysics(new e.Vector3(0,-9.81,0),new e.HavokPlugin(!0,i)),await e.AppendSceneAsync("data:"+t,this.scene),a=0===this.scene.cameras.length?new e.FreeCamera("摄影机",new e.Vector3(50,50,50),this.scene,!0):this.scene.activeCamera||this.scene.cameras[0],a.attachControl(this.canvas),n&&this.initScripts(n),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()}}exports.SceneLoader=i,exports.loadScene=function(e,s,t={}){return new i(e,s,t)};
2
+ //# sourceMappingURL=babyeditor.tool.cjs.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,148 @@
1
+ import { Engine, Scene, Vector3, HavokPlugin, AppendSceneAsync, FreeCamera } 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
+ var __defProp = Object.defineProperty;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
+ class SceneLoader {
11
+ /**
12
+ * 构造函数
13
+ * @param container 容器
14
+ * @param sceneData 场景数据
15
+ * @param scriptsMap 脚本代码列表
16
+ */
17
+ constructor(container, sceneData, scriptsMap) {
18
+ __publicField(this, "container");
19
+ __publicField(this, "canvas");
20
+ __publicField(this, "engine");
21
+ __publicField(this, "scene");
22
+ __publicField(this, "sceneData", "");
23
+ __publicField(this, "scritpsMap", {});
24
+ __publicField(this, "scriptInstanceList", []);
25
+ this.container = container;
26
+ this.canvas = document.createElement("canvas");
27
+ this.canvas.className = "main-display-canvas";
28
+ this.canvas.width = container.clientWidth;
29
+ this.canvas.height = container.clientHeight;
30
+ this.container.appendChild(this.canvas);
31
+ this.engine = new Engine(this.canvas, true);
32
+ this.scene = new Scene(this.engine);
33
+ this.load(sceneData, scriptsMap);
34
+ }
35
+ /**
36
+ * 加载场景
37
+ * @param sceneData 场景数据数据
38
+ * @param scriptsMap 代码脚本地图
39
+ */
40
+ async load(sceneData, scriptsMap) {
41
+ if (this.scene) {
42
+ this.scene.dispose();
43
+ }
44
+ if (scriptsMap) this.scritpsMap = scriptsMap;
45
+ this.scene = new Scene(this.engine);
46
+ this.sceneData = sceneData;
47
+ this.scriptInstanceList = [];
48
+ this.scene.onBeforeRenderObservable.add(() => {
49
+ if (this.scriptInstanceList) {
50
+ const deltaTime = this.engine.getDeltaTime();
51
+ for (let i = 0; i < this.scriptInstanceList.length; i++) {
52
+ const script = this.scriptInstanceList[i];
53
+ if (script.update) {
54
+ script.update(deltaTime);
55
+ }
56
+ }
57
+ }
58
+ });
59
+ const havokModule = await HavokPhysics();
60
+ this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));
61
+ await AppendSceneAsync("data:" + sceneData, this.scene);
62
+ let camera;
63
+ if (this.scene.cameras.length === 0) {
64
+ camera = new FreeCamera("摄影机", new Vector3(50, 50, 50), this.scene, true);
65
+ } else {
66
+ camera = this.scene.activeCamera || this.scene.cameras[0];
67
+ }
68
+ camera.attachControl(this.canvas);
69
+ if (scriptsMap) this.initScripts(scriptsMap);
70
+ this.render();
71
+ }
72
+ /**
73
+ * 初始化脚本
74
+ */
75
+ initScripts(scriptsMap) {
76
+ if (!scriptsMap) return;
77
+ if (this.scene.metadata) {
78
+ const scriptList = this.scene.metadata.scripts;
79
+ if (scriptList && scriptList.length > 0) {
80
+ this.runScript(this.scene, scriptsMap, scriptList);
81
+ }
82
+ }
83
+ const nodes = this.scene.getNodes();
84
+ for (let i = 0; i < nodes.length; i++) {
85
+ const node = nodes[i];
86
+ if (node.metadata?.scripts && node.metadata.scripts.length > 0) {
87
+ this.runScript(node, scriptsMap, node.metadata.scripts);
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * 执行代码
93
+ * @param node 代码绑定对象
94
+ * @param scriptsMap 注入的全部脚本
95
+ * @param scriptList 对象绑定的代码列表
96
+ * @returns
97
+ */
98
+ runScript(node, scriptsMap, scriptList) {
99
+ if (!scriptList) return;
100
+ for (let i = 0; i < scriptList.length; i++) {
101
+ const script = scriptList[i];
102
+ for (const key in scriptsMap) {
103
+ if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {
104
+ if (key === script.key && script.disabled !== true) {
105
+ let constructor = scriptsMap[script.key];
106
+ if (constructor instanceof Function) {
107
+ const instance = new constructor(this.scene, node, script.values || {});
108
+ if (instance.start) instance.start();
109
+ if (instance.dispose && node.onDisposeObservable) {
110
+ const callback = instance.dispose;
111
+ node.onDisposeObservable.addOnce(callback.bind(instance));
112
+ }
113
+ this.scriptInstanceList.push(instance);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ /**
121
+ * 开始渲染循环
122
+ */
123
+ render() {
124
+ let scene = this.scene;
125
+ this.engine.runRenderLoop(() => {
126
+ scene.render();
127
+ });
128
+ }
129
+ /**
130
+ * 重置canvas变形后的系统尺寸
131
+ */
132
+ resize() {
133
+ this.engine.resize();
134
+ }
135
+ dispose() {
136
+ this.scene.dispose();
137
+ this.engine.dispose();
138
+ }
139
+ }
140
+ function loadScene(container, sceneData, scriptsMap = {}) {
141
+ const sceneLoader = new SceneLoader(container, sceneData, scriptsMap);
142
+ return sceneLoader;
143
+ }
144
+ export {
145
+ SceneLoader,
146
+ loadScene
147
+ };
148
+ //# sourceMappingURL=babyeditor.tool.es.js.map
@@ -0,0 +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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"}
@@ -0,0 +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,c){"use strict";var r=Object.defineProperty,o=(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){o(this,"container"),o(this,"canvas"),o(this,"engine"),o(this,"scene"),o(this,"sceneData",""),o(this,"scritpsMap",{}),o(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.scritpsMap=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 c();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),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()}}e.SceneLoader=h,e.loadScene=function(e,s,t={}){return new h(e,s,t)},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
2
+ //# sourceMappingURL=babyeditor.tool.umd.js.map
@@ -0,0 +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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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "babyeditor-tool",
3
+ "version": "0.0.5",
4
+ "description": "BabyEditor场景加载工具库",
5
+ "main": "dist/babyeditor.tool.cjs.js",
6
+ "module": "distbabyeditor.tool.es.js",
7
+ "unpkg": "distbabyeditor.tool.umd.js",
8
+ "types": "types/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/babyeditor.tool.es.js",
12
+ "require": "./dist/babyeditor.tool.cjs.js",
13
+ "types": "./dist/types/index.d.ts"
14
+ }
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/happypaner/babyeditor-tool.git"
19
+ },
20
+ "keywords": [
21
+ "babylonjs",
22
+ "editor",
23
+ "3d",
24
+ "tool",
25
+ "webgl",
26
+ "webgpu"
27
+ ],
28
+ "author": "happypaner",
29
+ "license": "MIT",
30
+ "bugs": {
31
+ "url": "https://github.com/happypaner/babyeditor-tool/issues"
32
+ },
33
+ "homepage": "https://github.com/happypaner/babyeditor-tool#readme",
34
+ "scripts": {
35
+ "publish": "npm publish --access public"
36
+ }
37
+ }
@@ -0,0 +1,102 @@
1
+ import { Engine, Scene } 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
+ scritpsMap: 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
+ export declare function loadScene(container: HTMLDivElement, sceneData: string, scriptsMap?: ScriptsMap): SceneLoader;
97
+ export type IScript = {
98
+ start?: () => void;
99
+ update?: (deltaTime: number) => void;
100
+ dispose?: () => void;
101
+ };
102
+ //# 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,EAA2G,MAAM,iBAAiB,CAAC;AACzJ,OAAO,sBAAsB,CAAA;AAC7B,OAAO,oBAAoB,CAAA;AAC3B,OAAO,2BAA2B,CAAA;AAClC,OAAO,gCAAgC,CAAA;AAGvC;;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;IA0CtD;;OAEG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA4BjB;;OAEG;IACH,OAAO,CAAC,MAAM;IAOd;;OAEG;IACH,MAAM;IAIN,OAAO;CAIR;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"}
@@ -0,0 +1,159 @@
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
+ /**
8
+ * 运行场景加载的核心类
9
+ * @description 在这里创建初始化场景所需要的一切的东西
10
+ */
11
+ export class SceneLoader {
12
+ /**
13
+ * 构造函数
14
+ * @param container 容器
15
+ * @param sceneData 场景数据
16
+ * @param scriptsMap 脚本代码列表
17
+ */
18
+ constructor(container, sceneData, scriptsMap) {
19
+ /**
20
+ * 场景数据
21
+ */
22
+ this.sceneData = '';
23
+ /**
24
+ * 脚本代码列表
25
+ */
26
+ this.scritpsMap = {};
27
+ /**
28
+ * 脚本实例列表
29
+ */
30
+ this.scriptInstanceList = [];
31
+ this.container = container;
32
+ this.canvas = document.createElement('canvas');
33
+ this.canvas.className = 'main-display-canvas';
34
+ this.canvas.width = container.clientWidth;
35
+ this.canvas.height = container.clientHeight;
36
+ this.container.appendChild(this.canvas);
37
+ this.engine = new Engine(this.canvas, true);
38
+ this.scene = new Scene(this.engine);
39
+ this.load(sceneData, scriptsMap);
40
+ }
41
+ /**
42
+ * 加载场景
43
+ * @param sceneData 场景数据数据
44
+ * @param scriptsMap 代码脚本地图
45
+ */
46
+ async load(sceneData, scriptsMap) {
47
+ if (this.scene) {
48
+ this.scene.dispose();
49
+ }
50
+ if (scriptsMap)
51
+ this.scritpsMap = scriptsMap;
52
+ this.scene = new Scene(this.engine);
53
+ this.sceneData = sceneData;
54
+ this.scriptInstanceList = [];
55
+ // 执行更新代码
56
+ this.scene.onBeforeRenderObservable.add(() => {
57
+ if (this.scriptInstanceList) {
58
+ const deltaTime = this.engine.getDeltaTime();
59
+ for (let i = 0; i < this.scriptInstanceList.length; i++) {
60
+ const script = this.scriptInstanceList[i];
61
+ if (script.update) {
62
+ script.update(deltaTime);
63
+ }
64
+ }
65
+ }
66
+ });
67
+ const havokModule = await HavokPhysics();
68
+ this.scene.enablePhysics(new Vector3(0, -9.81, 0), new HavokPlugin(true, havokModule));
69
+ await AppendSceneAsync('data:' + sceneData, this.scene);
70
+ let camera;
71
+ if (this.scene.cameras.length === 0) {
72
+ camera = new FreeCamera('摄影机', new Vector3(50, 50, 50), this.scene, true);
73
+ console.log('场景中无摄影机,自动创建摄影机');
74
+ }
75
+ else {
76
+ camera = this.scene.activeCamera || this.scene.cameras[0];
77
+ console.log('解析并使用场景摄影机');
78
+ }
79
+ camera.attachControl(this.canvas);
80
+ if (scriptsMap)
81
+ this.initScripts(scriptsMap);
82
+ console.log('完成场景初始化');
83
+ this.render();
84
+ }
85
+ /**
86
+ * 初始化脚本
87
+ */
88
+ initScripts(scriptsMap) {
89
+ if (!scriptsMap)
90
+ return;
91
+ if (this.scene.metadata) {
92
+ const scriptList = this.scene.metadata.scripts;
93
+ if (scriptList && scriptList.length > 0) {
94
+ this.runScript(this.scene, scriptsMap, scriptList);
95
+ }
96
+ }
97
+ const nodes = this.scene.getNodes();
98
+ for (let i = 0; i < nodes.length; i++) {
99
+ const node = nodes[i];
100
+ if (node.metadata?.scripts && node.metadata.scripts.length > 0) {
101
+ this.runScript(node, scriptsMap, node.metadata.scripts);
102
+ }
103
+ }
104
+ }
105
+ /**
106
+ * 执行代码
107
+ * @param node 代码绑定对象
108
+ * @param scriptsMap 注入的全部脚本
109
+ * @param scriptList 对象绑定的代码列表
110
+ * @returns
111
+ */
112
+ runScript(node, scriptsMap, scriptList) {
113
+ if (!scriptList)
114
+ return;
115
+ for (let i = 0; i < scriptList.length; i++) {
116
+ const script = scriptList[i];
117
+ for (const key in scriptsMap) {
118
+ if (Object.prototype.hasOwnProperty.call(scriptsMap, key)) {
119
+ if (key === script.key && script.disabled !== true) {
120
+ let constructor = scriptsMap[script.key];
121
+ if (constructor instanceof Function) {
122
+ const instance = new (constructor)(this.scene, node, script.values || {});
123
+ if (instance.start)
124
+ instance.start();
125
+ if (instance.dispose && node.onDisposeObservable) {
126
+ const callback = instance.dispose;
127
+ node.onDisposeObservable.addOnce(callback.bind(instance));
128
+ }
129
+ this.scriptInstanceList.push(instance);
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ /**
137
+ * 开始渲染循环
138
+ */
139
+ render() {
140
+ let scene = this.scene;
141
+ this.engine.runRenderLoop(() => {
142
+ scene.render();
143
+ });
144
+ }
145
+ /**
146
+ * 重置canvas变形后的系统尺寸
147
+ */
148
+ resize() {
149
+ this.engine.resize();
150
+ }
151
+ dispose() {
152
+ this.scene.dispose();
153
+ this.engine.dispose();
154
+ }
155
+ }
156
+ export function loadScene(container, sceneData, scriptsMap = {}) {
157
+ const sceneLoader = new SceneLoader(container, sceneData, scriptsMap);
158
+ return sceneLoader;
159
+ }
@@ -0,0 +1,2 @@
1
+ export * from './SceneLoader';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA"}
package/types/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './SceneLoader';