Skip to content
This repository was archived by the owner on Mar 19, 2026. It is now read-only.

v0.12: デスクトップ・VR オブジェクト掴みインタラクション#83

Merged
HMasataka merged 21 commits into
mainfrom
feature/v0.12-grab-interaction
Mar 7, 2026
Merged

v0.12: デスクトップ・VR オブジェクト掴みインタラクション#83
HMasataka merged 21 commits into
mainfrom
feature/v0.12-grab-interaction

Conversation

@HMasataka
Copy link
Copy Markdown
Owner

Summary

  • デスクトップ(マウスクリック)とVR(グリップボタン)でオブジェクトを掴んで投げるインタラクションを実装
  • VR距離グラブ、スプリングジョイント、ハプティクスフィードバックを追加
  • PGSソルバーに角慣性サポートと線形のみ法線インパルスを導入し、接触時の不要な回転を防止
  • 永続接触マニフォールド(最大4点)とウォームスタートでソルバーの収束を改善
  • キューブの質量を体積比(密度8.0)で設定し、ダンピング調整で自然な物理挙動を実現

Changes

グラブシステム

  • Grabbable / GrabState コンポーネント
  • DesktopGrabSystem — マウスクリックでレイキャストし掴む、カメラ前方2.5mに保持、固定速度8m/sで投げる
  • VrGrabSystem — VRコントローラのグリップで掴む、手の速度で投げる
  • VrDistanceGrabSystem — 離れたオブジェクトを引き寄せて掴む
  • SpringJointSystem — スプリングジョイントによる追従
  • HapticFeedbackSystem — 掴み時の触覚フィードバック

物理エンジン改善

  • RigidBodyInverseInertia フィールド追加(単位球近似)
  • PgsSolver — 法線方向は線形のみのインパルス(角速度の正帰還ループ防止)、摩擦は角慣性込み
  • PersistentManifold — エンティティペアごとに最大4接触点をフレーム間で保持
  • ウォームスタート — 前フレームの累積インパルスで収束を高速化
  • Integrator に MaxRotation クランプ(π/2)
  • IntegrationSystem に角速度スリープ閾値
  • RotationSettlingSystem — 静止時の面整列スムージング
  • CreateDynamic のデフォルト: LinearDamping=0.5, AngularDamping=1.0
  • キューブ質量を体積×密度で設定(大=8.0kg, 小≈1.73kg)

その他

  • InputState にマウスボタン・カーソル位置を追加
  • DebugCrosshairSystem — カメラ前方にクロスヘア表示
  • WorldBoundsUpdateSystem — 動的オブジェクトのAABBを毎フレーム再計算

Test plan

  • デスクトップ: マウス左クリックでキューブを掴み、離すと前方に投げられること
  • デスクトップ: 小さいキューブを大きいキューブにぶつけても大きいキューブが過度に飛ばないこと
  • デスクトップ: キューブが床に落ちた後、回転せず速やかに静止すること
  • VR: グリップボタンでキューブを掴み、手の速度で投げられること
  • VR: 距離グラブで離れたオブジェクトを引き寄せられること
  • 全745テストがパスすること

🤖 Generated with Claude Code

HMasataka and others added 21 commits March 7, 2026 16:52
glfwGetMouseButton P/Invoke を追加し、マウス左ボタンの
押下・保持・解放エッジ検出とカーソル位置取得を実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
オブジェクトが掴み可能であることを示す Grabbable と、
現在の掴み状態を管理する GrabState コンポーネントを追加。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
マウスレイキャストによるオブジェクト選択、クリック長押しで
掴み、ドラッグで追従、リリースで投げるシステムを実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
VrHandState コンポーネントを追加し、XrInputUpdateSystem で
前フレームとの位置差分から手の速度を算出。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
グリップ+近接判定による直接掴み、手の速度伝達による投げ、
スプリングジョイントによるハンド-オブジェクト間の接続を実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
トリガー+レイキャストで離れたオブジェクトをポイントし、
手元に引き寄せて掴みに遷移する距離グラブを実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xrApplyHapticFeedback P/Invoke と VibrationOutput アクションを追加し、
HapticRequest コンポーネントで左右の手に振動を送信するシステムを実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
掴めるキューブエンティティの配置、VrHandState/HapticRequest
シングルトンの追加、全掴みシステムの登録を実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RigidBody や Grabbable で位置が変わるエンティティの WorldBounds が
初期位置のままだったため、カメラを振ると視錐台カリングで消えていた。
WorldBoundsUpdateSystem を Transform フェーズに追加し、
ColliderBounds.ComputeAABB で毎フレーム AABB を更新する。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GLFW は Y 座標が下方向に増加するため、deltaY の符号を反転して
マウスを下に動かしたときにカメラが下を向くようにする。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
レイ原点がプレイヤー足元だったため目線で狙ったオブジェクトに
当たらなかった。CameraMode.FirstPersonOffset を加算して
CameraViewSystem と同じ目線位置からレイを飛ばすように修正。
併せてクォータニオン Pitch の符号を CameraViewSystem の
三角関数計算と一致させた。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
小さなキューブをカメラ前方 3m に毎フレーム配置して
照準位置を可視化する仮実装。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ワールド空間の生オフセットではなくカメラローカル空間の
固定距離を使い、オブジェクトが視界外に引き寄せられる
問題を解消。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DesktopGrabPhysicsSystem が位置をセットした後に
ForceIntegrationSystem と IntegrationSystem が速度を積分して
位置をずらしていた。掴み中は Velocity を毎フレームゼロクリア
することで視界追従の遅れを解消。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
掴み時にカメラとの相対回転を GrabRotationOffset に保存し、
毎フレーム grabberRot * GrabRotationOffset で回転を更新する
ことで、視界を動かしても常に同じ面が見えるようにした。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
角速度の慣性計算に必要な逆慣性モーメント(スカラー、単位球近似)を
RigidBody コンポーネントに追加。CreateDynamic は 5/(2*mass) を設定し、
CreateKinematic は 0 を設定する。AngularDamping のデフォルトを 0.1 に変更。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ComputeEffectiveMass に角慣性項を追加し、摩擦方向の有効質量に
回転慣性を反映。法線方向は線形のみの有効質量・相対速度・インパルス
適用とすることで、接触点のオフセットによる角速度の正帰還ループを防止。
Baumgarte 安定化は線形のみなので安全に復活。WarmStart メソッドを追加し
法線は線形のみ、摩擦は角速度込みでウォームスタートする。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
エンティティペアごとに最大4接触点をボディローカル座標で保持する
PersistentManifold を導入。毎フレームの検証・マージ・最大面積維持の
接触点置換を実装。ConstraintSolverSystem をマニフォールドベースに
書き換え、フレーム間で累積インパルスを引き継ぐウォームスタートにより
ソルバーの収束を改善。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrator に MaxRotation (π/2) クランプを追加し数値安定性を確保。
IntegrationSystem に角速度スリープ閾値を追加し、低速時に角速度をゼロ化。
RotationSettlingSystem を新規追加し、静止状態のオブジェクトを最寄りの
面整列方向にスムーズに回転。デモアプリに InverseInertia と
RotationSettlingSystem を反映。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
密度 8.0 を基準にキューブの質量をサイズに応じて設定
(大=8.0kg、小≈1.73kg)。CreateDynamic のデフォルトに
LinearDamping=0.5、AngularDamping=1.0 を設定し、衝突後の
滑走・回転が速やかに収束するようにした。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@HMasataka HMasataka merged commit 32f0d33 into main Mar 7, 2026
3 checks passed
@HMasataka HMasataka deleted the feature/v0.12-grab-interaction branch March 7, 2026 12:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant