feat: [rd] 3D 샤프트 슬랫 감김 롤 표현

- 셔터 올라간 만큼 샤프트 주위에 감긴 롤 원통 표시
- 철재: ㄷ자 72mm 피치 (두꺼운 감김) + 골 링 라인 표현
- 스크린: 1mm 피치 (얇은 감김)
- 개폐 슬라이더 조작 시 롤 두께 실시간 변화
This commit is contained in:
김보곤
2026-03-08 21:20:47 +09:00
parent 0f96834214
commit 16d10c614d

View File

@@ -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 });