Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Media Art II 2013 第5回:openFrameworks Addonを使用する

22,657 views

Published on

Published in: Technology, Education
  • Be the first to comment

Media Art II 2013 第5回:openFrameworks Addonを使用する

  1. 1. Media Art II 2013 第5回:openFrameworks Addonを使用する 2013年10月14日 多摩美術大学 情報デザイン学科 メディア芸術コース 田所 淳
  2. 2. Addonとは? ‣ Addonとは、oepnFrameworksの機能を何らかの方法で拡張 するコード ‣ 「ofx」という接頭辞で始まる
  3. 3. Addonとは? ‣ openFrameworksに機能を拡張するためのライブラリー ‣ processingのLibrariesのような存在 ‣ openFrameworks単体ではできなかった様々な機能を実現 ‣ oF本体の開発者以外でも独自に開発して追加することが可能 ‣ アドオン情報 ‣ ofxAddons ‣ http://ofxaddons.com/
  4. 4. Addonとは? ‣ ofxAddons.com リニューアル
  5. 5. Addonとは? ‣ どうやってofxAddons.comのアドオンをインストールすのか? ‣ 方法1: git コマンドをつかって、コードの複製をつくる ‣ 方法2: WebサイトからZip形式ダウンロード $cd of_preRelease/addons/ $git clone https://github.com/obviousjim/ofxSomeAddon コレ
  6. 6. Addonとは? ‣ Addonは何のためにあるの? ‣ 外部ライブラリやフレームワークをoFに統合 ‣ ofxKinect, ofxMidi etc.. ‣ 定型の作業、複雑な操作を単純化 ‣ ofxQuadWrap、ofxControlPanel etc...
  7. 7. Addonsとは? コンピュータ・ビジョン / AR ofxOpenCv, ofxARToolkitPlus シミュレーション / 物理計算 / 流体力学 ofxBox2d, ofxMSAFluid, ofxMSAPhisics, ofxRuiPhusics2d 音響 ofxMidi, ofxOsc, ofxSoundObj, ofxSuperCollider デバイス / ハードウェア ofxiPhone, ofxSuddenMotion
  8. 8. Addonsとは? ‣ 最初からいくつかのアドオンが付属してくる アドオンの名称 説明 ofxDirList ディレクトリの項目の一覧を生成 ofxXmlSettings アプリケーションの設定をXML形式で保存、読込み ofxOsc Open Sound ControlをOpenFrameworksで使用する ofxOpenCv 画像処理・画像認識用のC言語ライブラリOpenCVを使用 できるようにする ofxNetwork ネットワーク通信のプロトコル、TCPとUDPを使用可能に する、マルチキャストにも対応 ofxThred クロスプラットフォームでスレッドの管理を実現 ofxVectorGraphics OpenFrameworksからPostscriptを生成し出力する ofx3dModelLoader 3ds形式の3DモデルをOpenFrameworksに読みこむ
  9. 9. Addonsとは? ‣ アドオンがインストールされている場所 ‣ 《oFをインストールしたフォルダ》/addons/
  10. 10. Addonsとは? ‣ 今回は題材として2つのAddonを試してみます ‣ ofxGui:GUI ‣ 長らく待望されていた、oFオフィシャルGUI ‣ プログラムで頻繁に調整する必要のあるパラメータを GUIから設定可能にする ‣ 設定した項目は、XML形式で設定ファイルとして保存と 読込が可能 ‣ ofxBox2d:物理演算 ‣ 重力や、物体同士の衝突、ばねや引力など様々な物理演 算を簡単に実装可能
  11. 11. ofxGui
  12. 12. ofxGui ‣ 長らく待望されていた(?) openFrameworks開発チーム純正の GUI を作成するためのAddon ‣ v.0.8.0 から配布パッケージに同梱 ‣ 簡単にプロジェクトにGUIを追加可能
  13. 13. ofxGui ‣ Addon の使用法を知るにはサンプルをみるのが一番! ‣ Addon の多くにはサンプルが付属してる ‣ ofxGuiの場合は「of_v0.8.0_osx_release/examples/gui/」に 大量に掲載 (オフィシャル感!!)
  14. 14. ofxGui ‣ まずは基本の「guiExample」をみてみる
  15. 15. ofxGui ‣ 「guiExample」に含まれる様々なGUIの機能 ‣ 数値のスライダー (int, float) ‣ カラー設定スライダー ‣ 位置 (ofVec2f) ‣ トグルボタン ‣ ボタン ‣ ... etc.
  16. 16. ofxGui ‣ ofxGuiで使用できる機能いろいろ アドオンの名称 説明 ofxIntSlider 整数型 (int) のスライダー ofxFloatSlider 浮動小数点型 (float) のスライダー ofxVec2Slider 2次元ベクトルのスライダー ofxColorSlider カラー生成スライダー ofxButton ボタン ofxToggle トグルスイッチ ofxLabel ラベル (テキスト表示) ofxPanel GUIの外枠
  17. 17. ofxGui ‣ 簡単なプログラムで使い方をマスター ‣ まずは新規プロジェクトの生成方法から ‣ ProjectGeneratorの設定方法から
  18. 18. ofxGui ‣ プロジェクト名を設定したら、「Addons」ボタンを押す ←ココ
  19. 19. ofxGui ‣ ofxGuiのチェックボックスをチェックして戻る ‣ GENERATE PROJECT ボタンを押して完了
  20. 20. ofxGui ‣ プロジェクトを開いてみる ‣ addonsフォルダにAddonsが追加され ているはず
  21. 21. ofxGui ‣ 以下のようなシンプルなGUI操作を実現したい ‣ 画面に円を描く ‣ 円の半径をスライダーで調整 ‣ 円の色もスライダーで調整
  22. 22. #pragma once #include "ofMain.h" #include "ofxGui.h" class testApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); void keyReleased(int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); }; ofxGui ‣ まず始めに、testApp.h の冒頭で ofxGui を 読み込む ←ココ
  23. 23. #pragma once #include "ofMain.h" #include "ofxGui.h" class testApp : public ofBaseApp{ public: void setup(); void update(); void draw(); ... ofxPanel gui; ofxFloatSlider radius; ofxColorSlider color; ofxVec2Slider position; }; ofxGui ‣ 必要なパーツを全てインスタンス化 ←ココ
  24. 24. ofxGui ‣ まず、gui.setup() でGUI生成 ‣ そこへ、スライダーの初期設定を追加していく ‣ gui.add(スライダー.setup( 名前 , 初期値, 最小値, 最大値));
  25. 25. #include "testApp.h" //-------------------------------------------------------------- void testApp::setup(){ ofSetFrameRate(60); ofBackground(127); ofSetCircleResolution(32); // colorの初期値、最小値、最大値を設定 ofColor initColor = ofColor(0, 127, 255, 255); ofColor minColor = ofColor(0,0,0,0); ofColor maxColor = ofColor(255,255,255,255); // positionの初期値、最小値、最大値を設定 ofVec2f initPos = ofVec2f(ofGetWidth()/2, ofGetHeight()/2); ofVec2f minPos = ofVec2f(0, 0); ofVec2f maxPos = ofVec2f(ofGetWidth(), ofGetHeight()); gui.setup(); gui.add(radius.setup("radius", 200, 0, 400)); gui.add(color.setup("color", initColor, minColor, maxColor)); gui.add(position.setup("position", initPos, minPos, maxPos)); } ofxGui ‣ testApp.cpp 必要なパーツを全てインスタンス化
  26. 26. void testApp::draw(){ // パラメータを適用して円を描画 ofSetColor(color); ofCircle(ofVec2f(position), radius); // GUIを表示 gui.draw(); } ofxGui ‣ あとは、その値を描画に適用するのみ (簡単!!)
  27. 27. ofxGui ‣ 実行結果
  28. 28. ofxGui ‣ ofxGuiのより実践的な練習 ‣ 先週のVector FieldのサンプルのパラメータをGUIで操作
  29. 29. ofxGui ‣ 先週のVector FieldのサンプルのパラメータをGUIで操作 ‣ GUIで操作するパラメータをスライダーで ‣ friction (摩擦) float ‣ radius (パーティクル半径) float ‣ color (パーティクル色) ofColor ...etc. ‣ イベントを発生させるボタン ‣ パーティクルの位置をリセット ‣ Vector Fieldの力をリセット ‣ Vector Fieldの力をランダマイズ
  30. 30. ‣ 既に生成されて、vectorに格納された大量のParticleのオブ ジェクトに対してパラメータ変更するにはちょっと工夫が必要 ‣ イベントリスナーをつかう ‣ 例えば、friction (摩擦) の場合 ‣ testApp.hで、イベントリスナーの関数を定義しておく ofxGui ofxFloatSlider friction; void frictionChanged(float & friction);
  31. 31. ‣ testApp.cpp スライダーを作成する際にイベントリスナーを追 加する ‣ 摩擦を変化させた際のイベントを記述する ‣ 同じようにして、半径や、各種ボタンに関しても ofxGui friction.addListener(this, &testApp::frictionChanged); void testApp::frictionChanged(float & friction){ for (int i = 0; i < particles.size(); i++){ particles[i].friction = friction; } }
  32. 32. ofxGui ‣ 完成!!
  33. 33. ofxBox2d
  34. 34. ofxBox2d ‣ 本日のAddonsその2 ‣ 2次元の物理シミュレーションのためのAddon ‣ ofxBox2d
  35. 35. ofxBox2d ‣ ofxBox2d: ‣ Box2DをoFのアドオン形式にしたもの ‣ Box2Dとは ‣ C++で書かれた、物理エンジン ‣ 重力や反発力、摩擦、衝突判定といった物理計算を複雑な 計算をすることなく利用できる ‣ ActionScript、Java、C#、Pythonなどにも移植されている
  36. 36. ofxBox2d ‣ Box2D Google Codeページ ‣ http://code.google.com/p/box2d/
  37. 37. ofxBox2d ‣ ofxBox2d → Box2Dを、openFrameworksのAddons形式にし たもの ‣ oF v007用に大幅に機能が向上している ‣ http://vanderlin.cc/2011/07/ofxbox2d-007/
  38. 38. Addonをプロジェクトに追加する ‣ Box2Dを題材にして、実際に空のプロジェクトにBox2Dを追加 してみる ‣ ProjectGeneratorから、ofxBox2dを追加する ‣ 必要となるAddonはofxBox2Dだけ
  39. 39. Box2D基本
  40. 40. Box2D基本 ‣ Box2Dに描かれる図形は全てBox2Dの物理世界に配置 ‣ testAppのsetup()関数内で、まずBox2Dの世界を初期化する ‣ 初期化の例 void testApp::setup() { ! ... ! ! box2d.init(); // Box2Dの世界の初期化 ! box2d.setGravity(0, 10); // 重力を下向きに10 ! box2d.createBounds(); // 地面を生成 ! box2d.setFPS(30.0); // Box2Dの世界でのFPS ! box2d.registerGrabbing(); // 物体に接触可能に }
  41. 41. Box2D基本 ‣ Box2Dの物理計算を実行するには、testAppのupdate()関数 で、ofxBox2Dのupdate()メソッドを呼びだすだけ ‣ 自動的に全ての「重力」「摩擦」「衝突」「反射」などの物理 計算を行なってくれる void testApp::update() { ! box2d.update(); // Box2Dの更新 }
  42. 42. Box2D基本 ‣ Box2Dの物理世界に配置する物体は、Box2Dで用いられる専用 のクラスから生成する ‣ 基本クラスを継承して、自分独自の形態にすることも可能 ‣ ofxBox2Dで使用できる物体 クラス名 形態 ofxBox2dCircle 円 ofxBox2dRect 四角形 ofxBox2dPolygon ポリゴン(多角形) ofxBox2dJoint 図形同士を結ぶジョイント
  43. 43. たくさんの円を配置してみる
  44. 44. たくさんの円を配置してみる ‣ まずはシンプルなサンプルを作成してみましょう ‣ Box2Dの物理世界に、沢山の円(ofxBox2dCircle)を配置してそ の動きを観察 ‣ 配置する円の数に制限を設けたくないので、ofxBox2dCircleの 動的配列(vector)を生成して管理すると便利 vector <ofxBox2dCircle> circles;! // Circleを格納する動的配列
  45. 45. Box2D基本:たくさんの円で物理演算 ‣ testApp.h ‣#pragma once #include "ofMain.h" #include "ofxBox2d.h" class testApp : public ofBaseApp { ! public: ! ! void setup(); ! void update(); ! void draw(); ! void keyPressed(int key); ! ! ofxBox2d box2d;!// Box2Dの世界を構築 ! vector <ofxBox2dCircle> circles;!// Circleを格納する動的配列 };
  46. 46. Box2D基本:たくさんの円で物理演算 ‣ testApp.cpp - 1 of 2 #include "testApp.h" void testApp::setup() { ! ofSetVerticalSync(true); ! ofBackgroundHex(0x000000); ! ! box2d.init(); // Box2Dの世界の初期化 ! box2d.setGravity(0, 10); // 重力を下向きに10 ! box2d.createBounds(); // 地面を生成 ! box2d.setFPS(30.0); // Box2Dの世界でのFPS ! box2d.registerGrabbing(); // 物体に接触可能に } void testApp::update() { ! box2d.update(); // Box2Dの更新 } void testApp::draw() { ! // circlesを描く ! for(int i=0; i<circles.size(); i++) { ! ! ofSetHexColor(0x3366ff); ! ! circles[i].draw(); ! } }
  47. 47. Box2D基本:たくさんの円で物理演算 ‣ testApp.cpp - 2 of 2 void testApp::keyPressed(int key) { ! // [c]キーを押すと、Circleを追加 ! if(key == 'c') { ! ! float r = ofRandom(4, 20); //半径をランダムに ! ! ofxBox2dCircle circle; //円 ! ! circle.setPhysics(3.0, 0.53, 0.1); //物理法則を追加 ! ! // Box2dの世界に生成した円を追加 ! ! circle.setup(box2d.getWorld(), mouseX, mouseY, r); ! ! circles.push_back(circle); // 動的配列に追加 ! } }
  48. 48. Box2D基本:たくさんの円で物理演算 ‣ 「c」キーを押すと、円が追加されていく
  49. 49. いろいろな形を描いてみる
  50. 50. いろいろな形を描いてみる ‣ さらに色々な形を描いてみましょう ‣ 円 - ofxBox2dCircle ‣ 四角形 - ofxBox2dRect ‣ ポリゴン - ofxBox2dPolygon ‣ それぞれ以下の操作でBox2Dの世界で追加 ‣ 円 - 「c」キーを押すと追加 ‣ 四角形 - 「r」キーを押すと追加 ‣ ポリゴン - 画面をマウスでドラッグして描く
  51. 51. いろいろな形を描いてみる ‣ testApp.h #pragma once #include "ofMain.h" #include "ofxBox2d.h" class testApp : public ofBaseApp { ! public: ! ! void setup(); ! void update(); ! void draw(); ! void keyPressed(int key); ! void mouseDragged(int x, int y, int button); ! void mousePressed(int x, int y, int button); ! void mouseReleased(int x, int y, int button); ! ! ofxBox2d box2d;!// Box2Dの世界を構築 ! vector <ofxBox2dCircle> circles;!// Circleを格納する動的配列 ! vector <ofxBox2dRect> rects;!// Rectを格納する動的配列 ! ofPolyline drawing; // 画面に描く線 ! ofxBox2dPolygon polyLine; // 描いた線から、多角形の物体を生成 };
  52. 52. いろいろな形を描いてみる ‣ testApp.cpp - 1 of 1 #include "testApp.h" void testApp::setup() { ! ofSetVerticalSync(true); ! ofBackgroundHex(0x000000); ! ! box2d.init(); // Box2Dの世界の初期化 ! box2d.setGravity(0, 10); // 重力を下向きに10 ! box2d.setFPS(30.0); // Box2Dの世界でのFPS ! box2d.registerGrabbing(); // 物体に接触可能に ! ! polyLine.setPhysics(0.0, 0.5, 0.5); ! polyLine.create(box2d.getWorld());! } void testApp::update() { ! box2d.update(); // Box2Dの更新 }
  53. 53. いろいろな形を描いてみる ‣ testApp.cpp - 1 of 3 void testApp::draw() { ! // 円を描く ! ofFill(); ! for(int i=0; i<circles.size(); i++) { ! ! ofSetHexColor(0x3366ff); ! ! circles[i].draw(); ! } ! ! // 四角形を描く ! for(int i=0; i<rects.size(); i++) { ! ! ofSetHexColor(0xff6633); ! ! rects[i].draw(); ! } ! ! // 多角形(描画した線分)を描く ! ofNoFill(); ! ofSetHexColor(0xffffff); ! if(drawing.size()==0) { ! ! polyLine.draw();! ! }! else { ! ! drawing.draw();! ! } }
  54. 54. いろいろな形を描いてみる ‣ testApp.cpp - 2 of 3 void testApp::keyPressed(int key) { ! // [c]キーを押すと、ofxBox2DCircleを追加 ! if(key == 'c') { ! ! float r = ofRandom(4, 20); //半径をランダムに ! ! ofxBox2dCircle circle; //円 ! ! circle.setPhysics(3.0, 0.53, 0.1); //物理法則を追加 ! ! // Box2dの世界に生成した円を追加 ! ! circle.setup(box2d.getWorld(), mouseX, mouseY, r); ! ! circles.push_back(circle); // 動的配列に追加 ! } ! // [r]キーを押すと、ofxBox2DRectを追加 ! if(key == 'r') { ! ! float w = ofRandom(4, 20); // 幅をランダムに ! ! float h = ofRandom(4, 20); // 高さをランダムに ! ! ofxBox2dRect rect; // 四角形 ! ! rect.setPhysics(3.0, 0.53, 0.1); // 物理法則を追加 ! ! // Box2dの世界に生成した四角形を追加 ! ! rect.setup(box2d.getWorld(), mouseX, mouseY, w, h); ! ! rects.push_back(rect); // 動的配列に追加 ! } }
  55. 55. いろいろな形を描いてみる ‣ testApp.cpp - 3 of 3 void testApp::mouseDragged(int x, int y, int button) { ! drawing.addVertex(x, y); } void testApp::mousePressed(int x, int y, int button) { ! // もしも既に多角形が存在していたら、消去する ! if(polyLine.isBody()) { ! ! drawing.clear(); ! ! polyLine.destroy();! ! } ! // 描画中の線分に辺を追加 ! drawing.addVertex(x, y); } void testApp::mouseReleased(int x, int y, int button) { ! // 描画していた多角形を確定 ! drawing.setClosed(false); ! drawing.simplify(); ! // ofxBox2dPlyLineとして生成 ! polyLine.addVertexes(drawing); ! polyLine.simplify(); ! polyLine.setPhysics(0.0, 0.5, 0.5); ! polyLine.create(box2d.getWorld()); ! drawing.clear(); }
  56. 56. いろいろな形を描いてみる ‣ マウスで描いた形にそって、円と四角が落ちていく
  57. 57. いろいろな形を描いてみる ‣ 参考:Line Rider ‣ 描いた線にそって、そり滑り!!
  58. 58. 「ばね」の運動
  59. 59. 「ばね」の運動 ‣ ofxBox2dJoint - Box2Dで生成した図形の間を連結する ‣ パラメータを調節することで、固い棒のような性質から、やわ らかい「ばね」の動きなど様々なシミュレーションが可能 ‣ 配置した全ての円の間を「ばね」で繋いでみる
  60. 60. いろいろな形を描いてみる ‣ testApp.h #pragma once #include "ofMain.h" #include "ofxBox2d.h" class testApp : public ofBaseApp { ! public: ! ! void setup(); ! void update(); ! void draw(); ! //void keyPressed(int key); ! void mouseReleased(int x, int y, int button); ! void mouseDragged(int x, int y, int button); ! ! ofxBox2d box2d;!// Box2Dの世界を構築 ! vector <ofxBox2dRect> rects;!// Circleを格納する動的配列 ! vector <ofxBox2dJoint> joints; // バネの配列 };
  61. 61. 「ばね」の運動 ‣ testApp.cpp - 1 of 3 #include "testApp.h" void testApp::setup() { ! ofSetVerticalSync(true); ! ofBackgroundHex(0x000000); ! ! box2d.init(); // Box2Dの世界の初期化 ! box2d.setGravity(0, 0); // 無重力に ! box2d.createBounds(); // 地面を生成 ! box2d.setFPS(30.0); // Box2Dの世界でのFPS ! box2d.registerGrabbing(); // 物体に接触可能に } void testApp::update() { ! box2d.update(); // Box2Dの更新 } void testApp::draw() { ! // バネを描く ! for(int i=0; i<joints.size(); i++) { ! ! ofNoFill(); ! ! ofSetHexColor(0x333333); ! ! joints[i].draw(); ! }
  62. 62. 「ばね」の運動 ‣ testApp.cpp - 2 of 3 ! // circlesを描く ! for(int i=0; i<rects.size(); i++) { ! ! ofFill(); ! ! ofSetHexColor(0x3366ff); ! ! rects[i].draw(); ! } } void testApp::mouseReleased(int x, int y, int button) { ! ofxBox2dRect rect; //円 ! rect.setPhysics(10.0, 0.99, 0.0); ! ! // Box2dの世界に生成した円を追加 ! rect.setup(box2d.getWorld(), x, y, 2, 2); ! rects.push_back(rect); // 動的配列に追加 ! ! if (rects.size() > 1) { ! ! for (int i = 0; i < rects.size()-1; i++) { ! ! ! ofxBox2dJoint joint; ! ! ! joint.setup(box2d.getWorld(), rects[rects.size()-1].body, rects[i].body); ! ! ! joint.setFrequency(0.4); ! ! ! joint.setDamping(0.1); ! ! ! joint.setLength(200); ! ! ! joints.push_back(joint);
  63. 63. 「ばね」の運動 ‣ testApp.cpp - 3 of 3 ! ! } ! } } void testApp::mouseDragged(int x, int y, int button) { ! for (int i = 0; i < rects.size()-1; i++) { ! ! rects[i].addRepulsionForce(x, y, -1); ! } }
  64. 64. 「ばね」の運動 ‣ ばねで連結された物体が出現 ‣ マウスをドラッグすると、動きまわる
  65. 65. 「ばね」の運動 ‣ 参考:SodaPlay (http://sodaplay.com/) ‣ ばねの連結でできた、生物たち

×