public static void Silhouette(SplineSys spline, MatrixWorld matrix, bool strokePrepared = false) /// 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 an empty matrix (can use matrix with the stroke, in this case strokePrepared should be set to true) { if (!strokePrepared) { Stroke(spline, matrix, white: true, intensity: 0.5f, antialiased: false, padOnePixel: false); } CoordRect rect = matrix.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 (matrix.arr[pos] < 0.01f) //free from stroke and fill { Vector3 pixelPos = matrix.PixelToWorld(x, z, center: true); bool handness = spline.Handness(pixelPos) >= 0; matrix.PaintBucket(new Coord(x, z), handness ? 0.75f : 0.25f); } } } }
public static void Silhouette(SplineSys spline, 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 { 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 { Vector3 pixelPos = dstMatrix.PixelToWorld(x, z, center: true); bool handness = spline.Handness(pixelPos) >= 0; 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 Silhouette(SplineSys spline, MatrixWorld matrix) /// Fills all pixels within closed spline with 1, and all outer pixels with 0 /// Pixels directly in the spline are filled with 0.5 /// Internally strokes matrix first { Stroke(spline, matrix, white: true, intensity: 0.5f, antialiased: false, padOnePixel: false); Silhouette(spline, matrix, matrix); }
public static void FloorSplines(SplineSys dst, MatrixWorld heights) { foreach (Line line in dst.lines) { for (int s = 0; s < line.segments.Length; s++) { line.segments[s].start.pos.y = FloorPoint(line.segments[s].start.pos, heights); } line.segments[line.segments.Length - 1].end.pos.y = FloorPoint(line.segments[line.segments.Length - 1].end.pos, heights); } }
public SplineSysWithPrefab(SplineSys src) { CopyLinesFrom(src.lines); scale = 1f; spacing = 1f; guiDrawNodes = src.guiDrawNodes; guiDrawSegments = src.guiDrawSegments; guiDrawDots = src.guiDrawDots; guiDotsCount = src.guiDotsCount; guiDotsEquidist = src.guiDotsEquidist; }
public void SetObject(IOutlet <object> outlet, TileData data) { if (data == null) { return; } this.splineSys = (SplineSys)data.products[outlet]; this.worldPos = data.area.active.worldPos; this.worldSize = data.area.active.worldSize; this.worldHeight = data.globals.height; Stage = PreviewStage.Generating; ThreadManager.Enqueue(ExecuteInThread, priority: -1000); }
public static void Stroke(SplineSys spline, MatrixWorld matrix, bool white = false, float intensity = 1, bool antialiased = false, bool padOnePixel = false) /// Draws a line on matrix /// White will fill the line with 1, when disabled it will use spline height /// PaddedOnePixel works similarly to AA, but fills border pixels with full value (to create main tex for the mask) { foreach (Line line in spline.lines) { for (int s = 0; s < line.segments.Length; s++) { int numSteps = (int)(line.segments[s].length / matrix.PixelSize.x * 0.1f + 1); Vector3 startPos = line.segments[s].start.pos; Vector3 prevCoord = matrix.WorldToPixelInterpolated(startPos.x, startPos.z); float prevHeight = white ? intensity : (startPos.y / matrix.worldSize.y); for (int i = 0; i < numSteps; i++) { float percent = numSteps != 1 ? 1f * i / (numSteps - 1) : 1; Vector3 pos = line.segments[s].GetPoint(percent); float posHeight = white ? intensity : (pos.y / matrix.worldSize.y); pos = matrix.WorldToPixelInterpolated(pos.x, pos.z); matrix.Line( new Vector2(prevCoord.x, prevCoord.z), new Vector2(pos.x, pos.z), prevHeight, posHeight, antialised: antialiased, paddedOnePixel: padOnePixel, endInclusive: i == numSteps - 1); prevCoord = pos; prevHeight = posHeight; } } } }
// TODO we could just use this to level the final objects rather than the horror-story ray casts. // public float terrainHeight; //to get relative object height (since all of the terrain data is 0-1). //TODO: maybe move it to HeightData in "Height in meters" task // TODO we could limit the perframe activities mid-spawn // public int objsPerIteration = 500; public void Apply(Terrain terrain) { // unless there is no spline data if (splines == null || splines.Count == 0 || splines[0].lines.Length == 0) { return; } // By this point this should absolutely exist - int totalNumberOfListsOfSplineMeshSplines = splines.Count; // There is nothing in the list if (totalNumberOfListsOfSplineMeshSplines == 0) { return; } List <GameObject> thingsToActivate = new List <GameObject>(); Coord data_area_cood = terrain.transform.parent.localPosition.ToCoord() * 0.001f; Coord locality = TownGlobalObject.GetIndexAtCoord(data_area_cood); // SplinePowerExtended var DynamicHolder = TownHolder.Instance.MapMagicObjectReference.transform.Find(string.Format("Tile {0},{1}", data_area_cood.x, data_area_cood.z)); // Create splines holder var splineHolder = new GameObject { name = "SPLINE_FOR_" + string.Format("Tile_{0},{1}", data_area_cood.x, data_area_cood.z) }; splineHolder.transform.parent = DynamicHolder; splineHolder.transform.localPosition = new Vector3(); Coord tilecoord = splineHolder.transform.parent.GetComponent <TerrainTile>().coord; // We walk over the nodes assuming pairs? for (int i = 0; i < totalNumberOfListsOfSplineMeshSplines; i++) { SplineSys spline = splines[i]; var myarray = new List <SplineMesh.SplineNode>(); // No splines for us... if (spline.NodesCount == 0) { continue; } var global = new List <SplineNode>(); var positionalFactor = 1f; myarray = new List <SplineNode>(); SplineNode refnode = new SplineNode(Vector3.positiveInfinity, Vector3.positiveInfinity); SplineNode startnode = refnode; SplineNode endnode = refnode; Segment lastSegment = new Segment(); Segment thissegment = new Segment(); lastSegment.end.pos = thissegment.start.pos = Vector3.positiveInfinity; foreach (var road in spline.lines.Reverse()) { if (!splines[i].mergeSegments) { myarray = new List <SplineNode>(); } foreach (var current in road.segments) { // We need to check if the last segments end connects to the next segments start or RenderOutSplinesSoFar; thissegment = road.segments.Where(x => x.GetHashCode() == current.GetHashCode()).First(); thissegment.start.pos -= DynamicHolder.transform.localPosition; thissegment.end.pos -= DynamicHolder.transform.localPosition; if (splines[i].mergeSegments) { // Render out the segments if they are far apart (square root of 200) - have some data get parsed - and have been selected for merging if (Vector3.SqrMagnitude(lastSegment.end.pos - thissegment.start.pos) > 200f && myarray.Count > 1) { RenderOutSplinesSoFar(splineHolder, i, myarray); myarray = new List <SplineNode>(); } } lastSegment = thissegment; // setup bool fence for list. // add start if we didnt. bool startExists = global.Exists(element => element.Position == thissegment.start.pos * positionalFactor); if (!startExists) { startnode = new SplineMesh.SplineNode(thissegment.start.pos * positionalFactor, thissegment.start.pos * positionalFactor); myarray.Add(startnode); global.Add(startnode); } // and add end if we didnt. bool endExists = global.Exists(element => element.Position == thissegment.end.pos * positionalFactor); if (!endExists) { endnode = new SplineMesh.SplineNode(thissegment.end.pos * positionalFactor, thissegment.end.pos * positionalFactor); myarray.Add(endnode); global.Add(endnode); } } if (myarray.Count == 0) { continue; } if (myarray.Count == 1) { // give us two by hook or crook if (myarray.Contains(startnode)) { endnode = new SplineMesh.SplineNode(lastSegment.end.pos * positionalFactor, lastSegment.end.pos * positionalFactor); myarray.Add(endnode); } else { startnode = new SplineMesh.SplineNode(lastSegment.start.pos * positionalFactor, lastSegment.start.pos * positionalFactor); myarray.Add(startnode); } continue; } if ((myarray[1].Position - myarray[0].Position).sqrMagnitude == 0) { continue; } // Render out as just segment node pairs if (!splines[i].mergeSegments) { RenderOutSplinesSoFar(splineHolder, i, myarray); } } // Attempt to merge near pairs if (splines[i].mergeSegments) { RenderOutSplinesSoFar(splineHolder, i, myarray); } } }
public SplineSysWrapper() { this.splineSys = new SplineSys(); // this.name = string.Empty; }
public SplineSysWrapper(string name, SplineSys sys, string outletname) { this.outletName = outletname; this.splineSys = new SplineSys(sys); this.name = name; }
public SplineSysWrapper(string name, SplineSys sys, MapMagic.Nodes.Outlet <SplineSys> outlet) { this.outlet = outlet; this.splineSys = new SplineSys(sys); this.name = name; }
public SplineSysWrapper(string name, SplineSys sys) { this.splineSys = new SplineSys(sys); this.name = name; }
public SplineSysWrapper(SplineSys sys, MapMagic.Nodes.Outlet <SplineSys> outlet) { this.splineSys = new SplineSys(sys); this.outlet = outlet; }
public SplineSysWrapper(SplineSys sys) { this.splineSys = new SplineSys(sys); }
public SplineSysWrapper(string name) { this.splineSys = new SplineSys(); this.name = name; }
public static ITestInput CreateTestInput(GameObject go, IInlet <SplineSys> inlet, SplineSys splineSys) { SplineObject splineObj = go.AddComponent <SplineObject>(); splineObj.splineSys = splineSys; SplineInout splineIn = new SplineInout() { splineObj = splineObj }; return(splineIn); }
public override void Generate(TileData data, StopToken stop) { if (!enabled) { return; } // if (data.isDraft) return; TransitionsList src = data.ReadInletProduct <TransitionsList>(this); TransitionsList copy = new TransitionsList(src); RemoveAnyBlanksInTransitionListArrayHelper(ref copy); // nodes for spline List <Vector3> markers = new List <Vector3>(copy.count); // setup the clamp mask var tileLocation = data.area.Coord.ToVector3(1000); // x 0 z var tileLocationV2 = tileLocation.V2(); // x z var tileSize = new Vector3(1000, 500, 1000); // TODO: Set this to the mapmagic tile size... not assume 1k // now magically create perfect size slices for this tile. Thanks Denis. // dst.Clamp(tileLocation, tileSize); //data - whatever data foreach (var item in copy.arr) { Vector2 offsetted = (item.pos.V2() + tileLocationV2); var offsettedstore = new Vector3(offsetted.x, item.pos.y, offsetted.y); if (!markers.Contains(offsettedstore)) { try { markers.Add(offsettedstore); } catch (Exception e) { Debug.LogErrorFormat(" Edge case {0} with location {1},{2},{3} and a list of Length {4}", e.Message, offsettedstore.x, offsettedstore.y, offsettedstore.z, markers.Count); // ignore this weird edge case. } } } // add the first one again, as a node. for a loop. and to ensure we have two.. which we will now test for.. markers.Add(markers[0]); // there was one object ONLY... if (markers[0] == markers[1]) { // this will just give is an N/A rather than bombing. Debug.LogErrorFormat(" Please add at least TWO objects"); return; } // make some holders SplineSys spline = new SplineSys(); Line line = new Line(); line.SetNodes(markers.ToArray()); spline.AddLine(line); // now magically create perfect size slices for this tile. Thanks Denis. spline.Clamp(tileLocation, tileSize); //save it. data.StoreProduct(this, spline); }