diff --git a/ScreenShot_2026-05-14_203252_470.png b/ScreenShot_2026-05-14_203252_470.png new file mode 100644 index 0000000..afc4c6c Binary files /dev/null and b/ScreenShot_2026-05-14_203252_470.png differ diff --git a/index copy 2.html b/index copy 2.html new file mode 100644 index 0000000..eadc79b --- /dev/null +++ b/index copy 2.html @@ -0,0 +1,933 @@ + + + + + + + 3D Model Showcase SDK - TS + + + + +
+ +
+ + + + + +
+ + +
+
选装选配
+ + + + + +
+
+ 棚子尺寸 + +
+
+
+ + + + +
+
+
+ + +
+
+ 棚子类型 + +
+
+
+ + + + +
+
+
+ + +
+
+ 百叶 + +
+
+
+ + + + + +
+
+
+ + +
+
+ 配色 + +
+
+
+ + + + +
+
+
+ + + +
+
+ + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html index eadc79b..d85b98d 100644 --- a/index.html +++ b/index.html @@ -512,6 +512,7 @@ if (enable_placement_zone) { sku = currentText; await placementWall(divisions); + //await initPlacementZoneConfig(divisions); } } @@ -793,50 +794,49 @@ } }); - const placementWall = (divisions) => { + // 初始化放置区域配置数据(只需设置一次) + const initPlacementZoneConfig = (divisions) => { // 只清除旧的放置区域网格,不清除模型 kernel.dropZone.clearZones(); - - // 生成新的放置区域(使用新的墙面参数化API) // 调整 baseY 来控制整体高度(正数向上,负数向下) - const baseY = 0.08; // 修改这个值来调整整体高度 - + const baseY = 0.09; // 修改这个值来调整整体高度 + const height = 2.27; // 调整 offset 来控制每个面向外或向内的偏移 // 正数 = 向外移动,负数 = 向内移动 const wallOffset = -0.07; // 修改这个值来调整墙面偏移 - kernel.dropZone.generate({ + kernel.dropZone.setData({ walls: [ { name: 'front', - startPoint: [-1.43, baseY, -1.4], - endPoint: [1.37, baseY, -1.4], - height: 2.2, + startPoint: [-1.82, baseY, -1.37], + endPoint: [1.87, baseY, -1.37], + height: height, divisions: divisions, offset: wallOffset // 向外或向内偏移 }, { name: 'back', - startPoint: [1.37, baseY, 1.4], - endPoint: [-1.43, baseY, 1.4], - height: 2.2, + startPoint: [1.87, baseY, 1.4], + endPoint: [-1.82, baseY, 1.4], + height: height, divisions: divisions, offset: wallOffset }, { name: 'left', - startPoint: [-1.43, baseY, 1.4], - endPoint: [-1.43, baseY, -1.43], - height: 2.2, + startPoint: [-1.82, baseY, 1.4], + endPoint: [-1.82, baseY, -1.37], + height: height, divisions: divisions, offset: wallOffset }, { name: 'right', - startPoint: [1.37, baseY, -1.43], - endPoint: [1.37, baseY, 1.4], - height: 2.2, + startPoint: [1.82, baseY, -1.37], + endPoint: [1.82, baseY, 1.4], + height: height, divisions: divisions, offset: wallOffset } @@ -848,8 +848,22 @@ borderColor: "#ffffff" }); + kernel.dropZone.generateDropZones(divisions); // 显示放置区域 - kernel.dropZone.showAll(); + kernel.dropZone.show(); + dropZoneVisible = true; + }; + + + const placementWall = (divisions) => { + // 只清除旧的放置区域网格,不清除模型 + kernel.dropZone.clearZones(); + + // 使用新的 API:只传入分割数量 + kernel.dropZone.generateDropZones(divisions); + + // 显示放置区域 + kernel.dropZone.show(); dropZoneVisible = true; } diff --git a/index.js b/index.js index d1cb216..d4fbf9a 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,4 @@ import { kernel } from './src/main.ts'; - // import { kernel } from 'https://sdk.zguiy.com/zt/assets/index.js'; // const config = { @@ -31,13 +30,15 @@ kernel.init(config); const response = await fetch('http://localhost:3001/api/models/auto-load/list') const data = await response.json() const models = data.data // 这就是模型列表 -console.log(models); models.forEach(model => { + console.log(model); + kernel.dropZone.setData(model.placement_zone); kernel.model.add({ modelId: model.id, - modelUrl: model.file_url || `http://localhost:3001${model.file_path}`, + modelUrl: model.file_url, modelControlType: model.model_control_type, + }); }) diff --git a/src/babylonjs/AppDropZone.ts b/src/babylonjs/AppDropZone.ts index cf85319..3b21f2d 100644 --- a/src/babylonjs/AppDropZone.ts +++ b/src/babylonjs/AppDropZone.ts @@ -29,6 +29,9 @@ export class AppDropZone { // 墙面 -> 该墙面模型对应的分割数(用于检测分割数变化) private wallModelDivisionsMap: Map = 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); } /** diff --git a/src/kernel/Adapter.ts b/src/kernel/Adapter.ts index a917fd9..e7722d8 100644 --- a/src/kernel/Adapter.ts +++ b/src/kernel/Adapter.ts @@ -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; - }); - }, /** * 清除所有放置区域(只清除网格,不清除模型) */