トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

ひな形のソース_PhysX

ひな形のソース (2006/09/11 更新)

PhysX SDKを使ったプロジェクト環境を作るにあたっては「プロジェクトの作成」を参照してください。

まずは、PhysXを使ったソースでの初期化・後始末を記述してみます。ソースに関しては、プロジェクト内に「xxx.cpp」として記述していると考えてください。

インクルードファイルの指定

#define NOMINMAX          // #include <windows.h>の前に必要
#include <windows.h>
#include <windowsx.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "NxPhysics.h"    // PhysXの物理演算定義など

必要なのは「NxPhysics.h」の参照です。が、windows.hファイルをインクルードする場合はmin/maxマクロがかぶることになります。ので、「#include <windows.h>」を呼ぶ前に「#define NOMINMAX」を指定するようにします。WinAPIを使用しないソースを書く場合はこれらは不要です。

PhysXでの物理演算に必要なグローバル変数

static NxPhysicsSDK *g_pPhysicsSDK = NULL;
static NxScene      *g_pScene      = NULL;

PhysXでの物理空間を管理するには、大元のPhysics SDKクラスである「NxPhysicsSDK」と、これから作成するシーンである「NxScene」が必要になります。上記はグローバルでstaticとしてますが、クラス内のprivateメンバでもOKです。とにかく、一意に存在する物理空間を構築するためにこの2つが最低限必要だ、と思ってください。

もちろん、生成する処理と終わった後に破棄する処理が必要です。

なお、PhysX関連の機能は「Nx」から始まるクラスにてカプセル化されています。また、マクロ指定は「NX_」から始まる英字大文字で定義されます。付属のサンプルソースなどを見て、どれがPhysXSDK関連のクラス・定義なのかという判断は、この命名規則で見分けるといいでしょう。

初期化処理

「NxPhysicsSDK」「NxScene」の初期化(生成)処理を行います。これは、アプリケーションが開始されるタイミングで行うとよいでしょう。あくまでもPhysXは「物理演算を行う機能を提供する」わけですので、グラフィック描画は別です。ので、HWNDと結びつけるなどの必要はありませんのでシンプルです。

bool InitPhysX() {
    // PhysX SDKの初期化処理
    g_pPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, NULL);
    if(g_pPhysicsSDK == NULL) return false;

    // 接触時に有効にする深さ
    g_pPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.05f);
 
    // シーン情報を作成
    NxSceneDesc sceneDesc;
    sceneDesc.gravity = NxVec3(0.0f, -9.8f, 0.0f);  // 重力は鉛直下向き
    g_pScene = g_pPhysicsSDK->createScene(sceneDesc);
    if(g_pScene == NULL) return false;

    // デフォルトのマテリアルをシーンに設定
    NxMaterial *defaultMaterial;
    defaultMaterial = g_pScene->getMaterialFromIndex(0);
    defaultMaterial->setRestitution(0.0f);        // 跳ね返り係数の指定
    defaultMaterial->setStaticFriction(0.5f);     // 静止摩擦係数の指定
    defaultMaterial->setDynamicFriction(0.5f);    // 動摩擦係数の指定

    return true;
}

「NxCreatePhysicsSDK」にてPhysXを使うにあたっての管理クラスを生成します。第三引数にてエラー出力用のクラスを指定することにより、ログを出力することができます。ここでは面倒なのでNULLを指定してます(解説についてはまた後ほど)。

次の「g_pPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.05f);」は、PhysXで共通で使用するパラメータを指定しています。「NX_SKIN_WIDTH」にて2物体が接触するときの衝突判定のための「厚み」を指定しています。デフォルトは「0.025」です。この「setParameter」はこれ以外にもいろいろ設定があります。

SDKのドキュメントには、各パラメータや機能について「PCのソフトウェア実行」「PPU(ハードウェア)実行」「Playstation 3」「XBOX 360」のどれでサポートされているのか、というのが詳しく書いてます。

次に「NxSceneDesc」にてシーン情報を指定します。「sceneDesc.gravity = NxVec3(0.0f, -9.8f, 0.0f);」でY軸の逆方向(鉛直下向き)に重力加速度を指定しています。「-9.8f」ですので単位はm/s^2ですね(地球の重力加速度指定)。NxSceneDescには、重力加速度の他に物理時間を進めるときの最大ステップ数(maxTimestep、デフォルトは1/60)、シーンのバウンディングボックス情報、ユーザデータなど、いろいろ指定・取得できるようです。とりあえず初期化時は重力加速度のみ指定します。「g_pScene = g_pPhysicsSDK->createScene(sceneDesc);」にてシーン情報をPhysics SDKのクラスに渡して、シーンクラスを生成しています。

次の「NxMaterial」を取得しての「デフォルトマテリアル」の設定ですが、ここで言う「デフォルトマテリアル」とは、シーンの情報(各物理オブジェクトにマテリアル設定をしない場合のデフォルト値)です。もちろん、物理オブジェクト(の表面)ごとにマテリアル設定を個別指定することができます。

初期化処理に関しては、とりあえずはこんな感じです。一度書いたら変更は少ないでしょうから、関数としてコピー&ペーストできるようにしておくほうが後々楽になるかもしれません。

破棄処理

すべてを使い終わった後の後始末を行います。削除するのは、シーン(NxScene)、PhysicsSDK(NxPhysicsSDK)の2つです。シーンに登録したオブジェクトは自動的に破棄されます。

bool TermPhysX()
{
    // シーンクラスとPhysX SDKクラスを解放
    if(g_pPhysicsSDK) {
        if(g_pScene) {
            g_pPhysicsSDK->releaseScene(*g_pScene);
        }
        g_pPhysicsSDK->release();

        g_pScene      = NULL;
        g_pPhysicsSDK = NULL;
    }
    return true;
}

説明するまでもないですが、シーン破棄→PhysicsSDKの順に破棄します。これも初期化処理同様に一度書いたら変更は少ないので、関数として再利用できるようにしておきましょう。

Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.