From 755375dddaea481be5dc5fdec3a01ee51c7972e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sun, 8 Mar 2026 21:37:10 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[rd]=20=EB=B2=BD=EC=B2=B4=20=EA=B0=9C?= =?UTF-8?q?=EA=B5=AC=EB=B6=80=20=ED=86=B5=EA=B3=BC=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 뒷벽을 좌/우 분리 + 상부 인방으로 3조각 구성 - 개구부(셔터 영역)는 뚫려서 통과 가능 - 셔터 열렸을 때 실제 건물처럼 통행 가능한 구조 --- .../rd/fire-shutter-drawing/index.blade.php | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/resources/views/rd/fire-shutter-drawing/index.blade.php b/resources/views/rd/fire-shutter-drawing/index.blade.php index 5ca8ea86..a81791b8 100644 --- a/resources/views/rd/fire-shutter-drawing/index.blade.php +++ b/resources/views/rd/fire-shutter-drawing/index.blade.php @@ -1280,28 +1280,45 @@ function fs3dBuild() { meshes.bottomBar.position.set(0, H - shutterH - 20, 0); scene.add(meshes.bottomBar); - // === WALL (3면 벽체: 좌날개 + 우날개 + 뒷벽) === + // === WALL (개구부 뚫린 벽체: 좌벽 + 우벽 + 상부 인방 + 좌/우 날개벽) === const wl = S.wall; const wallH = H + b.height + wl.topMargin; // 전체 벽 높이 const wallColor = new THREE.Color(wl.color); const wallMat = new THREE.MeshStandardMaterial({ color: wallColor, transparent: true, opacity: wl.opacity / 100, side: THREE.DoubleSide }); meshes.wall = new THREE.Group(); - // 뒷벽 (전체 폭 커버: 날개벽 포함) - const totalW = W1 + wl.wing * 2; - const backGeo = new THREE.BoxGeometry(totalW, wallH, wl.thick); - const backMesh = new THREE.Mesh(backGeo, wallMat); - backMesh.position.set(0, wallH / 2, -wl.thick / 2); - meshes.wall.add(backMesh); + // 뒷벽: 개구부(W1 x H) 부분을 제외하고 3조각으로 구성 + // 1) 좌측 뒷벽 (날개벽 폭만큼) + if (wl.wing > 0) { + const backLGeo = new THREE.BoxGeometry(wl.wing, wallH, wl.thick); + const backL = new THREE.Mesh(backLGeo, wallMat); + backL.position.set(-W1 / 2 - wl.wing / 2, wallH / 2, -wl.thick / 2); + meshes.wall.add(backL); - // 좌측 날개벽 + // 2) 우측 뒷벽 + const backR = new THREE.Mesh(backLGeo.clone(), wallMat); + backR.position.set(W1 / 2 + wl.wing / 2, wallH / 2, -wl.thick / 2); + meshes.wall.add(backR); + } + + // 3) 상부 인방 (개구부 위, 셔터박스+상단여유 높이) + const lintelH = b.height + wl.topMargin; + if (lintelH > 0) { + const totalW = W1 + wl.wing * 2; + const lintelGeo = new THREE.BoxGeometry(totalW, lintelH, wl.thick); + const lintel = new THREE.Mesh(lintelGeo, wallMat); + lintel.position.set(0, H + lintelH / 2, -wl.thick / 2); + meshes.wall.add(lintel); + } + + // 좌/우 날개벽 (앞쪽으로 돌출, 가이드레일 옆) if (wl.wing > 0) { const wingGeo = new THREE.BoxGeometry(wl.wing, wallH, wl.thick); const leftWing = new THREE.Mesh(wingGeo, wallMat); leftWing.position.set(-W1 / 2 - wl.wing / 2, wallH / 2, wl.thick / 2); meshes.wall.add(leftWing); - const rightWing = new THREE.Mesh(wingGeo, wallMat); + const rightWing = new THREE.Mesh(wingGeo.clone(), wallMat); rightWing.position.set(W1 / 2 + wl.wing / 2, wallH / 2, wl.thick / 2); meshes.wall.add(rightWing); }