Box2dxという物理エンジンがあるのですが、openFrmaeworksのaddonが用意されているようです。
Processingの時にお世話になった楽しいライブラリなので、openFrameworksでも試してみました。
[ 環境 ]
・Windows 10
・Visual Studio 2015
・openFramewoks 0.9.8
Box2D
https://ja.wikipedia.org/wiki/Box2D
とりあえず、通常のaddonと同じようにGitHubからデータを引っ張ってきます。
openFrameworksのバージョン0.9.8はstableを使うように書いてあるのでそちらのブランチから持ってきましょう。
ofxBox2d
https://github.com/vanderlin/ofxBox2d
そのままでは使えなかったのですが、2点程対応して使えるようにしました。
OSX/linuxユーザが多いためか、Windows環境だと手を加える必要があったり、色々なソフトを導入しないと使えないaddonとか良くあります。
C++なのでプログラミングできれば、SDKを直接呼んだ方が早い場合もありますね。OpenCVやKinectはそうしています。
1.追加のインクルードディレクトリに「[openFrameworks_dir]\addons\ofxBox2d\libs」を追記
openframerowks/addonsフォルダに配置して、プロジェクトを新規作成、使用するを選択する画面でofxBox2があることを確認して、チェック。そのままビルドするとエラーが数件発生しました。
headerファイルがないといわれますがフォルダを覗くと実体は存在しているようだったので、Pathが通じるようにしてあげましょう。
32bit,64bitのそれぞれあるので、注意しましょう
2.「ofxBox2dPolygonUtils.h」の「simplifyContour」関数を一部修正する
「式には定数値が必要です」というエラーが出ます。私もC#からC++に移行した身なので、始めの頃はやろうとしてエラーにしてましたね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
//------------------------------------------------------------------- // needs simplifyDP which is above static vector <ofVec2f> simplifyContour(vector <ofVec2f> &V, float tol) { int n = V.size(); vector <ofVec2f> sV; if(n <= 2) { return sV; } sV.assign(n, ofVec2f()); int i, k, m, pv; // misc counters float tol2 = tol * tol; // tolerance squared vector<ofVec2f> vt(n); int mk[n]; memset(mk, 0, sizeof(mk)); // STAGE 1. Vertex Reduction within tolerance of prior vertex cluster vt[0] = V[0]; // start at the beginning for (i=k=1, pv=0; i<n; i++) { if (V[i].squareDistance( V[pv] ) < tol2) continue; vt[k++] = V[i]; pv = i; } if (pv < n-1) vt[k++] = V[n-1]; // finish at the end // STAGE 2. Douglas-Peucker polyline simplification mk[0] = mk[k-1] = 1; // mark the first and last vertices simplifyDP( tol, &vt[0], 0, k-1, mk ); // copy marked vertices to the output simplified polyline for (i=m=0; i<k; i++) { if (mk[i]) sV[m++] = vt[i]; } //get rid of the unused points if( m < (int)sV.size() ) sV.erase( sV.begin()+m, sV.end() ); return sV; } |
変数の値で配列を作ろうとしているので、怒られます。
ネットで調べながら下記のように修正しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
//------------------------------------------------------------------- // needs simplifyDP which is above static vector <ofVec2f> simplifyContour(vector <ofVec2f> &V, float tol) { int n = V.size(); vector <ofVec2f> sV; if(n <= 2) { return sV; } sV.assign(n, ofVec2f()); int i, k, m, pv; // misc counters float tol2 = tol * tol; // tolerance squared vector<ofVec2f> vt(n); int* mk = (int*)malloc(sizeof(int) * n); memset(mk, 0, sizeof(int) * n); // STAGE 1. Vertex Reduction within tolerance of prior vertex cluster vt[0] = V[0]; // start at the beginning for (i=k=1, pv=0; i<n; i++) { if (V[i].squareDistance( V[pv] ) < tol2) continue; vt[k++] = V[i]; pv = i; } if (pv < n-1) vt[k++] = V[n-1]; // finish at the end // STAGE 2. Douglas-Peucker polyline simplification mk[0] = mk[k-1] = 1; // mark the first and last vertices simplifyDP( tol, &vt[0], 0, k-1, mk ); // copy marked vertices to the output simplified polyline for (i=m=0; i<k; i++) { if (mk[i]) sV[m++] = vt[i]; } //get rid of the unused points if( m < (int)sV.size() ) sV.erase( sV.begin()+m, sV.end() ); free(mk); return sV; } |
普段だと動的な配列はvectorとかのコンテナを使ってしまうので、こういうC言語由来の書き方は苦手ですね。自信は無いですが、大丈夫のはず…(危険なコードだったら誰か教えて)
とゆーか、stableにこのコードがあるってことは、コンパイラによってはOKのものもあるのかな。C/C++は奥が深すぎて毎日勉強ですね。