NVIDIA PhysX 4.0のビルドとサンプルプログラムの実行方法

# はじめに
2018年12月20日、物理エンジンPhysXのバージョンが3.4から4.0にバージョンアップするとともに、GitHub上でオープンソース化されました。PhysXを用いることで、球が落ちるや、重ねた積み木を壊すといった物理現象を、コンピュータ上で容易にシミュレーションできます。しかしながらPhysXのビルド手順は少し煩雑であり、初めての場合は躓きがちです。そこで本記事では、PhysXの導入方法および同梱されているサンプルプログラムの動作方法を解説し、個々人のPC上で、PhysXを用いた物理演算が可能な土台を整えたいと思います。

# PhysXとは
PhysXはNVIDIA社が提供している剛体物理エンジンです。元々はAgeia社が開発を行っていました(PhysX 2.x)が、2008年にNVIDIA社が買収し、PhysX 3.xへとメジャーバージョンアップが行われました。その後、処理速度の向上やGPU処理への対応が行われた後、今回の4.0がリリースされたという経緯を辿っています。3.xでは粒子や布のシミュレーション機能も搭載されていましたが、4.0へのバージョンアップでそれらの機能は削除され、剛体物理演算に特化した物理エンジンとなっています。粒子や布の物理演算機能は、PhysXではなく[NVIDIA FleX](https://developer.nvidia.com/flex)へと移行されました。  
PhysXは[Unity 3D](https://unity3d.com/jp)や[Unreal Engine 4](https://www.unrealengine.com/ja)といったゲームエンジンにも導入されているため、ゲーム分野に強みを持った物理エンジンと言えます。そのため、これまでは処理速度を重視したアップデートが多い印象でしたが、4.0へのアップデートでは、新たなソルバー導入や関節等の表現の精度向上等が行われており、深層強化学習等への応用を意識したアップデートとなっています。  
以降では、このようなPhysXのビルドおよびサンプルプログラムの実行方法を解説していきます。

# ゴール
本記事では、PhysXのビルドを行った後に、付属している"Kepla Demo"というサンプルプログラムを動作させます。Kepla Demoは、5種類のデモが含まれたプログラムであり、PhysXの性能を知ることが可能なデモとなっています。デモ中の1つには、以下のように数万の要素から成る構造物を壊すようなデモも含まれており、物理演算の面白さおよびPhysXの処理速度の速さを体感することができます。他にも車を運転して構造物を壊すモードや、生物を模したロボットが動くモード等も用意されており、そこそこ遊べます。
![keplademo2.gif](https://qiita-image-store.s3.amazonaws.com/0/61029/e509c635-82f0-4ca2-6aba-e8da30c7c54d.gif)

# 実行環境
今回の実行環境は、以下のようなものです。

- Windows 10 Home Edition
- Visual Studio 2017 Community(C++によるデスクトップ開発のコンポーネントをインストール)
- CMake 3.13
- python 3.5.2

なお、物理演算にはそこそこのCPUパワーが必要となります。またPhysXはGPUを用いた物理演算にも対応していますが、その際にはCUDA 10以上の導入と、Keplerアーキテクチャ以降のGPUが必要となります(十分な演算速度を出すためには、MaxwellやPascalアーキテクチャのものが推奨されており、例としてはGTX 970以上が挙げられています)。本記事では、CPU：AMD FX-8350、GPU：GeForce RTX2070、メモリ：16GBを搭載したPCを用いています。

# 手順
サンプルプログラムを動かすまでの手順は以下の通りです。

1. Visual Studio 2017のインストール
2. CMake(3.12以上)のインストール
3. Python(2.7.6以上)のインストール
4. PhysX 4.0のダウンロード
5. PhysXのビルド
6. Kepla Demo(サンプルプログラム)のビルド
7. Kepla Demoの実行

既にVisual Studio 2017や、CMake、Pythonをインストールしている場合は、それぞれの手順を適宜スキップしてください。

## 1. Visual Studio 2017のインストール
まずはじめに、IDEとしてVisual Studio 2017 Community(無料)をインストールします。インストール手順は、[Microsoft公式のドキュメント](https://docs.microsoft.com/ja-jp/visualstudio/install/install-visual-studio?view=vs-2017)が参考になります。インストールの途中でワークロードの選択が必要となりますが、そこでは"C++によるデスクトップ開発"をチェックしておきます。既にインストールしたVisual Studio 2017にワークロードを追加する場合、Visual Studio Installerを起動し、Visual Studio 2017を変更することで追加できます。

## 2. CMakeのインストール
次に、Visual Studioでのビルド環境を作成するために、CMakeを導入します。CMakeは、様々なコンパイラでのビルド環境を作るためのツールです。PhysXは、Visual Studio(VC++)のみならず、様々なコンパイラでビルド出来るように作成されています。そのため、リポジトリ中には、Visual Studioでビルドする際に必用なソリューションファイル等は含まれておらず、別途作成する必用があります。CMakeは、このようなビルド環境を作るためのソフトウェアであり、今回であればリポジトリ中のCMakeLists.txtの情報から、Visual Studio向けのソリューションファイルを生成してくれます。  
CMakeのインストールは、[CMake公式ページ](https://cmake.org/download/)からWindows向けのインストーラ(~.msi)をダウンロードし、実行することで行います。インストール中、CMakeの環境変数をPathに追加するかどうか聞かれるので、追加を指定します。インストール後に環境変数を追加する場合、`C:\Program Files\CMake\bin`を、コントロールパネル→システムとセキュリティ→システム→システムの詳細設定→環境変数→ユーザ環境変数→Pathを編集し、追加する必要があります。Pathが通っているかを確かめるためには、PowerShell等で`cmake --version`と打ち込み、バージョン番号が表示されていれば大丈夫です。  

## 3. Pythonのインストール
PhsyXのリポジトリ中には、CMakeでのビルド環境構築用スクリプトが用意されていますが、そのスクリプトはPythonで書かれているため、Pythonの実行環境も必要となります。[Python公式ページ](https://www.python.org/downloads/)より、Windows向けの最新のPythonインストーラをダウンロードし、実行することで、インストールを行います。インストール時にはPathを登録するために、"Add Python 3.x to PATH"のチェックを付けておきます。インストール後、Powershell等で`python --version`と打ち込み、バージョン番号が表示されていれば大丈夫です。

## 4. PhysX 4.0のダウンロード
いよいよPhysXのダウンロードを行います。PhysXは[GitHub上](https://github.com/NVIDIAGameWorks/PhysX)で公開されています。そのためPCにgitがインストールされている場合は、適用な箇所で`git clone https://github.com/NVIDIAGameWorks/PhysX`を実行し、ソースコード全体を落とします。gitが入っていない場合は、GitHub中の"Clone or download"ボタンをクリックし、Download ZIPを選択することで、ダウンロードすることができます。なお、以降の説明で用いるファイルパスは、ダウンロードしたリポジトリのルートディレクトリを`PhysX`とし、ここを起点として記載します。

## 5. PhysXのビルド
まず、ビルドするためのソリューションファイル作成します。手動でCMakeを利用し、作成することもできますが、PhysXリポジトリ中に便利なバッチファイルが用意されているので、そちらを利用します。`PhysX\physx\generate_project.bat`を実行すると、作成したいビルド環境の選択肢が表示されるため、6を入力しvc15win64を選択します。VC15は、Visual Studio 2017に搭載されているコンパイラとなります。選択後、cmakeコマンドを利用したビルド環境構築が自動で行われ、完了すると`PhysX\physx\compiler\vc15win64`が出来ます。ここでエラーが出る場合は、CMakeのインストール、もしくはPathへの登録が失敗している可能性があります。  

ビルド環境の構築が完了後、`PhysX\physx\compiler\vc15win64\PhysXSDK.sln`を開きます。そうするとVisual Studio 2017が立ち上がり、ビルド準備が整います。ビルドの種類としてはdebug/checked/profile/releaseが用意されており、メニューバー近くのプルダウンメニューにより変更できます。今回は処理が最速となるreleaseビルドを選択します。
![physx_build.png](https://qiita-image-store.s3.amazonaws.com/0/61029/2b4b9aff-cd0b-23cf-52b9-4c576c7479ce.png)


その後、ソリューションエクスプローラー中の**ALL_BUILD**を右クリックし、ビルドを選択することで、ビルド作業を行います。しばらく待つとビルドが完了し、`PhysX\physx\bin\win.x86_64.vc141.mt\release`の中にビルド結果が出力されています。出力されたビルド結果(libやdll等)を利用することで、PhysXを用いた処理が可能となります。
![physx_build2.png](https://qiita-image-store.s3.amazonaws.com/0/61029/ae736aed-b6c3-e7bb-3b71-81c5e27718aa.png)

## 6. Kepla Demo(サンプルプログラム)のビルド
続いて、PhysXを利用したサンプルプログラムである、Kepla Demoをビルドします。Kepla Demoについては、Visual Studio向けのソリューションファイルがリポジトリ中に含まれているため、`PhysX\kaplademo\source\compiler\vc15win64-PhysX_4.0\KeplaDemo.sln`を開きます。PhysXのビルド時と同じく、releaseビルドに設定し、ソリューションエクスプローラー中の**KeplaDemo**を右クリックし、ビルドします。その結果、KeplaDemoのコンパイルや、PhysXのビルドで生成されたライブラリ等とのリンク処理が行われた後に、`PhysX\kaplademo\bin\VC15WIN64\RELEASE\KeplaDemo.exe`が出力されます。

## 7. Kepla Demoの実行
出力された`KeplaDemo.exe`を実行することで、デモを動作させることができます。細かな操作方法はF1キーで表示することができます。
![Kepla Tower](https://qiita-image-store.s3.amazonaws.com/0/61029/e509c635-82f0-4ca2-6aba-e8da30c7c54d.gif)
<img src="https://qiita-image-store.s3.amazonaws.com/0/61029/8cb02769-8145-21bb-16c5-c6d943350a9e.png" width=70%>
<img src="https://qiita-image-store.s3.amazonaws.com/0/61029/1593ecfc-8f5e-a5a0-a63d-efb6afa07291.png" width=70%>


# おわりに
本記事では、PhysX 4.0のビルドおよびサンプルプログラムの実行方法について述べました。自分のPC上で物理演算が自由自在に行えるというのは、実に面白いものです。本記事を通して、少しでも多くの方が、物理シミュレーションの世界に興味を持っていただけると幸いです。


# おまけ
本記事では述べませんでしたが、PhysXのリポジトリには、Snippetと呼ばれるプログラムが含まれており、ビルド時にそれらのSnippetもビルドされています。SnippetのプログラムはPhysXの各要素を説明するための小さなプログラムで、PhysXを触り始める取っ掛かりとして、程よい規模のプログラムとなっています。(Kepla Demoのプログラムは巨大で、初めて読むには荷が重いです。)
`PhysX\physx\bin\win.x86_64.vc141.mt\release`中の`Snippet~.exe`というものが、Snippetのビルド結果であり、実行して試すことができます。例えば`SnippetHelloWorld_64.exe`は、積み重ねられた物体に球を当てるという、単純なプログラムになっています。ソースコードは`PhysX\physx\snippets\snippethelloworld`に含まれているため、興味のある方は覗いてみると面白いかもしれません。
![SnippetHelloWorld.gif](https://qiita-image-store.s3.amazonaws.com/0/61029/cb4ef77e-b5f6-4ced-5389-39f4d2e94208.gif)