可以替换模型
This commit is contained in:
@ -3,7 +3,8 @@
|
|||||||
"allow": [
|
"allow": [
|
||||||
"Bash(cd /d/VscodeProject/zhengte.babylonjs-sdk && npm run build 2>&1 | head -50)",
|
"Bash(cd /d/VscodeProject/zhengte.babylonjs-sdk && npm run build 2>&1 | head -50)",
|
||||||
"Bash(find \"D:\\\\VscodeProject\\\\zhengte.babylonjs-sdk\\\\src\" -name \"*.ts\" -type f -exec grep -l \"class Dictionary\" {} \\\\;)",
|
"Bash(find \"D:\\\\VscodeProject\\\\zhengte.babylonjs-sdk\\\\src\" -name \"*.ts\" -type f -exec grep -l \"class Dictionary\" {} \\\\;)",
|
||||||
"Bash(find \"D:\\\\VscodeProject\\\\zhengte.babylonjs-sdk\\\\src\" -name \"*.ts\" -type f -exec grep -l \"class.*Kernel\\\\|export.*kernel\" {} \\\\;)"
|
"Bash(find \"D:\\\\VscodeProject\\\\zhengte.babylonjs-sdk\\\\src\" -name \"*.ts\" -type f -exec grep -l \"class.*Kernel\\\\|export.*kernel\" {} \\\\;)",
|
||||||
|
"Bash(npm run *)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
index.html
26
index.html
@ -856,9 +856,10 @@
|
|||||||
|
|
||||||
// 监听放置区域点击事件
|
// 监听放置区域点击事件
|
||||||
kernel.on('dropzone:click', async (dropzone_data) => {
|
kernel.on('dropzone:click', async (dropzone_data) => {
|
||||||
console.log(dropzone_data);
|
console.log('点击了放置区域:', dropzone_data);
|
||||||
|
|
||||||
const { position, rotation } = dropzone_data.transform;
|
const { wallName, index, transform } = dropzone_data;
|
||||||
|
const { position, rotation } = transform;
|
||||||
|
|
||||||
// 将模型放置到该区域
|
// 将模型放置到该区域
|
||||||
try {
|
try {
|
||||||
@ -872,28 +873,35 @@
|
|||||||
// 使用 for...of 循环以支持 await
|
// 使用 for...of 循环以支持 await
|
||||||
for (const event of result.data.events) {
|
for (const event of result.data.events) {
|
||||||
if (event.event_type === 'change_model') {
|
if (event.event_type === 'change_model') {
|
||||||
console.log( event.target_data);
|
console.log(event.target_data);
|
||||||
|
|
||||||
const {id, name,file_url, model_control_type, category } = event.target_data;
|
const {id, name, file_url, model_control_type, category } = event.target_data;
|
||||||
console.log('替换百叶模型:', event);
|
console.log('替换百叶模型:', event);
|
||||||
console.log('替换百叶模型类型:', category);
|
console.log('替换百叶模型类型:', category);
|
||||||
|
|
||||||
|
// 生成唯一的模型ID
|
||||||
|
const modelId = id + '_' + Date.now();
|
||||||
|
|
||||||
|
// 先记录模型放置(会自动处理替换逻辑)
|
||||||
|
kernel.dropZone.recordModelPlacement(wallName, index, modelId);
|
||||||
|
|
||||||
|
// 加载并放置模型
|
||||||
await kernel.model.add({
|
await kernel.model.add({
|
||||||
modelId: id+Date.now(),
|
modelId: modelId,
|
||||||
modelUrl: file_url,
|
modelUrl: file_url,
|
||||||
modelControlType: model_control_type,
|
modelControlType: model_control_type,
|
||||||
drag: {
|
drag: {
|
||||||
enable: true,
|
enable: true,
|
||||||
axis: 'x',
|
axis: 'x',
|
||||||
step: 0.1,
|
step: 0.1,
|
||||||
}
|
},
|
||||||
,
|
|
||||||
transform: {
|
transform: {
|
||||||
position: position,
|
position: position,
|
||||||
rotation: rotation,
|
rotation: rotation,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`百叶模型已替换为 ${name}`);
|
console.log(`百叶模型已放置为 ${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.event_type === 'change_color') {
|
if (event.event_type === 'change_color') {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Scene, Vector3 } from '@babylonjs/core';
|
import { Scene, Vector3 } from '@babylonjs/core';
|
||||||
import { AppPlacementWall, WallConfig, PlacementZoneInfo } from './AppPlacementWall';
|
import { AppPlacementWall, WallConfig, PlacementZoneInfo } from './AppPlacementWall';
|
||||||
|
import { AppModel } from './AppModel';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 放置区域配置
|
* 放置区域配置
|
||||||
@ -19,20 +20,94 @@ export interface DropZoneConfig {
|
|||||||
export class AppDropZone {
|
export class AppDropZone {
|
||||||
private scene: Scene;
|
private scene: Scene;
|
||||||
private placementWall: AppPlacementWall;
|
private placementWall: AppPlacementWall;
|
||||||
|
private appModel: AppModel | null = null;
|
||||||
|
|
||||||
|
// 内部映射:放置区域 -> 模型ID
|
||||||
|
private zoneModelMap: Map<string, string> = new Map();
|
||||||
|
// 墙面 -> 当前分割数
|
||||||
|
private wallDivisionsMap: Map<string, number> = new Map();
|
||||||
|
|
||||||
constructor(scene: Scene) {
|
constructor(scene: Scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.placementWall = new AppPlacementWall(scene);
|
this.placementWall = new AppPlacementWall(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化模型管理器(内部使用)
|
||||||
|
*/
|
||||||
|
setModelManager(appModel: AppModel): void {
|
||||||
|
this.appModel = appModel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成放置区域
|
* 生成放置区域
|
||||||
* @param config 配置参数
|
* @param config 配置参数
|
||||||
*/
|
*/
|
||||||
generateDropZones(config: DropZoneConfig): PlacementZoneInfo[] {
|
generateDropZones(config: DropZoneConfig): PlacementZoneInfo[] {
|
||||||
|
// 检查每个墙面的分割数是否改变,如果改变则卸载该墙面的所有模型
|
||||||
|
config.walls.forEach(wall => {
|
||||||
|
const oldDivisions = this.wallDivisionsMap.get(wall.name);
|
||||||
|
if (oldDivisions !== undefined && oldDivisions !== wall.divisions) {
|
||||||
|
// 分割数改变,卸载该墙面的所有模型
|
||||||
|
this.unloadWallModels(wall.name);
|
||||||
|
console.log(`墙面 ${wall.name} 分割数从 ${oldDivisions} 改为 ${wall.divisions},已卸载所有模型`);
|
||||||
|
}
|
||||||
|
// 更新分割数记录
|
||||||
|
this.wallDivisionsMap.set(wall.name, wall.divisions);
|
||||||
|
});
|
||||||
|
|
||||||
return this.placementWall.generatePlacementAreas(config);
|
return this.placementWall.generatePlacementAreas(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卸载指定墙面的所有模型(内部方法)
|
||||||
|
*/
|
||||||
|
private unloadWallModels(wallName: string): void {
|
||||||
|
if (!this.appModel) return;
|
||||||
|
|
||||||
|
const modelsToUnload: string[] = [];
|
||||||
|
|
||||||
|
// 找出该墙面的所有模型
|
||||||
|
this.zoneModelMap.forEach((modelId, zoneKey) => {
|
||||||
|
if (zoneKey.startsWith(`${wallName}[`)) {
|
||||||
|
modelsToUnload.push(modelId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 卸载模型并清除映射
|
||||||
|
modelsToUnload.forEach(modelId => {
|
||||||
|
this.appModel!.removeByName(modelId);
|
||||||
|
// 清除该模型的映射
|
||||||
|
this.zoneModelMap.forEach((value, key) => {
|
||||||
|
if (value === modelId) {
|
||||||
|
this.zoneModelMap.delete(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (modelsToUnload.length > 0) {
|
||||||
|
console.log(`已卸载墙面 ${wallName} 的 ${modelsToUnload.length} 个模型`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录模型放置到区域(内部方法,在点击事件中自动调用)
|
||||||
|
*/
|
||||||
|
recordModelPlacement(wallName: string, index: number, modelId: string): void {
|
||||||
|
const zoneKey = `${wallName}[${index}]`;
|
||||||
|
|
||||||
|
// 检查该区域是否已有模型
|
||||||
|
const existingModelId = this.zoneModelMap.get(zoneKey);
|
||||||
|
if (existingModelId && this.appModel) {
|
||||||
|
// 卸载旧模型
|
||||||
|
console.log(`区域 ${zoneKey} 已有模型 ${existingModelId},将替换为 ${modelId}`);
|
||||||
|
this.appModel.removeByName(existingModelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录新模型
|
||||||
|
this.zoneModelMap.set(zoneKey, modelId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有放置区域
|
* 获取所有放置区域
|
||||||
*/
|
*/
|
||||||
@ -79,6 +154,17 @@ export class AppDropZone {
|
|||||||
* 清除所有放置区域
|
* 清除所有放置区域
|
||||||
*/
|
*/
|
||||||
clearAll(): void {
|
clearAll(): void {
|
||||||
|
// 清除所有模型
|
||||||
|
if (this.appModel) {
|
||||||
|
this.zoneModelMap.forEach(modelId => {
|
||||||
|
this.appModel!.removeByName(modelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除映射
|
||||||
|
this.zoneModelMap.clear();
|
||||||
|
this.wallDivisionsMap.clear();
|
||||||
|
|
||||||
this.placementWall.clearAll();
|
this.placementWall.clearAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,8 @@ export class MainApp {
|
|||||||
this.appModel.initManagers();
|
this.appModel.initManagers();
|
||||||
// 在场景创建后初始化 AppDropZone
|
// 在场景创建后初始化 AppDropZone
|
||||||
this.appDropZone = new AppDropZone(this.appScene.object);
|
this.appDropZone = new AppDropZone(this.appScene.object);
|
||||||
|
// 设置模型管理器引用
|
||||||
|
this.appDropZone.setModelManager(this.appModel);
|
||||||
this.update();
|
this.update();
|
||||||
EventBridge.sceneReady({ scene: this.appScene.object });
|
EventBridge.sceneReady({ scene: this.appScene.object });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -374,6 +374,12 @@ export class KernelAdapter {
|
|||||||
inZone: false,
|
inZone: false,
|
||||||
zone: null
|
zone: null
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 记录模型放置到区域(内部使用,自动处理替换)
|
||||||
|
*/
|
||||||
|
recordModelPlacement: (wallName: string, index: number, modelId: string): void => {
|
||||||
|
this.mainApp.appDropZone.recordModelPlacement(wallName, index, modelId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user