From 6c94559383a9e405cae0587bcdc9ec8642e54541 Mon Sep 17 00:00:00 2001 From: zguiy <1415466602@qq.com> Date: Fri, 24 Apr 2026 12:18:24 +0800 Subject: [PATCH] 1 --- assets/{百叶1.glb => 百叶A.glb} | Bin assets/{百叶2.glb => 百叶B.glb} | Bin assets/{百叶3.glb => 百叶C.glb} | Bin assets/{百叶4.glb => 百叶D.glb} | Bin index.html | 40 ++++++++++++-------- src/babylonjs/AppModel.ts | 63 +++++++++++++++++--------------- src/kernel/Adapter.ts | 16 ++++++-- 7 files changed, 70 insertions(+), 49 deletions(-) rename assets/{百叶1.glb => 百叶A.glb} (100%) rename assets/{百叶2.glb => 百叶B.glb} (100%) rename assets/{百叶3.glb => 百叶C.glb} (100%) rename assets/{百叶4.glb => 百叶D.glb} (100%) diff --git a/assets/百叶1.glb b/assets/百叶A.glb similarity index 100% rename from assets/百叶1.glb rename to assets/百叶A.glb diff --git a/assets/百叶2.glb b/assets/百叶B.glb similarity index 100% rename from assets/百叶2.glb rename to assets/百叶B.glb diff --git a/assets/百叶3.glb b/assets/百叶C.glb similarity index 100% rename from assets/百叶3.glb rename to assets/百叶C.glb diff --git a/assets/百叶4.glb b/assets/百叶D.glb similarity index 100% rename from assets/百叶4.glb rename to assets/百叶D.glb diff --git a/index.html b/index.html index 4d25b21..dd29883 100644 --- a/index.html +++ b/index.html @@ -275,19 +275,19 @@
- +
- +
- +
- +
@@ -365,10 +365,11 @@ // 多选复选框逻辑 document.querySelectorAll('.option-checkbox input[type="checkbox"]').forEach(checkbox => { - checkbox.addEventListener('change', function () { + checkbox.addEventListener('change', async function () { const category = this.closest('.config-category'); const categoryName = category.querySelector('.category-header').dataset.category; const optionGroup = this.closest('.option-group'); + const checked = this.checked; // 获取当前组所有选中的值 const selectedValues = Array.from( @@ -395,17 +396,26 @@ checked: this.checked, currentValue: this.dataset.option }); - if (category === "louver") { - selectedValues.forEach(element => { - if (checked) { - kernel.model.add(element.text,`https://sdk.zguiy.com/resurces/model/${element.text}.glb`); - } else { - kernel.model.destroy(element.text); - } - }); - } - // kernel.model.add('https://sdk.zguiy.com/resurces/model/百叶1.glb'); + // 百叶模型加载/卸载逻辑 + if (categoryName === "louver") { + const currentText = this.nextElementSibling.textContent; + const modelUrl = `https://sdk.zguiy.com/resurces/model/${currentText}.glb`; + console.log(modelUrl); + if (checked) { + // 加载模型 + try { + await kernel.model.add(currentText, modelUrl); + console.log(`模型 ${currentText} 加载成功`); + } catch (error) { + console.error(`模型 ${currentText} 加载失败:`, error); + } + } else { + // 卸载模型 + kernel.model.remove(currentText); + console.log(`模型 ${currentText} 已卸载`); + } + } }); }); diff --git a/src/babylonjs/AppModel.ts b/src/babylonjs/AppModel.ts index c6037a0..01ccbfc 100644 --- a/src/babylonjs/AppModel.ts +++ b/src/babylonjs/AppModel.ts @@ -19,7 +19,7 @@ type LoadResult = { * 模型管理类- 负责加载、缓存和管理3D模型 */ export class AppModel extends Monobehiver { - private modelDic: Dictionary; + private modelDic: Dictionary; private loadedMeshes: AbstractMesh[]; private skeletonManager: any; private outfitManager: any; @@ -28,7 +28,7 @@ export class AppModel extends Monobehiver { constructor(mainApp: any) { super(mainApp); - this.modelDic = new Dictionary(); + this.modelDic = new Dictionary(); this.loadedMeshes = []; this.skeletonManager = null; this.outfitManager = null; @@ -96,16 +96,14 @@ export class AppModel extends Monobehiver { */ async loadSingleModel(modelUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void): Promise { try { - const cached = this.getCachedMeshes(modelUrl); - if (cached) return { success: true, meshes: cached }; - const scene: Scene | null = this.mainApp.appScene.object; if (!scene) return { success: false, error: '场景未初始化' }; const result = await ImportMeshAsync(modelUrl, scene, { onProgress }); if (!result?.meshes?.length) return { success: false, error: '未找到网格' }; - this.modelDic.Set(modelUrl, result.meshes); + // 存储根网格(通常是第一个网格) + const rootMesh = result.meshes[0]; this.loadedMeshes.push(...result.meshes); return { success: true, meshes: result.meshes, skeletons: result.skeletons }; } catch (e: any) { @@ -131,12 +129,12 @@ export class AppModel extends Monobehiver { } /** 获取缓存的网格 */ - getCachedMeshes(url: string): AbstractMesh[] | undefined { + getCachedMeshes(url: string): AbstractMesh | undefined { return this.modelDic.Get(url); } - + /** 清理所有资源 */ clean(): void { @@ -151,9 +149,19 @@ export class AppModel extends Monobehiver { /** * 添加模型到场景 + * @param modelName 模型名称(用于后续引用) * @param modelUrl 模型URL路径 */ - async addModel(modelUrl: string): Promise { + async add(modelName: string, modelUrl: string): Promise { + // 检查是否已经存在该模型 + const existingMesh = this.modelDic.Get(modelName); + if (existingMesh && !existingMesh.isDisposed()) { + console.log(`模型 ${modelName} 已存在,直接显示`); + existingMesh.setEnabled(true); + existingMesh.getChildMeshes().forEach(child => child.setEnabled(true)); + return { success: true, meshes: [existingMesh, ...existingMesh.getChildMeshes()] }; + } + const handleProgress = (event: ISceneLoaderProgressEvent): void => { const progress = event.lengthComputable && event.total > 0 ? Math.min(1, event.loaded / event.total) @@ -175,7 +183,10 @@ export class AppModel extends Monobehiver { const result = await this.loadSingleModel(modelUrl, handleProgress); - if (result.success) { + if (result.success && result.meshes) { + // 使用modelName作为key存储根网格 + const rootMesh = result.meshes[0]; + this.modelDic.Set(modelName, rootMesh); EventBridge.modelLoaded({ urls: [modelUrl] }); } else { EventBridge.modelLoadError({ url: modelUrl, error: result.error }); @@ -191,35 +202,27 @@ export class AppModel extends Monobehiver { */ async replaceModel(modelName: string, newModelUrl: string): Promise { // 先销毁旧模型 - this.destroyModel(modelName); + this.remove(modelName); // 加载新模型 - return await this.addModel(newModelUrl); + return await this.add(modelName, newModelUrl); } /** * 销毁指定模型 * @param modelName 模型名称 */ - destroyModel(modelName: string): void { - // 遍历模型字典,查找匹配的模型 - const keys = this.modelDic.Keys(); - for (const key of keys) { - if (key.includes(modelName)) { - const meshes = this.modelDic.Get(key); - if (meshes) { - // 销毁所有网格 - meshes.forEach(mesh => mesh?.dispose()); - // 从字典中移除 - this.modelDic.Remove(key); - // 从加载的网格列表中移除 - this.loadedMeshes = this.loadedMeshes.filter(mesh => !meshes.includes(mesh)); - console.log(`Model destroyed: ${modelName}`); - return; - } - } + remove(modelName: string): void { + const mesh = this.modelDic.Get(modelName); + if (mesh) { + // 隐藏网格而不是销毁,以便后续可以重新显示 + mesh.setEnabled(false); + mesh.getChildMeshes().forEach(child => child.setEnabled(false)); + + console.log(`Model hidden: ${modelName}`); + } else { + console.warn(`Model not found: ${modelName}`); } - console.warn(`Model not found: ${modelName}`); } } diff --git a/src/kernel/Adapter.ts b/src/kernel/Adapter.ts index aa71224..fd3da62 100644 --- a/src/kernel/Adapter.ts +++ b/src/kernel/Adapter.ts @@ -17,15 +17,15 @@ export class KernelAdapter { * 添加模型到场景 * @param modelUrl 模型URL路径 */ - add: async (modelUrl: string): Promise => { - await this.mainApp.appModel.addModel(modelUrl); + add: async (name:string,modelUrl: string): Promise => { + await this.mainApp.appModel.add(name,modelUrl); }, /** * 销毁指定模型 * @param modelName 模型名称 */ - destroy: (modelName: string): void => { - this.mainApp.appModel.destroyModel(modelName); + remove: (modelName: string): void => { + this.mainApp.appModel.remove(modelName); }, /** * 替换模型 @@ -45,6 +45,14 @@ export class KernelAdapter { */ apply: (options: { target: string; attribute: string,value:number|string }): void => { this.mainApp.gameManager.applyMaterial(options.target, options.attribute,options.value); + }, + /** + * 更换材质颜色 + * @param materialName 材质名称 + * @param hexColor 16进制颜色值,例如 "#FF0000" + */ + color: (materialName: string, hexColor: string): void => { + this.mainApp.gameManager.applyMaterial(materialName, 'baseColor', hexColor); } };