Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created December 27, 2011 22:05
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roxlu/1525303 to your computer and use it in GitHub Desktop.
Save roxlu/1525303 to your computer and use it in GitHub Desktop.
Parallel Transport Frames - TEST
//--------------------------------------------------------------
void testApp::setup(){
ofSetFrameRate(60);
ofSetVerticalSync(true);
ofBackground(33);
donnie.create(125);
donnie.si.drawUsingQuads();
//renderer.addSceneItem(donnie.si);
renderer.translate(0,0,10);
// just creating some particles and springs.
Particle* a = ps.createParticle(Vec3(-5,9,0));
Particle* b = ps.createParticle(Vec3(-5,8.8,0));
Particle* c = ps.createParticle(Vec3(-5,8.6,0));
Particle* d = ps.createParticle(Vec3(-5,8.4,0));
a->disable();
ps.createSpring(a,b);
ps.createSpring(b,c);
ps.createSpring(c,d);
Particle* prev_particle = d;
int n = 15;
for(int i = 0; i < n; ++i) {
Particle* p = ps.createParticle(Vec3(-5+i*0.4, 7.5,0));
ps.createSpring(prev_particle, p);
p->setMass(0.5+(1.0-(float)i/n) * 4.0);
prev_particle = p;
}
wind = false;
invert = false;
paused = false;
}
//--------------------------------------------------------------
void testApp::update(){
static int counter = 0;
ofSetWindowTitle(ofToString(ofGetFrameRate()));
float t = ofGetElapsedTimeMillis() * noise_z;
donnie.noise(noise_x, noise_y, t, radius);
// apply some forces to the ParticleSystem (variable ps) so the springs move along.
if(!paused) {
++counter;
float x = 0.0f;
if(wind) {
x = sin(counter * 0.04) * 0.03;
}
float inv = (invert) ? -1 : 1;
ps.addForce(Vec3(x,-0.01 * inv,0));
ps.update();
}
}
//--------------------------------------------------------------
void testApp::draw(){
renderer.debugDraw();
ps.debugDraw();
// calculate orientation frames.
Vec3 V = ps.springs[0]->a->position - ps.springs[0]->b->position ; // these are the first points
Vec3 T(0,1,0);
Vec3 D(0,0,1);
Vec3 U(0,1,0);
Vec3 U_prev = U;
Vec3 D_prev = D;
Vec3 V_prev = V;
vector<Spring*>& springs = ps.springs;
int num = springs.size();
for(int i = 0; i < num-1; ++i) {
Spring* sa = springs[i];
Spring* sb = springs[i+1];
Particle* a = sa->a;
Particle* b = sa->b;
Particle* c = sb->b;
Vec3 t0 = (b->position - a->position).getNormalized();
Vec3 t1 = (c->position - b->position).getNormalized();
Vec3 B = cross(t0, t1);
if(B.length() <= 0.01) {
V = V_prev;
D = D_prev;
}
else {
B.normalize();
float theta = acos(dot(t0, t1));
V.rotate(theta, B);
D.rotate(theta, B);
U.rotate(theta, B);
}
float angle = acos(dot(t0, t1));
glBegin(GL_LINES);
// rotated up
glColor3f(0,1,0);
glVertex3fv(a->position.getPtr());
glVertex3fv((a->position + V).getPtr());
glColor3f(1,1,0);
glVertex3fv(a->position.getPtr());
glVertex3fv((a->position + D).getPtr());
glColor3f(0,1,1);
glVertex3fv(a->position.getPtr());
glVertex3fv((a->position + U).getPtr());
// corrected right
glColor3f(1,0,0);
glVertex3fv(a->position.getPtr());
glVertex3fv((a->position + B).getPtr());
glEnd();
// create circle around "U" axis.
int num_segments = 10;
Vec3 to_rotate = D;
float angle_to_rotate = TWO_PI/(float)num_segments;
V.normalize();
D.normalize();
glColor3f(1,1,1);
glBegin(GL_LINE_LOOP);
for(int i = 0; i < num_segments; ++i) {
to_rotate.rotate(angle_to_rotate, V);
glVertex3fv((a->position + to_rotate).getPtr());
}
glEnd();
V_prev = V;
D_prev = D;
}
}
@roxlu
Copy link
Author

roxlu commented Mar 13, 2012

Hi Trent and Nardove. The Vec3 is a typical vector3 class; you can use any, but if you're using openFrameworks that will be ofVec3f. The spring implements hooks law (http://en.wikipedia.org/wiki/Hooke's_law) It has two member "a" and "b" which are the particles. When a spring is create the distance between the particle (a and b) is used as the rest length.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment