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; }
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(); }