From 16d10c614d45ee98ff7df210dda962ca145a7749 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:20:47 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[rd]=203D=20=EC=83=A4=ED=94=84=ED=8A=B8?= =?UTF-8?q?=20=EC=8A=AC=EB=9E=AB=20=EA=B0=90=EA=B9=80=20=EB=A1=A4=20?= =?UTF-8?q?=ED=91=9C=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 셔터 올라간 만큼 샤프트 주위에 감긴 롤 원통 표시 - 철재: ㄷ자 72mm 피치 (두꺼운 감김) + 골 링 라인 표현 - 스크린: 1mm 피치 (얇은 감김) - 개폐 슬라이더 조작 시 롤 두께 실시간 변화 --- .../rd/fire-shutter-drawing/index.blade.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/resources/views/rd/fire-shutter-drawing/index.blade.php b/resources/views/rd/fire-shutter-drawing/index.blade.php index a55fb4df..0fab8b6b 100644 --- a/resources/views/rd/fire-shutter-drawing/index.blade.php +++ b/resources/views/rd/fire-shutter-drawing/index.blade.php @@ -1182,6 +1182,52 @@ function fs3dBuild() { meshes.slats.add(lineGroup); } + // === SLAT ROLL (샤프트에 감긴 슬랫) === + const rolledH = H - shutterH; // 올라간(감긴) 높이 + if (rolledH > 0) { + // 철재: ㄷ자 72mm 피치로 감김 / 스크린: 얇게 1mm씩 감김 + const wrapThick = S.productType === 'steel' ? 72 : 1; + const shaftR = b.shaftDia / 2; + // 감긴 바퀴 수 = 감긴 높이 / (샤프트 둘레 + 누적 두께 보정) + // 간략 계산: 감긴 총 두께 = sqrt(rolledH * wrapThick / π) + const rollThick = Math.sqrt(rolledH * wrapThick / Math.PI); + const rollOuterR = shaftR + rollThick; + // 롤 길이 = 주축 길이 (브라켓 사이) + const rollLen = mainShaftLen; + + const rollGeo = new THREE.CylinderGeometry(rollOuterR, rollOuterR, rollLen, 32); + rollGeo.rotateZ(Math.PI / 2); + const rollMat = new THREE.MeshStandardMaterial({ + color: S.productType === 'steel' ? 0x78716c : 0xa78bfa, + metalness: S.productType === 'steel' ? 0.3 : 0, + roughness: S.productType === 'steel' ? 0.6 : 0.8, + transparent: true, + opacity: 0.85, + }); + meshes.slatRoll = new THREE.Mesh(rollGeo, rollMat); + meshes.slatRoll.position.set(msCenterX, shaftY, 0); + scene.add(meshes.slatRoll); + + // 철재: 감긴 ㄷ자 슬랫 골 표현 (나선형 링 라인) + if (S.productType === 'steel' && rollThick > 10) { + const ringGroup = new THREE.Group(); + const ringCount = Math.min(Math.floor(rollThick / (wrapThick * 0.15)), 12); + for (let i = 1; i <= ringCount; i++) { + const r = shaftR + (rollThick * i / (ringCount + 1)); + const pts = []; + for (let a = 0; a <= 64; a++) { + const angle = (a / 64) * Math.PI * 2; + pts.push(new THREE.Vector3(0, Math.sin(angle) * r, Math.cos(angle) * r)); + } + const ringGeo = new THREE.BufferGeometry().setFromPoints(pts); + const ring = new THREE.Line(ringGeo, new THREE.LineBasicMaterial({ color: 0x57534e, opacity: 0.5, transparent: true })); + ring.position.x = msCenterX; + ringGroup.add(ring); + } + meshes.slatRoll.add(ringGroup); + } + } + // === BOTTOM BAR === const barGeo = new THREE.BoxGeometry(W - 20, 40, 60); const barMat = new THREE.MeshStandardMaterial({ color: 0xf59e0b, metalness: 0.3, roughness: 0.5 });