忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

XNAで物理シミュレーション(JigLibX) その1

物理シミュレーターJigLibX

このブログでは今までの所描画(それも基礎的な)ばかり扱っていました。
「見た目」ばかりで「動き」はほとんど無視です。

ここでは物理シミュレーションでよりリアルな動きを目指します。

物理シミュレーションといっても難しいことをする必要はありません。
ライブラリがいくつかあるからです。
私はODE(C/C++用ライブラリ)をC++/CLIでラップしてしばらく使っていました。
が、最近JigLibXというものを知りました。

JigLibX

これはC#で書かれています。
これの良いところは、ちょこっと修正すればSilverlightからも使えるところです。
オリジナルのソースにはunsafeとかがたくさんあってSilverlightから使えないようですが。
しかしunsafeを取り除いてSilverlightから使えるようにしたバージョンがあります

SilverlightのXNAはオリジナルのXNAよりややこしいので、簡単のため、ここではオリジナルのXNAを使うことにします。
でもこれから書くことはSilverlightのXNAに転用可能です。
安心して下さい。

まず次のページを参考にします。

Basic World

このページはJIgLibXで物理シミュレーションする方法を簡単に開設してくれています。
ここではそれをやや変更しながら紹介していきたいと思います。


物理システムと衝突システムの初期化とアップデート

まず一つ一つやっていきましょう。
次のようなコードを書きます。

using Microsoft.Xna.Framework;
using JigLibX.Physics;
using JigLibX.Collision;

public class BasicWorldGame : Game
{
    GraphicsDeviceManager graphics;
    PhysicsSystem world;

    public BasicWorldGame()
    {
        graphics = new GraphicsDeviceManager(this);
        InitializePhysics();
    }

    private void InitializePhysics()
    {
        world = new PhysicsSystem();
        world.CollisionSystem = new CollisionSystemSAP();
    }

    protected override void Update(GameTime gameTime)
    {
        world.Integrate(1 / 60f);

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        base.Draw(gameTime);
    }
}



このプログラムは初期化とアップデートするだけで何もしません。
(ですから実行画面は省きます)

コンストラクタ内で物理計算に必要なオブジェクトを初期化し、Updateメソッド内で物理計算をすすめるメソッドを呼んでいます。
(本来は初期化後に箱や球体を物理システムに追加して、箱がバウンスするさまを楽しめるのですが)


PhysicsSystemクラス

public class PhysicsSystem
{
    public PhysicsSystem();

    public CollisionSystem CollisionSystem { get; set; }
...
    public void Integrate(float dt);
...
}




PhysicsSystemクラスはシミュレーターで動かす物体を管理します。
今回は物体を追加しません。
今回はPhysicsSystem.CollisionSystemプロパティで衝突システムをセットしています。

衝突システムとはシミュレートする物体間の衝突を検知するシステムだと思われます。
(物体の動きをシミュレートするには、どの物体とどうぶつかったかを検出する必要があります)
次のような種類があります。

クラス名 解説
CollisionSystemBrute すべての物体を、全ての他の物体に対して衝突をチェックします。一見遅そうですが、小さなシーンではこれは速度が出て、CollisionSystemGridより速いでしょう。
CollisionSystemGrid 世界をあるサイズのグリッドに分割したCollisionSystemです。物体が均等に散らばっていると、チェックの回数が減ります(速度が出ます)。
CollisionSystemSAP sweep-and-pruneアルゴリズムを使ったCollisionSystemです。




PhysicsSystem.Integrate()メソッドはシミュレーションを行うメソッドです。
Integrateとは積分のことでしょう。
シミュレーションを動かす作業は積分だと考えることができます。
つまり力から速度を出し、速度から位置を出すわけですね。

Integrateの引数dtは、進める速度です。
XnaではUpdateは1秒間に60回呼ばれるので、dt = 1 / 60fでいいでしょう。










拍手[1回]

PR