How to smooth out spline tangents after offset rotation?

Hello. I am trying to make a road tool and have hit a snag with offset rotation.

A brief overview of my system is, the road actor has a spline, and then each child actor of the road (sidewalk, asphalt etc) offsets its own spline from the original spline using many points for accuracy so that a road may be created.

The problem: when I roll the spline of the raod, the tangents become out of sync with the general direction of the spline causing the staircasing in the picture.

Any idea what operations I can perform on the tangents to smoothen them out? Code below.

            // Create offset approximate spline
            for (int i = 0; i < NumSegments; i++)
            {
                float StartDistance = SectionSpline->GetDistanceAlongSplineAtSplinePoint(i);
                float EndDistance = ((i + 1) > (NumSegments - 1)) ? StartDistance : SectionSpline->GetDistanceAlongSplineAtSplinePoint(i + 1);
                float CurrentDistance = StartDistance;

                // Calculate number of subdivisions of spline.
                int NumPoints = CalculateNumberInNumber(EndDistance - StartDistance, 500.f); // Number of 500's in segment length

                float PointLength = (EndDistance - StartDistance) / NumPoints;

                for (int j = 0; j < NumPoints; j++)
                {
                    FTransform Point = FTransform::Identity;

                    if (j == 0)
                    {
                        // Add the start point of each segment.
                        Point = SectionSpline->GetTransformAtSplinePoint(CurrentSegment, ESplineCoordinateSpace::World, true);
                        CurrentSegment++;
                    }
                    else
                    {
                        // Add Subdivision points.
                        CurrentDistance += PointLength;
                        Point = SectionSpline->GetTransformAtDistanceAlongSpline(CurrentDistance, ESplineCoordinateSpace::World, true); // Use scale, or else.
                    }

                    FVector LocalOffset = Point.TransformVector(ElementData.Offset);
                    Point.AddToTranslation(FVector(LocalOffset.X, LocalOffset.Y, LocalOffset.Z));

                    Points.Add(Point);
                }
            }
            // Use positions on approximate spline and tangents from [road]Section spline to create final spline.
            for (int i = 0; i <= NumMeshes; i++)
            {
                int Index = (i < GeneratedMeshes.Num()) ? i : i - 1;
                float SegmentAlpha = GeneratedMeshes[Index].MeshLength / SplineLength;

                FTransform CurrentPoint = SplineComponent->GetTransformAtDistanceAlongSpline(CurrentDistance, ESplineCoordinateSpace::World, true);

                FVector Tangent = SectionSpline->GetTangentAtDistanceAlongSpline(CurrentDistance * LengthFactor, ESplineCoordinateSpace::Local) * SegmentAlpha;

                Points.Add(CurrentPoint);
                Arrives.Add(Tangent); // arrive tangents
                Leaves.Add(Tangent);
                
                CurrentDistance += GeneratedMeshes[Index].MeshLength;
            }

This too is a bad idea.
You want instances, not individual meshes that will ramp up your scene/memory/cpu/gpu consumption for no purpose what so ever.

As far as smoothing, bycubic should give you exactly what you need. But the Z height is your issue.
I think you need to preserve the same Z value on each transform to match the z value of the start/end segment of the other.
Possibly just avarage the start/end.
Because you add more segments between known segments you will always have issues. You are fabricating data where you have none.
Avarage seems like a decent compromise. But the road can be curved, all your spline points would end up flat.
Leaves you with having to fully calculate Z to match the point of the spline at that specific point in space of the point you add.
Maybe take the normal value at that point and use that somehow.

Still, usage wise this whole thing is rather pointless…

Thank you for your response, I hadn’t looked into the performance side of splinemeshes yet, so that is helpful to know.

You’re probably right, this approach of mine seems rather unsustainable. I will attempt to find a better way.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.