Game Development Community

Path & Marker calculate speed

by Nathan Bowhay - ESAL · in Torque 3D Professional · 11/30/2011 (12:18 pm) · 3 replies

I am trying to figure out how to best calculate the speed I should have on a markers in order for the object to have traveled the path in a specified time.

If it was just position being interpolated linearly it is pretty easy, because you simply us the speed = distance/time so:
for(%i = 0; %i < %path.getCount(); %i++)
{
   %marker = %path.getObject(%i);
   
   if(isObject(%lastMarker))
   {
      %time = %lastMarker.secToNext; //I set this to say take this many seconds to get to the next marker
      %distance = VectorDist(%lastMarker.getPosition(), %marker.getPosition());
      %lastmarker.speed = %distance/%time; //This is used when markers are pushed in default path follow code
   }
   %lastMarker = %marker;
}

However there are a couple issues:
1. This doesn't work for splines because the distance is usually greater.
2. Speed seems to be interpolated as well, so I think it will end up taking longer in most cases.
3. Rotation is interpolated and this doesn't look at rotation at all which in some small distances or when the distance is 0, but you are simply rotating at the same position the speed is incorrect.

So you can see I am not sure how to best do this. Also I am trying to find the time it will take to travel the path or between markers (reverse of first question). Obviously once I figure out how to get the speed based on time, getting time based on speed should be easy and vise versa.



#1
12/20/2011 (1:11 pm)
I noticed this a while back, but figured I would mention it as well. simPath uses markers which have a msToNext. Was this ever used to generate a camera spline and it's speed values? Because from what I understand everything that uses simPath and markers (path camera, ai...) all just push the values from the simpath markers to their own cameraspline which is then used to handle the interpolation.
#2
01/03/2012 (2:25 pm)
Ok so I made two function that loop through the entire timemap created for a cameraspline and get the time and distance between each element in the timemap. It simply adds up mTime and mDistance:

Here is an example of the time on and it is pretty easy to change it for distance instead:
F32 CameraSpline::getTotalTime(S32 p1, S32 p2)
{
	buildTimeMap();

	F32 time = 0;
	S32 index = 0;
	for(Vector<TimeMap>::iterator itr = mTimeMap.begin(); itr != mTimeMap.end(); itr++)
	{
		if((p1 <=  index || p1 < 0) && (p2 >= index || p2 < 0))
		{
			time += itr->mTime;
		}
		index++;
	}

	return time;
}

I then printed out the distance and time for my entire path as well as the size of the spline and this is what I got:
Total Time: 243
Total Distance: 13243.1
Total Distance: 82

This is for a linear path that after calculated using positions is only 269.16 meters (torque is in meters) long. There is one rotation in it in the beginning, but still don't get out it came up with a distance of 13k. Anyone have a clue exactly what the timemap is in correlation to the actual path? All I am trying to do is figure out the speed for each node so that it will take a given time to get to that node.

I looked at the code that calculates the timemap, but it didn't completely make sense. I mean I sort of understand it is going though the path and splitting it into 0.90 segments, but how do those segments add up to something bigger than the path? Is there something I am missing?

On another note currently I have an algorithm that sort of works, but it's off on my test path by about 15 seconds.

Here is what I do each previous node's msToNext is set to how many milliseconds I want it to take (just using that variable that seems to do nothing because it fits). Then I look through the path backwards getting the distance between the two nodes (last node and one before it and so on). If we are on the last node, the last node (a) and the one before it (b) should have the same speed and that is calculated using speed = distance/time, so if the distance between a and b is 22m and I want it to take 10000ms it is like this:
10000ms --> 10s (speed is in m/s or meters per second I think for paths)
22m/10s = 2.2m/s (for the speed for both nodes)

Then for all the rest of the nodes since I am assuming the speed is linearly interpolated, so I though I would just make sure the average speed is the speed I want so it will take the same time. So say node c to node (b) has a distance of 82m and I want it to take 10 seconds as well, then to figure out the speed for c it would be:
82m/10s = 8.2m/s
C.speed = (2 * 8.2) - b.speed
C.speed = (2 * 8.2) - 2.2
C.speed = 14.2;
That way the average speed from c to b will be the speed to make sure it takes 10 seconds. I just keep doing that backwards through the path until I have the speed for all the nodes. I then tried moving the object on it and it is 15 seconds off by the end, after the first second it is about 2.2 seconds off.

Is there something wrong in my calculation?

Any help with this at all would be awesome.

If you have any questions or need me to clarify something let me know.
#3
01/03/2012 (3:46 pm)
Maybe I don't exactly understand what you are looking at, but if you want to gauge distance over a curve you need the curve function itself. So you may need to dig deeper into the code to find the spline function, feed it the points and curve data (spline controls), and calculate distance along the spline. Also, if it is doing accel and decel along the spline then you need to know the accel and decel rates as well. This does not sound like an easy problem.

Edit: well you have a square in there so that is a start to make it a curve.

Maybe this will help: Curve Fitting