feat: [rd] 모터 형상 실제 DH-150K 스타일로 재설계

- 은색 본체 실린더 + 냉각 핀 리브 3줄
- 파란색 기어박스 (본체보다 넓음, 복주머니 쪽)
- 기어박스 전면 플랜지 (복주머니 결합면)
- 후면 마감판
- 마운팅 베이스 플레이트 + 3개 다리 (브라켓 위에 안착)
- 출력축 (기어박스 → 복주머니 방향)
This commit is contained in:
김보곤
2026-03-08 22:03:23 +09:00
parent 354ceda093
commit 7743246f64

View File

@@ -1112,50 +1112,91 @@ function fs3dBuild() {
meshes.shaft.position.set(0, shaftY, 0);
scene.add(meshes.shaft);
// === MOTOR (샤프트 1.2배 크기, 돌출축 + 복주머니 결합 구조) ===
// === MOTOR (DH-150K/300K 스타일: 본체 + 기어박스 + 베이스 + 다리) ===
meshes.motor = new THREE.Group();
const motorMat = new THREE.MeshStandardMaterial({ color: 0x2563eb, metalness: 0.4, roughness: 0.4 });
const legMat = new THREE.MeshStandardMaterial({ color: 0x374151, metalness: 0.5, roughness: 0.4 });
const motorR = b.shaftDia * 0.6; // 모터 반지름 (샤프트 1.2배)
const metalMat = new THREE.MeshStandardMaterial({ color: 0x94a3b8, metalness: 0.6, roughness: 0.3 });
const darkMat = new THREE.MeshStandardMaterial({ color: 0x374151, metalness: 0.5, roughness: 0.4 });
const blueMat = new THREE.MeshStandardMaterial({ color: 0x2563eb, metalness: 0.4, roughness: 0.4 });
// Motor body (원통형, 샤프트의 1.2배)
const motorR = b.shaftDia * 0.6; // 반지름 = 샤프트직경 * 1.2 / 2
const motorLen = motorR * 3; // 모터 길이
const motorBodyGeo = new THREE.CylinderGeometry(motorR, motorR, motorLen, 24);
motorBodyGeo.rotateZ(Math.PI / 2);
const motorBody = new THREE.Mesh(motorBodyGeo, motorMat);
// 브라켓 안쪽(샤프트 방향)에 모터 배치 — 복주머니 옆
const motorCenterX = motorDir * (W1 / 2 - bkW - couplingLen - motorLen / 2);
motorBody.position.set(motorCenterX, 0, 0);
meshes.motor.add(motorBody);
// 모터 위치: 브라켓 안쪽, 복주머니 옆
const motorBodyLen = motorR * 2.5; // 본체 길이
const gearBoxLen = motorR * 1.2; // 기어박스 길이
const totalMotorLen = motorBodyLen + gearBoxLen;
const motorStartX = motorDir * (W1 / 2 - bkW - couplingLen); // 복주머니 끝
const motorMidX = motorStartX - motorDir * totalMotorLen / 2; // 모터 전체 중심
// Motor end cap (바깥쪽 마감판 — 샤프트 반대편)
const endCapGeo = new THREE.CylinderGeometry(motorR + 5, motorR + 5, 8, 24);
endCapGeo.rotateZ(Math.PI / 2);
const endCapMat = new THREE.MeshStandardMaterial({ color: 0x1e40af, metalness: 0.5, roughness: 0.3 });
const endCap = new THREE.Mesh(endCapGeo, endCapMat);
endCap.position.set(motorCenterX - motorDir * (motorLen / 2 + 4), 0, 0);
meshes.motor.add(endCap);
// 1) 모터 본체 (은색 원통 — 메인 실린더)
const bodyGeo = new THREE.CylinderGeometry(motorR, motorR, motorBodyLen, 24);
bodyGeo.rotateZ(Math.PI / 2);
const body = new THREE.Mesh(bodyGeo, metalMat);
const bodyCX = motorStartX - motorDir * (gearBoxLen + motorBodyLen / 2);
body.position.set(bodyCX, 0, 0);
meshes.motor.add(body);
// Motor output shaft (모터 돌출축 — 모터에서 복주머니 방향으로 돌출)
const outShaftR = b.shaftDia * 0.25;
const outShaftLen = 40;
const outShaftGeo = new THREE.CylinderGeometry(outShaftR, outShaftR, outShaftLen, 16);
outShaftGeo.rotateZ(Math.PI / 2);
const outShaftMat = new THREE.MeshStandardMaterial({ color: 0x94a3b8, metalness: 0.8, roughness: 0.2 });
const outShaft = new THREE.Mesh(outShaftGeo, outShaftMat);
outShaft.position.set(motorCenterX + motorDir * (motorLen / 2 + outShaftLen / 2), 0, 0);
// 2) 상단 리브 (본체 위의 냉각 핀 3줄)
for (let i = 0; i < 3; i++) {
const ribGeo = new THREE.BoxGeometry(motorBodyLen * 0.7, 4, motorR * 0.15);
const rib = new THREE.Mesh(ribGeo, darkMat);
const ribZ = (i - 1) * motorR * 0.5;
rib.position.set(bodyCX, motorR + 2, ribZ);
meshes.motor.add(rib);
}
// 3) 기어박스 (파란색, 본체보다 살짝 넓은 박스 — 복주머니 쪽)
const gearR = motorR * 1.15;
const gearGeo = new THREE.CylinderGeometry(gearR, gearR, gearBoxLen, 24);
gearGeo.rotateZ(Math.PI / 2);
const gear = new THREE.Mesh(gearGeo, blueMat);
const gearCX = motorStartX - motorDir * (gearBoxLen / 2);
gear.position.set(gearCX, 0, 0);
meshes.motor.add(gear);
// 4) 기어박스 전면 플랜지 (복주머니 결합면)
const gfGeo = new THREE.CylinderGeometry(gearR + 8, gearR + 8, 5, 24);
gfGeo.rotateZ(Math.PI / 2);
const gf = new THREE.Mesh(gfGeo, darkMat);
gf.position.set(motorStartX - motorDir * 2.5, 0, 0);
meshes.motor.add(gf);
// 5) 후면 마감판 (본체 뒤쪽)
const ecGeo = new THREE.CylinderGeometry(motorR + 3, motorR + 3, 6, 24);
ecGeo.rotateZ(Math.PI / 2);
const ec = new THREE.Mesh(ecGeo, darkMat);
ec.position.set(bodyCX - motorDir * (motorBodyLen / 2 + 3), 0, 0);
meshes.motor.add(ec);
// 6) 마운팅 베이스 (브라켓 위에 안착하는 플레이트)
const baseW = totalMotorLen * 0.85;
const baseH = 6;
const baseD = motorR * 1.6;
const baseGeo = new THREE.BoxGeometry(baseW, baseH, baseD);
const basePlate = new THREE.Mesh(baseGeo, darkMat);
const baseY = -motorR - baseH / 2;
basePlate.position.set(motorMidX, baseY, 0);
meshes.motor.add(basePlate);
// 7) 마운팅 다리 (베이스 → 브라켓까지 연결, 3개)
const legH = bkH / 2 - motorR - baseH; // 베이스 하단 ~ 브라켓 상면
if (legH > 0) {
const legGeo = new THREE.BoxGeometry(10, legH, 20);
const legOffsets = [-baseW * 0.35, 0, baseW * 0.35];
legOffsets.forEach(dx => {
const leg = new THREE.Mesh(legGeo, darkMat);
leg.position.set(motorMidX + motorDir * dx, baseY - baseH / 2 - legH / 2, 0);
meshes.motor.add(leg);
});
}
// 8) 출력축 (기어박스 → 복주머니 방향)
const outR = b.shaftDia * 0.2;
const outLen = 30;
const outGeo = new THREE.CylinderGeometry(outR, outR, outLen, 12);
outGeo.rotateZ(Math.PI / 2);
const outShaft = new THREE.Mesh(outGeo, metalMat);
outShaft.position.set(motorStartX + motorDir * (outLen / 2), 0, 0);
meshes.motor.add(outShaft);
// Motor mounting legs (3개)
const legW = 10, legH = 50, legD = 25;
const legGeo = new THREE.BoxGeometry(legW, legH, legD);
const legOffsets = [-motorLen * 0.35, 0, motorLen * 0.35];
legOffsets.forEach(dx => {
const leg = new THREE.Mesh(legGeo, legMat);
leg.position.set(motorCenterX + motorDir * dx, -motorR - legH / 2, 0);
meshes.motor.add(leg);
});
meshes.motor.position.set(0, shaftY, 0);
scene.add(meshes.motor);