public Cell(Macro.Cell macro, MicroMap map) { Macro = macro; _map = map; BlockPositions = Rasterization.ConvexToBlocks(macro.Contains, macro.Bounds); Bounds = (Bounds2i)macro.Bounds; var vertices = new List <Vector2i>(BlockPositions); foreach (var blockPosition in BlockPositions) { if (!vertices.Contains(blockPosition + Vector2i.Forward)) { vertices.Add(blockPosition + Vector2i.Forward); } if (!vertices.Contains(blockPosition + Vector2i.Right)) { vertices.Add(blockPosition + Vector2i.Right); } if (!vertices.Contains(blockPosition + Vector2i.One)) { vertices.Add(blockPosition + Vector2i.One); } } VertexPositions = vertices.ToArray(); }
/// <summary> /// Paints a contiguous selection using a four-way flood fill, overwritting only those /// positions whose parquets match those initially found at the starting position. /// </summary> /// <param name="in_start">Where to start the fill.</param> public void PaintFloodFill(Point in_start) { PaintAtLocations(Rasterization.PlotFloodFill(in_start, _currentRegion.GetDefinitionAtPosition(in_start), _currentRegion.IsValidPosition, Matches)); }
public void TestCellRasterization() { var v1 = new Vector2(1.2f, 1.5f); var v2 = new Vector2(0.55f, -1.55f); var v3 = new Vector2(-2.4f, -1.1f); var v4 = new Vector2(-0.5f, 2.3f); var h1 = new HalfPlane(v1, v2, Vector2.Zero); var h2 = new HalfPlane(v2, v3, Vector2.Zero); var h3 = new HalfPlane(v3, v4, Vector2.Zero); var h4 = new HalfPlane(v4, v1, Vector2.Zero); var isContains = new Predicate <Vector2>(p => HalfPlane.ContainsInConvex(p, new [] { h1, h2, h3, h4 })); var boundingBox = new Box2(-2.4f, 2.3f, 1.2f, -1.55f); var result = Rasterization.ConvexToBlocks(isContains, boundingBox); var correctAnswer = new[] { new Vector2i(0, 1), new Vector2i(0, 0), new Vector2i(0, -1), new Vector2i(0, -2), new Vector2i(-1, 1), new Vector2i(-1, 0), new Vector2i(-1, -1), new Vector2i(-2, 0), new Vector2i(-2, -1) }; Assert.That(result, Is.EquivalentTo(correctAnswer)); //Draw polygon //UnityEngine.Debug.DrawLine(v1, v2, Color.blue, 10); //UnityEngine.Debug.DrawLine(v2, v3, Color.blue, 10); //UnityEngine.Debug.DrawLine(v3, v4, Color.blue, 10); //UnityEngine.Debug.DrawLine(v4, v1, Color.blue, 10); //Draw bbox //DrawRectangle.ForDebug(); }
public void PlotEmptyRectangleCompletesSquareOutlineTest() { const int upperLeftBound = 1; const int lowerRightBound = 9; var upperLeftCorner = new Vector2Int(upperLeftBound, upperLeftBound); var lowerRightCorner = new Vector2Int(lowerRightBound, lowerRightBound); var vectors = Rasterization.PlotEmptyRectangle(upperLeftCorner, lowerRightCorner, a => { return(true); }); for (var x = upperLeftBound; x <= lowerRightBound; x++) { var position = new Vector2Int(x, upperLeftBound); Assert.True(vectors.Remove(position)); position = new Vector2Int(x, lowerRightBound); Assert.True(vectors.Remove(position)); } for (var y = upperLeftBound + 1; y < lowerRightBound; y++) { var position = new Vector2Int(upperLeftBound, y); Assert.True(vectors.Remove(position)); position = new Vector2Int(lowerRightBound, y); Assert.True(vectors.Remove(position)); } Assert.Empty(vectors); }
/// <summary> /// Paints a contiguous selection using a four-way flood fill, overwritting only those /// positions whose parquets match those initially found at the starting position. /// </summary> /// <param name="in_start">Where to start the fill.</param> public void PaintFloodFill(Vector2Int in_start) { PaintAtLocations(Rasterization.PlotFloodFill(in_start, _currentRegion.GetAllParquetsAtPosition(in_start), _currentRegion.IsValidPosition, Matches)); }
public void DrawMesh(Rasterization rasterizer, VertexProcessor processor, Light l) { //Представление вершины в пространстве. for (int i = 0; i < indexes.Count; i += 3) { rasterizer.Triangle(processor.tr(vertexes[indexes[i]].position), processor.tr(vertexes[indexes[i + 1]].position), processor.tr(vertexes[indexes[i + 2]].position), vertexes[indexes[i]], vertexes[indexes[i + 1]], vertexes[indexes[i + 2]], l, processor); } }
public void TestLineRasterization() { var from = (Vector2i) new Vector2(-3.52f, -4.14f); var to = (Vector2i) new Vector2(-2.32f, -2.48f); var rasterize = Rasterization.lineNoDiag(from.X, from.Z, to.X, to.Z); //var rasterize = Rasterization.DDA((Vector2i)new Vector2(-3.52f, -4.14f), (Vector2i)new Vector2(-2.32f, -2.48f), true); //var rasterize = Rasterization.BresenhamInt((Vector2i)new Vector2(-3.52f, -4.14f), (Vector2i)new Vector2(-2.32f, -2.48f)); Assert.That(rasterize, Is.EquivalentTo(new[] { new Vector2i(-4, -5), new Vector2i(-4, -4), new Vector2i(-3, -4), new Vector2i(-3, -3) })); }
public void PlotFloodFillTest() { const int location = 1; const int target = 0; var fillLayer = new[, ] { { 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 1 }, { 1, 0, 2, 0, 0, 1 }, { 1, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1 } }; var start = new Vector2Int(location, location); bool IsVaild(Vector2Int in_position) { return(in_position.X >= 0 && in_position.X <= fillLayer.Length && in_position.Y >= 0 && in_position.Y <= fillLayer.Length); } bool Matches <T>(Vector2Int in_position, T in_matchAgainst) where T : struct { var matchAgainst = Convert.ToInt32(in_matchAgainst); return(fillLayer[in_position.Y, in_position.X] == matchAgainst); } int CountAllTargets(int[,] in_array) { var count = 0; foreach (var item in in_array) { if (item == target) { count++; } } return(count); } var vectors = Rasterization.PlotFloodFill(start, target, IsVaild, Matches); Assert.Equal(CountAllTargets(fillLayer), vectors.Count); foreach (var vector in vectors) { Assert.Equal(target, fillLayer[vector.Y, vector.X]); } }
public void DrawMesh(Rasterization rasterizer, VertexProcessor processor, Light l) { System.Console.WriteLine("Ilosc indeksow: " + indexes.Count); for (int i = 0; i < indexes.Count; i += 3) { rasterizer.Triangle(processor.tr(vertexes[indexes[i]].position), processor.tr(vertexes[indexes[i + 1]].position), processor.tr(vertexes[indexes[i + 2]].position), vertexes[indexes[i]], vertexes[indexes[i + 1]], vertexes[indexes[i + 2]], l, processor); stream.WriteLine("Indeks: " + indexes[i] + " " + indexes[i + 1] + " " + indexes[i + 2]); stream.WriteLine("Wierzchołki: " + vertexes[indexes[i]].position.ToString() + " | " + vertexes[indexes[i + 1]].position.ToString() + " | " + vertexes[indexes[i + 2]].position.ToString()); } stream.Close(); }
public IEnumerable <Vector2i> GetBlocks() { for (int i = 1; i < Cell.Vertices.Length - 1; i++) { foreach (var pos in Rasterization.Triangle(Cell.Vertices[0], Cell.Vertices[i], Cell.Vertices[i + 1])) { if (Bounds.Contains(pos)) { yield return(pos); } } } }
void OnDrawGizmos() { if (_handle1 && _handle2) { Gizmos.color = Color.white; Gizmos.DrawLine(_handle1.transform.position, _handle2.transform.position); //var p1 = new Vector2i(_handle1.transform.position.x, _handle1.transform.position.z); //var p2 = new Vector2i(_handle2.transform.position.x, _handle2.transform.position.z); var p1 = new Vector2(_handle1.transform.position.x, _handle1.transform.position.z); var p2 = new Vector2(_handle2.transform.position.x, _handle2.transform.position.z); var pi1 = (Vector2i)p1; var pi2 = (Vector2i)p2; //var points = Rasterization.DDA(p1, p2, true).ToArray(); Debug.Log("Rasterization.DDA conservative"); var pointsDDA = Rasterization.DDA(p1, p2, false).ToArray(); //var points = Rasterization.lineNoDiag(pi1.X, pi1.Z, pi2.X, pi2.Z).ToArray(); Debug.Log("Rasterization.lineNoDiag"); var pointsBresInt = Rasterization.BresenhamInt(pi1, pi2).ToArray(); var pointsBresFloat = Rasterization.BresenhamFloat(p1.X, p1.Y, p2.X, p2.Y).ToArray(); Assert.IsTrue(pointsDDA.Length == pointsDDA.Distinct().Count()); Assert.IsTrue(pointsBresInt.Length == pointsBresInt.Distinct().Count()); Assert.IsTrue(pointsBresFloat.Length == pointsBresFloat.Distinct().Count()); if (counter % 20 < 10) { foreach (var p in pointsDDA) { DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.white); } } /* * else if (counter % 21 < 14) * foreach (var p in pointsBresInt) * DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.red); */ else //if (counter % 21 >= 14) { foreach (var p in pointsBresFloat) { DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.green); } } counter++; } }
public void PlotLineCompletesStraightHorizontalLineTest() { const int leftBound = 1; const int rightBound = 10; var leftEnd = new Vector2Int(leftBound, 0); var rightEnd = new Vector2Int(rightBound, 0); var vectors = Rasterization.PlotLine(leftEnd, rightEnd, a => true); for (var x = leftBound; x <= rightBound; x++) { var position = new Vector2Int(x, 0); Assert.True(vectors.Remove(position)); } Assert.Empty(vectors); }
public void PlotLineCompletesStraightVerticalLineTest() { const int upperBound = 1; const int lowerBound = 10; var top = new Vector2Int(0, upperBound); var bottom = new Vector2Int(0, lowerBound); var vectors = Rasterization.PlotLine(top, bottom, a => { return(true); }); for (var y = upperBound; y <= lowerBound; y++) { var position = new Vector2Int(0, y); Assert.True(vectors.Remove(position)); } Assert.Empty(vectors); }
private IEnumerator FillTriangles() { for (int i = 0; i < indices.Length; i += 3) { var brush = crossBrushes[i / 3]; var color = brush.Color; foreach (var pixel in Rasterization.FillTriangle( vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], color, buffer, depth, 16, 0, 8, 0, 16)) { DrawCross(pixel.Item1, pixel.Item2, brush); yield return(null); } } }
public void PlotLineCompletesDiagonalLineWithUnitSlopeTest() { const int upperLeftBound = 1; const int lowerRightBound = 10; var upperLeftEnd = new Vector2Int(upperLeftBound, upperLeftBound); var lowerRightEnd = new Vector2Int(lowerRightBound, lowerRightBound); var vectors = Rasterization.PlotLine(upperLeftEnd, lowerRightEnd, a => { return(true); }); for (var i = upperLeftBound; i <= lowerRightBound; i++) { var position = new Vector2Int(i, i); Assert.True(vectors.Remove(position)); } Assert.Empty(vectors); }
public void PlotCircleCompletesMinimalOutlineTest() { const int location = 3; const int radius = 1; var center = new Vector2Int(location, location); var aboveCenter = new Vector2Int(location, location - 1); var leftOfCenter = new Vector2Int(location - 1, location); var rightOfCenter = new Vector2Int(location + 1, location); var belowCenter = new Vector2Int(location, location + 1); var vectors = Rasterization.PlotCircle(center, radius, false, a => { return(true); }); Assert.False(vectors.Remove(center)); Assert.True(vectors.Remove(aboveCenter)); Assert.True(vectors.Remove(leftOfCenter)); Assert.True(vectors.Remove(rightOfCenter)); Assert.True(vectors.Remove(belowCenter)); Assert.Empty(vectors); }
public IEnumerable <Vector2i> GetBlocks2() //Todo consider move to Rasterization class { var edges = new List <Vector2i>(); foreach (var edge in Cell.Edges) { edges.AddRange(Rasterization.DDA(edge.Vertex1, edge.Vertex2, false)); } var bounds = Bounds; edges = edges.Where(e => bounds.Contains(e)).Distinct().ToList(); edges.Sort(); for (int i = 0; i < edges.Count;) { if (i == edges.Count - 1) { yield return(edges.Last()); yield break; } var z1 = edges[i].Z; var j = i; while (j < edges.Count - 1 && edges[j + 1].Z == z1) { j++; } for (var x = edges[i].X; x <= edges[j].X; x++) { yield return(new Vector2i(x, z1)); } i = j + 1; } //foreach (var vector2I in edges) //{ // yield return vector2I; //} }
public Vector3?GetRayMapIntersection(Ray ray) { var from = new Vector2(ray.origin.x, ray.origin.z); var to = new Vector2(ray.GetPoint(1000).x, ray.GetPoint(1000).z); var blocks = Rasterization.DDA(from, to, true); foreach (var blockPos in blocks) { if (_settings.LandBounds.Contains(blockPos)) { var chunkPosition = Chunk.GetPosition(blockPos); Chunk chunk; if (Map.TryGetValue(chunkPosition, out chunk)) { var localPos = Chunk.GetLocalPosition(blockPos); var tr1 = new Vector3(blockPos.X, chunk.HeightMap[localPos.X, localPos.Z], blockPos.Z); var tr2 = new Vector3(blockPos.X + 1, chunk.HeightMap[localPos.X + 1, localPos.Z], blockPos.Z); var tr3 = new Vector3(blockPos.X, chunk.HeightMap[localPos.X, localPos.Z + 1], blockPos.Z + 1); var tr4 = new Vector3(blockPos.X + 1, chunk.HeightMap[localPos.X + 1, localPos.Z + 1], blockPos.Z + 1); Vector3 i; var ir = Intersections.LineTriangleIntersection(ray, tr1, tr2, tr3, out i); if (ir == 1) { return(i); } else { ir = Intersections.LineTriangleIntersection(ray, tr2, tr3, tr4, out i); if (ir == 1) { return(i); } } } } } return(null); }
/// <summary> /// Paints currently selected parquets in a circle of the given radius around the given position. /// </summary> /// <param name="in_center">The circle's center.</param> /// <param name="in_radius">The circle's radius.</param> /// <param name="in_filled"> /// If set to <c>true</c>, the circle will be filled in; otherwise, /// only the outline will be painted. /// </param> public void PaintCircle(Vector2Int in_center, int in_radius, bool in_filled) { PaintAtLocations(Rasterization.PlotCircle(in_center, in_radius, in_filled, _currentRegion.IsValidPosition)); }
public void DrawMesh(Rasterization rasterizer, VertexProcessor processor) { throw new NotImplementedException(); }
public override void Save(SaveContext saveContext) { base.Save(saveContext); var utility = saveContext.Utility; utility.Write(MaterialFlags); utility.Write((uint)TextureCoordinatesConfig); utility.Write((uint)TranslucencyKind); // NOTE: These are inline, not pointered to MaterialColor.Save(saveContext); Rasterization.Save(saveContext); FragmentOperation.Save(saveContext); // Texture coordinates utility.Write(UsedTextureCoordinates); for (var i = 0; i < TextureCoords.Length; i++) { var tc = TextureCoords[i]; utility.Write(tc.SourceCoordIndex); utility.Write((uint)tc.MappingType); utility.Write(tc.ReferenceCameraIndex); utility.Write((uint)tc.TransformType); tc.Scale.Write(utility); utility.Write(tc.Rotation); tc.Translation.Write(utility); utility.Write(tc.Flags); tc.Transform.Write(utility); } // Texture mappers for (var i = 0; i < TextureMappers.Length; i++) { saveContext.WritePointerPlaceholder(TextureMappers[i]); } saveContext.WritePointerPlaceholder(ShaderReference); saveContext.WritePointerPlaceholder(FragmentShader); utility.Write(ShaderProgramDescIndex); // NOT SUPPORTED utility.Write(ShaderParametersCount); utility.Write(ShaderParametersPointerTableOffset); if (ShaderParametersCount != 0 || ShaderParametersPointerTableOffset != 0) { throw new NotImplementedException($"ModelMaterial Save: Shader Parameters UNSUPPORTED"); } utility.Write(LightSetIndex); // Reference?? utility.Write(FogIndex); // Reference?? // NOTE -- See SPICA GfxMaterial.cs for computations involving these hash functions. // I ASSUME if I never change any values in the material these never need recomputed. // Let's try to get by without needing this support right now... utility.Write(MaterialFlagsHash); utility.Write(ShaderParamsHash); utility.Write(TextureCoordsHash); utility.Write(TextureSamplersHash); utility.Write(TextureMappersHash); utility.Write(MaterialColorsHash); utility.Write(RasterizationHash); utility.Write(FragLightHash); utility.Write(FragLightLUTHash); utility.Write(FragLightLUTSampHash); utility.Write(TextureEnvironmentHash); utility.Write(AlphaTestHash); utility.Write(FragOpHash); utility.Write(UniqueId); ///////////////////////////// // Begin saving dependent data TextureMappers.SaveList(saveContext); saveContext.SaveAndMarkReference(ShaderReference); saveContext.SaveAndMarkReference(FragmentShader); }
void OnDrawGizmos() { if (_h1 && _h2 && _h3 && _h4) { var center = (_h1.position + _h2.position + _h3.position + _h4.position) / 4; var h1 = new HalfPlane((Vector2)_h1.position, (Vector2)_h2.position, (Vector2)center); var h2 = new HalfPlane((Vector2)_h2.position, (Vector2)_h3.position, (Vector2)center); var h3 = new HalfPlane((Vector2)_h3.position, (Vector2)_h4.position, (Vector2)center); var h4 = new HalfPlane((Vector2)_h4.position, (Vector2)_h1.position, (Vector2)center); var containsCallCounter = 0; var isContains = new Predicate <Vector2>(delegate(Vector2 p) { containsCallCounter++; return(HalfPlane.ContainsInConvex(p, new [] { h1, h2, h3, h4 })); }); var bounds = new Box2( Mathf.Min(_h1.position.x, _h2.position.x, _h3.position.x, _h4.position.x), Mathf.Max(_h1.position.z, _h2.position.z, _h3.position.z, _h4.position.z), Mathf.Max(_h1.position.x, _h2.position.x, _h3.position.x, _h4.position.x), Mathf.Min(_h1.position.z, _h2.position.z, _h3.position.z, _h4.position.z)); //Draw test polygon Gizmos.color = Color.white; Gizmos.DrawLine(_h1.position, _h2.position); Gizmos.DrawLine(_h2.position, _h3.position); Gizmos.DrawLine(_h3.position, _h4.position); Gizmos.DrawLine(_h4.position, _h1.position); //Draw "world" bounds DrawRectangle.ForGizmo(bounds, Color.gray); if (Workmode == Mode.Blocks) { //Draw block bounds var blockBounds = (Bounds2i)bounds; //Draw block centers inside bounds foreach (var blockBound in blockBounds) { var blockCenter = BlockInfo.GetWorldCenter(blockBound); DebugExtension.DrawPoint((Vector3)blockCenter, Color.white / 2, 0.1f); } var blocks = Rasterization.ConvexToBlocks(isContains, bounds); Assert.IsTrue(blocks.Length == blocks.Distinct().Count()); //Draw rasterized blocks foreach (var p in blocks) { DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.green); } } else { var vertices = Rasterization.ConvexToVertices(isContains, bounds); Assert.IsTrue(vertices.Length == vertices.Distinct().Count()); //Draw rasterized vertices foreach (var p in vertices) { DebugExtension.DrawPoint(p, Color.green, 0.1f); } } Debug.LogFormat("Contains calls count {0}", containsCallCounter); } }
public void DrawMesh(Rasterization rasterizer, VertexProcessor processor) { //rasterizer.Triangle(processor.tr(vertices[0].position), processor.tr(vertices[1].position), processor.tr(vertices[2].position)); //rasterizer.Triangle(vertices[0].position, vertices[1].position, vertices[2].position); }
private void LateUpdate() { var camera = GetComponent <Camera>(); Profiler.BeginSample("ClearBuffers"); if (pixelWidth != camera.pixelWidth || pixelHeight != camera.pixelHeight) { pixelWidth = camera.pixelWidth; pixelHeight = camera.pixelHeight; int pixelCount = pixelWidth * pixelHeight; if (colorBuffer == null || colorBuffer.Length != pixelCount) { colorBuffer = new Color32[pixelCount]; } if (depthBuffer == null || depthBuffer.Length != pixelCount) { depthBuffer = new float[pixelCount]; } } else { while (bufferLock > 0) { Thread.SpinWait(4); } } Profiler.EndSample(); // Race condition: if viewport was resized, we don't wait for buffer clear tasks to finish, // but if they were not scheduled by this point, they will clear the image being rendered! var worldToProjectionMatrix = camera.projectionMatrix * camera.worldToCameraMatrix; var worldToScreenMatrix = Matrix4x4.TRS( new Vector3(pixelWidth * 0.5f, pixelHeight * 0.5f, 0), Quaternion.identity, new Vector3(pixelWidth * 0.5f, pixelHeight * 0.5f, 1)) * worldToProjectionMatrix; Vector4 p1 = worldToProjectionMatrix.GetRow(0); Vector4 p2 = worldToProjectionMatrix.GetRow(1); Vector4 p3 = worldToProjectionMatrix.GetRow(2); Vector4 p4 = worldToProjectionMatrix.GetRow(3); planes[0] = p4 + p3; planes[1] = p4 - p3; planes[2] = p4 + p1; planes[3] = p4 - p1; planes[4] = p4 + p2; planes[5] = p4 - p2; for (int i = 0; i < planes.Length; i++) { planes[i] /= ((Vector3)planes[i]).magnitude; } for (int r = 0; r < SoftwareRenderer.renderers.Count; r++) { var renderer = SoftwareRenderer.renderers[r]; var transform = renderer.transform; Profiler.BeginSample("Culling"); Vector4 position4 = transform.position; position4.w = 1; if (Vector4.Dot(planes[0], position4) < -renderer.radius || Vector4.Dot(planes[1], position4) < -renderer.radius || Vector4.Dot(planes[2], position4) < -renderer.radius || Vector4.Dot(planes[3], position4) < -renderer.radius || Vector4.Dot(planes[4], position4) < -renderer.radius || Vector4.Dot(planes[5], position4) < -renderer.radius) { renderer.gizmoColor = Color.red; Profiler.EndSample(); continue; } else { renderer.gizmoColor = Color.green; Profiler.EndSample(); } var localToScreenMatrix = worldToScreenMatrix * transform.localToWorldMatrix; Vector3[] vertices = renderer.vertices; if (vertexBuffer == null || vertexBuffer.Length < vertices.Length) { vertexBuffer = new Vector3[vertices.Length]; } for (int i = 0; i < vertices.Length; i++) { vertexBuffer[i] = localToScreenMatrix.MultiplyPoint(vertices[i]); } // Optimization: get scale from localToWorldMatrix instead? Vector3 scale = transform.lossyScale; float flipFaces = Mathf.Sign(scale.x * scale.y * scale.z); Profiler.BeginSample("Drawing"); int[] triangles = renderer.triangles; Color32 color32 = renderer.color; for (int t = 0; t < triangles.Length;) { Vector3 a = vertexBuffer[triangles[t++]]; Vector3 b = vertexBuffer[triangles[t++]]; Vector3 c = vertexBuffer[triangles[t++]]; if (a.z > -1 && a.z < 1 && b.z > -1 && b.z < 1 && c.z > -1 && c.z < 1 && Vector3.Cross(b - a, c - a).z *flipFaces < 0) { Rasterization.FillTriangle(a, b, c, color32, colorBuffer, depthBuffer, pixelWidth, 0, pixelHeight, 0, pixelWidth); } } Profiler.EndSample(); } }
/// <summary> /// Paints currently selected parquets in a rectangle between the given positions. /// </summary> /// <param name="in_upperLeft">The upper left corner of the rectangle.</param> /// <param name="in_lowerRight">The lower right corner of the rectangle.</param> /// <param name="in_filled"> /// If set to <c>true</c>, the rectangle will be filled in; otherwise, /// only the outline will be painted. /// </param> public void PaintRectangle(Vector2Int in_upperLeft, Vector2Int in_lowerRight, bool in_filled) { PaintAtLocations(in_filled ? Rasterization.PlotFilledRectangle(in_upperLeft, in_lowerRight, _currentRegion.IsValidPosition) : Rasterization.PlotEmptyRectangle(in_upperLeft, in_lowerRight, _currentRegion.IsValidPosition)); }
/// <summary> /// Paints currently selected parquets along a line between the given positions. /// </summary> /// <param name="in_start">The line's start.</param> /// <param name="in_end">The line's end.</param> public void PaintLine(Vector2Int in_start, Vector2Int in_end) { PaintAtLocations(Rasterization.PlotLine(in_start, in_end, _currentRegion.IsValidPosition)); }