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 override void Generate(TileData data, StopToken stop) { MatrixWorld matrix = new MatrixWorld(data.area.full.rect, data.area.full.worldPos, data.area.full.worldSize, data.globals.height); for (int x = matrix.rect.offset.x; x < matrix.rect.offset.x + matrix.rect.size.x; x++) { for (int z = matrix.rect.offset.z; z < matrix.rect.offset.z + matrix.rect.size.z; z++) { matrix[x, z] = grid * (x % 2) * (z % 2); } } if (interpolated) { Vector3 vec = matrix.WorldToPixelInterpolated(pos.x, pos.z); Coord coord = Coord.Floor((Vector2D)vec); matrix[coord] = level; matrix[coord.x + 1, coord.z] = level * 0.75f; matrix[coord.x, coord.z + 1] = level * 0.5f; matrix[coord.x + 1, coord.z + 1] = level * 0.25f; Vector3 retVec = matrix.PixelToWorld(vec.x, vec.z); DebugGizmos.DrawDot("WorldToPixelTest", retVec, 6, Color.green); } else { Coord coord = matrix.WorldToPixel(pos.x, pos.z); matrix[coord] = level; Vector3 retVec = matrix.PixelToWorld(coord.x, coord.z); DebugGizmos.DrawDot("WorldToPixelTest", retVec, 6, Color.green); } data.StoreProduct(this, matrix); }
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); } }
private void DrawField() { Gizmos.color = Color.green; Gizmos.DrawLine(bottomLeft, bottomRight); Gizmos.DrawLine(topLeft, topRight); Gizmos.DrawLine(bottomLeft, topLeft); Gizmos.DrawLine(bottomRight, topRight); DebugGizmos.DrawX(mouseReticle, .1f * factor, mainCamera.transform, Color.red, 0); }
public void Push(Vector3[] points, float[] ranges, float intensity = 1, float nodesPointsRatio = 0, bool horizontalOnly = true) /// Moves points away from the segment so that they lay no closer than range /// If nodesPointsRatio = 0 pushing nodes only, if 1 - pushing points only /// Changes the points array (if nodesPointsRatio!=0) /// DistFactor multiplies the range to move point (for iteration push it should be less than 1) { for (int n = 0; n < nodes.Length - 1; n++) { Vector3 min = Vector3.Min(nodes[n], nodes[n + 1]); Vector3 max = Vector3.Max(nodes[n], nodes[n + 1]); float length = (nodes[n] - nodes[n + 1]).magnitude; Vector3 start = nodes[n]; //will change the nodes position, thus keeping original values Vector3 end = nodes[n + 1]; for (int p = 0; p < points.Length; p++) { Vector3 point = points[p]; float range = ranges[p]; if (min.x > point.x + range || max.x < point.x - range || min.z > point.z + range || max.z < point.z - range || (!horizontalOnly && (min.y > point.y + range || max.y < point.y - range))) { continue; } Vector3 closestPoint = PointNearestToPos(point, start, end); closestPoint = ClampPointToSegment(closestPoint, start, end); float percent = (closestPoint - start).magnitude / length; percent = 2 * percent * percent * percent - 3 * percent * percent + 2 * percent; DebugGizmos.DrawLine("Push1", start, end); DebugGizmos.DrawDot("Push", closestPoint, 6); Vector3 pushVector = PushVector(point, closestPoint, range, horizontalOnly) * intensity; points[p] += pushVector * nodesPointsRatio; float pStart = (1 - percent) * 2; if (pStart > 1) { pStart = 1; } nodes[n] -= pushVector * (1 - nodesPointsRatio) * pStart; float pEnd = percent * 2; if (pEnd > 1) { pEnd = 1; } nodes[n + 1] -= pushVector * (1 - nodesPointsRatio) * pEnd; } } }
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); } }
private void OnDrawGizmos() { if (Application.isPlaying) { Gizmos.color = Color.red; Gizmos.DrawLine(bottomLeft, bottomRight); Gizmos.DrawLine(topLeft, topRight); Gizmos.DrawLine(bottomLeft, topLeft); Gizmos.DrawLine(bottomRight, topRight); DebugGizmos.DrawX(center, .1f * factor, mainCamera.transform, Color.red); DebugGizmos.DrawX(crosshair, .2f * factor, mainCamera.transform, Color.yellow); Vector3 cameraToCrosshair = (crosshair - mainCamera.transform.position).normalized; Gizmos.DrawRay(crosshair, cameraToCrosshair * 10); } }
private static float GetNodeWeight(Vector3 prev, Vector3 node, Vector3 next, SerpentineFactors factors, float maxHeight) /// returns node candidate rating 0-infinity, lower is better { //incline Vector3 prevDelta = prev - node; float prevHorDist = ((Vector2D)prevDelta).Magnitude; float prevElevation = prevDelta.y > 0 ? prevDelta.y : -prevDelta.y; float prevIncline = prevElevation / prevHorDist; Vector3 nextDelta = node - next; float nextHorDist = ((Vector2D)nextDelta).Magnitude; float nextElevation = nextDelta.y > 0 ? nextDelta.y : -nextDelta.y; float nextIncline = nextElevation / nextHorDist; float inclineRating = prevIncline > nextIncline ? prevIncline : nextIncline; //0 (planar), 1 (45 degree), to infinity (90 degree) inclineRating = 1 - Mathf.Atan(inclineRating) / (Mathf.PI / 2f); //1 (planar), 0.5 (45 degree), 0 (90 degree) //inclineRating *= inclineRating; //length Vector2D vec = ((Vector2D)(prev - next)).Normalized; float prevDot = Vector2D.Dot(vec, ((Vector2D)(node - prev)).Normalized); float nextDot = Vector2D.Dot(vec, ((Vector2D)(node - next)).Normalized); float length = ((Vector2D)(prev - next)).Magnitude; float nLength = ((Vector2D)(prev - node)).Magnitude + ((Vector2D)(node - next)).Magnitude; float lengthRating = length / nLength; //1 (straight), 0.7071 (90 degree), 0 (sharp corner) //lengthRating *= lengthRating; //height float heightRating = node.y / maxHeight; if (factors.height < 0) { heightRating = 1 - heightRating; } // if (lengthFactor < 1) lengthFactor = 1; //now 1 to 2 only // lengthFactor -= 1; //now 0 to 1; // if (lengthFactor == 1) lengthFactor = float.MaxValue; // else lengthFactor = 1 / (1-lengthFactor); //now 0 to infinity float rating = inclineRating * factors.incline + lengthRating * factors.length + heightRating * Mathf.Abs(factors.height); //Mathf.Pow(inclineRating, (1-factors.incline)) * Mathf.Pow(lengthRating, (1-factors.length)); if (tmpIteration == tmpHighlightIteration && tmpNode == tmpHighlightNode) { DebugGizmos.DrawLabel("Serp", node, "Node:" + tmpNode + " var:" + tmpVariant + "\nInc:" + inclineRating.ToString() + "(" + prevIncline.ToString() + ", " + nextIncline.ToString() + ")" + "\nLen:" + lengthRating.ToString() + //"(" + length + ", " + nLength + ")" + "\nSum:" + rating.ToString(), additive: true); DebugGizmos.DrawLine("Serp", node, prev, Color.red, additive: true); DebugGizmos.DrawDot("Serp", node, 6, Color.red, additive: true); } return(rating); }
private void OnEnable() { targetScript = target as DebugGizmos; gameObject = targetScript.gameObject; GetValues(); }
public void Update() { DebugGizmos.DrawWireSphere(transform.position, Level * ExplosionRadiusPerLevel, Color.red); }
/// <summary> Executes the enable action. </summary> /// /// <remarks> Dave, 10/26/2014. </remarks> #endregion private void OnEnable() { targetScript = target as DebugGizmos; gameObject = targetScript.gameObject; GetValues(); }