void AddSolidLaneLine(
            NativeArray <RigidTransform> samples,
            float xOffset,
            RoadMarking marking,
            DynamicBuffer <CombinedVertex> vertexBuffer,
            DynamicBuffer <Triangle> triangleBuffer,
            DynamicBuffer <SubMesh> subMeshBuffer)
        {
            var newSubMesh        = new SubMesh();
            var markingWidth      = marking.Width / 2;
            var leftOffsetSpline  = SplineUtility.OffsetSpline(samples, new float3(-markingWidth + xOffset, 0f, 0f), Allocator.Temp);
            var rightOffsetSpline = SplineUtility.OffsetSpline(samples, new float3(markingWidth + xOffset, 0f, 0f), Allocator.Temp);

            newSubMesh.VertexStartIndex = vertexBuffer.Length;
            newSubMesh.VertexCount      = samples.Length * 2;
            vertexBuffer.ResizeUninitialized(vertexBuffer.Length + samples.Length * 2);

            var upVector = new float3(0f, 1f, 0f);

            for (int i = 0, j = newSubMesh.VertexStartIndex; i < samples.Length; i++)
            {
                var leftPoint = leftOffsetSpline[i];
                vertexBuffer[j++] = new CombinedVertex
                {
                    Vertex = leftPoint.pos,
                    Normal = math.mul(leftPoint.rot, upVector),
                    Uv     = leftPoint.pos.xz
                };
                var rightPoint = rightOffsetSpline[i];
                vertexBuffer[j++] = new CombinedVertex
                {
                    Vertex = rightPoint.pos,
                    Normal = math.mul(rightPoint.rot, upVector),
                    Uv     = rightPoint.pos.xz
                };
            }
            leftOffsetSpline.Dispose();
            rightOffsetSpline.Dispose();

            newSubMesh.TriangleStartIndex = triangleBuffer.Length;
            newSubMesh.TriangleCount      = (samples.Length - 1) * 6;
            triangleBuffer.ResizeUninitialized(triangleBuffer.Length + newSubMesh.TriangleCount);
            for (int i = 0, j = newSubMesh.TriangleStartIndex; i < newSubMesh.VertexCount - 2; i += 2)
            {
                triangleBuffer[j++] = i;
                triangleBuffer[j++] = i + 3;
                triangleBuffer[j++] = i + 1;

                triangleBuffer[j++] = i;
                triangleBuffer[j++] = i + 2;
                triangleBuffer[j++] = i + 3;
            }

            newSubMesh.Material = marking.Material;
            subMeshBuffer.Add(newSubMesh);
        }
        public void AddRoadMarking(int idx, RoadMarking roadMarking)
        {
            var roadMarkingIndex  = RoadMarkings.Length;
            var roadMarkingEntity = m_RoadMarkingEntities[roadMarkingIndex];
            var leftSurfaceIndex  = m_NumLeftSurfaces + idx - 1;

            roadMarking.LeftSurface  = m_SurfaceEntities[leftSurfaceIndex];
            roadMarking.RightSurface = m_SurfaceEntities[leftSurfaceIndex + 1];
            roadMarking.Profile      = m_ProfileEntity;
            RoadMarkings.Add(roadMarking);

            var leftSurface = Surfaces[leftSurfaceIndex];

            leftSurface.RightLaneMarking = roadMarkingEntity;
            Surfaces[leftSurfaceIndex]   = leftSurface;

            var rightSurface = Surfaces[leftSurfaceIndex + 1];

            rightSurface.LeftLaneMarking   = roadMarkingEntity;
            Surfaces[leftSurfaceIndex + 1] = rightSurface;
        }
示例#3
0
        LateralProfileBuilder CreateBuilder(int index)
        {
            var numLanes          = NumLanes[index];
            var numSurfaces       = 2 * numLanes + 12;
            var surfaceStartIndex = SurfaceStartIndices[index];
            var surfaceEntities   = SurfaceEntities.GetSubArray(surfaceStartIndex, numSurfaces);

            var numRoadMarkings       = 2 * numLanes + 1;
            var roadMarkingStartIndex = RoadMarkingStartIndices[index];
            var roadMarkingEntities   = RoadMarkingEntities.GetSubArray(roadMarkingStartIndex, numRoadMarkings);

            var builder = new LateralProfileBuilder(
                Allocator.Temp,
                RoadEntities[index],
                ProfileEntities[index],
                surfaceEntities,
                roadMarkingEntities);

            var curbHeight = math.max(ProfileParams.CurbHeight, ProfileParams.CurbRadius * 1.5f);

            for (var i = 0; i < numLanes; i++)
            {
                builder.AddRoad(ProfileParams.LaneWidth);
            }
            builder.AddRoad(1f);
            builder.AddGutter(ProfileParams.GutterWidth, ProfileParams.GutterDepth);
            builder.AddCurb(curbHeight, ProfileParams.CurbRadius / 2, ProfileParams.CurbRadius, 5);
            builder.AddExpansionJoint(ProfileParams.ExpansionJointWidth);
            builder.AddSidewalk(ProfileParams.SidewalkWidth);
            builder.AddEndCap(ProfileParams.EndCapHeight);

            builder.SwitchSides();

            for (var i = 0; i < numLanes; i++)
            {
                builder.AddRoad(ProfileParams.LaneWidth);
            }
            builder.AddRoad(1f);
            builder.AddGutter(ProfileParams.GutterWidth, ProfileParams.GutterDepth);
            builder.AddCurb(curbHeight, ProfileParams.CurbRadius / 2, ProfileParams.CurbRadius, 5);
            builder.AddExpansionJoint(ProfileParams.ExpansionJointWidth);
            builder.AddSidewalk(ProfileParams.SidewalkWidth);
            builder.AddEndCap(ProfileParams.EndCapHeight);

            builder.Complete();

            var solidWhiteMarking = new RoadMarking
            {
                Material           = RoadMaterial.WhiteLaneLine,
                Width              = MarkingParams.LineWidth,
                DashLength         = 0,
                SeparationDistance = 0,
                BeginningOffset    = 0
            };

            var solidYellowMarking = new RoadMarking
            {
                Material           = RoadMaterial.YellowLaneLine,
                Width              = MarkingParams.LineWidth,
                DashLength         = 0,
                SeparationDistance = 0,
                BeginningOffset    = 0
            };

            var dashedWhiteMarking = new RoadMarking
            {
                Material           = RoadMaterial.WhiteLaneLine,
                Width              = MarkingParams.LineWidth,
                DashLength         = MarkingParams.DashLength,
                SeparationDistance = MarkingParams.DashSeparationDistance,
                BeginningOffset    = MarkingParams.DashBeginningOffset
            };

            builder.AddRoadMarking(-numLanes, solidWhiteMarking);
            builder.AddRoadMarking(0, solidYellowMarking);
            builder.AddRoadMarking(numLanes, solidWhiteMarking);

            for (var i = 1; i < numLanes; i++)
            {
                builder.AddRoadMarking(i, dashedWhiteMarking);
                builder.AddRoadMarking(-i, dashedWhiteMarking);
            }

            return(builder);
        }
        void DashSamples(
            NativeArray <RigidTransform> samples,
            RoadMarking marking,
            out NativeList <RigidTransform> dashSamples,
            out NativeList <DashPoint> dashPoints)
        {
            var sampleDistances = SplineUtility.SplineDistanceArray(samples, Allocator.Temp);
            var totalDist       = sampleDistances[sampleDistances.Length - 1];

            marking.BeginningOffset %= marking.DashLength;

            var patternDist     = marking.DashLength + marking.SeparationDistance;
            var numPatterns     = (int)(totalDist / patternDist) + 2;
            var patternPoints   = new NativeArray <DashPoint>(numPatterns * 2, Allocator.Temp);
            var accumulatedDist = marking.BeginningOffset;

            for (var i = 0; i < patternPoints.Length;)
            {
                patternPoints[i++] = new DashPoint
                {
                    Distance = accumulatedDist,
                    Cap      = DashCap.Start
                };
                accumulatedDist   += marking.DashLength;
                patternPoints[i++] = new DashPoint
                {
                    Distance = accumulatedDist,
                    Cap      = DashCap.End
                };
                accumulatedDist += marking.SeparationDistance;
            }

            dashSamples = new NativeList <RigidTransform>(patternPoints.Length + sampleDistances.Length, Allocator.Temp);
            dashPoints  = new NativeList <DashPoint>(patternPoints.Length + sampleDistances.Length, Allocator.Temp);
            dashSamples.Add(samples[0]);
            dashPoints.Add(new DashPoint
            {
                Distance = 0f,
                Cap      = DashCap.End
            });

            for (int i = 1, j = 0; i < samples.Length; i++)
            {
                var prevSample  = samples[i - 1];
                var nextSample  = samples[i];
                var prevDist    = sampleDistances[i - 1];
                var nextDist    = sampleDistances[i];
                var betweenDist = nextDist - prevDist;

                while (patternPoints[j].Distance < nextDist)
                {
                    var t = (patternPoints[j].Distance - prevDist) / betweenDist;
                    dashSamples.Add(SplineUtility.LerpTransform(prevSample, nextSample, t));
                    dashPoints.Add(new DashPoint
                    {
                        Distance = i - 1 + t,
                        Cap      = patternPoints[j].Cap
                    });
                    j++;
                }
                dashSamples.Add(nextSample);
                dashPoints.Add(new DashPoint
                {
                    Distance = i,
                    Cap      = dashPoints[dashPoints.Length - 1].Cap
                });
            }

            sampleDistances.Dispose();
            patternPoints.Dispose();
        }
        void AddDashedLaneLine(
            NativeArray <RigidTransform> samples,
            float xOffset,
            RoadMarking marking,
            DynamicBuffer <CombinedVertex> vertexBuffer,
            DynamicBuffer <Triangle> triangleBuffer,
            DynamicBuffer <SubMesh> subMeshBuffer,
            DynamicBuffer <RigidTransform> roadMarkingSamples,
            DynamicBuffer <DashPoint> dashPoints)
        {
            DashSamples(samples, marking, out var dashSamples, out var dashCaps);
            roadMarkingSamples.AddRange(dashSamples);
            dashPoints.AddRange(dashCaps);

            var markingWidth      = marking.Width / 2;
            var leftOffsetSpline  = SplineUtility.OffsetSpline(dashSamples, new float3(-markingWidth + xOffset, 0f, 0f), Allocator.Temp);
            var rightOffsetSpline = SplineUtility.OffsetSpline(dashSamples, new float3(markingWidth + xOffset, 0f, 0f), Allocator.Temp);
            var dashVertices      = new NativeList <CombinedVertex>(leftOffsetSpline.Length / 2, Allocator.Temp);
            var nonDashVertices   = new NativeList <CombinedVertex>(leftOffsetSpline.Length / 2, Allocator.Temp);

            var upVector = new float3(0f, 1f, 0f);

            for (var i = 0; i < dashSamples.Length - 1; i++)
            {
                if (dashCaps[i].Cap == DashCap.Start)
                {
                    var leftPoint = leftOffsetSpline[i];
                    dashVertices.Add(new CombinedVertex
                    {
                        Vertex = leftPoint.pos,
                        Normal = math.mul(leftPoint.rot, upVector),
                        Uv     = leftPoint.pos.xz
                    });
                    var rightPoint = rightOffsetSpline[i];
                    dashVertices.Add(new CombinedVertex
                    {
                        Vertex = rightPoint.pos,
                        Normal = math.mul(rightPoint.rot, upVector),
                        Uv     = rightPoint.pos.xz
                    });
                    leftPoint = leftOffsetSpline[i + 1];
                    dashVertices.Add(new CombinedVertex
                    {
                        Vertex = leftPoint.pos,
                        Normal = math.mul(leftPoint.rot, upVector),
                        Uv     = leftPoint.pos.xz
                    });
                    rightPoint = rightOffsetSpline[i + 1];
                    dashVertices.Add(new CombinedVertex
                    {
                        Vertex = rightPoint.pos,
                        Normal = math.mul(rightPoint.rot, upVector),
                        Uv     = rightPoint.pos.xz
                    });
                }
                else
                {
                    var leftPoint = leftOffsetSpline[i];
                    nonDashVertices.Add(new CombinedVertex
                    {
                        Vertex = leftPoint.pos,
                        Normal = math.mul(leftPoint.rot, upVector),
                        Uv     = leftPoint.pos.xz
                    });
                    var rightPoint = rightOffsetSpline[i];
                    nonDashVertices.Add(new CombinedVertex
                    {
                        Vertex = rightPoint.pos,
                        Normal = math.mul(rightPoint.rot, upVector),
                        Uv     = rightPoint.pos.xz
                    });
                    leftPoint = leftOffsetSpline[i + 1];
                    nonDashVertices.Add(new CombinedVertex
                    {
                        Vertex = leftPoint.pos,
                        Normal = math.mul(leftPoint.rot, upVector),
                        Uv     = leftPoint.pos.xz
                    });
                    rightPoint = rightOffsetSpline[i + 1];
                    nonDashVertices.Add(new CombinedVertex
                    {
                        Vertex = rightPoint.pos,
                        Normal = math.mul(rightPoint.rot, upVector),
                        Uv     = rightPoint.pos.xz
                    });
                }
            }
            leftOffsetSpline.Dispose();
            rightOffsetSpline.Dispose();
            dashSamples.Dispose();
            dashCaps.Dispose();

            var dashSubMesh = new SubMesh
            {
                VertexCount        = dashVertices.Length,
                VertexStartIndex   = vertexBuffer.Length,
                TriangleCount      = (dashVertices.Length * 3) / 2,
                TriangleStartIndex = triangleBuffer.Length,
                Material           = marking.Material
            };

            var nonDashSubMesh = new SubMesh
            {
                VertexCount        = nonDashVertices.Length,
                VertexStartIndex   = dashSubMesh.VertexStartIndex + dashSubMesh.VertexCount,
                TriangleCount      = (nonDashVertices.Length * 3) / 2,
                TriangleStartIndex = dashSubMesh.TriangleStartIndex + dashSubMesh.TriangleCount,
                Material           = RoadMaterial.RoadSurface
            };

            vertexBuffer.AddRange(dashVertices);
            vertexBuffer.AddRange(nonDashVertices);

            triangleBuffer.ResizeUninitialized(triangleBuffer.Length + dashSubMesh.TriangleCount + nonDashSubMesh.TriangleCount);
            for (int i = 0, j = dashSubMesh.TriangleStartIndex; i < dashSubMesh.VertexCount; i += 4)
            {
                triangleBuffer[j++] = i;
                triangleBuffer[j++] = i + 3;
                triangleBuffer[j++] = i + 1;

                triangleBuffer[j++] = i;
                triangleBuffer[j++] = i + 2;
                triangleBuffer[j++] = i + 3;
            }

            for (int i = 0, j = nonDashSubMesh.TriangleStartIndex; i < nonDashSubMesh.VertexCount; i += 4)
            {
                triangleBuffer[j++] = i;
                triangleBuffer[j++] = i + 3;
                triangleBuffer[j++] = i + 1;

                triangleBuffer[j++] = i;
                triangleBuffer[j++] = i + 2;
                triangleBuffer[j++] = i + 3;
            }

            subMeshBuffer.Add(dashSubMesh);
            subMeshBuffer.Add(nonDashSubMesh);
            dashVertices.Dispose();
            nonDashVertices.Dispose();
        }