Example #1
0
        private static bool TryFindWidthRecord(EcsRoadData roadData, EcsLane lane, float sLocal,
                                               out LaneWidthRecord laneWidthRecord)
        {
            var widthRecordIdx   = 0;
            var foundWidthRecord = false;

            laneWidthRecord = default;

            var laneWidthRecords = lane.GetLaneWidthRecords(roadData.laneWidthRecords);

            for (; widthRecordIdx < laneWidthRecords.Length; widthRecordIdx++)
            {
                var widthRecordNext = laneWidthRecords[widthRecordIdx];
                var sOffsetNext     = widthRecordNext.sSectionOffset;
                if (sOffsetNext > sLocal)
                {
                    break;
                }

                laneWidthRecord  = widthRecordNext;
                foundWidthRecord = true;
            }

            return(foundWidthRecord);
        }
Example #2
0
        // TODO: Width records are still searched every time - this could be optimized by tracking the current record
        /// <summary>
        /// Sample the laneSection at the given s position.
        /// </summary>
        /// <param name="sDelta">s position to sample. Must be between laneSection and s + length.</param>
        internal static PointSampleLocal BuildLaneSample(EcsRoadData roadData, EcsLane lane, float laneOffset, float sSection)
        {
            if (!TryFindWidthRecord(roadData, lane, sSection, out var widthRecord))
            {
                if (lane.laneType == LaneType.Border)
                {
                    return(new PointSampleLocal(0.0f, 0.0f, 0.0f));
                }

                throw new Exception("Couldn't find width record for lane... xodr file may be malformed.'");
            }

            var sign    = lane.id > 0 ? 1f : -1f;
            var sDelta  = sSection - widthRecord.sSectionOffset;
            var width   = sign * Poly3ComputeV(widthRecord.poly3, sDelta);
            var heading = sign * Poly3ComputeHeading(widthRecord.poly3, sDelta);

            return(new PointSampleLocal(new Vector2(0, width + laneOffset), heading));
        }
Example #3
0
        protected override void OnUpdate()
        {

            var rnd = Parameters.roadNetworkDescription == null ? staticRnd : Parameters.roadNetworkDescription;
            if (rnd == null)
                return;

            var id = rnd.entityRoadId == 0 ? nextId++ : rnd.entityRoadId;
            rnd.entityRoadId = id;
            var ecsRoadNetwork = new EcsRoadNetwork() { id = id };

            //check for an existing road network
            var query = EntityManager.CreateEntityQuery(typeof(EcsRoadNetwork), typeof(EcsRoad));
            query.AddSharedComponentFilter(ecsRoadNetwork);
            if (query.CalculateChunkCount() > 0)
                return;

            var roadEntities = new NativeArray<Entity>(rnd.AllRoads.Length, Allocator.Temp);
            EntityManager.CreateEntity(m_RoadArchetype, roadEntities);

            var junctionEntities = new NativeArray<Entity>(rnd.AllJunctions.Length, Allocator.Temp);
            EntityManager.CreateEntity(m_JunctionArchetype, junctionEntities);

            for (var roadIndex = 0; roadIndex < rnd.AllRoads.Length; roadIndex++)
            {
                var road = rnd.AllRoads[roadIndex];
                var entity = roadEntities[roadIndex];
                EntityManager.SetSharedComponentData(entity, ecsRoadNetwork);
                EntityManager.SetComponentData(entity, new EcsRoad
                {
                    length = road.length,
                    junction = string.IsNullOrEmpty(road.junction) || string.Equals("-1", road.junction) ? Entity.Null : junctionEntities[rnd.GetJunctionIndexById(road.junction)],
                    name = road.name,
                    predecessor = CreateEcsRoadLink(road.predecessor, rnd, roadEntities, junctionEntities),
                    successor = CreateEcsRoadLink(road.successor, rnd, roadEntities, junctionEntities)
                });

                //multiple copies - there is almost certainly a better way
                FillBuffer(road.elevationProfiles, entity);
                FillBuffer(road.geometry, entity);
                FillBuffer(road.laneOffsets, entity);

                var laneSections = EntityManager.GetBuffer<EcsLaneSection>(entity);
                var lanes = EntityManager.GetBuffer<EcsLane>(entity);
                var laneWidthRecords = EntityManager.GetBuffer<LaneWidthRecord>(entity);
                laneSections.ResizeUninitialized(road.laneSections.Count);
                for (var i = 0; i < road.laneSections.Count; i++)
                {
                    var section = road.laneSections[i];

                    laneSections[i] = new EcsLaneSection
                    {
                        centerLaneIndex = lanes.Length + section._centerIdx,
                        firstLaneIndex = lanes.Length,
                        laneCount = section._allLanes.Length,
                        sRoad = section.sRoad
                    };

                    foreach (var lane in section._allLanes)
                    {
                        var ecsLane = new EcsLane
                        {
                            firstLaneWidthRecordIndex = laneWidthRecords.Length,
                            laneWidthRecordCount = lane.widthRecords.Length,
                            firstPredecessorId = FirstOrZero(lane.link.predecessors),
                            predecessorIdCount = lane.link.predecessors?.Length ?? 0,
                            firstSuccessorId = FirstOrZero(lane.link.successors),
                            successorIdCount = lane.link.successors?.Length ?? 0,
                            id = lane.id
                        };

                        var nativeData = new NativeArray<LaneWidthRecord>(lane.widthRecords, Allocator.Temp);
                        laneWidthRecords.AddRange(nativeData);
                        nativeData.Dispose();

                        lanes.Add(ecsLane);
                    }
                }
            }

            for (var junctionIndex = 0; junctionIndex < rnd.AllJunctions.Length; junctionIndex++)
            {
                var junction = rnd.AllJunctions[junctionIndex];
                var entity = junctionEntities[junctionIndex];

                EntityManager.SetSharedComponentData(entity, ecsRoadNetwork);
                EntityManager.SetComponentData(entity, new EcsJunction
                {
                    name = junction.name,
                    junctionId = junction.junctionId
                });
                var connectionBuffer = EntityManager.GetBuffer<EcsJunctionConnection>(entity);
                connectionBuffer.ResizeUninitialized(junction.connections.Count);
                for (int connectionIndex = 0; connectionIndex < junction.connections.Count; connectionIndex++)
                {
                    var connection = junction.connections[connectionIndex];
                    connectionBuffer[connectionIndex] = new EcsJunctionConnection
                    {
                        connectingRoad = roadEntities[rnd.GetRoadIndexById(connection.connectingRoadId)],
                        incomingRoad = roadEntities[rnd.GetRoadIndexById(connection.incomingRoadId)],
                        linkContactPoint = connection.contactPoint
                    };
                }
            }
        }