public void Execute(int index) { var numDecals = NumDecalsPerRoad[index]; if (numDecals == 0) { return; } var random = RandomUtility.ParallelForRandom(RandomSeed, index); var roadEntity = RoadEntities[index]; var sampleBuffer = RoadSampleBuffers[roadEntity].Reinterpret <RigidTransform>().AsNativeArray(); var startIndex = DecalStartIndices[index]; var decalPositions = DecalPoses.GetSubArray(startIndex, numDecals); var decalTrackDistances = new NativeArray <float>(numDecals, Allocator.Temp); var distancePerDecal = SplineUtility.SplineLength(sampleBuffer) / (numDecals); // Offset the decals by a third instead of a half of the separation dist to decrease the chances of // overlapping decals being generated. var thirdDistPerDecal = distancePerDecal / 3f; var currDist = distancePerDecal / 2f; for (var i = 0; i < numDecals; i++) { decalTrackDistances[i] = currDist + random.NextFloat(-thirdDistPerDecal, thirdDistPerDecal); currDist += distancePerDecal; } var remappedSpline = SplineUtility.SampleSplineAtDistances(sampleBuffer, decalTrackDistances, Allocator.Temp); var lateralProfile = Profiles[ProfileBuffers[roadEntity].Reinterpret <Entity>()[0]]; var minLateralRange = lateralProfile.LeftDrivableOffset.x; var maxLateralRange = lateralProfile.RightDrivableOffset.x; minLateralRange = math.clamp(minLateralRange, minLateralRange + 1, 0); maxLateralRange = math.clamp(maxLateralRange, 0, maxLateralRange - 1); for (var i = 0; i < remappedSpline.Length; i++) { var pose = remappedSpline[i]; var randOffset = random.NextFloat(minLateralRange, maxLateralRange); var randRotation = quaternion.RotateY(random.NextFloat(0, math.PI * 2f)); var offset = new float3(randOffset, 0f, 0f); decalPositions[i] = new RigidTransform { pos = math.transform(pose, offset), rot = math.mul(pose.rot, randRotation) }; } remappedSpline.Dispose(); }