[ Video ]
[ About ]
ofTrueTypeFontから文字の輪郭の座標を取得して、Sphereを設置しています。
それぞれのSphereは初期位置に戻ろうとする力が常に働いていますが、LeapMotionから取得した人差指の座標にはSphereに反発する力があり、反発する力の有効範囲に入ったSphereは初期位置からずれてしまいます。反発力の有効範囲外になれば元に戻ろうとする力だけになるので、初期位置に戻ります。
Leap Motion + ofxBulletなので、もう少し3Dが分かるようにしたかったのですが、あまり上手くいきませんでしたね。
[ Source ]
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 |
#pragma once #include "ofMain.h" #include "ofxBullet.h" // Leap Motion SDK #include "Leap.h" #pragma comment(lib, "Leap.lib") class ofApp : public ofBaseApp { public: ~ofApp(); 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) {}; ofCamera cam; ofLight light; ofTrueTypeFont font; ofxBulletWorldRigid world; vector<ofxBulletSphere*> spheres; vector<ofColor> spheres_color; vector<ofVec3f> spheres_location; // Leap Motion Leap::Controller leap; ofVec3f finger_position; }; |
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
#include "ofApp.h" //-------------------------------------------------------------- ofApp::~ofApp() { for (ofxBulletSphere* tmp : this->spheres) { delete tmp; } this->spheres.clear(); } //-------------------------------------------------------------- void ofApp::setup() { ofSetFrameRate(60); ofEnableDepthTest(); ofBackground(0); ofSetWindowTitle("Insta"); this->cam.setPosition(ofVec3f(0, 3.f, -30.f)); this->cam.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0)); this->world.setup(); this->world.enableGrabbing(); this->world.setCamera(&this->cam); this->world.setGravity(ofVec3f(0.0, 0.0, 0.0)); this->font.loadFont("fonts/Kazesawa-Bold.ttf", 130, true, false, true); vector<string> words; words.push_back("JUN"); words.push_back("KIYOSHI"); for (int word_index = 0; word_index < words.size(); word_index++) { ofVec2f word_size = ofVec2f(this->font.stringWidth(words[word_index]), -this->font.stringHeight(words[word_index])); vector<ofTTFCharacter> char_paths = this->font.getStringAsPoints(words[word_index]); for (int path_index = 0; path_index < char_paths.size(); path_index++) { vector<ofPolyline> outline = char_paths[path_index].getOutline(); for (int outline_index = 0; outline_index < outline.size(); outline_index++) { outline[outline_index] = outline[outline_index].getResampledBySpacing(5); vector<ofPoint> vertices = outline[outline_index].getVertices(); for (int vertices_index = 0; vertices_index < vertices.size(); vertices_index++) { ofVec3f location = vertices[vertices_index] - word_size / 2; location.y = location.y + 150 * (word_index - 1); ofxBulletSphere* sphere = new ofxBulletSphere(); ofVec3f box_location = ofVec3f(location.x, location.y, location.z); float size = 2.5; sphere->create(this->world.world, box_location, 1.0, size); sphere->setRestitution(1.0); sphere->add(); this->spheres.push_back(sphere); ofColor color; color.setHsb(ofRandom(255), 255, 255); this->spheres_color.push_back(color); this->spheres_location.push_back(box_location); } } } } } //-------------------------------------------------------------- void ofApp::update() { ofVec3f diff; for (int i = 0; i < this->spheres.size(); i++) { diff = this->spheres_location[i] - this->spheres[i]->getPosition(); diff *= 10; this->spheres[i]->applyCentralForce(diff); } Leap::Frame frame = this->leap.frame(); for (Leap::Hand hand : frame.hands()) { if(hand.isRight()){ for (Leap::Finger finger : hand.fingers()) { if (finger.type() == Leap::Finger::Type::TYPE_INDEX) { float x = ofMap(finger.tipPosition().x, -200, 200, -ofGetWidth() / 2, ofGetWidth() / 2); float y = ofMap(finger.tipPosition().y, 300, 0, -ofGetHeight() / 2, ofGetHeight() / 2); float power = finger.tipPosition().z * -1; this->finger_position = ofVec3f(x, y, 0); ofVec3f diff; for (int i = 0; i < this->spheres.size(); i++) { diff = this->finger_position - this->spheres[i]->getPosition(); if (diff.length() < power) { diff *= 5; this->spheres[i]->applyCentralForce(-diff); } } } } } } this->world.update(); } //-------------------------------------------------------------- void ofApp::draw() { ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2); ofDrawBox(this->finger_position, 5); float len = 50; for (int i = 0; i < this->spheres.size(); i++) { ofSetColor(this->spheres_color[i]); this->spheres[i]->draw(); ofDrawLine(this->spheres[i]->getPosition(), this->spheres_location[i]); } } //======================================================================== int main() { ofSetupOpenGL(720, 720, OF_WINDOW); ofRunApp(new ofApp()); } |