OrbitControls 추가 - 향상된 3D 카메라 제어
개선사항: - Three.js OrbitControls 라이브러리 추가 - 부재 중심을 회전 타겟으로 설정 - 부드러운 확대/축소 (damping 활성화) - 직관적인 마우스 제어: * 좌클릭 드래그 = 회전 * 우클릭 드래그 = 패닝 (이동) * 휠 = 확대/축소 카메라 설정: - 타겟: (-216, -2554, 0) - 부재 중심 - 자동 회전 비활성화 - 댐핑 활성화 (부드러운 움직임) - 줌 속도 조정 그리드/축 스케일 축소: - 부재 크기에 맞게 조정 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4e7c4e2972
commit
f4d22f71f5
1 file changed
+26
-44
+26
-44
@@ -290,6 +290,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/controls/OrbitControls.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const canvas = document.getElementById('canvas');
|
const canvas = document.getElementById('canvas');
|
||||||
const width = canvas.clientWidth;
|
const width = canvas.clientWidth;
|
||||||
@@ -335,6 +336,15 @@
|
|||||||
|
|
||||||
const DISPLAY_SCALE = 0.01; // mm → cm (1:100)
|
const DISPLAY_SCALE = 0.01; // mm → cm (1:100)
|
||||||
|
|
||||||
|
// 먼저 샘플 부재 1개로 테스트
|
||||||
|
console.log('=== 샘플 부재 테스트 ===');
|
||||||
|
const testGeometry = new THREE.BoxGeometry(4, 4, 80); // 400×400×8000mm → 4×4×80 (축소)
|
||||||
|
const testMaterial = new THREE.MeshStandardMaterial({ color: 0x7ed321, roughness: 0.7 });
|
||||||
|
const testMesh = new THREE.Mesh(testGeometry, testMaterial);
|
||||||
|
testMesh.position.set(470, -2830, 100); // 첫 번째 h-pile2 좌표
|
||||||
|
scene.add(testMesh);
|
||||||
|
console.log('✓ 샘플 부재 추가됨 @ (470, -2830)');
|
||||||
|
|
||||||
// stats.json 로드 및 부재 생성
|
// stats.json 로드 및 부재 생성
|
||||||
fetch('gasiseol-correct-v2-stats.json')
|
fetch('gasiseol-correct-v2-stats.json')
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
@@ -424,58 +434,30 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 그리드 & 축
|
// 그리드 & 축
|
||||||
const gridHelper = new THREE.GridHelper(300000, 20, 0x444444, 0x222222);
|
const gridHelper = new THREE.GridHelper(3000, 20, 0x444444, 0x222222);
|
||||||
gridHelper.position.y = -1000;
|
gridHelper.position.y = -2300;
|
||||||
scene.add(gridHelper);
|
scene.add(gridHelper);
|
||||||
|
|
||||||
const axisHelper = new THREE.AxesHelper(50000);
|
const axisHelper = new THREE.AxesHelper(500);
|
||||||
scene.add(axisHelper);
|
scene.add(axisHelper);
|
||||||
|
|
||||||
// 마우스 조작
|
// OrbitControls로 카메라 제어
|
||||||
let isDragging = false;
|
const controls = new THREE.OrbitControls(camera, canvas);
|
||||||
let previousMousePosition = { x: 0, y: 0 };
|
controls.target.set(-216, -2554, 0); // 부재 중심을 타겟으로
|
||||||
|
controls.autoRotate = false;
|
||||||
canvas.addEventListener('mousedown', (e) => {
|
controls.autoRotateSpeed = 2;
|
||||||
isDragging = true;
|
controls.enableDamping = true;
|
||||||
previousMousePosition = { x: e.clientX, y: e.clientY };
|
controls.dampingFactor = 0.05;
|
||||||
});
|
controls.enableZoom = true;
|
||||||
|
controls.zoomSpeed = 1.0;
|
||||||
canvas.addEventListener('mousemove', (e) => {
|
controls.enablePan = true;
|
||||||
if (!isDragging) return;
|
controls.panSpeed = 0.5;
|
||||||
|
controls.update();
|
||||||
const deltaX = e.clientX - previousMousePosition.x;
|
|
||||||
const deltaY = e.clientY - previousMousePosition.y;
|
|
||||||
|
|
||||||
const targetPoint = new THREE.Vector3(0, 0, 0);
|
|
||||||
const direction = camera.position.clone().sub(targetPoint);
|
|
||||||
|
|
||||||
const rotationMatrix = new THREE.Matrix4()
|
|
||||||
.makeRotationAxis(new THREE.Vector3(0, 1, 0), deltaX * 0.005);
|
|
||||||
|
|
||||||
const rightVector = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion);
|
|
||||||
rotationMatrix.multiply(new THREE.Matrix4().makeRotationAxis(rightVector, deltaY * 0.005));
|
|
||||||
|
|
||||||
direction.applyMatrix4(rotationMatrix);
|
|
||||||
camera.position.copy(targetPoint).add(direction);
|
|
||||||
camera.lookAt(targetPoint);
|
|
||||||
|
|
||||||
previousMousePosition = { x: e.clientX, y: e.clientY };
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.addEventListener('mouseup', () => { isDragging = false; });
|
|
||||||
|
|
||||||
canvas.addEventListener('wheel', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const targetPoint = new THREE.Vector3(0, 0, 0);
|
|
||||||
const direction = camera.position.clone().sub(targetPoint).normalize();
|
|
||||||
const distance = camera.position.distanceTo(targetPoint);
|
|
||||||
const newDistance = distance + e.deltaY * 20;
|
|
||||||
camera.position.copy(targetPoint).addScaledVector(direction, newDistance);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 렌더링
|
// 렌더링
|
||||||
function animate() {
|
function animate() {
|
||||||
requestAnimationFrame(animate);
|
requestAnimationFrame(animate);
|
||||||
|
controls.update();
|
||||||
renderer.render(scene, camera);
|
renderer.render(scene, camera);
|
||||||
}
|
}
|
||||||
animate();
|
animate();
|
||||||
|
|||||||
Reference in new issue
Block a user