まだ片手にしか対応できてませんが、コントローラーでオブジェクトを掴むことができるWebVRをつくりました。
cannon.jsで物理演算しているので、掴んだオブジェクトを放り投げることもできます。
実装方針
マウスで3Dオブジェクトを掴んで放り投げるモック をVR化しようと思ったのですが、どうにもうまくいかず、実装方針を大きく変更しました。
❶ コントローラーとオブジェクトの当たり判定を取る
❷ コントローラーとオブジェクトが接触している際、トリガーの入力を確認する
❸ コントローラーとオブジェクトが接触していて、トリガーが引かれている際、コントローラーの位置に力を掛ける
❹ トリガーを離した際、掛けていた力を解除する
という流れで実装しました。
❸のときに、pivotを考慮していないので、必ずコントローラーの座標にオブジェクトの中心がきます。
また、コントローラーを回転させてもオブジェクトは回転しないという問題もあります。この辺りは要改善です。
ソースコード(抜粋)
renderer.setAnimationLoop(() => { controllerRef.current[0].hit.center.set( controllerRef.current[0].position.x, controllerRef.current[0].position.y, controllerRef.current[0].position.z ); cubeRef.current.hit.center.set( cubeRef.current.position.x, cubeRef.current.position.y, cubeRef.current.position.z ); isHitRef.current = controllerRef.current[0].hit.intersectsSphere(cubeRef.current.hit); // 毎フレーム接触を判定 handlePointerMove(); // コントローラー移動時のコールバックを呼び出す renderer.render(scene, camera); }); function handlePointerDown() { // トリガーを引いた際のコールバック if (isHitRef.current) { // コントローラーとオブジェクトが接触している時 targerCannonObjectRef.current = findCannonBodyFromId(cubeRef.current.uuid); targerCannonObjectRef.current.position.copy(controllerRef.current[0].position); targerCannonObjectRef.current.quaternion.copy(controllerRef.current[0].quaternion); addPointToPointConstraint( // コントローラーの位置に力を掛ける controllerRef.current[0].position.x, controllerRef.current[0].position.y, controllerRef.current[0].position.z, targerCannonObjectRef.current ); } } function handlePointerMove() { if ( targerCannonObjectRef.current && pointToPointConstraintRef.current ) { if (isHitRef.current) { currsor.position.copy(controllerRef.current[0].position); // 力を掛ける位置を移動 } else { handlePointerUp(); } } } function handlePointerUp() { targerCannonObjectRef.current = null; world.removeConstraint(pointToPointConstraintRef.current); // pointToPointConstraintRef.current = null; }