Raycaster
Raycasting is used for mouse picking (working out what objects in the 3d space the mouse is over) amongst other things.
PointerLockControls
모달 컴포넌트 재사용
Raycaster를 사용하여 사용자가 클릭한 object를 인식할 수 있게 했다. (원하는 거리에서 클릭했을 때만 동작하게도 가능)
그리고 기존의 모달 컴포넌트를 재사용성에 유리하게 작성한 덕분에 이 기능을 만들 때도 유용하게 작성할 수 있었다.
나중에 다시 봤을 때, 고려하면 좋을 점이
1. document에 이벤트리스너를 달아줬기 때문에 버블링을 주의해야 한다.
useEffect(() => {
const onDocumentMouseDown = (e: MouseEvent) => {
e.preventDefault();
const obj = ref.current as Object3D;
const cameraDir = new Vector3();
camera.getWorldDirection(cameraDir);
const raycaster = new Raycaster(camera.position, cameraDir);
// mousedown을 했을 때의 카메라의 시선과 obj가 동일시 되면 intersects에 값이 존재하게 된다.
const intersects = raycaster.intersectObject(obj);
if (
intersects.length > 0 &&
intersects[0].distance < DETECT_FROM_DISTANCE
) {
pickItem(data);
}
};
document.addEventListener('mousedown', onDocumentMouseDown);
return () => {
document.removeEventListener('mousedown', onDocumentMouseDown);
};
}, [camera, ref, pickItem, data]);
전역으로 PointerLockControls 객체를 관리하여 PointerLockControls가 Unlock일 때는 (즉, 마우스를 자유롭게 움직일 수 있을 때) 해당 obj를 클릭하여도 모달이 뜨지 않게끔 방지
const handlePictureClick = (item: any) => {
// 자유롭게 마우스를 움직일 수 있을 때는 클릭방지
if (!control.isLocked) return;
modalRef.current?.show();
setSelectedItem(item);
control?.unlock && control?.unlock();
};