Create joint generating code for multi-segment lines and refactor code for end caps.
This commit is contained in:
		
							parent
							
								
									772906bec7
								
							
						
					
					
						commit
						502eb95278
					
				| @ -1,4 +1,5 @@ | ||||
| using System; | ||||
| using Quik.VertexGenerator; | ||||
| 
 | ||||
| namespace Quik | ||||
| { | ||||
| @ -10,9 +11,15 @@ namespace Quik | ||||
|         public float X; | ||||
|         public float Y; | ||||
| 
 | ||||
|         public float Length() => MathF.Sqrt(X * X + Y * Y); | ||||
|         public float Magnitude => MathF.Sqrt(X * X + Y * Y); | ||||
| 
 | ||||
|         public QuikVec2 Normalize() => this * (1.0f / this.Length()); | ||||
|         public QuikVec2(float x, float y) | ||||
|         { | ||||
|             X = x; | ||||
|             Y = y; | ||||
|         } | ||||
| 
 | ||||
|         public QuikVec2 Normalize() => this * (1.0f / Magnitude); | ||||
| 
 | ||||
|         public float Atan2() => MathF.Atan2(Y, X); | ||||
|         public static QuikVec2 operator +(QuikVec2 a, QuikVec2 b) | ||||
| @ -52,6 +59,32 @@ namespace Quik | ||||
|         } | ||||
| 
 | ||||
|         public static QuikVec2 operator *(QuikVec2 a, float b) => b * a; | ||||
| 
 | ||||
|         public static bool operator ==(QuikVec2 a, QuikVec2 b) => a.X == b.X && a.Y == b.Y; | ||||
| 
 | ||||
|         public static bool operator !=(QuikVec2 a, QuikVec2 b) => a.X != b.X || a.Y != b.Y; | ||||
| 
 | ||||
|         public override bool Equals(object obj) | ||||
|         { | ||||
|             if (obj is QuikVec2) | ||||
|             { | ||||
|                 return (QuikVec2) obj == this; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override int GetHashCode() | ||||
|         { | ||||
|             return 63671 * X.GetHashCode() ^ 81083 * Y.GetHashCode(); | ||||
|         } | ||||
| 
 | ||||
|         public static float Dot(QuikVec2 a, QuikVec2 b) | ||||
|         { | ||||
|             return a.X * b.X + a.Y * b.Y; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
| @ -162,6 +195,20 @@ namespace Quik | ||||
|         /// End point. | ||||
|         /// </summary> | ||||
|         public QuikVec2 End; | ||||
| 
 | ||||
|         public QuikLine(QuikVec2 start, QuikVec2 end) | ||||
|         { | ||||
|             Start = start; | ||||
|             End = end; | ||||
|         } | ||||
| 
 | ||||
|         public QuikLine(float startX, float startY, float endX, float endY) | ||||
|         { | ||||
|             Start.X = startX; | ||||
|             Start.Y = startY; | ||||
|             End.X = endX; | ||||
|             End.Y = endY; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|  | ||||
| @ -189,7 +189,323 @@ namespace Quik.VertexGenerator | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Generates a basic line segment. | ||||
|         /// </summary> | ||||
|         /// <param name="baseVertex">The vertex base to modify when generating vertices.</param> | ||||
|         /// <param name="line">The line segment.</param> | ||||
|         /// <param name="width">The width of the line.</param> | ||||
|         /// <param name="lineStartIndex">Start index of the generated line.</param> | ||||
|         /// <param name="normal">The line normal.</param> | ||||
|         private void GenerateLineSegment( | ||||
|             QuikVertex baseVertex, | ||||
|             QuikLine line, | ||||
|             float width, | ||||
|             out short lineStartIndex, | ||||
|             out QuikVec2 normal) | ||||
|         { | ||||
|             QuikVec2 tangent = (line.End - line.Start).Normalize(); | ||||
|             normal = new QuikVec2() {X = -tangent.Y, Y = tangent.X}; | ||||
|             lineStartIndex = (short)_vertexBufferPointer; | ||||
| 
 | ||||
|             QuikVertex startA = baseVertex, startB = baseVertex; | ||||
|             QuikVertex endA = baseVertex, endB = baseVertex; | ||||
| 
 | ||||
|             startA.Position = line.Start + width / 2 * normal; | ||||
|             startB.Position = line.Start - width / 2 * normal; | ||||
|             endA.Position = line.End + width / 2 * normal; | ||||
|             endB.Position = line.End - width / 2 * normal; | ||||
| 
 | ||||
|             // Add the major line vertices. | ||||
|             AddVertex(startA, startB, endA, endB); | ||||
|              | ||||
|             // Add the line indices. | ||||
|             AddElement( | ||||
|                 (short) (lineStartIndex + 1), | ||||
|                 (short) (lineStartIndex + 2), | ||||
|                 (short) (lineStartIndex + 0), | ||||
|                 (short) (lineStartIndex + 1), | ||||
|                 (short) (lineStartIndex + 3), | ||||
|                 (short) (lineStartIndex + 2) | ||||
|             ); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Gets the rounding resolution for a line segment. | ||||
|         /// </summary> | ||||
|         /// <param name="width">The width of the line.</param> | ||||
|         /// <param name="arc">The angle of the cap or joint arc.</param> | ||||
|         /// <returns>The rounding resolution.</returns> | ||||
|         private int GetRoundingResolution(float width, float arc) | ||||
|         { | ||||
|             int endCapResolution = (int) Math.Ceiling(arc * width * CurveGranularity); | ||||
|             return endCapResolution; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Generate a round start cap on a line. | ||||
|         /// </summary> | ||||
|         /// <param name="baseVertex">The base vertex to modify for generation.</param> | ||||
|         /// <param name="start">The start point.</param> | ||||
|         /// <param name="normal">The line normal.</param> | ||||
|         /// <param name="width">The width of line to generate.</param> | ||||
|         /// <param name="resolution">End cap resolution.</param> | ||||
|         /// <param name="lineStartPositiveIndex">The positive vertex index of the line start.</param> | ||||
|         /// <param name="lineStartNegativeIndex">The negative vertex index of the line start.</param> | ||||
|         public void GenerateStartCap( | ||||
|             QuikVertex baseVertex, | ||||
|             QuikVec2 start, | ||||
|             QuikVec2 normal, | ||||
|             float width, | ||||
|             int resolution, | ||||
|             short lineStartPositiveIndex, | ||||
|             short lineStartNegativeIndex | ||||
|         ) | ||||
|         { | ||||
|             QuikVertex circlePoint = baseVertex; | ||||
|             short lastIndex = lineStartPositiveIndex; | ||||
|             for (int i = 0; i < resolution; i++) | ||||
|             { | ||||
|                 float angle = (float) (i + 1) / (resolution + 1) * MathF.PI; | ||||
|                 float cosT = MathF.Cos(angle); | ||||
|                 float sinT = MathF.Sin(angle); | ||||
| 
 | ||||
|                 QuikVec2 displacement = new QuikVec2() | ||||
|                 { | ||||
|                     X = normal.X * cosT - normal.Y * sinT, | ||||
|                     Y = normal.X * sinT + normal.Y * cosT | ||||
|                 } * (width / 2); | ||||
| 
 | ||||
|                 circlePoint.Position = start + displacement; | ||||
| 
 | ||||
|                 short segmentIndex = (short)_vertexBufferPointer; | ||||
| 
 | ||||
|                 AddVertex(circlePoint); | ||||
|                 AddElement( | ||||
|                     lineStartNegativeIndex, | ||||
|                     lastIndex, | ||||
|                     segmentIndex); | ||||
| 
 | ||||
|                 lastIndex = segmentIndex; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Generate a round line end cap. | ||||
|         /// </summary> | ||||
|         /// <param name="baseVertex">Base vertex to modify for generation.</param> | ||||
|         /// <param name="end">The line end.</param> | ||||
|         /// <param name="normal">The line normal.</param> | ||||
|         /// <param name="width">The line width.</param> | ||||
|         /// <param name="resolution">Cap generation resolution.</param> | ||||
|         /// <param name="lineEndPositiveIndex">Vertex index of the positive line end.</param> | ||||
|         /// <param name="lineEndNegativeIndex">Vertex index of the negative line end.</param> | ||||
|         public void GenerateEndCap( | ||||
|             QuikVertex baseVertex, | ||||
|             QuikVec2 end, | ||||
|             QuikVec2 normal, | ||||
|             float width, | ||||
|             int resolution, | ||||
|             short lineEndPositiveIndex, | ||||
|             short lineEndNegativeIndex | ||||
|         ) | ||||
|         { | ||||
|             QuikVertex circlePoint = baseVertex; | ||||
|             short lastIndex = lineEndPositiveIndex; | ||||
|             for (int i = 0; i < resolution; i++) | ||||
|             { | ||||
|                 float angle = -(float) (i + 1) / (resolution + 1) * MathF.PI; | ||||
|                 float cosT = MathF.Cos(angle); | ||||
|                 float sinT = MathF.Sin(angle); | ||||
| 
 | ||||
|                 QuikVec2 displacement = new QuikVec2() | ||||
|                 { | ||||
|                     X = normal.X * cosT - normal.Y * sinT, | ||||
|                     Y = normal.X * sinT + normal.Y * cosT | ||||
|                 } * (width / 2); | ||||
| 
 | ||||
|                 circlePoint.Position = end + displacement; | ||||
| 
 | ||||
|                 AddVertex(circlePoint); | ||||
|                 AddElement( | ||||
|                     lineEndNegativeIndex, | ||||
|                     lastIndex, | ||||
|                     (short) (_vertexBufferPointer - 1)); | ||||
| 
 | ||||
|                 lastIndex = (short) (_vertexBufferPointer - 1); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Generate a joint on the line negative edge. | ||||
|         /// </summary> | ||||
|         /// <param name="baseVertex">Base vertex to modify for generation.</param> | ||||
|         /// <param name="focus">The focus of the joint.</param> | ||||
|         /// <param name="width">With of the lines.</param> | ||||
|         /// <param name="prevNegativeLineIndex">Index of the negative end vertex.</param> | ||||
|         /// <param name="nextNegativeLineIndex">Index of the negative start vertex.</param> | ||||
|         /// <param name="resolution">Joint resolution.</param> | ||||
|         /// <param name="arc">Arc length of the joint.</param> | ||||
|         /// <param name="prevNormal">Normal of the previous line.</param> | ||||
|         private void GenerateNegativeJoint( | ||||
|             QuikVertex baseVertex, | ||||
|             QuikVec2 focus, | ||||
|             float width, | ||||
|             short prevNegativeLineIndex, | ||||
|             short nextNegativeLineIndex, | ||||
|             int resolution, | ||||
|             float arc, | ||||
|             QuikVec2 prevNormal) | ||||
|         { | ||||
|             QuikVertex focusVertex = baseVertex; | ||||
|             short focusIndex = (short) _vertexBufferPointer; | ||||
|             short lastIndex = prevNegativeLineIndex; | ||||
| 
 | ||||
|             focusVertex.Position = focus; | ||||
|             AddVertex(focusVertex); | ||||
| 
 | ||||
|             for (int i = 0; i < resolution; i++) | ||||
|             { | ||||
|                 float angle = (float) (i + 1) / (resolution + 1) * arc; | ||||
|                 float cosT = MathF.Cos(angle); | ||||
|                 float sinT = MathF.Sin(angle); | ||||
| 
 | ||||
|                 QuikVec2 displacement = new QuikVec2() | ||||
|                 { | ||||
|                     X = -prevNormal.X * cosT + prevNormal.Y * sinT, | ||||
|                     Y = -prevNormal.X * sinT - prevNormal.Y * cosT | ||||
|                 } * (width / 2); | ||||
| 
 | ||||
|                 QuikVertex segmentVertex = focusVertex; | ||||
|                 segmentVertex.Position += displacement; | ||||
| 
 | ||||
|                 short segmentIndex = (short) _vertexBufferPointer; | ||||
|                 AddVertex(segmentVertex); | ||||
| 
 | ||||
|                 AddElement(lastIndex, segmentIndex, focusIndex); | ||||
|                  | ||||
|                 lastIndex = segmentIndex; | ||||
|             } | ||||
| 
 | ||||
|             // Add final triangle. | ||||
|             AddElement(lastIndex, nextNegativeLineIndex, focusIndex); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Generate a joint on the line negative edge. | ||||
|         /// </summary> | ||||
|         /// <param name="baseVertex">Base vertex to modify for generation.</param> | ||||
|         /// <param name="focus">The focus of the joint.</param> | ||||
|         /// <param name="width">With of the lines.</param> | ||||
|         /// <param name="prevPositiveLineIndex">Index of the positive end vertex.</param> | ||||
|         /// <param name="nextPositiveLineIndex">Index of the positive start vertex.</param> | ||||
|         /// <param name="resolution">Joint resolution.</param> | ||||
|         /// <param name="arc">Arc length of the joint.</param> | ||||
|         /// <param name="nextNormal">Normal of the next line.</param> | ||||
|         private void GeneratePositiveJoint( | ||||
|             QuikVertex baseVertex, | ||||
|             QuikVec2 focus, | ||||
|             float width, | ||||
|             short prevPositiveLineIndex, | ||||
|             short nextPositiveLineIndex, | ||||
|             int resolution, | ||||
|             float arc, | ||||
|             QuikVec2 nextNormal) | ||||
|         { | ||||
|             QuikVertex focusVertex = baseVertex; | ||||
|             short focusIndex = (short) _vertexBufferPointer; | ||||
|             short lastIndex = nextPositiveLineIndex; | ||||
| 
 | ||||
|             focusVertex.Position = focus; | ||||
|             AddVertex(focusVertex); | ||||
| 
 | ||||
|             for (int i = 0; i < resolution; i++) | ||||
|             { | ||||
|                 float angle = (float) (i + 1) / (resolution + 1) * arc; | ||||
|                 float cosT = MathF.Cos(angle); | ||||
|                 float sinT = MathF.Sin(angle); | ||||
| 
 | ||||
|                 QuikVec2 displacement = new QuikVec2() | ||||
|                 { | ||||
|                     X = nextNormal.X * cosT - nextNormal.Y * sinT, | ||||
|                     Y = nextNormal.X * sinT + nextNormal.Y * cosT | ||||
|                 } * (width / 2); | ||||
| 
 | ||||
|                 QuikVertex segmentVertex = focusVertex; | ||||
|                 segmentVertex.Position += displacement; | ||||
| 
 | ||||
|                 short segmentIndex = (short) _vertexBufferPointer; | ||||
|                 AddVertex(segmentVertex); | ||||
| 
 | ||||
|                 AddElement(lastIndex, segmentIndex, focusIndex); | ||||
| 
 | ||||
|                 lastIndex = segmentIndex; | ||||
|             } | ||||
| 
 | ||||
|             // Add final triangle. | ||||
|             AddElement(lastIndex, prevPositiveLineIndex, focusIndex); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Generate a joint. | ||||
|         /// </summary> | ||||
|         /// <param name="baseVertex">Base vertex to modify.</param> | ||||
|         /// <param name="focus">Focus of the joint.</param> | ||||
|         /// <param name="prevTangent">Tangent of the previous line segment.</param> | ||||
|         /// <param name="nextTangent">Tangent of the next line segment.</param> | ||||
|         /// <param name="width">Width of the lines.</param> | ||||
|         /// <param name="prevPositiveEndIndex">Vertex index of the positive end.</param> | ||||
|         /// <param name="prevNegativeEndIndex">Vertex index of the negative end.</param> | ||||
|         /// <param name="nextPositiveStartIndex">Vertex index of the positive start.</param> | ||||
|         /// <param name="nextNegativeStartIndex">Vertex index of the negative start.</param> | ||||
|         public void GenerateJoint( | ||||
|             QuikVertex baseVertex, | ||||
|             QuikVec2 focus, | ||||
|             QuikVec2 prevTangent, | ||||
|             QuikVec2 nextTangent, | ||||
|             float width, | ||||
|             short prevPositiveEndIndex, | ||||
|             short prevNegativeEndIndex, | ||||
|             short nextPositiveStartIndex, | ||||
|             short nextNegativeStartIndex | ||||
|         ) | ||||
|         { | ||||
|             QuikVec2 prevNormal,  nextNormal; | ||||
|             QuikVec2 averageTangent; | ||||
| 
 | ||||
|             prevNormal = new QuikVec2() { X = -prevTangent.Y, Y = prevTangent.X }; | ||||
|             nextNormal = new QuikVec2() { X = -nextTangent.Y, Y = nextTangent.X }; | ||||
| 
 | ||||
|             averageTangent = 0.5f * (prevTangent + nextTangent); | ||||
| 
 | ||||
|             // Figure out which side needs the joint. | ||||
|             QuikVec2 positiveEdge = ((focus + nextNormal) - (focus + prevNormal)).Normalize(); | ||||
|             QuikVec2 negativeEdge = ((focus - nextNormal) - (focus - prevNormal)).Normalize(); | ||||
| 
 | ||||
|             float positiveDot, negativeDot; | ||||
|             positiveDot = QuikVec2.Dot(averageTangent, positiveEdge); | ||||
|             negativeDot = QuikVec2.Dot(averageTangent, negativeEdge); | ||||
| 
 | ||||
|             float arc = MathF.Acos(QuikVec2.Dot(prevNormal, nextNormal)); | ||||
|             int resolution = GetRoundingResolution(width, arc); | ||||
| 
 | ||||
|             if (positiveDot < negativeDot) | ||||
|             { | ||||
|                 // Negative edge rounding. | ||||
|                 GenerateNegativeJoint(baseVertex, focus, width, prevNegativeEndIndex, nextNegativeStartIndex, resolution, arc, prevNormal); | ||||
|             } | ||||
|             else if (negativeDot < positiveDot) | ||||
|             { | ||||
|                 // Positive edge rounding. | ||||
|                 GeneratePositiveJoint(baseVertex, focus, width, prevPositiveEndIndex, nextPositiveStartIndex, resolution, arc, nextNormal); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // There is no need to generate anything because the lines are the same??? | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Renders a line. | ||||
|         /// </summary> | ||||
| @ -198,98 +514,86 @@ namespace Quik.VertexGenerator | ||||
|         private void RenderLine(ref QuikDrawCall call, QuikCommandLine line) | ||||
|         { | ||||
|             // Skip over stipple patterns for now. | ||||
|             QuikStrokeStyle style = line.Style ?? Context.DefaultStroke;  | ||||
|             int endCapResolution;                               // Resolution of the end cap. | ||||
|             short startOffset = (short) _vertexBufferPointer;   // Starting index pointer. | ||||
|             QuikVec2 tangent; | ||||
|             QuikVec2 normal; | ||||
| 
 | ||||
|             tangent = (line.Line.End - line.Line.Start).Normalize(); | ||||
|             normal = new QuikVec2() {X = -tangent.Y, Y = tangent.X}; | ||||
| 
 | ||||
|             QuikVertex baseVertex = new QuikVertex() {Color = style.Color }; | ||||
|             QuikVertex startA = baseVertex, startB = baseVertex; | ||||
|             QuikVertex endA = baseVertex, endB = baseVertex; | ||||
| 
 | ||||
|             startA.Position = line.Line.Start + style.Width / 2 * normal; | ||||
|             startB.Position = line.Line.Start - style.Width / 2 * normal; | ||||
|             endA.Position = line.Line.End + style.Width / 2 * normal; | ||||
|             endB.Position = line.Line.End - style.Width / 2 * normal; | ||||
| 
 | ||||
|             // Add the major line vertices. | ||||
|             AddVertex(startA, startB, endA, endB); | ||||
|             QuikStrokeStyle style = line.Style ?? Context.DefaultStroke; | ||||
|             QuikVertex baseVertex = new QuikVertex() { Color = style.Color }; | ||||
|              | ||||
|             // Add the line indices. | ||||
|             AddElement( | ||||
|                 (short) (startOffset + 1), | ||||
|                 (short) (startOffset + 2), | ||||
|                 (short) (startOffset + 0), | ||||
|                 (short) (startOffset + 1), | ||||
|                 (short) (startOffset + 3), | ||||
|                 (short) (startOffset + 2) | ||||
|                 ); | ||||
|             GenerateLineSegment(baseVertex, line.Line, style.Width, out short startOffset, out QuikVec2 normal); | ||||
| 
 | ||||
|             // Now calculate the end caps. | ||||
|             endCapResolution = (int)Math.Ceiling(MathF.PI * style.Width * CurveGranularity); | ||||
|             int endCapResolution = GetRoundingResolution(style.Width, MathF.PI); | ||||
| 
 | ||||
|             // Construct start cap. | ||||
|             QuikVertex circlePoint = baseVertex; | ||||
|             short lastIndex = startOffset; | ||||
|             for (int i = 0; i < endCapResolution; i++) | ||||
|             { | ||||
|                 float angle = (float) (i + 1) / (endCapResolution + 1) * MathF.PI; | ||||
|                 float cosT = MathF.Cos(angle); | ||||
|                 float sinT = MathF.Sin(angle); | ||||
| 
 | ||||
|                 QuikVec2 displacement = new QuikVec2() | ||||
|                 { | ||||
|                     X = normal.X * cosT - normal.Y * sinT, | ||||
|                     Y = normal.X * sinT + normal.Y * cosT | ||||
|                 } * (style.Width / 2); | ||||
| 
 | ||||
|                 circlePoint.Position = line.Line.Start + displacement;  | ||||
|                  | ||||
|                 AddVertex(circlePoint); | ||||
|                 AddElement( | ||||
|                     (short)(startOffset + 1), | ||||
|                     lastIndex, | ||||
|                     (short)(_vertexBufferPointer - 1)); | ||||
| 
 | ||||
|                 lastIndex = (short) (_vertexBufferPointer - 1); | ||||
|             } | ||||
|             GenerateStartCap(baseVertex, line.Line.Start, normal, style.Width, endCapResolution, startOffset, (short) | ||||
|                 (startOffset + 1)); | ||||
|              | ||||
|             // Construct end cap. | ||||
|             lastIndex = (short)(startOffset + 2); | ||||
|             for (int i = 0; i < endCapResolution; i++) | ||||
|             { | ||||
|                 float angle = -(float) (i + 1) / (endCapResolution + 1) * MathF.PI; | ||||
|                 float cosT = MathF.Cos(angle); | ||||
|                 float sinT = MathF.Sin(angle); | ||||
|             GenerateEndCap(baseVertex, line.Line.End, normal, style.Width, endCapResolution, (short) (startOffset + 2),(short) | ||||
|                 (startOffset + 3)); | ||||
| 
 | ||||
|                 QuikVec2 displacement = new QuikVec2() | ||||
|                 { | ||||
|                     X = normal.X * cosT - normal.Y * sinT, | ||||
|                     Y = normal.X * sinT + normal.Y * cosT | ||||
|                 } * (style.Width / 2); | ||||
| 
 | ||||
|                 circlePoint.Position = line.Line.End + displacement;  | ||||
|                  | ||||
|                 AddVertex(circlePoint); | ||||
|                 AddElement( | ||||
|                     (short)(startOffset + 3), | ||||
|                     lastIndex, | ||||
|                     (short)(_vertexBufferPointer - 1)); | ||||
| 
 | ||||
|                 lastIndex = (short) (_vertexBufferPointer - 1); | ||||
|             } | ||||
| 
 | ||||
|             call.Offset =(short) (startOffset * 2); | ||||
|             call.Offset = (short) (startOffset * 2); | ||||
|             call.Count = (short) (_elementBufferPointer - startOffset); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Render lines. | ||||
|         /// </summary> | ||||
|         /// <param name="call">The draw call to generate.</param> | ||||
|         /// <param name="lines">The lines command.</param> | ||||
|         private void RenderLine(ref QuikDrawCall call, QuikCommandLines lines) | ||||
|         { | ||||
|              | ||||
|             // Skip over stipple patterns for now. | ||||
|             QuikStrokeStyle style = lines.Style ?? Context.DefaultStroke; | ||||
|             QuikVertex baseVertex = new QuikVertex() { Color = style.Color }; | ||||
|             bool isStart; | ||||
|             bool isEnd; | ||||
|             short startOffset = (short)_elementBufferPointer; | ||||
|             short lastStartIndex = 0; | ||||
|             short lineStartIndex; | ||||
|             QuikVec2 normal; | ||||
|             int resolution = GetRoundingResolution(style.Width, MathF.PI); | ||||
| 
 | ||||
|             for (int i = 0; i < lines.Lines.Length; i++) | ||||
|             { | ||||
|                 QuikLine line = lines.Lines[i]; | ||||
| 
 | ||||
|                 isStart = i == 0 || line.Start != lines.Lines[i - 1].End; | ||||
|                 isEnd = i == lines.Lines.Length - 1 || line.End != lines.Lines[i + 1].Start; | ||||
|                  | ||||
|                 GenerateLineSegment(baseVertex, line, style.Width, out lineStartIndex, out normal); | ||||
| 
 | ||||
|                 if (isStart) | ||||
|                 { | ||||
|                     GenerateStartCap(baseVertex, line.Start, normal, style.Width, resolution, lineStartIndex, | ||||
|                         (short)(lineStartIndex + 1)); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     QuikLine prev = lines.Lines[i - 1]; | ||||
|                     QuikVec2 prevTangent = (prev.End - prev.Start).Normalize(); | ||||
|                     QuikVec2 nextTangent = (line.End - line.Start).Normalize(); | ||||
| 
 | ||||
|                     GenerateJoint( | ||||
|                         baseVertex,  | ||||
|                         line.Start, | ||||
|                         prevTangent, | ||||
|                         nextTangent, | ||||
|                         style.Width, | ||||
|                         (short) (lastStartIndex + 2), | ||||
|                         (short) (lastStartIndex + 3), | ||||
|                         lineStartIndex, | ||||
|                         (short)(lineStartIndex + 1)); | ||||
|                 } | ||||
|                  | ||||
|                 if (isEnd) | ||||
|                 { | ||||
|                     GenerateEndCap(baseVertex, line.End, normal, style.Width, resolution, (short)(lineStartIndex + 2), (short)(lineStartIndex + 3)); | ||||
|                 } | ||||
| 
 | ||||
|                 lastStartIndex = lineStartIndex; | ||||
|             } | ||||
| 
 | ||||
|             call.Offset = (short) (startOffset * 2); | ||||
|             call.Count = (short) (_elementBufferPointer - startOffset); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -127,27 +127,34 @@ void main() | ||||
|                  | ||||
|                 Matrix4 matrix = Matrix4.CreateOrthographicOffCenter( | ||||
|                     0, | ||||
|                     window.Size.X, | ||||
|                     (float)window.Size.X / 2, | ||||
|                     0, | ||||
|                     window.Size.Y, | ||||
|                     (float)window.Size.Y / 2, | ||||
|                     1,  | ||||
|                     -1); | ||||
|                 GL.UniformMatrix4(loc, false, ref matrix); | ||||
| 
 | ||||
|                 context.DefaultStroke.Color = new QuikColor(40, 128, 60, 255); | ||||
|                  | ||||
|                 context.Draw.Line( | ||||
|                     new QuikLine() | ||||
|                     { | ||||
|                         Start = new QuikVec2() | ||||
|                         { | ||||
|                             X = 20, | ||||
|                             Y = 40 | ||||
|                         }, | ||||
|                         End = new QuikVec2() | ||||
|                         { | ||||
|                             X=100, | ||||
|                             Y=100 | ||||
|                         } | ||||
|                     }); | ||||
|                     // > | ||||
|                     new QuikLine(10,10, 20, 20), | ||||
|                     new QuikLine(20, 20, 10, 30), | ||||
|                      | ||||
|                     // s | ||||
|                     new QuikLine(28, 10, 38, 10), | ||||
|                     new QuikLine(38, 10, 38, 20), | ||||
|                     new QuikLine(38, 20, 28, 20), | ||||
|                     new QuikLine(28, 20, 28, 30), | ||||
|                     new QuikLine(28, 30, 38, 30), | ||||
|                      | ||||
|                     // e | ||||
|                     new QuikLine(64, 20, 74, 20), | ||||
|                     new QuikLine(74, 20, 74, 30), | ||||
|                     new QuikLine(74, 30, 64, 30), | ||||
|                     new QuikLine(64, 30, 64, 10), | ||||
|                     new QuikLine(64, 10, 74, 10) | ||||
|                     ); | ||||
| 
 | ||||
|                 QuikCommand command; | ||||
|                 while (context.Draw.Commands.TryDequeue(out command)) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user