Skip to content

Instantly share code, notes, and snippets.

@OliverUv
Created March 16, 2014 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OliverUv/4b7cc7e31a4630d88b6f to your computer and use it in GitHub Desktop.
Save OliverUv/4b7cc7e31a4630d88b6f to your computer and use it in GitHub Desktop.
#include "ofApp.h"
#include "ofFbo.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;
render_buffer.allocate(1920, 1200, GL_RGBA);
render_buffer.begin();
ofClear(0);
render_buffer.end();
bokeh_effect.allocate(1920, 1200);
bokeh_effect.setRadius(1.5);
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};
render_buffer.begin();
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();
render_buffer.end();
/* bokeh_effect << render_buffer; */
/* bokeh_effect.draw(0, 0, ofGetWidth(), ofGetHeight()); */
render_buffer.draw(0, 0);
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