1
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 清除所有放置区域(只清除网格,不清除模型)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user