internal SamplingStatePoly3(ParamPoly3Data poly3, float dsStepForApproximation = 0.1f)
        {
            m_poly3 = poly3;
            m_dsStepForApproximation = dsStepForApproximation;

            m_currentIdx = 0;
            var initialValues = new SimpsonsRuleValues(0, GeometrySampling.Poly3ComputeL(m_poly3, 0), 0);

            m_values = new[]
            {
                initialValues,
                GeometrySampling.Poly3ComputeSimpsonStep(m_poly3, initialValues, dsStepForApproximation)
            };
        }
        public bool Step(EcsRoadData road)
        {
            if (Mathf.Approximately(sRoadLastComputed, road.ecsRoad.length))
            {
                return(false);
            }

            if (GeometrySampling.IsApproximatelyLessThan(sRoadCurrent + sRoadStep, road.ecsRoad.length))
            {
                sRoadCurrent += sRoadStep;
            }
            else
            {
                sRoadCurrent = road.ecsRoad.length;
            }

            CheckStateAndUpdate(road);
            return(true);
        }
        private void ComputeSamples(EcsRoadData road)
        {
            if (Mathf.Approximately(sRoadCurrent, sRoadLastComputed))
            {
                Debug.LogWarning("Compute samples called for the same s-value twice.");
            }

            sRoadLastComputed = sRoadCurrent;

            var geometry = road.ecsGeometries[geometryIdx];

            //var sGeometry = sRoadCurrent - geometry.sRoad;
            geometrySample = geometry.Sample(sRoadCurrent);
            if (road.laneOffsets.Length > 0)
            {
                var laneOffsetRecord = road.laneOffsets[laneOffsetIdx];
                var sLaneOffset      = sRoadCurrent - laneOffsetRecord.sRoad;
                laneOffset = GeometrySampling.Poly3ComputeV(laneOffsetRecord.poly3, sLaneOffset);
            }
        }
        internal SamplingStatePoly3(Geometry geometry, float dsStepForApproximation = 0.1f)
        {
            if (geometry.geometryKind == GeometryKind.Poly3)
            {
                m_poly3 = new ParamPoly3Data(geometry.poly3Data);
            }
            else
            {
                m_poly3 = geometry.paramPoly3Data;
            }

            m_dsStepForApproximation = dsStepForApproximation;

            m_currentIdx = 0;
            var initialValues = new SimpsonsRuleValues(0, GeometrySampling.Poly3ComputeL(m_poly3, 0), 0);

            m_values = new[]
            {
                initialValues,
                GeometrySampling.Poly3ComputeSimpsonStep(m_poly3, initialValues, m_dsStepForApproximation)
            };
        }
        private void CheckStateAndUpdate(EcsRoadData road)
        {
            if (!IsStale())
            {
                return;
            }

            if (!GeometrySampling.IsApproximatelyLessThan(sRoadCurrent, geometryEndS))
            {
                (geometryIdx, geometryEndS) =
                    FindNextAlongLength(road.ecsGeometries, sRoadCurrent, geometryIdx, road.ecsRoad.length);
                geometryState = new SamplingStateGeometry(road.ecsGeometries[geometryIdx]);
            }

            if (!GeometrySampling.IsApproximatelyLessThan(sRoadCurrent, laneOffsetEndS))
            {
                (laneOffsetIdx, laneOffsetEndS) =
                    FindNextAlongLength(road.laneOffsets, sRoadCurrent, laneOffsetIdx, road.ecsRoad.length);
            }

            if (!GeometrySampling.IsApproximatelyLessThan(sRoadCurrent, laneSectionEndS))
            {
                if (canMoveToNextLaneSection)
                {
                    (laneSectionIdx, laneSectionEndS) =
                        FindNextAlongLength(road.ecsLaneSections, sRoadCurrent, laneSectionIdx, road.ecsRoad.length);
                }
                else if (!Mathf.Approximately(sRoadCurrent, laneSectionEndS))
                {
                    throw new Exception("Attempted to traverse past end of lane section, but " +
                                        $"{nameof(canMoveToNextLaneSection)} is {canMoveToNextLaneSection}");
                }
            }

            ComputeSamples(road);
        }