This commit is contained in:
2026-05-14 20:40:56 +08:00
parent 19bb93dce4
commit efc3951227
6 changed files with 1063 additions and 64 deletions

View File

@ -29,6 +29,9 @@ export class AppDropZone {
// 墙面 -> 该墙面模型对应的分割数(用于检测分割数变化)
private wallModelDivisionsMap: Map<string, number> = new Map();
// 存储放置区域配置数据
private dropZoneConfig: DropZoneConfig | null = null;
constructor(scene: Scene) {
this.scene = scene;
this.placementWall = new AppPlacementWall(scene);
@ -42,16 +45,41 @@ export class AppDropZone {
}
/**
* 生成放置区域
* 设置放置区域数据
* @param config 配置参数
*/
generateDropZones(config: DropZoneConfig): PlacementZoneInfo[] {
setData(config: DropZoneConfig): void {
this.dropZoneConfig = config;
}
/**
* 生成放置区域
* @param divisions 分割数量(必传)
* @param config 配置参数(可选,如果不传则使用 setData 设置的数据)
*/
generateDropZones(divisions: number, config?: DropZoneConfig): PlacementZoneInfo[] {
const finalConfig = config || this.dropZoneConfig;
if (!finalConfig) {
console.error('未设置放置区域配置数据,请先调用 setData 或传入 config 参数');
return [];
}
// 为所有墙面设置分割数,同时保留其他配置属性
const configWithDivisions: DropZoneConfig = {
...finalConfig, // 保留所有配置属性color, alpha, thickness, showBorder, borderColor
walls: finalConfig.walls.map(wall => ({
...wall,
divisions: divisions
}))
};
// 只记录分割数,不自动卸载模型
config.walls.forEach(wall => {
configWithDivisions.walls.forEach(wall => {
this.wallDivisionsMap.set(wall.name, wall.divisions);
});
return this.placementWall.generatePlacementAreas(config);
return this.placementWall.generatePlacementAreas(configWithDivisions);
}
/**

View File

@ -236,80 +236,103 @@ export class KernelAdapter {
/** 放置区域管理 */
dropZone = {
/**
* 生成放置区域
* @param options 配置选项
* 设置放置区域配置数据(不生成,只存储)
* @param config 配置数据
* @example
* kernel.dropZone.generate({
* kernel.dropZone.setData({
* walls: [
* {
* name: 'front',
* startPoint: new Vector3(-50, 0, -50),
* endPoint: new Vector3(50, 0, -50),
* startPoint: [-50, 0, -50],
* endPoint: [50, 0, -50],
* height: 30,
* divisions: 5
* offset: 0
* }
* ],
* color: "#21c7ff",
* alpha: 0.3
* });
*/
generate: (options: {
setData: (config: {
walls: Array<{
name: string;
startPoint: [number, number, number];
endPoint: [number, number, number];
height: number;
divisions: number;
offset?: number;
}>;
color?: string;
alpha?: number;
thickness?: number;
showBorder?: boolean;
borderColor?: string;
}): any[] => {
} | any): void => {
// 检查 config 是否有效
if (!config || !config.walls || !Array.isArray(config.walls)) {
console.error('setData: 无效的配置数据', config);
return;
}
// 如果传入的是后端返回的 placement_zone 对象,自动转换字段名
let finalConfig = config;
if (config.show_border !== undefined || config.border_color !== undefined) {
finalConfig = {
walls: config.walls,
color: config.color,
alpha: config.alpha,
thickness: config.thickness,
showBorder: config.show_border,
borderColor: config.border_color
};
}
// 转换数组坐标为 Vector3
const config = {
...options,
walls: options.walls.map(wall => ({
...wall,
startPoint: new Vector3(wall.startPoint[0], wall.startPoint[1], wall.startPoint[2]),
endPoint: new Vector3(wall.endPoint[0], wall.endPoint[1], wall.endPoint[2])
}))
const convertedConfig = {
...finalConfig,
walls: finalConfig.walls.map((wall: any) => {
// 自动转换字段名start_point -> startPoint, end_point -> endPoint
const startPoint = wall.startPoint || wall.start_point;
const endPoint = wall.endPoint || wall.end_point;
// 检查墙面数据是否完整
if (!startPoint || !endPoint) {
console.error('setData: 墙面数据不完整', wall);
return null;
}
return {
name: wall.name,
startPoint: new Vector3(startPoint[0], startPoint[1], startPoint[2]),
endPoint: new Vector3(endPoint[0], endPoint[1], endPoint[2]),
height: parseFloat(wall.height),
offset: wall.offset ? parseFloat(wall.offset) : undefined
};
}).filter((wall: any) => wall !== null) // 过滤掉无效的墙面
};
return this.mainApp.appDropZone.generateDropZones(config);
this.mainApp.appDropZone.setData(convertedConfig);
},
/**
* 生成放置区域(使用已存储的配置数据)
* @param divisions 分割数量
* @example
* kernel.dropZone.generateDropZones(5);
*/
generateDropZones: (divisions: number): any[] => {
return this.mainApp.appDropZone.generateDropZones(divisions);
},
/**
* 显示所有放置区域
*/
showAll: (): void => {
show: (): void => {
this.mainApp.appDropZone.show();
},
/**
* 隐藏所有放置区域
*/
hideAll: (): void => {
hide: (): void => {
this.mainApp.appDropZone.hide();
},
/**
* 根据墙面名称显示放置区域
*/
show: (wallName: string): void => {
const zones = this.mainApp.appDropZone.getZonesByWall(wallName);
zones.forEach(zone => {
zone.mesh.isVisible = true;
});
},
/**
* 根据墙面名称隐藏放置区域
*/
hide: (wallName: string): void => {
const zones = this.mainApp.appDropZone.getZonesByWall(wallName);
zones.forEach(zone => {
zone.mesh.isVisible = false;
});
},
/**
* 清除所有放置区域(只清除网格,不清除模型)
*/