🎯 Raycaster座標変換プロセス

ステップ1: マウス座標を正規化
画面座標を-1~1の範囲に変換
const mouse = new THREE.Vector2( ((clientX - rect.left) / rect.width) * 2 - 1, -((clientY - rect.top) / rect.height) * 2 + 1 );
ステップ2: Raycasterで交差判定
カメラからレイを飛ばして、メッシュとの交点を取得
const raycaster = new THREE.Raycaster(); raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObject(mesh);
ステップ3: ワールド座標→ローカル座標
メッシュの逆行列を使ってローカル座標に変換
const inverseMatrix = new THREE.Matrix4() .copy(mesh.matrixWorld) .invert(); const localPoint = intersection.point .clone() .applyMatrix4(inverseMatrix);
ステップ4: ローカル座標→SVG座標
メッシュのサイズに合わせてSVG座標(0~width, 0~height)に変換
const xSVG = ((localPoint.x + planeWidth/2) / planeWidth) * width; const ySVG = ((planeHeight/2 - localPoint.y) / planeHeight) * height;
ステップ5: HTML要素の判定
SVG座標がどのHTML要素に含まれるかチェック
for (let element of interactiveElements) { if (element.contains(xSVG, ySVG)) { element.elem.dispatchEvent(clonedEvent); break; } }