Possible SplinePath Speed Bug

It looks like speed changes between control point path segment. See gif below.
I set the speed of each node to be the same. But it changes between control points.
On short segment node move slower.

Spline Bug

1 Like

What you mean?
If I have a linear line to travel. With a constant speed ( same for each characters), Shouldn’t I get a constant gap between the characters.

I’m not sure if the interpolate position GetPoint return the correct position. The following calculation is done similar to a single node Move method.

I do think this is intended behaviour for a spline path.

This is the calculation.

float newDistance = lstPed_[i]->relativePosInQueue_ + dt * lstPed_[i]->speed_;
float traveled_ = newDistance / queuePath_->GetLength();
lstPed_[i]->GetNode()->SetWorldPosition(queuePath_->GetPoint(traveled_));

If you divide the speed by the length of the current segment it should be constant.

I don’t believe this is correct.

If it is a linear. It is easy to get the correct position.

The behaviour is wrong. Theoretically.

For your use case, yes.
The interpolation logic is consistent along different interpolation modes.

The current logic return incorrect position as you can see in the gif.

What if you were to move the knots during runtime? Which behaviour would you expect?

I recalculate the length using the built in SplinePath function when I move the knots.

Anyway maybe leave it here.
I’m only trying to report a possible bug/behaviour.

I will fix the interpolation.

The math should be easy.

Best regards

“There are a few ways to move along at a constant speed along a path whose “segments” are not a constant length - and it’s not trivial to make them that way.” - ClickerMonkey

This supports my not-a-bug theory. :wink:

Thanks I have done this a number of years ago in Irrlicht.

Best regards

1 Like

Are you talking about linear interpolation between control points or more complex cases too?

Yes! Navigate through multi control points.

For linear polyline.
It is easier to fix the behaviour. E.g.
I speed up my simulation clock to reduce the file size of the gif.

Linear Spline fixed

For catmul-rom I can use this multi linear line segment method or the calculus method via simson’s rule.

2 Likes

A simple piecewise linear over existing interpolation.

Linear Spline fixed

I first linearized the spline.

void LinearisedPath()
{

	if (queuePath_->GetControlPoints().Size() > 2)
	{
		Spline spline = queuePath_->GetSpline();
		int size = queuePath_->GetControlPoints().Size();
		double rate = 0.001f;
		splinePath_.Clear();
		for (float f = 0.f; f <= 1.0f; f += rate)
		{
			Vector3 b = spline.GetPoint(f).GetVector3();
			splinePath_.AddKnot(b);
		}
	}
	else if (queuePath_->GetControlPoints().Size() == 2)
	{
		splinePath_ = queuePath_->GetSpline();
	}

}

Then loop through like below.

    Vector<Variant> knots_ = splinePath_.GetKnots();
int size = knots_.Size();
int segment = 1;
float sumLength = 0.0f;

for (; segment < size; segment++)
{

	float segmentLength = (knots_[segment].GetVector3() - knots_[segment - 1].GetVector3()).Length();
	sumLength += segmentLength;
	if (sumLength >= relativeDistance)
		break;
}

if (segment == size)
{
	segment--;
}

Vector3 dir = knots_[segment].GetVector3() - knots_[segment - 1].GetVector3();
dir.y_ = 0;
dir.Normalize();
Vector3 pos = knots_[segment].GetVector3() - dir * (sumLength - character->relativePosInQueue_);
Quaternion Q;
Q.FromLookRotation(dir);
Q.Normalize();
character->GetNode()->SetRotation(Quaternion());
character->GetNode()->SetWorldRotation(Q);
character->GetNode()->SetWorldPosition(pos);

I recommend we have dynamic number of interpolate segment increases with number of control points. This will remove the debug line drawn bug.

2 Likes