aa develop

開発と成長

openFrameworksでofxCvとofxBox2dを組み合わせる

openFrameworksのofxCvアドオンとofxBox2dアドオンを組み合わせて,映像中の動きに合わせてメッシュ状に配置したオブジェクトを動かすプログラムを書いた.

f:id:aa_debdeb:20160714110906p:plain

box2dオブジェクトはその位置のオプティカルフローの値とバネで繋がった他のオブジェクトから力を受ける.端のオブジェクトだけは固定してある.

ofMain.cpp

#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main( ){
    ofSetupOpenGL(1000,750,OF_WINDOW);          // <-------- setup the GL context

    // this kicks off the running of my app
    // can be OF_WINDOW or OF_FULLSCREEN
    // pass in width and height too:
    ofRunApp(new ofApp());

}
ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxBox2d.h"
#include "ofxCv.h"

class ofApp : 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 mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
    
    ofxBox2d box2d;
    vector  > circles;
    vector  > joints;
    
    ofVideoGrabber camera;
    ofxCv::FlowFarneback fbFlow;
    
};
ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

    ofBackground(0);
    ofSetVerticalSync(true);
    
    box2d.init();
    box2d.setGravity(0, 0);
    box2d.setFPS(30.0);
    box2d.registerGrabbing();
    
    int interval = 50;
    int x_num = ofGetWidth() / interval + 1;
    int y_num = ofGetHeight() / interval + 1;
    
    
    for(int y = 0; y < y_num; y++){
        for(int x = 0; x < x_num; x++){
            shared_ptr circle = shared_ptr(new ofxBox2dCircle);
            if(!(x == 0 || x == x_num - 1 || y == 0 || y == y_num - 1)){
                circle.get()->setPhysics(3.0, 0.53, 0.1);
            }
            circle.get()->setup(box2d.getWorld(), x * interval, y * interval, 10);
            circles.push_back(circle);
        }
    }
    
    for(int y = 0; y < y_num; y++){
        for(int x = 0; x < x_num; x++){
            if(x != x_num - 1){
                shared_ptr joint = shared_ptr(new ofxBox2dJoint);
                joint.get()->setup(box2d.getWorld(), circles[y * x_num + x].get()->body, circles[y * x_num + x + 1].get()->body);
                joint.get()->setLength(interval);
                joints.push_back(joint);
            }
            if(y != y_num - 1){
                shared_ptr joint = shared_ptr(new ofxBox2dJoint);
                joint.get()->setup(box2d.getWorld(), circles[y * x_num + x].get()->body, circles[(y + 1) * x_num + x].get()->body);
                joint.get()->setLength(interval);
                joints.push_back(joint);
            }
        }
    }
    
    camera.setup(320, 240);
    fbFlow.setPyramidScale(0.5);
    fbFlow.setNumLevels(4);
    fbFlow.setWindowSize(32);
    fbFlow.setNumIterations(2);
    fbFlow.setPolyN(7);
}

//--------------------------------------------------------------
void ofApp::update(){
    box2d.update();
    camera.update();
    fbFlow.calcOpticalFlow(camera);
    
    for(int i = 0; i < circles.size(); i++){
        ofVec2f position = circles[i].get()->getPosition();
        float camX = position.x * float(camera.getWidth()) / ofGetWidth();
        float camY = position.y * float(camera.getHeight()) / ofGetHeight();
        circles[i].get()->addForce(fbFlow.getFlowOffset(camX, camY), 10.0);
    }
}

//--------------------------------------------------------------
void ofApp::draw(){

    ofSetColor(255);
    camera.draw(0, 0, ofGetWidth(), ofGetHeight());

    ofSetColor(255, 128);
    for(int i = 0; i < circles.size(); i++){
        ofSetColor(255, 128);
        circles[i].get()->draw();
    }
    
    for(int i = 0; i < joints.size(); i++){
        joints[i].get()->draw();
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

openFrameworks/touchableSurface at master · aa-debdeb/openFrameworks