Beispiel #1
0
        internal static void SampleLanesOneSideUpTo(Road road, SamplingStateRoad state, Side side, float sRoad,
                                                    int outputIdx, ref NativeArray <PointSampleGlobal> samples, LaneType stopAtLane)
        {
            var lanes = GetLaneSectionSideUpTo(state.GetLaneSection(road, sRoad), side, stopAtLane);

            SampleLanesOneSide(road, state, side, sRoad, outputIdx, ref samples, lanes.Count());
        }
Beispiel #2
0
        // TODO: Refactor to separate lane sampling into helper which is agnostic to Side or LaneSection
        //       Find all invocations of SampleLanes_____ and modify them to move the lanes array initialization
        //       into the calling function
        internal static void SampleLanesOneSide(Road road, SamplingStateRoad state, Side side, float sRoad,
                                                int outputIdx, ref NativeArray <PointSampleGlobal> samples, int stopBeforeIdx = int.MaxValue)
        {
            var laneEdgeOffsetLocal = state.GetLaneOffset(road, sRoad);

            // TODO: Direct access to the Idx should be revoked and replaced with Getter methods
            var laneSection = state.GetLaneSection(road, sRoad);
            var lanes       = GetLaneSectionSide(laneSection, side);

            if (!lanes.Any())
            {
                return;
            }

            var numLanes          = lanes.Count();
            var laneIter          = lanes.GetEnumerator();
            var numSamplesPerLane = samples.Length / math.min(numLanes, stopBeforeIdx);
            var sLaneSection      = sRoad - laneSection.sRoad;
            var geometrySample    = state.GetGeometrySample(road, sRoad);

            for (var laneIdx = 0; laneIdx < numLanes && laneIdx < stopBeforeIdx; ++laneIdx)
            {
                // For some reason, in IEnumerables, the 'current' field actually returns the value at index-1 rather
                // than the actual current value, so we need to move the iterator first to set 'current' to the value
                // we'd expect
                laneIter.MoveNext();
                var lane        = laneIter.Current;
                var sampleLocal = BuildLaneSample(lane, laneEdgeOffsetLocal, sLaneSection);
                laneEdgeOffsetLocal = sampleLocal.position.y;

                var currentIdx = ComputeLaneSampleIdx(laneIdx, numSamplesPerLane, outputIdx);
                if (currentIdx >= samples.Length)
                {
                    throw new Exception("Computed an out of range index.");
                }

                // The offset for the lane edge is measured along the normal of the reference line
                samples[currentIdx] =
                    FromLocalToGlobal(geometrySample.pose, sampleLocal);
            }
            laneIter.Dispose();
        }
Beispiel #3
0
        internal static NativeArray <PointSampleGlobal> BuildSamplesFromRoadOutline(
            Road road, float samplesPerMeter, LaneType stopAtLane)
        {
            if (road.geometry.Count == 0)
            {
                throw new Exception($"The road {road} has no reference line.");
            }
            var numTotalSamples  = ComputeNumSamplesForRoadLength(road.length, samplesPerMeter) * 2;
            var samplingState    = new SamplingStateRoad(road, samplesPerMeter);
            var numSectionsLeft  = road.laneSections.Max(s => s.leftLanes.Count());
            var numSectionsRight = road.laneSections.Max(s => s.rightLanes.Count());
            var leftSamplesTemp  = new NativeArray <PointSampleGlobal>(numSectionsLeft, Allocator.Temp);
            var rightSamplesTemp = new NativeArray <PointSampleGlobal>(numSectionsRight, Allocator.Temp);
            var allSamples       = new NativeArray <PointSampleGlobal>(numTotalSamples, Allocator.Temp);

            for (var sampleIdx = 0; sampleIdx < numTotalSamples / 2; sampleIdx++)
            {
                var sRoad = samplingState.sRoadLastComputed;
                // We intentionally do not pass state as a reference here, as each sampling pass will cover the same
                // segment of road. We would need to do some refactoring to sample all lanes for a given s-coordinate
                // in one call in order to use sampling state more effectively
                SampleLanesOneSideUpTo(
                    road, samplingState, Side.Left, sRoad, 0, ref leftSamplesTemp, stopAtLane);
                SampleLanesOneSideUpTo(
                    road, samplingState, Side.Right, sRoad, 0, ref rightSamplesTemp, stopAtLane);
                var currentSection = road.laneSections[samplingState.laneSectionIdx];
                if (currentSection.rightLanes.Any())
                {
                    var sampledLanes = GetLaneSectionSideUpTo(samplingState.GetLaneSection(road, sRoad), Side.Right,
                                                              stopAtLane);
                    allSamples[sampleIdx] = sampledLanes.Any()
                        ? rightSamplesTemp[sampledLanes.Count() - 1]
                        : SampleCenter(road, samplingState, sRoad);
                }
                else
                {
                    allSamples[sampleIdx] = SampleCenter(road, samplingState, sRoad);
                }

                // allSamples must be ordered to form a counter-clockwise outline, so left samples get added
                // in reverse order to the end of the array
                var leftIdx = numTotalSamples - 1 - sampleIdx;
                if (currentSection.leftLanes.Any())
                {
                    var sampledLanes = GetLaneSectionSideUpTo(samplingState.GetLaneSection(road, sRoad), Side.Left,
                                                              stopAtLane);
                    allSamples[leftIdx] = sampledLanes.Any()
                        ? leftSamplesTemp[sampledLanes.Count() - 1]
                        : SampleCenter(road, samplingState, sRoad);
                }
                else
                {
                    allSamples[leftIdx] = SampleCenter(road, samplingState, sRoad);
                }

                var stepSucceeded = samplingState.Step(road);

                // We expect stepping to fail at the end of the current segment, but otherwise this would be a problem
                if (!stepSucceeded && sampleIdx * 2 + 2 != numTotalSamples)
                {
                    Debug.LogWarning($"Reached end of road {road.roadId} early. Still have " +
                                     $"{numTotalSamples / 2 - sampleIdx - 1} samples to do.");
                }
            }

            leftSamplesTemp.Dispose();
            rightSamplesTemp.Dispose();
            return(allSamples);
        }