Created
March 13, 2014 13:36
-
-
Save OliverUv/9528606 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ofApp.h" | |
//-------------------------------------------------------------- | |
// STARS! | |
// | |
// Object hand: | |
// position -> position of the star | |
// z position -> opacity of lines | |
// finger spread -> line density | |
// | |
// Effect hand: | |
// x position -> line flickering | |
// y position -> line color | |
// z position -> plane rotation speed | |
// finger spread -> color flickering | |
void ofApp::setup(){ | |
ofSetFrameRate(60); | |
ofEnableAlphaBlending(); | |
ofSetVerticalSync(true); | |
ofSetLogLevel(OF_LOG_VERBOSE); | |
leap.open(); | |
ofBackground(0,0,0); | |
summed_plane_rotation = 0; | |
star_spread = 0.2; | |
effect_spread = 0.2; | |
shader.load("shadersGL3/shader"); | |
// We enlarge the plane so it will always cover the entire screen. | |
plane_width = ofGetWidth() * 3; | |
plane_height = ofGetHeight() * 3; | |
plane_grid_size = PLANE_DENSITY_BASE; | |
plane_columns = plane_width / plane_grid_size; | |
plane_rows = plane_height / plane_grid_size; | |
plane.set(plane_width, plane_height, plane_columns, plane_rows, OF_PRIMITIVE_TRIANGLES); | |
} | |
//Assumes density is [0,1] | |
void ofApp::set_plane_density(float density) { | |
plane_grid_size = PLANE_DENSITY_BASE * ofMap(density, 0, 1, 0.25, 1); | |
plane_columns = plane_width / plane_grid_size; | |
plane_rows = plane_height / plane_grid_size; | |
plane.set(plane_width, plane_height, plane_columns, plane_rows, OF_PRIMITIVE_TRIANGLES); | |
} | |
float get_simple_hand_spread(ofxLeapMotionSimpleHand hand) { | |
// Assumes we have mapped leap to our world space... | |
// The widest spread I have managed is ~650, the narrowest ~50. | |
// TODO this should depend on millimetres, not world positions, | |
// and the in-min/in-max should be adjustable per user. | |
const float NARROWEST_POSSIBLE = 40; | |
const float WIDEST_POSSIBLE = 650; | |
if (hand.fingers.size() < 2) | |
return 0.2; | |
float widest_spread = NARROWEST_POSSIBLE; | |
for (int i = 0; i < hand.fingers.size(); ++i) | |
{ | |
ofPoint iPos = hand.fingers[i].pos; | |
for (int j = 0; j < hand.fingers.size(); ++j) | |
{ | |
if (i == j) | |
continue; | |
float spread = iPos.distance(hand.fingers[j].pos); | |
if (spread > widest_spread) | |
widest_spread = spread; | |
} | |
} | |
return ofMap(widest_spread, NARROWEST_POSSIBLE, WIDEST_POSSIBLE, 0, 1, true); | |
} | |
//-------------------------------------------------------------- | |
void ofApp::update(){ | |
simple_hands = leap.getSimpleHands(); | |
if( leap.isFrameNew() && simple_hands.size() ) { | |
//leap returns data in mm - lets set a mapping to our world space. | |
leap.setMappingX(-230, 230, -ofGetWidth()/2, ofGetWidth()/2); | |
leap.setMappingY(90, 490, -ofGetHeight()/2, ofGetHeight()/2); | |
leap.setMappingZ(-150, 150, -200, 200); | |
star_point = simple_hands[0].handPos; | |
star_point.y *= -1; | |
star_spread = get_simple_hand_spread(simple_hands[0]); | |
if (simple_hands.size() > 1) { | |
effect_point = simple_hands[1].handPos; | |
effect_point.y *= -1; | |
effect_spread = get_simple_hand_spread(simple_hands[1]); | |
} | |
} | |
leap.markFrameAsOld(); | |
} | |
//-------------------------------------------------------------- | |
void ofApp::draw(){ | |
/* float object_x_norm = ofNormalize(star_point.x, -ofGetWidth()/2, ofGetWidth()/2); */ | |
/* float object_y_norm = ofNormalize(star_point.y, -ofGetHeight()/2, ofGetHeight()/2); */ | |
float object_z_norm = ofNormalize(star_point.z, -200, 200); | |
float effect_y_norm = ofNormalize(effect_point.y, -ofGetHeight()/2, ofGetHeight()/2); | |
float effect_x_norm = ofNormalize(effect_point.x, -ofGetWidth()/2, ofGetWidth()/2); | |
float effect_z_norm = ofNormalize(effect_point.z, -200, 200); | |
// TODO figure out why we can't draw strings before shader stuff, when it | |
// works perfectly well in examples/gl/shaderExample | |
/* ofSetColor(225); */ | |
/* char info_string[300]; */ | |
/* sprintf(info_string, "effect_y_norm: %f\n", effect_y_norm); */ | |
/* printf("%s", info_string); */ | |
/* std::string info = info_string; */ | |
/* ofDrawBitmapString(info, 10, 20); */ | |
set_plane_density(1 - star_spread); | |
// Set up values for rotating input in the same way that we have rotated the plane. | |
float plane_rotation = 5 * (1 - effect_z_norm); | |
summed_plane_rotation += plane_rotation; | |
if (summed_plane_rotation > 360) | |
summed_plane_rotation -= 360; | |
ofFloatColor c = ofColor::fromHsb(255 * effect_y_norm, 255, 255); | |
// Set transparency to depend on object hand z position | |
// TODO: Make it easier to move within the fading area. | |
c.a = 1 - object_z_norm; | |
float line_color[4] = {c.r, c.g, c.b, c.a}; | |
shader.begin(); | |
{ | |
shader.setUniform4fv("line_color", &line_color[0]); | |
shader.setUniform1f("color_modifier", ofMap(effect_spread, 0, 1, 0.2, 15)); | |
shader.setUniform1f("time", ofGetElapsedTimef()); | |
shader.setUniform1f("flicker_magnitude", effect_x_norm * 100); | |
// center screen. | |
float cx = ofGetWidth() / 2.0; | |
float cy = ofGetHeight() / 2.0; | |
ofTranslate(cx, cy); | |
// rotate the star-plane | |
plane.rotate(plane_rotation, ofVec3f(0, 0, 1)); | |
// Rotate and set star position, note that we have to inverse the rotation! | |
// This is probably related to the TODO above, where we have to reverse the | |
// y-axis to get the leap -> shader input working properly. | |
ofPoint rotated_star_point(star_point.x, star_point.y, star_point.z); | |
rotated_star_point.rotate(-summed_plane_rotation, ofVec3f(0, 0, 1)); | |
shader.setUniform2f("star_pos", rotated_star_point.x, rotated_star_point.y); | |
shader.setUniform1f("gravity_range", 120); | |
plane.drawWireframe(); | |
} | |
shader.end(); | |
ofLog(OF_LOG_VERBOSE, "\n\nWidth: %d, Height: %d", ofGetWidth(), ofGetHeight()); | |
ofLog(OF_LOG_VERBOSE, "star_spread: %f, effect_spread: %f", star_spread, effect_spread); | |
ofLog(OF_LOG_VERBOSE, "object: x %f, y %f, z %f", star_point.x, star_point.y, star_point.z); | |
/* ofLog(OF_LOG_VERBOSE, "x_norm: %f, y_norm: %f, z_norm: %f\n", object_x_norm, object_y_norm, object_z_norm); */ | |
ofLog(OF_LOG_VERBOSE, "effect: Pos: x %f, y %f, z %f", effect_point.x, effect_point.y, effect_point.z); | |
ofLog(OF_LOG_VERBOSE, "x_norm: %f, y_norm: %f, z_norm: %f\n", effect_x_norm, effect_y_norm, effect_z_norm); | |
} | |
//-------------------------------------------------------------- | |
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::windowResized(int w, int h){ | |
} | |
//-------------------------------------------------------------- | |
void ofApp::gotMessage(ofMessage msg){ | |
} | |
//-------------------------------------------------------------- | |
void ofApp::dragEvent(ofDragInfo dragInfo){ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment