diff --git a/src/components/Building3D.jsx b/src/components/Building3D.jsx
index 970ae94..0ba70ce 100644
--- a/src/components/Building3D.jsx
+++ b/src/components/Building3D.jsx
@@ -37,7 +37,7 @@ const ROOMS = [
// 企业按 Excel 场地安排:成长1=Facebook 越南跨境电商 → 成长8=综合直播私域平台
{ x: [45, 51], z: [1, 3], type: 'office', zone: '成长区', no: 'G8', company: '综合性云南直播私域平台' },
{ x: [53, 54], z: [1, 3], type: 'hallway', no: 'H01' },
- { x: [55, 58], z: [1, 3], type: 'desk', no: 'W01' },
+ { x: [55, 58], z: [1, 3], type: 'stair', no: 'W01' },
{ x: [45, 48], z: [5, 6], type: 'office', zone: '成长区', no: 'G7', company: '云南星瑞航空' },
{ x: [45, 48], z: [8, 9], type: 'office', zone: '成长区', no: 'G6', company: '五华区丽裳文化' },
{ x: [45, 48], z: [11, 12], type: 'office', zone: '成长区', no: 'G5', company: '南菌优培食用菌' },
@@ -82,42 +82,68 @@ const ROOMS = [
{ x: [32, 33], z: [36, 40], type: 'stair', no: 'S01' }, // 楼道(真实楼梯通向一楼)
{ x: [35, 45], z: [36, 40], type: 'meeting', no: 'M01' }, // 大会议室(长桌+讲台)
{ x: [47, 49], z: [36, 40], type: 'office', zone: '加速区', no: 'A2', company: '米勒克尔蓝宝石珠宝' },
- { x: [51, 54], z: [36, 40], type: 'office', zone: '加速区', no: 'A1', company: '云南派音人工智能科技' },
+ { x: [51, 53.5], z: [36, 40], type: 'office', zone: '加速区', no: 'A1', company: '云南派音人工智能科技' },
];
/* ---- 水平墙段 [z, x0, x1](像素精确提取)----
说明:行1-3 顶部 G01 南墙在行4;行4/7/10/13/16/19/22/25 为成长区/国际区段间墙;
过道(列50-53)处无墙;行27 玻璃顶南墙;行28-40 加速区内部墙(单格垂直墙点) */
const HWALLS = [
- [0, 0, 58], // 北外墙
- [4, 44, 49], [4, 51, 51], [4, 54, 58], // 顶部 G01 南墙(含列51 隔墙;列50 为过道口)
- [7, 44, 49], [7, 54, 58],
- [10, 44, 49], [10, 54, 58],
- [13, 44, 49], [13, 54, 58],
- [16, 44, 49], [16, 54, 58],
- [19, 44, 49], [19, 54, 58],
- [22, 44, 49], [22, 54, 58],
- [25, 44, 49], [25, 54, 58],
+ [0, 0.5, 57.5], // 北外墙
+ [4, 44.5, 48.5],
+ [4, 51, 51],
+ [4, 54, 57.5], // 顶部 G01 南墙(含列51 隔墙;列50 为过道口)
+ [7, 44.5, 48.5],
+ [7, 54, 57.5],
+ [10, 44.5, 48.5],
+ [10, 54, 57.5],
+ [13, 44.5, 48.5],
+ [13, 54, 57.5],
+ [16, 44.5, 48.5],
+ [16, 54, 57.5],
+ [19, 44.5, 48.5],
+ [19, 54, 57.5],
+ [22, 44.5, 48.5],
+ [22, 54, 57.5],
+ [25, 44.5, 48.5],
+ [25, 54, 57.5],
[27, 0, 44], // 玻璃顶南墙(全高)
+ // 过道上侧
+ [32.5, 0.5, 2.5],
+ [32.5, 5, 10],
+ [32.5, 13, 15],
+ [32.5, 17.3, 19],
+ [32.5, 21, 25],
+ // z=36 横墙已去除;补相邻垂直墙(z36.6-40.5)间的横向短墙段(z=36.6,x 从第一堵起到第二堵-1)
+ [36, 0.5, 2.5],
+ [36, 5, 10],
+ [36, 13, 14.5],
+ [36, 17, 19],
+ [36, 22, 24],
+ [36, 27, 29],
+ [36, 33.5, 34], // 过道
+ [36, 37, 44],
+ [36, 46.3, 48.5],
+ [36, 51, 53.1], // 派音右
[41, 0, 53], // 南外墙
];
/* ---- 垂直墙段 [x, z0, z1](像素精确提取)---- */
const VWALLS = [
- [0, 0, 41], // 西外墙
- [5, 27, 32], [5, 36, 41],
- [13, 27, 32], [13, 36, 41],
- [17, 27, 32], [17, 36, 41],
- [22, 27, 32], [22, 36, 41],
- [27, 27, 32], [27, 36, 41],
- [31, 36, 41], // 小会议室与楼道之间
- [34, 36, 41], // 楼道与大会议室之间
- [44, 0, 32], [44, 36, 41], // 玻璃顶东墙 / 大会议室西墙
- [46, 36, 41], // 大会议室东墙
+ [0, 0.5, 41], // 西外墙
+ [5, 27, 32], [5, 36.6, 40.5],
+ [13, 27, 32], [13, 36.6, 40.5],
+ [17, 27, 32], [17, 36.6, 40.5],
+ [22, 27, 32], [22, 36.6, 40.5],
+ [27, 27, 32], [27, 36.6, 40.5],
+ [31, 36.6, 40.5], // 小会议室与楼道之间
+ [34, 36.6, 40.5], // 楼道与大会议室之间
+ [44, 0.5, 32], [44, 36.6, 40.5], // 玻璃顶东墙 / 大会议室西墙
[49, 4, 5], [49, 7, 8], [49, 10, 11], [49, 13, 14], [49, 16, 17], [49, 19, 20], [49, 22, 23], // 成长区段间西侧墙
- [49, 36, 41], // 底部
- [50, 36, 41], // 底部 A12/A13 之间
- [51, 0, 4], // 顶部共享工位西缘(G01 东墙)
- [58, 0, 25], // 东外墙
+ [53.5, 4, 5], [53.5, 7, 8], [53.5, 10, 11], [53.5, 13, 14], [53.5, 16, 17], [53.5, 19, 20], [53.5, 22, 23], // 成长区段间西侧墙
+ [48.5, 36.6, 40.5], // 底部 A12/A13 之间
+ [53.5, 36.6, 40.5], // 底部 A1 右墙(X-0.5=53.5,Z-0.5=[35.5,40.5])
+ [51, 0.5, 3.4], // 顶部共享工位西缘(G01 东墙)
+ [58, 0.5, 24.7], // 东外墙(原 [58,0,25],延伸覆盖底部 A1 东侧)
];
const W = 60, D = 42;
@@ -126,14 +152,22 @@ const cz = (z) => (z - D / 2) * U;
/* ---------- 基础组件 ---------- */
-function Wall({ x, z, w, h, axis = 'z', color = WALL_COLOR, edge = WALL_EDGE, y = 0 }) {
+function Wall({ x, z, w, h, axis = 'z', color = WALL_COLOR, edge = WALL_EDGE, y = 0, gridLabel = '' }) {
const size = axis === 'z' ? [w, h, T] : [T, h, w];
return (
-
-
-
-
-
+
+
+
+
+
+
+ {/* 临时调试:墙面数值标签 */}
+ {gridLabel && (
+
+ {gridLabel}
+
+ )}
+
);
}
@@ -148,25 +182,6 @@ function Window({ x, z, w, h = 1.0, axis = 'z', y = 0.85 }) {
);
}
-/* 门(门框 + 门板 + 把手) */
-function Door({ x, z, rotY = 0, y = 0 }) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
/* 办公桌(办公桌 + 座椅) */
function Desk({ x, z, y = 0, rotY = 0 }) {
@@ -322,36 +337,22 @@ function Plant({ x, z, y = 0, s = 1 }) {
);
}
-/* 楼梯(楼道:从二楼通向一楼,真实踏步+扶手) */
-function Stairs({ x, z, y = 0, rotY = 0, steps = 9, stepW = 0.9, stepD = 0.24, rise = 0.21 }) {
+/* 楼梯(楼梯间:从二楼通向一楼 —— 踏步自二楼逐级向下延伸至地面,居中铺满房间) */
+function Stairs({ x, z, y = 0, rotY = 0, steps = 9, stepW = 0.9, stepD = 0.24, rise }) {
+ // 默认向下:最高一级落在 y(二楼楼面),最低一级落在 y - rise*(steps-1) = 0(一楼地面)
+ const r = rise ?? (steps > 1 ? y / (steps - 1) : y);
+ const len = steps * stepD;
const els = [];
for (let i = 0; i < steps; i++) {
- const dz = i * stepD;
- const h = y + rise * i;
+ const dz = i * stepD - len / 2; // 居中铺满房间(避免穿墙)
+ const h = y - r * i; // 从二楼向下逐级降低
els.push(
-
-
+
+
);
}
- // 扶手(两侧)
- const railLen = steps * stepD + 0.3;
- const railH = y + rise * (steps - 1) + 0.95;
- [-stepW / 2 - 0.06, stepW / 2 + 0.06].forEach((rx) => {
- els.push(
-
-
-
-
- );
- els.push(
-
-
-
-
- );
- });
return (
{els}
@@ -380,7 +381,6 @@ function Building() {
const roofs = [];
const furniture = [];
const tags = [];
- const doors = [];
/* ===== 1. 一楼大厅(玻璃顶下方挑空) ===== */
const hx0 = cx(0), hx1 = cx(44);
@@ -560,12 +560,15 @@ function Building() {
furniture.push();
}
} else if (r.type === 'stair') {
- // 楼道:真实楼梯(二楼 → 一楼)
+ // 楼梯间:真实楼梯(二楼 → 一楼),自动按房间宽/深选择梯段方向与级数
+ const alongX = (x1 - x0) >= (z1 - z0); // 房间宽≥深 → 梯段沿 X 方向
const sX = (x0 + x1) / 2;
const sZ = (z0 + z1) / 2;
- const sLen = z1 - z0;
+ const sLen = alongX ? (x1 - x0) : (z1 - z0);
+ const steps = Math.max(4, Math.min(11, Math.round(sLen / 0.45)));
furniture.push(
-
+
);
}
// 标签:每个房间显示编号(编号 + 名称),办公室显示入驻企业名
@@ -574,7 +577,7 @@ function Building() {
r.type === 'desk' ? '共享工位区' :
r.type === 'lounge' ? '休息区' :
r.type === 'meeting' ? '会议室' :
- r.type === 'stair' ? '楼道' :
+ r.type === 'stair' ? '楼梯间' :
r.type === 'office' ? (r.company || r.zone || '办公室') :
'过道';
tags.push(
@@ -589,12 +592,14 @@ function Building() {
/* ===== 4. 墙体(像素墙段精确生成,无交叉穿出) ===== */
HWALLS.forEach(([z, x0, x1], i) => {
walls.push(
-
+
);
});
VWALLS.forEach(([x, z0, z1], i) => {
walls.push(
-
+
);
});
@@ -608,37 +613,6 @@ function Building() {
walls.push();
walls.push();
- /* ===== 5. 办公室门:全部开向过道一侧(门嵌于墙段位置) ===== */
- ROOMS.forEach((r, i) => {
- if (r.type !== 'office') return;
- const z0 = cz(r.z[0]), z1 = cz(r.z[1]);
- const cZ = (z0 + z1) / 2;
- const cX = (cx(r.x[0]) + cx(r.x[1])) / 2;
-
- if (r.zone === '成长区') {
- // 成长区东侧是过道(列50-53),门开在 x=49 墙段位置(列49 是墙)
- doors.push();
- } else if (r.zone === '国际区') {
- // 国际区西侧是过道,门开在 x=54 墙段位置(列54 是墙)
- doors.push();
- } else if (r.zone === '加速区' || r.zone === '管理') {
- if (r.z[1] <= 32) {
- // 上排:南侧是横向过道(行33-35),门开在 z=32
- doors.push();
- } else {
- // 下排:北侧是横向过道,门开在 z=36
- doors.push();
- }
- }
- });
-
- /* ===== 6. 区域标签 ===== */
- tags.push();
- tags.push();
- tags.push();
- tags.push();
- tags.push();
- tags.push();
return (
@@ -646,19 +620,43 @@ function Building() {
-
+
{floors}
{walls}
- {doors}
{roofs}
{furniture}
{tags}
{/* 底座平台 */}
-
-
+
+
+
+
+ );
+}
+
+/* ---------- 临时坐标轴指示(XYZ,用于点位沟通调试) ---------- */
+function TempAxis() {
+ return (
+
+ {/* 三色轴:X 红 → +x,Y 绿 ↑ +y,Z 蓝 → +z(长度 6) */}
+
+ {/* 轴端文字标签 */}
+
+ +X →
+
+
+ +Y ↑
+
+
+ +Z →
+
+ {/* 原点 */}
+
+
+
);
@@ -671,23 +669,26 @@ export default function Building3D({ interactive = true }) {
);
-}
+}
\ No newline at end of file