[SOLVED] Jme3 Beginner: Something wrong with my frame tpf timer

So I am adding this Cinematic event

[java]cinematic.addCinematicEvent(trigger_time, new AbstractCinematicEvent() { // this event at time 0 will start when accelerate is called

@Override

public void onPlay() {

}

@Override

public void onUpdate(float tpf) {

final_destination = destination; // update ok

current_location = spatialToMove.getLocalTranslation(); // update ok

// read mySpeed from file --> passes the speed correctly

System.out.println("My SPEED: "+mySpeed);

if(isMoving)

{

scale += tpf/( distance / mySpeed); // dist/speed is a number like 10 --> problem not here

Vector3f newLocation = FastMath.interpolateLinear(scale, current_location, final_destination);

spatialToMove.setLocalTranslation(newLocation);

}

else if(scale == 0) // for first time run

{

isMoving = true;

}

if(scale >= 1) //then you reached the end/destination

{

isMoving = false;

}

}[/java]

The issue here is the tpf. It is not updating correctly. The spatial moves just fine however the duration (dist over speed) or the spatial movement speed is wrong. Although I am passing the params correctly. I realize that tpf is never increasing correctly. here’s the trace:

TPF: 6.5625005E-4

SPEED: 2.0

DISTANCE: 20

TPF: 6.8750005E-4

SPEED: 2.0

DISTANCE: 20

TPF: 6.8750005E-4

SPEED: 2.0

DISTANCE: 20

TPF: 6.5625005E-4


etc

what am I doing wrong?

even more weird the spatial tends to decelerate right before reaching the destination and coming to a complete stop.

tpf = time per frame. In an app with a constant frame rate it will be the same every time… though most of the time it will vary just slightly.



So I’m not sure what’s wrong with the output provided.



Usually, you use tpf to update or act as acceleration that is accumulated in velocity. The only way you could interpolate is by keeping your own total time that you add tpf to. (or keep track of total time relative to some start time using something like System.nanoTime()).

Then why is the spatial moving too fast compared to speed and distance?

Also why is it decelerating at the end without a speed reduction?



Note that if I replace change to tpf/1000; the speed is logical. Must be some simple conversion error that I am missing here.



and honestly I don’t understand how scale += tpf/(a duration for the animation) works. Can you explain?

Well, I was speaking to this: “The issue here is the tpf. It is not updating correctly.”



Which is incorrect. tpf IS getting updated. It is the time taken by the last frame. Not the total time taken by all frames… so your numbers are not strange to me.



6.5625005E-4 = 0.000656



Which to me indicates you are getting about 1500 FPS and that it’s pretty consistent.



As to your math… I’m not sure. I will say that taking tpf and dividing it by 10 again in cases where you are getting really high frame rates may make the float imprecise enough that it doesn’t accumulate well. It’s hard to say since you aren’t printing those values.



Oh, wait… you are interpolating between the current location and the end location… not start and end. So of course it’s going to decelerate at the end since you are interpolating ever smaller amounts. And at the beginning you are essentially double-accumulating your gains. For example, 10% of the distance between point A and B then 15% of the distance between A * 110% and B, and so on.

More to the point… what is the effect that you want, exactly?



Do you want the object to travel at a fixed velocity between point A and B?

Actually I am trying to implement acceleration /deceleration. So I thought by getting a normal constant velocity running I can eventually increase that velocity by a certain acceleration factor and get it working.

Constant velocity would either be speedPerSecond * tpf or accumulate total time and interpolate between start and end. The former is easier to add acceleration to.



What will your inputs be? Do you know how long it should take to get from point A to point B or do you know how fast you want to go as in maximum speed?

Could you give a quick example? not sure I quite got it.



my inputs could be current_speed, Max_speed, distance between A and B, acceleration_factor (pretty flexible inputs as u see )

For constant velocity:

[java]

…pseudo code sort of

Vector3f dir = pointB.substract( pointA );

Vector3f velocity = dir.mult( speedPerSecond * tpf );

Vector3f pos = spatial.getLocalTranslation();

spatial.setLocalTranslation( pos.add(velocity) );

[/java]



Acceleration is not bad… decelerating to land on point B is a bit harder using just acceleration. But get constant speed working first and make sure you understand it.

I realized my problem was start_pos not being fixed in the interpolation and not using the current spatial position; so that fixed my constant speed timing issue in my code and now the spatial moves at a correct constant speed → GREAT.



However, I had to specify start_pos explicitly. Although in my project I can read that start_pos vector from a file, it would be interesting to know how to set it to a fixed point so I don’t have to pass it. Placing start = spatialToMove.getLocalTranslation() outside the update() still somehow results in getting me the updated local translation of the spatial. Is there some function for that? (I apologize in advance if this question is really stupid)





As for the accelerate. I just realized that increasing the speed only animates the maximum speed allowed and does not show you the actual acceleration (which of course defies the purpose of having it). Is there something I am missing?



PS: using your code makes the spatial move at a constant speed however it does not stop at the right location but twice further ahead.

garnaout said:
I realized my problem was start_pos not being fixed in the interpolation and not using the current spatial position; so that fixed my constant speed timing issue in my code and now the spatial moves at a correct constant speed --> GREAT.

However, I had to specify start_pos explicitly. Although in my project I can read that start_pos vector from a file, it would be interesting to know how to set it to a fixed point so I don't have to pass it. Placing start = spatialToMove.getLocalTranslation() outside the update() still somehow results in getting me the updated local translation of the spatial. Is there some function for that? (I apologize in advance if this question is really stupid)


You probably need to clone the getLocalTranslation() result or it will continue to reflect the values of the spatial's translation as it moves.

garnaout said:
As for the accelerate. I just realized that increasing the speed only animates the maximum speed allowed and does not show you the actual acceleration (which of course defies the purpose of having it). Is there something I am missing?


Acceleration must be done differently. I was trying to help you crawl before trying to walk. You cannot really use interpolation for acceleration which was why I was trying to get you to a velocity approach. Once there, acceleration acts to influence velocity... or the speed you use to scale direction.

[java]
speed += tpf * accelerationRatePerSecond;
if( speed > maxSpeedPerSecond ) speed = maxSpeedPerSecond;
Vector3f velocity = dir.mult( tpf * speed );
[/java]

"Braking" to hit a specific target requires more math than I'm willing to conjure for a forum post. :) It's officially into the "hard" realm.

garnaout said:
PS: using your code makes the spatial move at a constant speed however it does not stop at the right location but twice further ahead.


Actually, if done right my example should never stop. I didn't implement any stopping behavior. The easiest way to implement stopping behavior with constant velocity is to check to see if you are at point B and then stop. Alternately, you can keep track of how much time you've run and figure out how long it takes to get there and just go for that amount of time... but duration is hard to calculate when acceleration and braking are factored in.

You know it occurs to me that if you just want to simulate acceleration and deceleration from point A to B it might be possible to fake it with some kind of cubic function. Like 3 x^2 - 2 x^3 might work. I'll follow up with that solution in a minute.

[java]

float smooth( float t ) {

if( t < 0 ) return 0;

if( t > 1 ) return 1;

return (3 * t * t) - (2 * t * t * t);

}

[/java]



…man, I hope I got that right. :wink:



Then:

[java]

init:

Vector3f dir = pointB.subtract(pointA);

float totalDistance = dir.length();

float totalTime = totalDistance / speedPerSecond;

float duration = 0;



update:

duration += tpf;

if( duration > totalTime )

don’t do anything else

float part = duration / totalTime;

float interp = smooth(part);

Vector3f newPosition = FastMath.interpolateLinear( interp, pointA, pointB);

[/java]



Something like that. Note that this is really duration based and not speed based as the speed is just used to calculate the total duration. That means that the real speed will never actually reach the supplied speed I think. But you should have nice smooth acceleration and deceleration… though no real way to control it.

Thanks! I will give it a shot.



btw how do you stop the spatial movement? If I have an if statement that compares the 2 vectors, so when the spatial reaches the destination:



what should I replace this with?



[java]spatial.setLocalTranslation( pos.add(velocity) ); [/java]

I don’t know enough about cinematics… but when you reach the destination then you need to somehow make that event end, get removed, stop updating, or whatever.



Otherwise, you could just stop moving the spatial, ie: don’t call setLocalTranslation(). The interpolation method doesn’t have this problem as it will never go past the end point.



However, it seems wasteful to me that the event keeps getting called after it has finished so I assume there is some way to make it go away.

This might sound stupid but as for deceleration/ braking can’t I just do the same concept as acceleration but using a negative sign? isn’t deceleration = negative acceleration?

Yes… apply braking is easy: negative acceleration. Deciding when to apply braking to stop exactly on a certain point… that’s trickier.

This is very strange the accelerate works fine but the decelerate does not work:



[java]@Override

public void onUpdate(float tpf) {



if(acceleration > 0)

{ // this code works - same concept }



if(acceleration < 0)

{

speed -= tpf * accelerationFactor;

System.out.println("reduced Speed: "+speed);



if( speed < minSpeedPerSecond ) speed = minSpeedPerSecond;



}



if (spatial != null) {

Vector3f dir = endPosition.subtract( startPosition );

Vector3f velocity = dir.mult( speed * tpf );

Vector3f pos = spatial.getLocalTranslation();

spatial.setLocalTranslation( pos.add(velocity) );

}



}[/java]



I only want to brake… what am I doing wrong?

Well I just want to brake and the following code only in braking does not work:



[java] @Override

public void onUpdate(float tpf) {



if(acceleration > 0)

{

speed += tpf * accelerationFactor;



if( speed > (acceleration + previous_speed)) // this is current speed clone

{

speed = acceleration + previous_speed;

//System.out.println("Reached acceleration");

}



if( speed > maxSpeed )

{

speed = maxSpeed;

}

}



if(acceleration < 0)

{

speed -= tpf * accelerationFactor;



if( speed < (acceleration + previous_speed))

{

speed = acceleration + previous_speed;

System.out.println("Reached Deceleration");



}

if( speed < 0 )

{

speed = 0;

}

}



if (spatial != null) {

value += Math.min(tpf * speed / duration, 1.0f);

System.out.println("VALUUE: "+value);

Vector3f pos = FastMath.interpolateLinear(value, startPosition, endPosition);

System.out.println("START POS "+ startPosition);

System.out.println("END POS "+ endPosition);

spatial.setLocalTranslation(pos);

System.out.println("POSITION TO GO TO "+ pos);

}



}[/java]



even if I replace interpolate (that does work in acceleration fine) with your code - same issue. It accelerates and does not brake (stops immediately before reaching the deceleration location

You can’t really combine velocity style acceleration and linear interpolation. You make your job 100 times harder. Use one or the other but not both. I think it just confuses things. Still nothing jumps out at me as obviously wrong in the above, I just think it’s more complicated than it needs to be.



Also, I can’t see how you set acceleration to negative… there really isn’t enough information provided to debug your issue. If it were my own code, I’d print the speed and acceleration and make sure they are changing as expected. For example, from the code I cannot tell that acceleration ever goes negative before endPosition is reached.