Created
February 21, 2013 19:55
-
-
Save jacres/5007633 to your computer and use it in GitHub Desktop.
This file contains 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 "testApp.h" | |
void addFace(ofMesh& mesh, ofVec3f a, ofVec3f b, ofVec3f c) { | |
mesh.addVertex(a); | |
mesh.addVertex(b); | |
mesh.addVertex(c); | |
ofVec3f p0 = (a-b).getNormalized(); | |
ofVec3f p1 = (b-c).getNormalized(); | |
ofVec3f n = p0.getCrossed(p1).getNormalized(); | |
mesh.addNormal(n); | |
mesh.addNormal(n); | |
mesh.addNormal(n); | |
ofFloatColor col = ofFloatColor(ofRandomuf(), ofRandomuf(), ofRandomuf(), 0.2f); | |
mesh.addColor(col); | |
mesh.addColor(col); | |
mesh.addColor(col); | |
} | |
//-------------------------------------------------------------- | |
void addFace(ofMesh& mesh, ofVec3f a, ofVec3f b, ofVec3f c, ofVec3f d) { | |
addFace(mesh, a, b, c); | |
addFace(mesh, a, c, d); | |
} | |
//-------------------------------------------------------------- | |
void testApp::setup() { | |
ofSetFrameRate(60); | |
glEnable( GL_DEPTH_TEST ); | |
glEnable( GL_CULL_FACE ); | |
glCullFace( GL_BACK ); | |
ofSetLogLevel(OF_LOG_VERBOSE); | |
spineMeshes.push_back( ofVboMesh() ); | |
spines.push_back( vector<SpinePoint>() ); | |
light.setup(); | |
light.setDirectional(); | |
light.setOrientation( ofVec3f( 45.0f, 45.0f, 45.0f ) ); | |
light.setDiffuseColor( ofFloatColor( 1.0f, 1.0f, 1.0f, 1.0f ) ); | |
noiseAmount = 10.0f; | |
noise1 = 0.01f; | |
curveResolution = 6.0f; | |
for ( int i=0; i<spines.size(); i++ ) { | |
polyline.clear(); | |
spines[i].clear(); | |
for ( int z=0; z<720; z += 20.0f ) { | |
float val = noiseAmount * ofSignedNoise( noise1 * (float)i/(float)spines.size() * 2.0f, z ); | |
polyline.curveTo( ofVec3f( 0.0, val, z ), curveResolution ); | |
} | |
vector<ofPoint> verts = polyline.getVertices(); | |
ofVec3f lastVert; | |
int index = 0; | |
for ( int j=0; j<verts.size(); ++j ) { | |
if ( lastVert.distanceSquared( verts[j] ) > 0.1f ) { | |
spines[i].push_back( SpinePoint() ); | |
spines[i][index].loc = verts[j]; | |
lastVert = verts[j]; | |
index++; | |
} | |
} | |
calculatePTF( spines[i] ); | |
createVboFromSpine( spineMeshes[i], spines[i], 4.0f, 1.0f ); | |
} | |
} | |
//-------------------------------------------------------------- | |
void testApp::draw() { | |
ofClear( 255, 255, 255 ); | |
ofSetColor(255, 0, 0); | |
ofDisableAlphaBlending(); | |
glDisable( GL_CULL_FACE ); | |
cam.begin(); | |
light.enable(); | |
// ofDisableLighting(); // DEBUG | |
// drawSpineAxes( spines[0] ); // DEBUG | |
vector<ofVboMesh>::iterator it; | |
for ( it=spineMeshes.begin(); it != spineMeshes.end(); ++it ) { | |
it->drawFaces(); | |
} | |
cam.end(); | |
} | |
//-------------------------------------------------------------- | |
void testApp::update() { | |
} | |
void testApp::createVboFromSpine( ofVboMesh& vboMesh, const vector<SpinePoint>& spine, float width, float thickness ) { | |
vboMesh.clear(); | |
int num_segments = 32; | |
vector<ofVec3f> verts; | |
float radius = 6.0f; | |
for ( int a=0; a<spine.size(); a++ ) { | |
ofVec3f side = spine[a].orientation.up; | |
float angle_to_rotate = TWO_PI/(float)num_segments; | |
ofVec3f axis = spine[a].orientation.forward; | |
for( int i = 0; i < num_segments; ++i ) { | |
side.rotateRad( angle_to_rotate, axis ); | |
verts.push_back( spine[a].loc + side * radius ); | |
} | |
} | |
vector<int> indices; | |
for ( int i=1; i<spine.size()-2; i++ ) { | |
int index = i*num_segments; | |
for ( int j=0; j<num_segments-1; j++ ) { | |
ofVec3f a = verts[index + j]; | |
ofVec3f b = verts[index + j + 1]; | |
ofVec3f c = verts[index + j + num_segments + 1]; | |
ofVec3f d = verts[index + j + num_segments]; | |
addFace( vboMesh, a, b, c, d ); | |
} | |
// close end to beginning | |
ofVec3f a = verts[index + num_segments-1]; | |
ofVec3f b = verts[index + 0]; | |
ofVec3f c = verts[index + num_segments]; | |
ofVec3f d = verts[index + num_segments + num_segments-1]; | |
addFace( vboMesh, a, b, c, d ); | |
} | |
} | |
void testApp::drawSpineAxes( const vector<SpinePoint>& spine ) { | |
for ( int i=0; i<spine.size()-1; i++ ) { | |
// draw axis | |
glBegin(GL_LINES); | |
// rotated up | |
glColor3f(0,1,0); | |
glVertex3fv( spine[i].loc.getPtr() ); | |
glVertex3fv( (spine[i].loc + spine[i].orientation.up*5.0f).getPtr() ); | |
glColor3f(1,0,1); | |
glVertex3fv( spine[i].loc.getPtr() ); | |
glVertex3fv( (spine[i].loc + spine[i].orientation.forward*5.0f).getPtr() ); | |
// corrected right | |
glColor3f(1,0,0); | |
glVertex3fv( spine[i].loc.getPtr() ); | |
glVertex3fv( (spine[i].loc + spine[i].orientation.side*5.0f).getPtr() ); | |
// connect points | |
glColor3f(0.6,0.6,0.6); | |
glVertex3fv( spine[i].loc.getPtr() ); | |
glVertex3fv( (spine[i].loc + spine[i+1].loc-spine[i].loc).getPtr() ); | |
glEnd(); | |
int num_segments = 10; | |
glBegin(GL_LINE_LOOP); | |
glColor3f(1.0, 0.0, 1.0); | |
glVertex3fv( ( spine[i].loc + spine[i].orientation.side * 5.0f + spine[i].orientation.up * 5.0f ).getPtr() ); | |
glColor3f(1.0,0.0,0.0); | |
glVertex3fv( ( spine[i].loc + spine[i].orientation.side * 5.0f - spine[i].orientation.up * 5.0f ).getPtr() ); | |
glColor3f(0.0, 1.0, 0.0); | |
glVertex3fv( ( spine[i].loc - spine[i].orientation.side * 5.0f - spine[i].orientation.up * 5.0f ).getPtr() ); | |
glColor3f(0.0, 0.0, 1.0); | |
glVertex3fv( ( spine[i].loc - spine[i].orientation.side * 5.0f + spine[i].orientation.up * 5.0f ).getPtr() ); | |
glEnd(); | |
} | |
} | |
void testApp::calculatePTF( vector<SpinePoint>& spine ) { | |
ofVec3f dirNormal; | |
ofVec3f prevSide, prevForward, prevUp; | |
// Initial point in spine | |
dirNormal = (spine[1].loc - spine[0].loc).getNormalized(); | |
ofVec3f temp_up = ofVec3f(0.0f, 1.0f, 0.0f); | |
ofVec3f new_forward = dirNormal; | |
ofVec3f new_side = new_forward.crossed(temp_up).getNormalized(); | |
ofVec3f new_up = new_forward.crossed(new_side).getNormalized(); | |
spine[0].orientation.up = new_up; | |
spine[0].orientation.forward = new_forward; | |
spine[0].orientation.side = new_side; | |
prevSide = new_side; | |
prevForward = new_forward; | |
prevUp = new_up; | |
spine[0].color = ofFloatColor( 1.0f, 0.0f, 0.0f, 1.0f ); | |
for ( int i=1; i<spine.size()-1; ++i ) { | |
ofVec3f T1(spine[i].loc - spine[i-1].loc); | |
ofVec3f T2(spine[i+1].loc - spine[i].loc); | |
T1.normalize(); | |
T2.normalize(); | |
ofVec3f A = T1.crossed(T2); | |
if ( A.length() <= 0.001f ) { // is angle too small? cross product result of zero means lines are parallel | |
new_up = prevUp; | |
new_forward = prevForward; | |
new_side = prevSide; | |
} else { | |
float alpha = T1.angleRad(T2); | |
new_forward.rotateRad( alpha, A ); | |
new_side.rotateRad( alpha, A ); | |
new_up.rotateRad( alpha, A ); | |
} | |
spine[i].orientation.up = new_up; | |
spine[i].orientation.forward = new_forward; | |
spine[i].orientation.side = new_side; | |
prevSide = new_side; | |
prevForward = new_forward; | |
prevUp = new_up; | |
} | |
} | |
//-------------------------------------------------------------- | |
void testApp::exit() { | |
} | |
//-------------------------------------------------------------- | |
void testApp::keyPressed (int key) { | |
ofSaveFrame(); | |
} | |
//-------------------------------------------------------------- | |
void testApp::mouseDragged(int x, int y, int button) | |
{} | |
//-------------------------------------------------------------- | |
void testApp::mousePressed(int x, int y, int button) | |
{} | |
//-------------------------------------------------------------- | |
void testApp::mouseReleased(int x, int y, int button) | |
{} | |
//-------------------------------------------------------------- | |
void testApp::windowResized(int w, int h) | |
{} |
This file contains 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
#pragma once | |
#include "ofMain.h" | |
class testApp : public ofBaseApp { | |
public: | |
struct SpinePoint { | |
struct orientation { | |
ofVec3f up; | |
ofVec3f forward; | |
ofVec3f side; | |
} orientation; | |
ofFloatColor color; | |
ofVec3f loc; | |
}; | |
void setup(); | |
void update(); | |
void draw(); | |
void exit(); | |
void calculatePTF( vector<SpinePoint>& spine ); | |
void createVboFromSpine( ofVboMesh& vboMesh, const vector<SpinePoint>& spine, float width=1.0f, float thickness=1.0f ); | |
void drawSpineAxes( const vector<SpinePoint>& spine ); | |
void keyPressed(int key); | |
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); | |
ofPolyline polyline; | |
vector< vector<SpinePoint> > spines; | |
vector<ofVboMesh> spineMeshes; | |
ofLight light; | |
float noiseAmount; | |
float noise1; | |
int curveResolution; | |
ofEasyCam cam; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment