ODEをMacにインストール
Mac OS X Mountain Lion に物理シミュレーションエンジンの Open Dynamics Engine (ODE) を入れようとしてすごく苦労したのでまとめておきます。macportsにもodeはありますが、これだとdrawstuffというライブラリが入っていなかったのでソースコードからコンパイルしています。
コンパイルに使ったg++は、macportsではなく、Xcode4.4のものです。Xcode4.4のコマンドラインツールのインストールは、こちらを参考にしてください。
> which g++ /usr/bin/g++ > ls -l /usr/bin/g++ lrwxr-xr-x 1 root wheel 12 7 28 21:19 /usr/bin/g++@ -> llvm-g++-4.2
Open Dynamics Engine のサイトから ode-0.12.tar.bz2 をダウンロードし、倍精度でコンパイルしました。
tar xvzf ode-0.12.tar.bz2 cd ode-0.12 ./configure --enable-double-precision make sudo make install
ここまでで、/usr/local/libと/usr/local/includeにODEがインストールされますが、実はこれだけではダメでデフォルトだとなぜかdrawstuffがインストールされなかったです。なので、drawstuffのライブラリファイルとヘッダファイルを手動でコピーします。
sudo cp drawstuff/src/.libs/libdrawstuff.* /usr/local/lib/ sudo mkdir /usr/local/include/drawstuff sudo cp include/drawstuff/*.h /usr/local/include/drawstuff/
また、デフォルトのテクスチャファイルはあとで使うので作業ディレクトリにコピーしておくとよいです。
cp -R drawstuff/textures ~/work
最後にODEチュートリアルのソースコードをコンパイルして動作確認。fn.path_to_texturesのtexturesは先ほどテクスチャをコピーした場所を設定します。
/* sample.cpp */ #include <ode/ode.h> #include <drawstuff/drawstuff.h> #ifdef dDOUBLE #define dsDrawSphere dsDrawSphereD #endif static dWorldID world; dBodyID ball; const dReal radius = 0.2, mass = 1.0; static void simLoop(int pause) { const dReal *pos, *R; dWorldStep(world, 0.05); dsSetColor(1.0, 0.0, 0.0); pos = dBodyGetPosition(ball); R = dBodyGetRotation(ball); dsDrawSphere(pos, R, radius); } void start() { static float xyz[3] = {0.0, -3.0, 1.0}; static float hpr[3] = {90.0, 0.0, 0.0}; dsSetViewpoint(xyz, hpr); } int main(int argc, char **argv) { dReal x0 = 0.0, y0 = 0.0, z0 = 1.0; dMass m1; dsFunctions fn; fn.version = DS_VERSION; fn.start = &start; fn.step = &simLoop; fn.command = NULL; fn.stop = NULL; fn.path_to_textures = "./textures"; dInitODE(); world = dWorldCreate(); dWorldSetGravity(world, 0, 0, -0.01); ball = dBodyCreate(world); dMassSetZero(&m1); dMassSetSphereTotal(&m1, mass, radius); dBodySetMass(ball, &m1); dBodySetPosition(ball, x0, y0, z0); dsSimulationLoop(argc, argv, 352, 288, &fn); dWorldDestroy(world); dCloseODE(); return 0; }
で、最後にコンパイルですが、ここではまりにはまった。まず、
g++ sample.cpp -lode -ldrawstuff -DdDOUBLE
とやってみた。libodeとlibdrawstuffは、標準の/usr/local/libにあるので-Lでパスを指定する必要はないはず。それなのに、下のようなよくわからないコンパイルエラー。
Undefined symbols for architecture x86_64: "_glBegin", referenced from: drawConvexD(double*, unsigned int, double*, unsigned int, unsigned int*)in libdrawstuff.a(drawstuff.o) drawCapsule(float, float)in libdrawstuff.a(drawstuff.o) drawCylinder(float, float, float)in libdrawstuff.a(drawstuff.o) drawConvex(float*, unsigned int, float*, unsigned int, unsigned int*)in libdrawstuff.a(drawstuff.o) drawBox(float const*)in libdrawstuff.a(drawstuff.o) _dsDrawTriangleD in libdrawstuff.a(drawstuff.o) _dsDrawLine in libdrawstuff.a(drawstuff.o) ... ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status
このエラーは Mac OS X Lion 以降頻発するらしくWeb上にいろいろ情報があったのですが、なかなか解決しなかった・・・
で、数時間格闘したあと、最終的に下のように-frameworkでGLUTとOpenGLを指定することでコンパイルできることが判明。ここのサイトが決め手になりました。64bitとか関係あったの???
g++ sample.cpp -lode -ldrawstuff -DdDOUBLE -framework GLUT -framework OpenGL
もしくは、ODEのコマンドode-configを使って下のようにも書けます。
g++ sample.cpp `ode-config --cflags --libs` -ldrawstuff -framework GLUT -framework OpenGL
ode-configは、ライブラリ、ヘッダファイルのパスとインストールしたときの精度を返してくれるようです。
> ode-config --cflags --libs -I/usr/local/include -DdDOUBLE -L/usr/local/lib -lode
よーし、これで動作確認もできたし、本格的に物理シミュで遊ぶぞ!