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);
}
};