Skip to content

MeshBender.cs floating point precision problem with Repeat mode #45

@brightest1102

Description

@brightest1102

Hi,
I've encounter some problem these days when I adjust the scale X in repeat mode.

When using curve spcce, If I adjust the (scale X) that
(size of mesh) x (scale X ) x (repetitionCount) ≒ spline.Length
Some meshes would fail with following error message.
Error message like

"Mesh.uv is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array."
"Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: X, VertexCount: Y"

It seems that the number of vertices does not match to (source.Mesh.vertices.Count() x repetitionCount)

After some test, I found that the problem is caused by floating point precision problem
The value "distOnSpline" of "distance" will be slight greater than slpine.Length (about 10^06).
And it will cause different problem in non-curve space and curve space setting.

In Non-curve space:

} else {
	float distOnSpline = intervalStart + distance;
	//if (true) { //spline.isLoop) {
		while (distOnSpline > spline.Length) {
			distOnSpline -= spline.Length;
		}
	//} else if (distOnSpline > spline.Length) {
	//    continue;
	//}
	sample = spline.GetSampleAtDistance(distOnSpline);
}

This will make the end of the mesh incorrectly links to the begin of the mesh.

In Curve space:

if (!useSpline) {
	if (distance > curve.Length) 
		continue;
	sample = curve.GetSampleAtDistance(distance);
}

And it will make these vertices skips when adding them into 'bentVertices' after iterations.

bentVertices.Add(sample.GetBent(vert));

I think that's how the vertices number do not meet uv and triangle numbers.

Here's my workaround now, but I think there's some better way.

if (!useSpline)
{
	if (distance > curve.Length)
	{ 
		distance = curve.Length;
	}
	sample = curve.GetSampleAtDistance(distance);
} else {
	float distOnSpline = intervalStart + distance;
	if (distOnSpline > spline.Length + 0.0001f)
	{
		while (distOnSpline > spline.Length)
		{
			distOnSpline -= spline.Length;
		}
	}
	else if (distOnSpline > spline.Length)
		distOnSpline = spline.Length;
	sample = spline.GetSampleAtDistance(distOnSpline);        
}
sampleCache[distance] = sample;

I just brutally add some offset (0.0001f) to avoid floating point precision.
It works for me but there should be some better solutions.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions