!!!ひな形のソース (2006/09/11 更新) PhysX SDKを使ったプロジェクト環境を作るにあたっては「[[プロジェクトの作成|プロジェクトの作成_PhysX]]」を参照してください。 まずは、PhysXを使ったソースでの初期化・後始末を記述してみます。 ソースに関しては、プロジェクト内に「xxx.cpp」として記述していると考えてください。 !!インクルードファイルの指定 #define NOMINMAX // #include の前に必要 #include #include #include #include #include #include "NxPhysics.h" // PhysXの物理演算定義など 必要なのは「NxPhysics.h」の参照です。が、windows.hファイルを インクルードする場合はmin/maxマクロがかぶることになります。 ので、「#include 」を呼ぶ前に「#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の順に破棄します。 これも初期化処理同様に一度書いたら変更は少ないので、関数として再利用できるようにしておきましょう。