[SOLVED] Allocation errors occuring from animation of mesh colors

I was trying to come to an efficient method for animating movement along a line segment. In update, there is always a “lead” vertex, and using another for loop, a length of vertices behind that lead are colored with a decreasing alpha value, making it appear to have a trail behind it.

int leadVertex = fmodf(ofGetElapsedTimef()*speed,150);

for(int i=0; i<150; i++){
    connections.setColor(i,ofColor(ofColor(255),0));
}

//as we count to the 50 trailing vertices, the number for the alpha value decreases    
for(int i=0, cc=50; i<50; i++,cc--){ 
    connections.setColor(leadVertex-i,ofColor(ofColor(255),ofMap(cc,0,50,0,255)));
}

And here is the update method in this larger project:

void oscThread::update()
{
    float time = ofGetElapsedTimef()/speed;
    int leadVertex = fmodf(ofGetElapsedTimef()*cSpeed,res);
    
    for (int x=0;x<res;x++){
        ofVec3f oscTemp = this->getMesh().getVertex(x);
        float p = x;
        float oscillation = amp * sin(2 * pi * f * time + p)/20;
        oscTemp.rotate(x/f,ofVec3f(1,0,0));
        this->getMesh().setVertex(x,oscTemp);
        this->getMesh().setColor(x,ofColor(ofColor(255),0));
    }
   
    for(int i=0, tAlpha=100; i<100; i++,tAlpha--){
        this->getMesh().setColor(leadVertex-i,ofColor(ofColor(255),ofMap(tAlpha,0,50,0,255)));
    }
 }

What I believe is going on is while trying to select the previous 100 vertices behind the leadVertex, it points to vertices that are not there (until of course leadVertex-i actually exists). Does anyone have some tips on how to assure those actually exist? Or make leadVertex-i never go below 0? Thank you.

ofApp.h
http://pastebin.com/D3D1LLbb

ofApp.cpp
http://pastebin.com/BD0zMyvL

It looks like you’re right about that, at least in terms of the second for loop. I’m not sure what ‘res’ is returning, so it’s not clear whether or not that’s a problem in the first for loop. Fixing the second one could be something as simple as an if statement with a break in it:

for(int i=0, tAlpha=100; i<100; i++,tAlpha--){
    this->getMesh().setColor(leadVertex-i,ofColor(ofColor(255),ofMap(tAlpha,0,50,0,255)));
    if(i == this->getMesh().getNumVertices() - 1)
        break;
}

And something similar for the first for loop, depending on whether or not ‘res’ ever goes over your number of vertices.

I just gave this a try right before you replied, which seems to work decently well. Remembering to check if something exists, then breaking if not is a good thing for me to remember though.

if(leadVertex < tLength){
    ttLength = leadVertex;//jerky because of leadVertex dupes
}else{
    ttLength = tLength;
}


ofLog(OF_LOG_NOTICE, "tLength=" + ofToString(ttLength) + " leadVertex=" + ofToString(leadVertex));

for(int i=0, tAlpha=ttLength; i<ttLength; i++,tC--){
    this->getMesh().setColor(leadVertex-i,ofColor(ofColor(255),ofMap(tC,0,50,0,255)));
}

Which seems to get me really close (despite my bad naming). Now there is just some jerkiness in those first (tLength) number of vertices, because since leadVertex is updated at framerate I’m get duplicates. Looks like this is well enough on it’s way now though. Res was referring to the number of vertices in the line segment (I should have cleared that up earlier)

The problem now is that I’m realizing the way I am counting for the leadVertex is choppy. I would assume this has to do with it’s relationship to the framerate. Here is a bit of what my log puts out:

[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=20 leadVertex=20
[notice ] tLength=21 leadVertex=21
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23
[notice ] tLength=23 leadVertex=23

I’m not sure why you’re doing a modulus of res, so I can’t give you an exact formula, but traditionally to get a framerate independent animation, you multiply speed by the change in time since the last frame. For example:

void oscThread::setup(){
    time0 = ofGetElapsedTimef();
}

void oscThread::update(){
    float dt = ofClamp(ofGetElapsedTimef() - time0, 0, 0.1);
    time0 = ofGetElapsedTimef();

    float lead = time0 * cSpeed * dt;
    if (lead > leadVertex)
        leadVertex = lead;
}

Edit: forgot leadVertex is an int, fixed rounding issues.

1 Like

Good thing to know, things are working smoothly, thanks again @tabularasa1992!

1 Like

I might have spoken too soon (I understood what you proposed, but didn’t get the chance to implement until now). I’m doing a modulus of res so that it will count through the number of vertices in the line segment (150 at the moment), and then return to 0 and loop that way. I can’t seem to wrap my mind around how I would get the small number from lead to correspond to the leadVertex. Any tips? Thanks again, this has been a huge help.

What I think I need is for time0 * dt to function AS my framerate-independent time.

Hey, I’m sorry I messed up the formula a little bit. If you want a smooth animation it should really be this:

ofApp.h

float time0;
int leadVertex;
float lead;

ofApp.cpp

void ofApp::setup(){
    time0 = ofGetElapsedTimef();
    leadVertex = 0;
    lead = 0;
}

void ofApp::update(){
   float time = ofGetElapsedTimef();
   float dt = ofClamp(time - time0, 0, 0.1);
   time0 = time;

   lead += cSpeed * dt;
   if (lead > leadVertex)
       leadVertex = lead;
   if (leadVertex > 150){
       leadVertex = 0;
       lead = 0;
   }
}

That’s designed to make it look smooth, so at a low framerate and high speed, it will not hit every integer on the way up to 150. It will, however, increment by a consistent amount. I.e. it may go from 135 to 137 to 139, etc… Does it matter if it doesn’t hit every vertex?

If the speed is greater than the framerate, there is no problem if it doesn’t hit every one (that is actually perfect, as long as it’s consistent). Tested and working! Thanks again for the help @tabularasa1992.