[ Video ]
[ About ]
昨日のやつをLeap Motionで操作してみました。
Leap::HandクラスのgrabStrengthメソッドを使うと、手の握り具合(0.0-1.0)が取得できます。今回は手を握っている(0.5以上)状態の場合に、手の加速度を使って、中央の大きなBoxを動かすように指定しました。
この関数が返す値は、極端に0.0または1.0に寄るので、微妙な握り加減は調整出来ません。もし、そのような加減が知りたければ、似たような関数にpinchStrengthメソッドというピンチ(親指と人差指の関係 0.0-1.0)を取得する関数や、pinchDistanceという距離を返してくれるメソッドがあるので、そちらを使うと良いかと思います。
前にもofxBulletを使ってLeap Motion + 3D 物理演算を作ったことありますが、やっぱり楽しいですね。コーディングと結果で遊べる、2回美味しいやつです。
[ 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 |
#pragma once #include "ofMain.h" #include "ofxBullet.h" // Leap Motion SDK #include "Leap.h" 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; ofxBulletWorldRigid world; ofxBulletCustomShape* boundsShape; vector<ofxBulletBox*> boxes; vector<ofColor> boxes_color; // Leap Motion Leap::Controller leap; }; |
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
#include "ofApp.h" //-------------------------------------------------------------- ofApp::~ofApp() { delete this->boundsShape; for (ofxBulletBox* tmp : this->boxes) { delete tmp; } this->boxes.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, 64.0, 0)); ofVec3f start_location; ofPoint dimens; float bounds_width = 300; float h_width = bounds_width * 0.5; float depth = 10.; float h_depth = depth * 0.5; this->boundsShape = new ofxBulletCustomShape(); this->boundsShape->create(world.world, ofVec3f(0, 0, 0), 10.); for (int i = 0; i < 6; i++) { if (i == 0) { // ground // start_location.set(0., h_width + h_depth, 0.); dimens.set(bounds_width, depth, bounds_width); } else if (i == 1) { // back wall // start_location.set(0, 0, h_width + h_depth); dimens.set(bounds_width, bounds_width, depth); } else if (i == 2) { // right wall // start_location.set(h_width + h_depth, 0, 0.); dimens.set(depth, bounds_width, bounds_width); } else if (i == 3) { // left wall // start_location.set(-h_width - h_depth, 0, 0.); dimens.set(depth, bounds_width, bounds_width); } else if (i == 4) { // ceiling // start_location.set(0, -h_width - h_depth, 0.); dimens.set(bounds_width, depth, bounds_width); } else if (i == 5) { // front wall // start_location.set(0, 0, -h_width - h_depth); dimens.set(bounds_width, bounds_width, depth); } btBoxShape* boxShape = ofBtGetBoxCollisionShape(dimens.x, dimens.y, dimens.z); this->boundsShape->addShape(boxShape, start_location); } this->boundsShape->add(); for (int i = 0; i < 50; i++) { ofxBulletBox* box = new ofxBulletBox(); float size = 15; box->create(this->world.world, ofVec3f(ofRandom(-100, 100), ofRandom(-100, 100), ofRandom(-100, 100)), 1.0, size, size, size); box->setRestitution(1.0); box->add(); this->boxes.push_back(box); ofColor color; color.setHsb(ofRandom(255), 255, 255); this->boxes_color.push_back(color); } this->light.setPosition(ofVec3f(0, 0, 512)); } //-------------------------------------------------------------- void ofApp::update() { bool flg = true; ofSetColor(255); Leap::Frame frame = this->leap.frame(); for (Leap::Hand hand : frame.hands()) { if (hand.grabStrength() > 0.5) { ofSetColor(255, 255, 0); ofVec3f diff = ofVec3f(hand.palmVelocity().x, -hand.palmVelocity().y, hand.palmVelocity().z); diff *= 50.f; boundsShape->applyCentralForce(diff); } } ofVec3f diff = ofVec3f(0, 0, 0) - boundsShape->getPosition(); diff *= 300.f; boundsShape->applyCentralForce(diff); this->world.update(); } //-------------------------------------------------------------- void ofApp::draw() { ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2); //ofEnableLighting(); //this->light.enable(); ofNoFill(); boundsShape->transformGL(); ofDrawBox(ofVec3f(0, 0, 0), 300); boundsShape->restoreTransformGL(); ofFill(); for (int i = 0; i < this->boxes.size(); i++) { ofSetColor(this->boxes_color[i]); this->boxes[i]->draw(); } } //======================================================================== int main() { ofSetupOpenGL(720, 720, OF_WINDOW); ofRunApp(new ofApp()); } |