/// <summary>The length of this path.</summary> public float Length() { float length = 0f; VectorPoint current = FirstPathNode; while (current != null) { if (current.HasLine) { VectorLine line = current as VectorLine; length += line.Length; } // Hop to the next one: current = current.Next; } return(length); }
public void GetVertices(Vector3[] vertices, Vector3[] normals, float accuracy, float offsetX, float offsetY, float scale, ref int index, List <int> contourStarts) { // We need to know where index starts at: int offset = index; // Next, we must consider all extra points caused by curves: VectorPoint current = FirstPathNode; if (current != null) { contourStarts.Add(0); } while (current != null) { if (current.IsCurve) { // It's a curve - get the line length: VectorLine line = current as VectorLine; float length = line.Length; int count = (int)(length / accuracy); if (count > 0) { float deltaC = 1f / (count + 1); float c = deltaC; for (int i = 0; i < count; i++) { // Read curve at c: float x; float y; line.SampleAt(c, out x, out y); vertices[index] = new Vector3(offsetX + (x * scale), offsetY + (y * scale), 0f); //normals[index]=new Vector3(current.NormalX,current.NormalY,0f); index++; c += deltaC; } } } if (current.IsClose) { // Immediately following current is the next first node, if it exists. if (current.Next != null) { // Great, add it: contourStarts.Add(index - offset); } } else { vertices[index] = new Vector3(offsetX + (current.X * scale), offsetY + (current.Y * scale), 0f); //normals[index]=new Vector3(current.NormalX,current.NormalY,0f); index++; } // Hop to the next one: current = current.Next; } }
/// <summary>Gets the number of verts/tris to use.</summary> public int GetVertCount(VectorPath path, out int triCount) { // Hole sort it if needed: path.HoleSort(); if (path.Width == 0f) { path.RecalculateMeta(); } // How many samples? int samples = 0; triCount = 0; int moveToCount = 0; float accuracy = TextureCameras.Accuracy; VectorPoint current = path.FirstPathNode; while (current != null) { if (current.IsClose || current.Next == null) { moveToCount--; } if (!current.HasLine) { // Ignore moveto's - Hop to the next one: moveToCount++; current = current.Next; continue; } if (current.IsCurve || !TextureCameras.SD) { // It's a curve (or a HD line) - get the line length: VectorLine line = current as VectorLine; float length = line.Length; // And just add on extra points: int count = (int)(length / accuracy); if (count <= 0) { count = 1; } samples += count; // Anything that isn't a moveto also has 6 additional triangle indices (2 tris): triCount += count * 6; } else { // Add the end node: samples++; // Anything that isn't a moveto also has 6 additional triangle indices (2 tris): triCount += 6; } // Hop to the next one: current = current.Next; } // Each sample point has an associated line. // Each line generates 2 vertices and 2 triangles. int vertCount = samples * 2; triCount += samples * 2 * 3; // Triangulation set next. int triangulatedVerts = 0; current = path.FirstPathNode; while (current != null) { if (current.HasLine && current.IsCurve) { VectorLine line = current as VectorLine; int extraPoints = (int)(line.Length / TextureCameras.Accuracy); if (extraPoints <= 0) { extraPoints = 1; } triangulatedVerts += extraPoints; } else { triangulatedVerts++; } if (current.IsClose || current.Next == null) { // End of a main contour. vertCount += triangulatedVerts; if (triangulatedVerts > 2) { triCount += (triangulatedVerts - 2) * 3; } triangulatedVerts = 0; } // Hop to the next one: current = current.Next; } // For each MoveToPair (moveToCount/2), add 2 tri's [Completes the shape]: if (moveToCount != 0) { moveToCount = moveToCount >> 1; triCount += 2 * 3 * moveToCount; } return(vertCount); }
public void BuildMesh(float xOffset, float yOffset, TextureCamera camera) { // Hole sort it if needed: Path.HoleSort(); // How many samples? int samples = 0; int triCount = 0; int moveToCount = 0; float accuracy = TextureCameras.Accuracy; VectorPoint current = Path.FirstPathNode; while (current != null) { if (current.IsClose || current.Next == null) { moveToCount--; } if (!current.HasLine) { // Ignore moveto's - Hop to the next one: moveToCount++; current = current.Next; continue; } if (current.IsCurve || !TextureCameras.SD) { // It's a curve (or a HD line) - get the line length: VectorLine line = current as VectorLine; float length = line.Length; // And just add on extra points: int count = (int)(length / accuracy); if (count <= 0) { count = 1; } samples += count; // Anything that isn't a moveto also has 6 additional triangle indices (2 tris): triCount += count * 6; } else { // Add the end node: samples++; // Anything that isn't a moveto also has 6 additional triangle indices (2 tris): triCount += 6; } // Hop to the next one: current = current.Next; } // Each sample point has an associated line. // Each line generates 6 vertices and 4 triangles. int vertCount = samples * 6; triCount += samples * 4 * 3; // Triangulation set next. int triangulatedVerts = 0; current = Path.FirstPathNode; while (current != null) { if (current.HasLine && current.IsCurve) { VectorLine line = current as VectorLine; int extraPoints = (int)(line.Length / TextureCameras.TriangulationAccuracy); if (extraPoints <= 0) { extraPoints = 1; } triangulatedVerts += extraPoints; } else { triangulatedVerts++; } if (current.IsClose || current.Next == null) { // End of a main contour. vertCount += triangulatedVerts; if (triangulatedVerts > 2) { triCount += (triangulatedVerts - 2) * 3; } triangulatedVerts = 0; } // Hop to the next one: current = current.Next; } camera.Triangulator.Clockwise = true; Mesh = TextureCameras.GetBuffer(); // For each MoveToPair (moveToCount/2), add 4 tri's [2 tris for each "gap"]: if (moveToCount != 0) { moveToCount = moveToCount >> 1; triCount += 12 * moveToCount; } Mesh.RequireSize(vertCount, triCount); // Map offsets: xOffset += OffsetX * Mesh.XScaleFactor; yOffset += OffsetY * Mesh.YScaleFactor; // Let's get generating! Mesh.AddMesh(Path, xOffset - ((float)X * 0.1f), yOffset + ((float)Y * 0.1f), camera.Triangulator); }
/// <summary>Converts this path to straight lines only. /// Accuracy is the approx average length of each line segment.</summary> public void ToStraightLines(float accuracy) { if (Width == 0f) { // Calc lengths etc: RecalculateBounds(); } MoveToPoint prevMoveTo = null; VectorPoint point = FirstPathNode; while (point != null) { // If it's straight/ a MoveTo, skip: if (point.IsCurve) { VectorLine line = point as VectorLine; // Replace it with n line segments: int segmentCount = (int)(line.Length / accuracy); if (segmentCount < 1) { segmentCount = 1; } // Setup: float delta = 1f / (float)segmentCount; float progress = delta; // Sample it segmentCount times: VectorPoint previous = point.Previous; for (int i = 0; i < segmentCount; i++) { float x; float y; line.SampleAt(progress, out x, out y); // Create line segment: StraightLinePoint slp = new StraightLinePoint(x, y); slp.Previous = previous; if (previous == null) { FirstPathNode = slp; } else { previous.Next = slp; } previous = slp; progress += delta; } // Increase node count: PathNodeCount += segmentCount - 1; // Link up after too: if (point.Next == null) { LatestPathNode = previous; } else { point.Next.Previous = previous; } if (point.IsClose) { previous.IsClose = true; if (prevMoveTo != null) { prevMoveTo.ClosePoint = previous; } } } else if (point is MoveToPoint) { prevMoveTo = point as MoveToPoint; } // Next one: point = point.Next; } // Recalc: RecalculateBounds(); }