public static void Silhouette(Spline[] splines, MatrixWorld strokeMatrix, MatrixWorld dstMatrix) /// Fills all pixels within closed spline with 1, and all outer pixels with 0 /// Pixels directly in the spline are filled with 0.5 /// Requires the matrix with line stroked. StrokeMatrix and DstMatrix could be the same { DebugGizmos.Clear("Slhuette"); if (strokeMatrix != dstMatrix) { dstMatrix.Fill(strokeMatrix); } //and then using dst matrix only CoordRect rect = dstMatrix.rect; Coord min = rect.Min; Coord max = rect.Max; for (int x = min.x; x < max.x; x++) { for (int z = min.z; z < max.z; z++) { int pos = (z - rect.offset.z) * rect.size.x + x - rect.offset.x; if (dstMatrix.arr[pos] < 0.01f) //free from stroke and fill { Vector2D pixelPos = (Vector2D)dstMatrix.PixelToWorld(x, z); bool handness = Spline.Handness(splines, pixelPos) >= 0; DebugGizmos.DrawDot("Slhuette", (Vector3)pixelPos, 6, color: handness ? Color.red : Color.green, additive: true); dstMatrix.PaintBucket(new Coord(x, z), handness ? 0.75f : 0.25f); } } } }
public void ProcessToFloor(Inlet <SplineSys> splineIn, Outlet <SplineSys> splineOut, TileData data, StopToken stop) { SplineSys src = data.ReadInletProduct(splineIn); MatrixWorld heights = data.ReadInletProduct(heightIn); if (src == null) { return; } if (!enabled || heights == null) { data.StoreProduct(splineOut, src); return; } if (stop != null && stop.stop) { return; } SplineSys dst = new SplineSys(src); FloorSplines(dst, heights); dst.Update(); if (stop != null && stop.stop) { return; } data.StoreProduct(splineOut, dst); DebugGizmos.Clear("Spline"); foreach (Segment segment in dst.lines[0].segments) { DebugGizmos.DrawLine("Spline", segment.start.pos, segment.end.pos, Color.white, additive: true); } }
public static void Serpentine(MatrixWorld heights, Spline spline, float segLength, int iterations, SerpentineFactors factors) { DebugGizmos.Clear("Serp"); factors.Normalize(); float DistFn(Vector3 n1, Vector3 n2) => Mathf.Sqrt((n1.x - n2.x) * (n1.x - n2.x) + (n1.z - n2.z) * (n1.z - n2.z)); for (int i = 0; i < iterations; i++) { tmpIteration = i; tmpHighlightIteration = iterations - 1; spline.SubdivideDist(segLength, DistFn); Floor(heights, spline); CoordRect rect = heights.rect; Coord rectMin = heights.rect.offset; Coord rectMax = heights.rect.offset + heights.rect.size; float pixelSize = heights.PixelSize.x; Vector3[] newNodes = new Vector3[spline.nodes.Length]; for (int n = 1; n < spline.nodes.Length - 1; n++) { //if (n>2) { newNodes[n]=spline.nodes[n]; continue; } tmpNode = n; float weight = GetNodeWeight(spline.nodes[n - 1], spline.nodes[n], spline.nodes[n + 1], factors, heights.worldSize.y); Vector3 moveVector = GetMoveVector(heights, spline.nodes[n - 1], spline.nodes[n], spline.nodes[n + 1], weight, 1, heights.PixelSize.x, factors); newNodes[n] = spline.nodes[n] + moveVector * 3f; //*heights.PixelSize*0.2f;// * (2f/iterations); if (tmpHighlightIteration == i) { DebugGizmos.DrawRay("Serp", newNodes[n], moveVector, Color.yellow, additive: true); } } newNodes[0] = spline.nodes[0]; newNodes[newNodes.Length - 1] = spline.nodes[spline.nodes.Length - 1]; spline.nodes = newNodes; spline.Weld(segLength / 2, DistFn); } }
public static void SerpentineUnordered(MatrixWorld heights, Spline spline, float segLength, int iterations, SerpentineFactors factors) { DebugGizmos.Clear("Serp"); factors.Normalize(); float DistFn(Vector3 n1, Vector3 n2) => Mathf.Sqrt((n1.x - n2.x) * (n1.x - n2.x) + (n1.z - n2.z) * (n1.z - n2.z)); CoordRect rect = heights.rect; Coord rectMin = heights.rect.offset; Coord rectMax = heights.rect.offset + heights.rect.size; float pixelSize = heights.PixelSize.x; for (int i = 0; i < iterations; i++) { spline.SubdivideDist(segLength, DistFn); Floor(heights, spline); tmpIteration = i; tmpHighlightIteration = iterations - 1; //finding node with lowest rating float lowestRating = float.MaxValue; int lowestNum = 0; for (int n = 1; n < spline.nodes.Length - 1; n++) { float rating = GetNodeWeight(spline.nodes[n - 1], spline.nodes[n], spline.nodes[n + 1], factors, heights.worldSize.y); if (rating < lowestRating) { lowestRating = rating; lowestNum = n; } } tmpNode = lowestNum; float weight = GetNodeWeight(spline.nodes[lowestNum - 1], spline.nodes[lowestNum], spline.nodes[lowestNum + 1], factors, heights.worldSize.y); Vector3 moveVector = GetMoveVector(heights, spline.nodes[lowestNum - 1], spline.nodes[lowestNum], spline.nodes[lowestNum + 1], weight, 1, heights.PixelSize.x, factors); spline.nodes[lowestNum] += moveVector; //*heights.PixelSize*0.2f;// * (2f/iterations); spline.Weld(segLength / 2, DistFn); } }