Contenu connexe Similaire à Media Art II 2013 第5回:openFrameworks Addonを使用する Similaire à Media Art II 2013 第5回:openFrameworks Addonを使用する (20) Plus de Atsushi Tadokoro (20) Media Art II 2013 第5回:openFrameworks Addonを使用する1. Media Art II 2013
第5回:openFrameworks
Addonを使用する
2013年10月14日
多摩美術大学 情報デザイン学科 メディア芸術コース
田所 淳
7. Addonsとは?
コンピュータ・ビジョン / AR
ofxOpenCv, ofxARToolkitPlus
シミュレーション / 物理計算 / 流体力学
ofxBox2d, ofxMSAFluid, ofxMSAPhisics, ofxRuiPhusics2d
音響
ofxMidi, ofxOsc, ofxSoundObj, ofxSuperCollider
デバイス / ハードウェア
ofxiPhone, ofxSuddenMotion
8. Addonsとは?
‣ 最初からいくつかのアドオンが付属してくる
アドオンの名称 説明
ofxDirList ディレクトリの項目の一覧を生成
ofxXmlSettings アプリケーションの設定をXML形式で保存、読込み
ofxOsc Open Sound ControlをOpenFrameworksで使用する
ofxOpenCv
画像処理・画像認識用のC言語ライブラリOpenCVを使用
できるようにする
ofxNetwork
ネットワーク通信のプロトコル、TCPとUDPを使用可能に
する、マルチキャストにも対応
ofxThred クロスプラットフォームでスレッドの管理を実現
ofxVectorGraphics OpenFrameworksからPostscriptを生成し出力する
ofx3dModelLoader 3ds形式の3DモデルをOpenFrameworksに読みこむ
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. #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
‣ 必要なパーツを全てインスタンス化
←ココ
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 必要なパーツを全てインスタンス化
29. ofxGui
‣ 先週のVector FieldのサンプルのパラメータをGUIで操作
‣ GUIで操作するパラメータをスライダーで
‣ friction (摩擦) float
‣ radius (パーティクル半径) float
‣ color (パーティクル色) ofColor ...etc.
‣ イベントを発生させるボタン
‣ パーティクルの位置をリセット
‣ Vector Fieldの力をリセット
‣ Vector Fieldの力をランダマイズ
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;
}
}
37. ofxBox2d
‣ ofxBox2d → Box2Dを、openFrameworksのAddons形式にし
たもの
‣ oF v007用に大幅に機能が向上している
‣ http://vanderlin.cc/2011/07/ofxbox2d-007/
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. 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. 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); // 動的配列に追加
! }
}
50. いろいろな形を描いてみる
‣ さらに色々な形を描いてみましょう
‣ 円 - ofxBox2dCircle
‣ 四角形 - ofxBox2dRect
‣ ポリゴン - ofxBox2dPolygon
‣ それぞれ以下の操作でBox2Dの世界で追加
‣ 円 - 「c」キーを押すと追加
‣ 四角形 - 「r」キーを押すと追加
‣ ポリゴン - 画面をマウスでドラッグして描く
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. いろいろな形を描いてみる
‣ 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. いろいろな形を描いてみる
‣ 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. いろいろな形を描いてみる
‣ 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. いろいろな形を描いてみる
‣ 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();
}
59. 「ばね」の運動
‣ ofxBox2dJoint - Box2Dで生成した図形の間を連結する
‣ パラメータを調節することで、固い棒のような性質から、やわ
らかい「ばね」の動きなど様々なシミュレーションが可能
‣ 配置した全ての円の間を「ばね」で繋いでみる
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. 「ばね」の運動
‣ 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. 「ばね」の運動
‣ 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. 「ばね」の運動
‣ 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);
! }
}