From ce73c35b8a5e98854c59b66d910b7215c1cbd18d Mon Sep 17 00:00:00 2001 From: zguiy <1415466602@qq.com> Date: Thu, 14 May 2026 12:09:10 +0800 Subject: [PATCH] =?UTF-8?q?=E7=82=B9=E5=87=BB=E7=A9=BA=E7=99=BD=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E6=94=BE=E7=BD=AE=E5=8C=BA=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 1 + index.js | 21 --------------------- src/babylonjs/AppModel.ts | 31 ++++++++++++++++++++++++++++++- src/babylonjs/AppRay.ts | 5 ++++- src/babylonjs/GameManager.ts | 36 +++++++++++++++++++++++++++--------- src/kernel/Adapter.ts | 1 + 6 files changed, 63 insertions(+), 32 deletions(-) diff --git a/index.html b/index.html index b4d0558..657fd0f 100644 --- a/index.html +++ b/index.html @@ -911,6 +911,7 @@ kernel.material.apply({ target: materialName, + modelId: modelId, // 指定模型ID,只修改该模型的材质 albedoColor: color, albedoTexture: color_map_url, normalMap: normal_map_url, diff --git a/index.js b/index.js index a15345e..d1cb216 100644 --- a/index.js +++ b/index.js @@ -41,27 +41,6 @@ models.forEach(model => { }); }) -// kernel.model.add({ -// modelId: "框架", -// modelUrl: "https://sdk.zguiy.com/resurces/model/框架.glb", -// modelControlType: "color" -// }); -// kernel.model.add({ -// modelId: "卷帘大", -// modelUrl: "https://sdk.zguiy.com/resurces/model/卷帘大.glb", -// modelControlType: "color" -// }); -// kernel.model.add({ -// modelId: "配件中", -// modelUrl: "https://sdk.zguiy.com/resurces/model/卷帘小.glb", -// modelControlType: "color" -// }); -// kernel.model.add({ -// modelId: "小桌", -// modelUrl: "https://sdk.zguiy.com/resurces/model/小桌.glb", -// modelControlType: "rotation" -// }); - kernel.on('model:load:progress', (data) => { console.log('模型加载事件', data); }); diff --git a/src/babylonjs/AppModel.ts b/src/babylonjs/AppModel.ts index bcf117e..842ce6c 100644 --- a/src/babylonjs/AppModel.ts +++ b/src/babylonjs/AppModel.ts @@ -152,8 +152,31 @@ export class AppModel extends Monobehiver { /** * 克隆模型材质,避免多个模型共享同名材质 * @param meshes 网格数组 - * @param modelName 模型名称 + * @param modelId 模型ID */ + private cloneMaterials(meshes: AbstractMesh[], modelId: string): void { + const scene = this.mainApp.appScene.object; + const clonedMaterials = new Map(); + + meshes.forEach(mesh => { + if (mesh.material) { + const originalMaterial = mesh.material; + const originalName = originalMaterial.name; + + // 如果该材质还没有被克隆过,则克隆它 + if (!clonedMaterials.has(originalName)) { + const clonedMaterial = originalMaterial.clone(`${originalName}_${modelId}`); + clonedMaterials.set(originalName, clonedMaterial); + } + + // 应用克隆的材质 + mesh.material = clonedMaterials.get(originalName); + } + }); + + console.log(`已为模型 ${modelId} 克隆 ${clonedMaterials.size} 个材质`); + } + /** 为网格设置阴影(投射和接收) */ private createModelRoot(modelId: string, meshes: AbstractMesh[]): AbstractMesh[] { const scene = this.mainApp.appScene.object; @@ -254,6 +277,9 @@ export class AppModel extends Monobehiver { }); if (result.success && result.meshes) { + // 克隆材质,确保每个模型有独立的材质 + this.cloneMaterials(result.meshes, modelName); + result.meshes = this.createModelRoot(modelName, result.meshes); this.modelDic.Set(modelName, result.meshes); @@ -304,6 +330,9 @@ export class AppModel extends Monobehiver { }); if (result.success && result.meshes) { + // 克隆材质,确保每个模型有独立的材质 + this.cloneMaterials(result.meshes, modelId); + result.meshes = this.createModelRoot(modelId, result.meshes); this.modelDic.Set(modelId, result.meshes); diff --git a/src/babylonjs/AppRay.ts b/src/babylonjs/AppRay.ts index a6db1e3..31b22b7 100644 --- a/src/babylonjs/AppRay.ts +++ b/src/babylonjs/AppRay.ts @@ -157,7 +157,10 @@ class AppRay extends Monobehiver { this.mainApp.appSelectionOutline.clear(); this.mainApp.appPositionGizmo.detach(); - this.mainApp.appDomTo3D.hideAll() + this.mainApp.appDomTo3D.hideAll(); + + // 隐藏放置区域 + this.mainApp.appDropZone?.hide(); } } diff --git a/src/babylonjs/GameManager.ts b/src/babylonjs/GameManager.ts index d7cbe52..367a83e 100644 --- a/src/babylonjs/GameManager.ts +++ b/src/babylonjs/GameManager.ts @@ -751,6 +751,7 @@ export class GameManager extends Monobehiver { */ applyMaterial(options: { target: string; + modelId?: string; // 新增:指定模型ID,只修改该模型的材质 albedoColor?: string; albedoTexture?: string; normalMap?: string; @@ -762,15 +763,32 @@ export class GameManager extends Monobehiver { // 1. 查找目标材质 const targetMaterials: PBRMaterial[] = []; - this.materialDic.Values().forEach(material => { - if (material.name === options.target) { - targetMaterials.push(material); - } - }); - if (targetMaterials.length === 0) { - console.warn(`Material not found: ${options.target}`); - return; + if (options.modelId) { + // 如果指定了模型ID,只查找该模型的材质 + const materialName = `${options.target}_${options.modelId}`; + this.materialDic.Values().forEach(material => { + if (material.name === materialName) { + targetMaterials.push(material); + } + }); + + if (targetMaterials.length === 0) { + console.warn(`Material not found for model ${options.modelId}: ${materialName}`); + return; + } + } else { + // 没有指定模型ID,查找所有匹配的材质(旧逻辑) + this.materialDic.Values().forEach(material => { + if (material.name === options.target || material.name.startsWith(`${options.target}_`)) { + targetMaterials.push(material); + } + }); + + if (targetMaterials.length === 0) { + console.warn(`Material not found: ${options.target}`); + return; + } } // 2. 应用材质属性到目标材质 @@ -810,6 +828,6 @@ export class GameManager extends Monobehiver { material.markDirty(); }); - console.log(`Material applied to: ${options.target}`, options); + console.log(`Material applied to: ${options.target}${options.modelId ? ` (model: ${options.modelId})` : ''}`, options); } } diff --git a/src/kernel/Adapter.ts b/src/kernel/Adapter.ts index 0863c89..a917fd9 100644 --- a/src/kernel/Adapter.ts +++ b/src/kernel/Adapter.ts @@ -69,6 +69,7 @@ export class KernelAdapter { */ apply: (options: { target: string; + modelId?: string; // 可选:指定模型ID,只修改该模型的材质 albedoColor?: string; albedoTexture?: string; normalMap?: string;