//----------------------------------------------------------clipping_flags // Determine the clipping code of the vertex according to the // Cyrus-Beck line clipping algorithm // // | | // 0110 | 0010 | 0011 // | | // -------+--------+-------- clip_box.y2 // | | // 0100 | 0000 | 0001 // | | // -------+--------+-------- clip_box.y1 // | | // 1100 | 1000 | 1001 // | | // clip_box.x1 clip_box.x2 // // //template<class T> public static int Flags(int x, int y, RectInt clip_box) { return ((x > clip_box.Right) ? 1 : 0) | ((y > clip_box.Top) ? 1 << 1 : 0) | ((x < clip_box.Left) ? 1 << 2 : 0) | ((y < clip_box.Bottom) ? 1 << 3 : 0); }
//------------------------------------------------------------------------ //----------------------------------------------------------clipping_flags // Determine the clipping code of the vertex according to the // Cyrus-Beck line clipping algorithm // // | | // 0110 | 0010 | 0011 // | | // -------+--------+-------- clip_box.y2 // | | // 0100 | 0000 | 0001 // | | // -------+--------+-------- clip_box.y1 // | | // 1100 | 1000 | 1001 // | | // clip_box.x1 clip_box.x2 // // //template<class T> public static uint GetClippingFlags(int x, int y, RectInt clip_box) { return (uint)(((x > clip_box.X2) ? 1 : 0) | ((y > clip_box.Y2) ? 1 << 1 : 0) | ((x < clip_box.X1) ? 1 << 2 : 0) | ((y < clip_box.Y1) ? 1 << 3 : 0)); }
/// <summary> /// This will create a new ImageBuffer that references the same memory as the image that you took the sub image from. /// It will modify the original main image when you draw to it. /// </summary> /// <param name="parentImage"></param> /// <param name="childImageBounds"></param> /// <returns></returns> public static ChildImage CreateChildImage(IImageReaderWriter parentImage, RectInt childImageBounds) { if (childImageBounds.Left < 0 || childImageBounds.Bottom < 0 || childImageBounds.Right > parentImage.Width || childImageBounds.Top > parentImage.Height || childImageBounds.Left >= childImageBounds.Right || childImageBounds.Bottom >= childImageBounds.Top) { throw new ArgumentException("The subImageBounds must be on the image and valid."); } int left = Math.Max(0, childImageBounds.Left); int bottom = Math.Max(0, childImageBounds.Bottom); int width = Math.Min(parentImage.Width - left, childImageBounds.Width); int height = Math.Min(parentImage.Height - bottom, childImageBounds.Height); int bufferOffsetToFirstPixel = parentImage.GetBufferOffsetXY(left, bottom); return new ChildImage(parentImage, bufferOffsetToFirstPixel, width, height); }
public bool SetClippingBox(int x1, int y1, int x2, int y2) { RectInt cb = new RectInt(x1, y1, x2, y2); cb.Normalize(); if (cb.Clip(new RectInt(0, 0, (int)Width - 1, (int)Height - 1))) { m_ClippingRect = cb; return true; } m_ClippingRect.Left = 1; m_ClippingRect.Bottom = 1; m_ClippingRect.Right = 0; m_ClippingRect.Top = 0; return false; }
//-------------------------------------------------------------------- //public IPixelFormat ren() { return m_ren; } //-------------------------------------------------------------------- public bool SetClippingBox(int x1, int y1, int x2, int y2) { RectInt cb = new RectInt(x1, y1, x2, y2); cb.Normalize(); if (cb.Clip(new RectInt(0, 0, (int)Width - 1, (int)Height - 1))) { m_clip_box = cb; return true; } m_clip_box.X1 = 1; m_clip_box.Y1 = 1; m_clip_box.X2 = 0; m_clip_box.Y2 = 0; return false; }
public RectInt GetClipArea(ref RectInt destRect, ref RectInt sourceRect, int sourceWidth, int sourceHeight) { RectInt rc = new RectInt(0, 0, 0, 0); RectInt cb = ClipBox; ++cb.Right; ++cb.Top; if (sourceRect.Left < 0) { destRect.Left -= sourceRect.Left; sourceRect.Left = 0; } if (sourceRect.Bottom < 0) { destRect.Bottom -= sourceRect.Bottom; sourceRect.Bottom = 0; } if (sourceRect.Right > sourceWidth) sourceRect.Right = sourceWidth; if (sourceRect.Top > sourceHeight) sourceRect.Top = sourceHeight; if (destRect.Left < cb.Left) { sourceRect.Left += cb.Left - destRect.Left; destRect.Left = cb.Left; } if (destRect.Bottom < cb.Bottom) { sourceRect.Bottom += cb.Bottom - destRect.Bottom; destRect.Bottom = cb.Bottom; } if (destRect.Right > cb.Right) destRect.Right = cb.Right; if (destRect.Top > cb.Top) destRect.Top = cb.Top; rc.Right = destRect.Right - destRect.Left; rc.Top = destRect.Top - destRect.Bottom; if (rc.Right > sourceRect.Right - sourceRect.Left) rc.Right = sourceRect.Right - sourceRect.Left; if (rc.Top > sourceRect.Top - sourceRect.Bottom) rc.Top = sourceRect.Top - sourceRect.Bottom; return rc; }
public override void Attach(IPixelFormat ren) { base.Attach(ren); m_clip_box = new RectInt(0, 0, (int)ren.Width - 1, (int)ren.Height - 1); }
public void CopyFrom(RasterBuffer src, RectInt rect_src_ptr, int dx, int dy) { RectInt rsrc = new RectInt(rect_src_ptr.X1, rect_src_ptr.Y1, rect_src_ptr.X2 + 1, rect_src_ptr.Y2 + 1); // Version with xdst, ydst (absolute positioning) //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); // Version with dx, dy (relative positioning) RectInt rdst = new RectInt(rsrc.X1 + dx, rsrc.Y1 + dy, rsrc.X2 + dx, rsrc.Y2 + dy); RectInt rc = ClipRectArea(ref rdst, ref rsrc, (int)src.Width, (int)src.Height); if(rc.X2 > 0) { int incy = 1; if(rdst.Y1 > rsrc.Y1) { rsrc.Y1 += rc.Y2 - 1; rdst.Y1 += rc.Y2 - 1; incy = -1; } while(rc.Y2 > 0) { base.CopyFrom(src, rdst.X1, rdst.Y1, rsrc.X1, rsrc.Y1, (uint)rc.X2); rdst.Y1 += incy; rsrc.Y1 += incy; --rc.Y2; } } }
public RectInt ClipRectArea(ref RectInt dst, ref RectInt src, int wsrc, int hsrc) { RectInt rc = new RectInt(0,0,0,0); RectInt cb = ClipBox(); ++cb.X2; ++cb.Y2; if(src.X1 < 0) { dst.X1 -= src.X1; src.X1 = 0; } if(src.Y1 < 0) { dst.Y1 -= src.Y1; src.Y1 = 0; } if(src.X2 > wsrc) src.X2 = wsrc; if(src.Y2 > hsrc) src.Y2 = hsrc; if(dst.X1 < cb.X1) { src.X1 += cb.X1 - dst.X1; dst.X1 = cb.X1; } if(dst.Y1 < cb.Y1) { src.Y1 += cb.Y1 - dst.Y1; dst.Y1 = cb.Y1; } if(dst.X2 > cb.X2) dst.X2 = cb.X2; if(dst.Y2 > cb.Y2) dst.Y2 = cb.Y2; rc.X2 = dst.X2 - dst.X1; rc.Y2 = dst.Y2 - dst.Y1; if(rc.X2 > src.X2 - src.X1) rc.X2 = src.X2 - src.X1; if(rc.Y2 > src.Y2 - src.Y1) rc.Y2 = src.Y2 - src.Y1; return rc; }
public Convolution2D Extract(RectInt rect, ConvolutionExtractType extractType) { bool isNegPos = this.IsNegPos; double[] values = ExtractValues(rect); switch (extractType) { case ConvolutionExtractType.Raw: break; case ConvolutionExtractType.RawUnit: values = Convolutions.ToUnit(values); break; case ConvolutionExtractType.RawUnitSoftBorder: values = ApplySoftBorder(values, rect.Width, rect.Height); values = Convolutions.ToUnit(values); break; case ConvolutionExtractType.Edge: isNegPos = true; values = ConvertToEdge(values); values = Convolutions.ToUnit(values); break; case ConvolutionExtractType.EdgeSoftBorder: isNegPos = true; values = ConvertToEdge(values); values = ApplySoftBorder(values, rect.Width, rect.Height); values = Convolutions.ToUnit(values); break; //case ConvolutionExtractType.EdgeCircleBorder: // isNegPos = true; // values = ConvertToEdge(values); // values = ApplyCircleBorder(values); // values = Convolutions.ToUnit(values); // break; default: throw new ApplicationException("Unknown ConvolutionExtractType: " + extractType.ToString()); } return new Convolution2D(values, rect.Width, rect.Height, isNegPos, this.Gain, this.Iterations, this.ExpandBorder); }
/// <summary> /// Divides the chute into a contiguous series of rectangles. /// </summary> /// <param name="origin">The area that the chute starts from.</param> /// <returns>The collection of rectangles that form the chute.</returns> public abstract IEnumerable <RectInt> From(RectInt origin);
public override Roof GenerateRoof(BuildingSettings settings, RectInt bounds) { return(new Roof()); }
public static void Deconstruct(this RectInt self, out Vector2Int position, out Vector2Int size) { position = self.position; size = self.size; }
bool Attach(IImageReaderWriter sourceImage, int x1, int y1, int x2, int y2) { m_ByteBuffer = null; if (x1 > x2 || y1 > y2) { throw new Exception("You need to have your x1 and y1 be the lower left corner of your sub image."); } RectInt boundsRect = new RectInt(x1, y1, x2, y2); if (boundsRect.Clip(new RectInt(0, 0, (int)sourceImage.Width - 1, (int)sourceImage.Height - 1))) { SetDimmensionAndFormat(boundsRect.Width, boundsRect.Height, sourceImage.Stride, sourceImage.BitDepth, sourceImage.BytesBetweenPixelsInclusive); int bufferOffset = sourceImage.GetBufferOffsetXY(boundsRect.Left, boundsRect.Bottom); byte[] buffer = sourceImage.GetBuffer(); SetBuffer(buffer, bufferOffset); return true; } return false; }
public override void CopyFrom(IImageReaderWriter sourceImage, RectInt sourceImageRect, int destXOffset, int destYOffset) { RectInt destRect = sourceImageRect; destRect.Offset(destXOffset, destYOffset); RectInt clippedSourceRect = new RectInt(); if (clippedSourceRect.IntersectRectangles(destRect, m_ClippingRect)) { // move it back relative to the source clippedSourceRect.Offset(-destXOffset, -destYOffset); base.CopyFrom(sourceImage, clippedSourceRect, destXOffset, destYOffset); } }
public ClipProxyImage(IImageReaderWriter refImage) : base(refImage) { m_ClippingRect = new RectInt(0, 0, (int)refImage.Width - 1, (int)refImage.Height - 1); }
/// <summary> /// Проверка прямоугольника /// </summary> /// <param name="rect">Прямоугольник для проверки</param> /// <param name="sliceWidth">Ширина куска</param> /// <param name="sliceHeight">Высота куска</param> /// <returns>Стороны прямоугольника делятся нацело на куски</returns> public static bool IsDevided(RectInt rect, int sliceWidth, int sliceHeight) { return(IsDevided(rect.width, sliceWidth) && IsDevided(rect.height, sliceHeight)); }
/// <summary> /// Find the brightest spot, then find the next brightest spot that is outside the result rectangle, etc. /// Stop when that value is less than some % of original /// </summary> private static Tuple<VectorInt, ApplyResult_Match[]>[] AnalyzeBrightSpots(Convolution2D image, FeatureRecognizer_Extract_Result[] comparePatches) { var retVal = new List<Tuple<VectorInt, ApplyResult_Match[]>>(); List<RectInt> previous = new List<RectInt>(); // The compare patches are sorted descending by size, so the largest patch will also be sure to contain the brightest value (the // brightest value should be the same for all, because they are centered on it) double minBrightness = comparePatches[0].BrightestValue * .33; double minWeight = comparePatches[0].Score * .5; while (true) { // Find the brightest point in the image passed in var brightest = image.GetMax(previous); if (brightest == null || brightest.Item2 < minBrightness) { break; } List<ApplyResult_Match> patches = new List<ApplyResult_Match>(); foreach (FeatureRecognizer_Extract_Result comparePatch in comparePatches) { RectInt patchRect = new RectInt(brightest.Item1 + comparePatch.Offset, comparePatch.Result.Size); patchRect = RectInt.Intersect(patchRect, new RectInt(0, 0, image.Width, image.Height)).Value; previous.Add(patchRect); Convolution2D patchConv = image.Extract(patchRect, ConvolutionExtractType.Raw); VectorInt brightestPos = brightest.Item1 - patchRect.Position; // Initial check (pure algorithm) double weight1 = Convolutions.GetExtractScore(patchConv, brightestPos, comparePatch.BrightestValue); // this method should be pure algorithm if (weight1 < minWeight) { patches.Add(new ApplyResult_Match(false, weight1, patchConv)); continue; } patches.Add(new ApplyResult_Match(true, weight1, patchConv)); // Second check (compare with the original patch) //double weight2 = Convolutions.GetExtractScore(patchConv, brightestPos, comparePatch.Result, -comparePatch.Offset, comparePatch.BrightestValue); // this method should subtract the two patches and compare the difference //patches.Add(new ApplyResult_Match(true, weight2, patchConv)); } retVal.Add(Tuple.Create(brightest.Item1, patches.ToArray())); } return retVal.ToArray(); }
void RenderWorldSingle() { lock (ChunkEventManager.viewHashSet) { foreach (var manager in ChunkEventManager.viewHashSet) { while (manager.GetBucket(out var bucket)) { viewThread.Enqueue(bucket); } } } foreach (var manager in ChunkEventManager.coroutineHashSet) { while (manager.GetBucket(out var bucket)) { coroutineQueue.Enqueue(bucket); } } int minX = 0; int maxX = 0; int minY = 0; int maxY = 0; // Ordering: [0] = Left, [1] = Right, [2] = Down, [3] = Up, [4] = Near, [5] = Far GeometryUtility.CalculateFrustumPlanes(View.setup._camera, planes); float enter; UnityEngine.Profiling.Profiler.BeginSample("Calc planes"); var depth = View.setup.viewSize.z * 16; RectInt[] zz = new RectInt[depth]; for (int z = 0; z < depth; z++) { var calcPos = new Vector3(View.setup._camera.transform.position.x, View.setup._camera.transform.position.y, z); // left var ray = new Ray(calcPos, Vector3.left); if (planes[0].Raycast(ray, out enter)) { var point = ray.GetPoint(enter).Floor(); if (planes[0].GetSide(point + new Vector3(0.5f, 0, -0.5f))) { minX = point.x - 1; } else { minX = point.x - 1; } } // right ray = new Ray(calcPos, Vector3.right); if (planes[1].Raycast(ray, out enter)) { var point = ray.GetPoint(enter).Floor(); if (planes[1].GetSide(point + new Vector3(-0.5f, 0, -0.5f))) { maxX = point.x + 1; } else { maxX = point.x + 1; } } // bottom ray = new Ray(calcPos, Vector3.down); if (planes[2].Raycast(ray, out enter)) { var point = ray.GetPoint(enter).Floor(); if (planes[2].GetSide(point + new Vector3(0, 0.5f, -0.5f))) { minY = point.y - 1; } else { minY = point.y - 1; } } // top ray = new Ray(calcPos, Vector3.up); if (planes[3].Raycast(ray, out enter)) { var point = ray.GetPoint(enter).Floor(); if (planes[3].GetSide(point + new Vector3(0, -0.5f, -0.5f))) { maxY = point.y + 1; } else { maxY = point.y + 1; } } zz[z] = new RectInt(minX, minY, maxX - minX, maxY - minY); } UnityEngine.Profiling.Profiler.EndSample(); var hp = new Plane(Vector3.up, View.setup._camera.transform.position); var vp = new Plane(Vector3.right, View.setup._camera.transform.position); var playerPos = new Vector3(View.setup._camera.transform.position.x, View.setup._camera.transform.position.y, 0); var queue = new Queue <RenderChunk>(); var startChunkPos = BlockPos.From(Vector3Int.FloorToInt(playerPos)); minX = (startChunkPos.x >> 4) - View.setup.viewSize.x; maxX = (startChunkPos.x >> 4) + View.setup.viewSize.x; minY = (startChunkPos.y >> 4) - View.setup.viewSize.y; maxY = (startChunkPos.y >> 4) + View.setup.viewSize.y; var chunkPos = new BlockPos(); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { chunkPos.SetChunk(x, y, 0); var renderChunk = renderProvider.GetChunk(chunkPos); if (GeometryUtility.TestPlanesAABB(planes, renderChunk.bounds)) { renderChunk.SetFrameIndex(Time.frameCount); queue.Enqueue(renderChunk); } else { renderChunk.Update(); } } } while (queue.Count > 0 && queue.Count < 100) { var renderChunk = queue.Dequeue(); renderChunk.Update(); if (renderChunk.empty == 4096) { DrawBounds(renderChunk.bounds, Color.white); } else { DrawBounds(renderChunk.bounds, Color.red); } Graphics.DrawMesh(renderChunk.mesh, Matrix4x4.identity, material2, 0); for (Facing facing = Facing.First; facing <= Facing.Last; facing++) { chunkPos.Set(renderChunk.chunk.position); chunkPos.AddChunk(facing.GetVector()); var renderChunkOffset = renderProvider.GetChunk(startChunkPos, chunkPos); if (renderChunkOffset != null) { renderChunkOffset.Update(); if (renderChunkOffset != null && GeometryUtility.TestPlanesAABB(planes, renderChunkOffset.bounds) && renderChunk.IsVisible(facing) && renderChunkOffset.SetFrameIndex(Time.frameCount)) { queue.Enqueue(renderChunkOffset); } } } } }
private static ReducedExtract[] GetExtractSizes(BitmapSource bitmap, ConvolutionBase2D filter, RectInt rect, int minExtractSize = 10) { List<ReducedExtract> retVal = new List<ReducedExtract>(); VectorInt filterReduce = filter == null ? new VectorInt(0, 0) : filter.GetReduction(); Rect percents = new Rect() { X = rect.X.ToDouble() / bitmap.PixelWidth.ToDouble(), Y = rect.Y.ToDouble() / bitmap.PixelHeight.ToDouble(), Width = rect.Width.ToDouble() / bitmap.PixelWidth.ToDouble(), Height = rect.Height.ToDouble() / bitmap.PixelHeight.ToDouble(), }; double percent = 1d; while (true) { VectorInt imageSize = new VectorInt() { X = (bitmap.PixelWidth * percent).ToInt_Round(), Y = (bitmap.PixelHeight * percent).ToInt_Round(), }; VectorInt postSize = imageSize - filterReduce; RectInt newRect = new RectInt() { X = (percents.X * postSize.X).ToInt_Round(), Y = (percents.Y * postSize.Y).ToInt_Round(), Width = (percents.Width * postSize.X).ToInt_Round(), Height = (percents.Height * postSize.Y).ToInt_Round(), }; if (newRect.Width < minExtractSize || newRect.Height < minExtractSize) { break; } retVal.Add(new ReducedExtract() { Percent = percent, ImageSize = imageSize, Extract = newRect, }); percent *= .75; } return retVal.ToArray(); }
void SampleCopyChannel( CommandBuffer cmd, RectInt rect, int _source, RenderTargetIdentifier source, int _target, RenderTargetIdentifier target, int slices, int kernel8, int kernel1) { RectInt main, topRow, rightCol, topRight; unsafe { RectInt *dispatch1Rects = stackalloc RectInt[3]; int dispatch1RectCount = 0; RectInt dispatch8Rect = new RectInt(0, 0, 0, 0); if (TileLayoutUtils.TryLayoutByTiles( rect, 8, out main, out topRow, out rightCol, out topRight)) { if (topRow.width > 0 && topRow.height > 0) { dispatch1Rects[dispatch1RectCount] = topRow; ++dispatch1RectCount; } if (rightCol.width > 0 && rightCol.height > 0) { dispatch1Rects[dispatch1RectCount] = rightCol; ++dispatch1RectCount; } if (topRight.width > 0 && topRight.height > 0) { dispatch1Rects[dispatch1RectCount] = topRight; ++dispatch1RectCount; } dispatch8Rect = main; } else if (rect.width > 0 && rect.height > 0) { dispatch1Rects[dispatch1RectCount] = rect; ++dispatch1RectCount; } cmd.SetComputeTextureParam(m_Shader, kernel8, _source, source); cmd.SetComputeTextureParam(m_Shader, kernel1, _source, source); cmd.SetComputeTextureParam(m_Shader, kernel8, _target, target); cmd.SetComputeTextureParam(m_Shader, kernel1, _target, target); if (dispatch8Rect.width > 0 && dispatch8Rect.height > 0) { var r = dispatch8Rect; // Use intermediate array to avoid garbage _IntParams[0] = r.x; _IntParams[1] = r.y; cmd.SetComputeIntParams(m_Shader, _RectOffset, _IntParams); cmd.DispatchCompute(m_Shader, kernel8, (int)Mathf.Max(r.width / 8, 1), (int)Mathf.Max(r.height / 8, 1), slices); } for (int i = 0, c = dispatch1RectCount; i < c; ++i) { var r = dispatch1Rects[i]; // Use intermediate array to avoid garbage _IntParams[0] = r.x; _IntParams[1] = r.y; cmd.SetComputeIntParams(m_Shader, _RectOffset, _IntParams); cmd.DispatchCompute(m_Shader, kernel1, (int)Mathf.Max(r.width, 1), (int)Mathf.Max(r.height, 1), slices); } } }
public static bool GetBoundingRect(VertexStoreSnap vs, ref RectInt rect) { int x1, y1, x2, y2; bool rValue = GetBoundingRect(vs, out x1, out y1, out x2, out y2); rect.Left = x1; rect.Bottom = y1; rect.Right = x2; rect.Top = y2; return rValue; }
public static TerrainTile Make(Terrain terrain, int tileOriginPixelsX, int tileOriginPixelsY, RectInt pixelRect, int targetTextureWidth, int targetTextureHeight) { var tile = new TerrainTile() { terrain = terrain, gatherEnable = true, scatterEnable = true, tileOriginPixels = new Vector2Int(tileOriginPixelsX, tileOriginPixelsY), clippedTerrainPixels = new RectInt() { x = Mathf.Max(0, pixelRect.x - tileOriginPixelsX), y = Mathf.Max(0, pixelRect.y - tileOriginPixelsY), xMax = Mathf.Min(targetTextureWidth, pixelRect.xMax - tileOriginPixelsX), yMax = Mathf.Min(targetTextureHeight, pixelRect.yMax - tileOriginPixelsY) }, }; tile.clippedPCPixels = new RectInt( tile.clippedTerrainPixels.x + tile.tileOriginPixels.x - pixelRect.x, tile.clippedTerrainPixels.y + tile.tileOriginPixels.y - pixelRect.y, tile.clippedTerrainPixels.width, tile.clippedTerrainPixels.height); if (tile.clippedTerrainPixels.width == 0 || tile.clippedTerrainPixels.height == 0) { tile.gatherEnable = false; tile.scatterEnable = false; Debug.LogError("PaintContext.ClipTerrainTiles found 0 content rect"); // we really shouldn't ever have this.. } return(tile); }
public virtual void CopyFrom(IImageReaderWriter sourceImage, RectInt sourceImageRect, int destXOffset, int destYOffset) { linkedImage.CopyFrom(sourceImage, sourceImageRect, destXOffset, destYOffset); }
public override void Draw() { var rectPuzzle = Puzzle.Area.Move((2, 4)); Renderer.Box(rectPuzzle.Outset(2)); Renderer.DrawMap(Puzzle, rectPuzzle.TL, x => Style[x]); if (Solver is null) { var stats = RectInt.FromTwoPoints(Renderer.Geometry.TM, Renderer.Geometry.BR); Renderer.TitleBox(stats, "Select Solver"); var start = stats.TL + (2, 2); start = Renderer.DrawText(start, $"[F] {nameof(SingleThreadedForwardSolver)}", Style.DefaultPixel); start = Renderer.DrawText(start, $"[R] {nameof(SingleThreadedReverseSolver)}", Style.DefaultPixel); start = Renderer.DrawText(start, $"[M] {nameof(MultiThreadedForwardReverseSolver)}", Style.DefaultPixel); } else { // Solver Running, show progress if (SolverTask.IsFaulted || SolverException != null) { // Error Renderer.DrawText((0, 0), (SolverException ?? SolverTask.Exception).Message, Style.Error.AsPixel()); } else if (SolverTask.IsCompleted) { // Done Renderer.DrawText((0, 0), $"[{SolverState.Exit}:{(SolverState.EarlyExit ? "EARLY-EXIT": "")}] Solutions:{SolverState.SolutionsNodes?.Count ?? 0}", Style.DefaultPixel); } else { // Running Renderer.DrawText((0, 0), $"[RUNNING] {SolverState?.Statistics?.Elapsed}", Style.DefaultPixel); } // For all if (SolverState?.Statistics != null) { var s = SolverState.Statistics; var stats = RectInt.FromTwoPoints(Renderer.Geometry.TM, Renderer.Geometry.BR); Renderer.TitleBox(stats, "Statistics"); var start = stats.TL + (2, 2); start = Renderer.DrawText(start, $"Solutions: {SolverState.SolutionsNodes?.Count}", Style.DefaultPixel); start = Renderer.DrawText(start, $"Nodes: {s.TotalNodes} @ {s.TotalNodes / s.DurationInSec:0.0}/sec", Style.DefaultPixel); if (Solver.Statistics != null) { foreach (var stLine in Solver.Statistics) { start = Renderer.DrawText(start, stLine.ToStringShort(), Style.DefaultPixel); } } // if (SolverState is ISolverVisualisation vs && vs.TrySample(out var node)) // { // Renderer.DrawMapWithPosition(node.CrateMap, rectPuzzle.TL, // (p, c) => new CHAR_INFO(Puzzle[p].Underlying, // c ? CHAR_INFO_Attr.BACKGROUND_GREEN | CHAR_INFO_Attr.FOREGROUND_GRAY: CHAR_INFO_Attr.FOREGROUND_GRAY)); // // } } } }
//---------------------------------------------------------------------------- //template<class T> public static bool ClipMovePoint(int x1, int y1, int x2, int y2, RectInt clip_box, ref int x, ref int y, uint flags) { int bound; if ((flags & (uint)ClippingFlags.XClipped) != 0) { if (x1 == x2) { return false; } bound = ((flags & (uint)ClippingFlags.X1Clipped) != 0) ? clip_box.X1 : clip_box.X2; y = (int)((double)(bound - x1) * (y2 - y1) / (x2 - x1) + y1); x = bound; } flags = GetClippingFlagsY(y, clip_box); if ((flags & (uint)ClippingFlags.YClipped) != 0) { if (y1 == y2) { return false; } bound = ((flags & (uint)ClippingFlags.X1Clipped) != 0) ? clip_box.Y1 : clip_box.Y2; x = (int)((double)(bound - y1) * (x2 - x1) / (y2 - y1) + x1); y = bound; } return true; }
public static bool ClipMovePoint(int x1, int y1, int x2, int y2, RectInt clip_box, ref int x, ref int y, int flags) { int bound; if ((flags & ClippingFlags.cX1X2) != 0) { if (x1 == x2) { return false; } bound = ((flags & ClippingFlags.cX1) != 0) ? clip_box.Left : clip_box.Right; y = (int)((double)(bound - x1) * (y2 - y1) / (x2 - x1) + y1); x = bound; } flags = GetFlagsY(y, clip_box); if ((flags & ClippingFlags.cY1Y2) != 0) { if (y1 == y2) { return false; } bound = ((flags & ClippingFlags.cX1) != 0) ? clip_box.Bottom : clip_box.Top; x = (int)((double)(bound - y1) * (x2 - x1) / (y2 - y1) + x1); y = bound; } return true; }
public Room(Vector2Int location, Vector2Int size) { bounds = new RectInt(location, size); }
public static int GetFlagsY(int y, RectInt clip_box) { return (((y > clip_box.Top ? 1 : 0) << 1) | ((y < clip_box.Bottom ? 1 : 0) << 3)); }
/// <summary> /// Некорректный или пустой прямоугольник /// </summary> /// <param name="rect">Прямоугольник</param> /// <returns>Результат проверки</returns> private static bool IsEmpty(this RectInt rect) { return(rect.height < 1 || rect.width < 1); }
public GridPreview(Func <T, char> getTilePreview, RectInt viewport) { _getTilePreview = getTilePreview; Viewport = viewport; }
//-------------------------------------------------------------------- public FormatClippingProxy(IPixelFormat ren) : base(ren) { m_clip_box = new RectInt(0, 0, (int)ren.Width - 1, (int)ren.Height - 1); }
/// <summary> /// Прямоугольники пересекаются /// </summary> /// <param name="rect1">Первый прямоугольник</param> /// <param name="rect2">Второй прямоугольник</param> /// <returns>Результат проверки</returns> private static bool IsIntersect(RectInt rect1, RectInt rect2) { return((rect1.x >= rect2.xMax || rect1.xMax <= rect2.x || rect1.y >= rect2.yMax || rect1.yMax <= rect2.y) == false); }
//--------------------------------------------------------clipping_flags_x //template<class T> public static uint GetClippingFlagsX(int x, RectInt clip_box) { return (uint)((x > clip_box.X2 ? 1 : 0) | ((x < clip_box.X1 ? 1 : 0) << 2)); }
/// <summary> /// Проверка прямоугольника /// </summary> /// <param name="rect">Прямоугольник для проверки</param> /// <param name="sliceSize">Размер куска</param> /// <returns>Стороны прямоугольника делятся нацело на куски</returns> public static bool IsDevided(RectInt rect, int sliceSize) { return(IsDevided(rect.width, sliceSize) && IsDevided(rect.height, sliceSize)); }
//--------------------------------------------------------clipping_flags_y //template<class T> public static uint GetClippingFlagsY(int y, RectInt clip_box) { return (uint)(((y > clip_box.Y2 ? 1 : 0) << 1) | ((y < clip_box.Y1 ? 1 : 0) << 3)); }
public bool Overlaps(RectInt other) { return(other.max.x > min.x && other.min.x < max.x && other.max.y > min.y && other.min.y < max.y); }
public void ScatterAlphamap(string editorUndoName) { Vector4[] layerMasks = { new Vector4(1, 0, 0, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1) }; Material copyTerrainLayerMaterial = GetCopyTerrainLayerMaterial(); for (int i = 0; i < terrainTiles.Length; i++) { if (clippedTiles[i].width == 0 || clippedTiles[i].height == 0) { continue; } TerrainTile terrainTile = terrainTiles[i]; if (onTerrainTileBeforePaint != null) { onTerrainTileBeforePaint(terrainTile, ToolAction.PaintTexture, editorUndoName); } var rtdesc = new RenderTextureDescriptor(destinationRenderTexture.width, destinationRenderTexture.height, RenderTextureFormat.ARGB32); rtdesc.sRGB = false; rtdesc.useMipMap = false; rtdesc.autoGenerateMips = false; RenderTexture destTarget = RenderTexture.GetTemporary(rtdesc); RenderTexture.active = destTarget; var writeRect = new RectInt( clippedTiles[i].x + terrainTile.rect.x - brushRect.x + terrainTile.writeOffset.x, clippedTiles[i].y + terrainTile.rect.y - brushRect.y + terrainTile.writeOffset.y, clippedTiles[i].width, clippedTiles[i].height); var readRect = new Rect( writeRect.x / (float)brushRect.width, writeRect.y / (float)brushRect.height, writeRect.width / (float)brushRect.width, writeRect.height / (float)brushRect.height); destinationRenderTexture.filterMode = FilterMode.Point; for (int j = 0; j < terrainTile.terrain.terrainData.alphamapTextureCount; j++) { Texture2D sourceTex = terrainTile.terrain.terrainData.alphamapTextures[j]; int mapIndex = terrainTile.mapIndex; int channelIndex = terrainTile.channelIndex; Rect combineRect = new Rect( clippedTiles[i].x / (float)sourceTex.width, clippedTiles[i].y / (float)sourceTex.height, clippedTiles[i].width / (float)sourceTex.width, clippedTiles[i].height / (float)sourceTex.height); copyTerrainLayerMaterial.SetTexture("_MainTex", destinationRenderTexture); copyTerrainLayerMaterial.SetTexture("_OldAlphaMapTexture", sourceRenderTexture); copyTerrainLayerMaterial.SetTexture("_AlphaMapTexture", sourceTex); copyTerrainLayerMaterial.SetVector("_LayerMask", j == mapIndex ? layerMasks[channelIndex] : Vector4.zero); copyTerrainLayerMaterial.SetPass(1); GL.PushMatrix(); GL.LoadOrtho(); GL.LoadPixelMatrix(0, destTarget.width, 0, destTarget.height); GL.Begin(GL.QUADS); GL.Color(new Color(1.0f, 1.0f, 1.0f, 1.0f)); GL.MultiTexCoord2(0, readRect.x, readRect.y); GL.MultiTexCoord2(1, combineRect.x, combineRect.y); GL.Vertex3(writeRect.x, writeRect.y, 0.0f); GL.MultiTexCoord2(0, readRect.x, readRect.yMax); GL.MultiTexCoord2(1, combineRect.x, combineRect.yMax); GL.Vertex3(writeRect.x, writeRect.yMax, 0.0f); GL.MultiTexCoord2(0, readRect.xMax, readRect.yMax); GL.MultiTexCoord2(1, combineRect.xMax, combineRect.yMax); GL.Vertex3(writeRect.xMax, writeRect.yMax, 0.0f); GL.MultiTexCoord2(0, readRect.xMax, readRect.y); GL.MultiTexCoord2(1, combineRect.xMax, combineRect.y); GL.Vertex3(writeRect.xMax, writeRect.y, 0.0f); GL.End(); GL.PopMatrix(); if (paintTextureUsesCopyTexture) { var rtdesc2 = new RenderTextureDescriptor(sourceTex.width, sourceTex.height, RenderTextureFormat.ARGB32); rtdesc2.sRGB = false; rtdesc2.useMipMap = true; rtdesc2.autoGenerateMips = false; var mips = RenderTexture.GetTemporary(rtdesc2); if (!mips.IsCreated()) { mips.Create(); } // Composes mip0 in a RT with full mipchain. Graphics.CopyTexture(sourceTex, 0, 0, mips, 0, 0); Graphics.CopyTexture(destTarget, 0, 0, writeRect.x, writeRect.y, writeRect.width, writeRect.height, mips, 0, 0, clippedTiles[i].x, clippedTiles[i].y); mips.GenerateMips(); // Copy them into sourceTex. Graphics.CopyTexture(mips, sourceTex); RenderTexture.ReleaseTemporary(mips); } else { GraphicsDeviceType deviceType = SystemInfo.graphicsDeviceType; if (deviceType == GraphicsDeviceType.Metal || deviceType == GraphicsDeviceType.OpenGLCore) { sourceTex.ReadPixels(new Rect(writeRect.x, writeRect.y, writeRect.width, writeRect.height), clippedTiles[i].x, clippedTiles[i].y); } else { sourceTex.ReadPixels(new Rect(writeRect.x, destTarget.height - writeRect.y - writeRect.height, writeRect.width, writeRect.height), clippedTiles[i].x, clippedTiles[i].y); } sourceTex.Apply(); } } RenderTexture.active = null; RenderTexture.ReleaseTemporary(destTarget); OnTerrainPainted(terrainTile, ToolAction.PaintTexture); } }
static public IUIElement WithRegion(this IUIElement Base, RectInt Region) => null == Base ? null : new UIElement(Base) { Region = Region };
public TerrainTile(Terrain newTerrain, RectInt newRegion) { rect = newRegion; terrain = newTerrain; }
public static RectInt With(this RectInt self, Vector2Int?position = null, Vector2Int?size = null) => new RectInt( position ?? self.position, size ?? self.size );
public static TerrainTile[] FindTerrainTiles(Terrain terrain, int width, int height, RectInt brushRect) { List <TerrainTile> terrainTiles = new List <TerrainTile>(); Terrain left = terrain.leftNeighbor; Terrain right = terrain.rightNeighbor; Terrain top = terrain.topNeighbor; Terrain bottom = terrain.bottomNeighbor; bool wantLeft = (brushRect.x < 0); bool wantRight = (brushRect.xMax > (width - 1)); bool wantTop = (brushRect.yMax > (height - 1)); bool wantBottom = (brushRect.y < 0); if (wantLeft && wantRight) { Debug.Log("FindTerrainTiles query rectangle too large!"); wantRight = false; } if (wantTop && wantBottom) { Debug.Log("FindTerrainTiles query rectangle too large!"); wantBottom = false; } // add center tile TerrainTile tile = new TerrainTile(terrain, new RectInt(0, 0, width, height)); tile.readOffset = Vector2Int.zero; tile.writeOffset = Vector2Int.zero; terrainTiles.Add(tile); // add horizontal and vertical neighbors Terrain horiz = null; Terrain vert = null; Terrain cornerTerrain = null; int xBias = 0; int yBias = 0; int xReadBias = 0; int yReadBias = 0; int xWriteBias = 0; int yWriteBias = 0; if (wantLeft) { xBias = -1; xReadBias = -1; xWriteBias = 1; horiz = left; } else if (wantRight) { xBias = 1; xReadBias = 1; xWriteBias = -1; horiz = right; } if (wantTop) { yBias = 1; yReadBias = 1; yWriteBias = -1; vert = top; } else if (wantBottom) { yBias = -1; yReadBias = -1; yWriteBias = 1; vert = bottom; } if (horiz) { tile = new TerrainTile(horiz, new RectInt(xBias * width, 0, width, height)); tile.readOffset = new Vector2Int(xReadBias, 0); tile.writeOffset = new Vector2Int(xWriteBias, 0); terrainTiles.Add(tile); // add corner, if we have a link if (wantTop && horiz.topNeighbor) { cornerTerrain = horiz.topNeighbor; } else if (wantBottom && horiz.bottomNeighbor) { cornerTerrain = horiz.bottomNeighbor; } } if (vert) { tile = new TerrainTile(vert, new RectInt(0, yBias * height, width, height)); tile.readOffset = new Vector2Int(0, yReadBias); tile.writeOffset = new Vector2Int(0, yWriteBias); terrainTiles.Add(tile); // add corner, if we have a link if (wantLeft && vert.leftNeighbor) { cornerTerrain = vert.leftNeighbor; } else if (wantRight && vert.rightNeighbor) { cornerTerrain = vert.rightNeighbor; } } if (cornerTerrain != null) { tile = new TerrainTile(cornerTerrain, new RectInt(xBias * width, yBias * height, width, height)); tile.readOffset = new Vector2Int(xReadBias, yReadBias); tile.writeOffset = new Vector2Int(xWriteBias, yWriteBias); terrainTiles.Add(tile); } return(terrainTiles.ToArray()); }
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RTHandle source, RTHandle target, RectInt rect) { Debug.Assert(source.rt.volumeDepth == target.rt.volumeDepth); SampleCopyChannel(cmd, rect, _Source4, source, _Result1, target, source.rt.volumeDepth, k_SampleKernel_xyzw2x_8, k_SampleKernel_xyzw2x_1); }
public RenderTexture oldRenderTexture; // active render texture before PaintContext was initialized public void CalculateBrushRect(Terrain terrain, Rect bounds, int inputTextureWidth, int inputTextureHeight) { brushRect = CalcBrushRectInPixels(terrain, bounds, inputTextureWidth, inputTextureHeight); }
public static SwfRectIntData FromURect(RectInt rect) { return(new SwfRectIntData(rect.xMin, rect.yMin, rect.width, rect.height)); }
public static void SetScissorRect(RectInt scissorRect) { Utility.SetScissorRect_Injected(ref scissorRect); }
public override void Update() { timer += Time.Delta; var player = World().First <Player>(); var mover = Get <Mover>(); var anim = Get <Animator>(); var hitbox = Get <Collider>(); // No player - turn off AI. if (player == null) { return; } var x = Entity.Position.X; var y = Entity.Position.Y; var playerX = player.Entity.Position.X; // Flip sprite. anim.Scale = new System.Numerics.Vector2(facing, 1); // NORMAL STATE if (state == ST_READYING_ATTACK) { facing = Math.Sign(playerX - x); if (facing == 0) { facing = 1; } float targetX = playerX + 32 * -facing; mover.Speed.X = Calc.Approach(mover.Speed.X, Math.Sign(targetX - x) * 40, 400 * Time.Delta); mover.Friction = 100; anim.Play("run"); if (timer > 3.0f || (timer > 1.0f && hitbox.Check(Mask.Solid, new Point2(-facing * 8, 0)))) { mover.Speed.X = 0; SetState(ST_PERFORM_SLASH); } } // SLASH STATE else if (state == ST_PERFORM_SLASH) { // Start attack anim. anim.Play("attack"); mover.Friction = 500; // After 0.8s, do the lunge. if (Time.OnTime(timer, 0.8f)) { mover.Speed.X = facing * 250; hitbox.SetRect(new RectInt(-4 + facing * 4, -12, 8, 12)); RectInt rect = new RectInt(8, -8, 20, 8); if (facing < 0) { rect.X = -(rect.X + rect.Width); } if (attackCollider != null) { attackCollider.Destroy(); } attackCollider = Entity.Add <Collider>(Collider.MakeRect(rect)); attackCollider.Mask = Mask.Enemy; } // Turn off attack collider. else if (Time.OnTime(timer, anim.Animation().Duration() - 1.0f)) { if (attackCollider != null) { attackCollider.Destroy(); } attackCollider = null; } // End attack state. else if (timer >= anim.Animation().Duration()) { hitbox.SetRect(new RectInt(-4, -12, 8, 12)); if (Health > 0) { SetState(ST_READYING_ATTACK); } else { Phase = 1; Health = MAX_HEALTH_2; side = Rand.Instance.Next(0, 2) == 0 ? -1 : 1; SetState(ST_FLOATING); } } } // FLOATING STATE else if (state == ST_FLOATING) { anim.Play("float"); mover.Friction = 0; mover.Collider = null; float targetY = home.Y - 50; float targetX = home.X + side * 50; if (Math.Sign(targetY - y) != Math.Sign(targetY - lastPos.Y)) { mover.Speed.Y = 0; Entity.Position.Y = (int)targetY; } else { mover.Speed.Y = Calc.Approach(mover.Speed.Y, Math.Sign(targetY - y) * 50, 800 * Time.Delta); } if (Math.Abs(y - targetY) < 8) { mover.Speed.X = Calc.Approach(mover.Speed.X, Math.Sign(targetX - x) * 80, 800 * Time.Delta); } else { mover.Speed.X = 0; } if (timer > 5.0f || (Math.Abs(targetX - x) < 8 && Math.Abs(targetY - y) < 8)) { SetState(ST_SHOOT); } } // SHOOTING STATE else if (state == ST_SHOOT) { mover.Speed = Calc.Approach(mover.Speed, Vector2.Zero, 300 * Time.Delta); facing = Math.Sign(playerX - x); if (facing == 0) { facing = 1; } if (Time.OnTime(timer, 1.0f)) { anim.Play("reflect"); } else if (Time.OnTime(timer, 1.2f)) { Factory.Orb(World(), Entity.Position + new Point2(facing * 12, -8)); reflectCount = 0; } else if (Time.OnTime(timer, 1.4f)) { anim.Play("float"); SetState(ST_REFLECT); } } // REFLECT STATE else if (state == ST_REFLECT) { if (Time.OnTime(timer, 0.4f)) { anim.Play("float"); } var orb = World().First <Orb>(); if (orb == null) { if (timer > 1.0f) { side = -side; SetState(ST_FLOATING); } } else if (!orb.TowardsPlayer) { float distance = new Vector2( orb.Entity.Position.X - orb.Target().X, orb.Entity.Position.Y - orb.Target().Y ).Length(); if (reflectCount < 2) { if (distance < 16) { var sign = Math.Sign(orb.Entity.Position.X - x); if (sign != 0) { facing = sign; } anim.Play("reflect"); orb.OnHit(); reflectCount++; timer = 0; } } else { if (distance < 8) { Factory.Pop(World(), Entity.Position + new Point2(0, -8)); orb.Entity.Destroy(); Get <Hurtable>().Hurt(); timer = 0; } } } } // DEAD STATE else if (state == ST_DEAD_STATE) { anim.Play("dead"); World().Game.Shake(1.0f); if (Time.OnInterval(0.25f)) { var offset = new Point2(Rand.Instance.Next(-16, 16), Rand.Instance.Next(-16, 16)); Factory.Pop(World(), Entity.Position + new Point2(0, -8) + offset); } if (Time.OnTime(timer, 3.0f)) { for (int popx = -1; x < 2; x++) { for (int popy = -1; y < 2; y++) { Factory.Pop(World(), Entity.Position + new Point2(popx * 12, -8 + popy * 12)); } } Time.PauseFor(0.3f); World().Game.Shake(0.1f); Entity.Destroy(); } } if (state == ST_FLOATING || state == ST_SHOOT || state == ST_REFLECT) { anim.Offset.Y = (int)(Math.Sin(Time.Duration.TotalSeconds * 2f) * 3); } lastPos = Entity.Position; }
private static extern void SetScissorRect_Injected(ref RectInt scissorRect);
private void setVertex() { float xmin = float.MaxValue; float ymin = float.MaxValue; float xmax = float.MinValue; float ymax = float.MinValue; for (int i = 0; i < 4; i++) { xmax = Math.Max(xmax, vertex[i].X); ymax = Math.Max(ymax, vertex[i].Y); xmin = Math.Min(xmin, vertex[i].X); ymin = Math.Min(ymin, vertex[i].Y); } rect = new RectInt((int)xmin, (int)ymin, (int)(xmax - xmin), (int)(ymax - ymin)); AB = new Vector(vertex[0], vertex[1]); BC = new Vector(vertex[1], vertex[2]); CD = new Vector(vertex[2], vertex[3]); DA = new Vector(vertex[3], vertex[0]); // get unit vector AB /= AB.Magnitude; BC /= BC.Magnitude; CD /= CD.Magnitude; DA /= DA.Magnitude; }
private static extern void GetActiveViewport_Injected(out RectInt ret);
public bool Attach(IPixelFormat pixf, int x1, int y1, int x2, int y2) { RectInt r = new RectInt(x1, y1, x2, y2); if (r.Clip(new RectInt(0, 0, (int)pixf.Width - 1, (int)pixf.Height - 1))) { int stride = pixf.Stride; unsafe { m_rbuf.attach(pixf.PixPtr(r.X1, stride < 0 ? r.Y2 : r.Y1), (uint)(r.X2 - r.X1) + 1, (uint)(r.Y2 - r.Y1) + 1, stride, 3); } return true; } return false; }
public HtmlImage(RectInt area, Texture2DInfo image) { Area = area; Texture = image; }
private double[] ExtractValues(RectInt rect) { double[] retVal = new double[rect.Width * rect.Height]; for (int y = 0; y < rect.Height; y++) { int yOffsetSrc = (y + rect.Y) * this.Width; int yOffsetDest = y * rect.Width; for (int x = 0; x < rect.Width; x++) { retVal[yOffsetDest + x] = this.Values[yOffsetSrc + x + rect.X]; } } return retVal; }
public static Rectangle ToRectangle(this RectInt r) { return(new Rectangle(r.LeftTop.X, r.LeftTop.Y, (int)r.Width, (int)r.Height)); }
//-------------------------------------------------------clip_line_segment // Returns: ret >= 4 - Fully clipped // (ret & 1) != 0 - First point has been moved // (ret & 2) != 0 - Second point has been moved // //template<class T> public static int ClipLineSegment(ref int x1, ref int y1, ref int x2, ref int y2, RectInt clip_box) { int f1 = Flags(x1, y1, clip_box); int f2 = Flags(x2, y2, clip_box); int ret = 0; if ((f2 | f1) == 0) { // Fully visible return 0; } if ((f1 & ClippingFlags.cX1X2) != 0 && (f1 & ClippingFlags.cX1X2) == (f2 & ClippingFlags.cX1X2)) { // Fully clipped return 4; } if ((f1 & ClippingFlags.cY1Y2) != 0 && (f1 & ClippingFlags.cY1Y2) == (f2 & ClippingFlags.cY1Y2)) { // Fully clipped return 4; } int tx1 = x1; int ty1 = y1; int tx2 = x2; int ty2 = y2; if (f1 != 0) { if (!ClipMovePoint(tx1, ty1, tx2, ty2, clip_box, ref x1, ref y1, f1)) { return 4; } if (x1 == x2 && y1 == y2) { return 4; } ret |= 1; } if (f2 != 0) { if (!ClipMovePoint(tx1, ty1, tx2, ty2, clip_box, ref x2, ref y2, f2)) { return 4; } if (x1 == x2 && y1 == y2) { return 4; } ret |= 2; } return ret; }
// Method/algorithm that determiens what type of hallway should be generated between the two rooms // Determines wheter a vertical hallway, horizontal hallway or an L-shaped hallway (horizontal and vertical) is most suitable. void createHallways(int mapWidth, int mapHeight, List <Edge> edges) { tEdges = new List <Edge>(); foreach (Edge edge in edges) { int x1 = Mathf.RoundToInt((float)mesh.vertices[edge.P0].x); int y1 = Mathf.RoundToInt((float)mesh.vertices[edge.P0].y); int x2 = Mathf.RoundToInt((float)mesh.vertices[edge.P1].x); int y2 = Mathf.RoundToInt((float)mesh.vertices[edge.P1].y); RectInt room1 = new RectInt(0, 0, 0, 0); RectInt room2 = new RectInt(0, 0, 0, 0); foreach (RectInt room in rooms) { if (x1 > room.xMin && x1 < room.xMax && y1 > room.yMin && y1 < room.yMax) { room1 = room; } if (x2 > room.xMin && x2 < room.xMax && y2 > room.yMin && y2 < room.yMax) { room2 = room; } } int xMid = Mathf.RoundToInt((x1 + x2) / 2); int yMid = Mathf.RoundToInt((y1 + y2) / 2); if (yMid <= room1.yMax - 3 && yMid <= room2.yMax - 3 && yMid >= room1.yMin + 2 && yMid >= room2.yMin + 2) { CreateHorTunnel(Mathf.Min(room1.xMax, room2.xMax), Mathf.Max(room1.xMin, room2.xMin), yMid, room1, room2); } else if (xMid <= room1.xMax - 3 && xMid <= room2.xMax - 3 && xMid >= room1.xMin + 2 && xMid >= room2.xMin + 2) { CreateVerTunnel(Mathf.Min(room1.yMax, room2.yMax), Mathf.Max(room1.yMin, room2.yMin), xMid, room1, room2); } else { tEdges.Add(edge); } } foreach (Edge edge in tEdges) { int x1 = Mathf.RoundToInt((float)mesh.vertices[edge.P0].x); int y1 = Mathf.RoundToInt((float)mesh.vertices[edge.P0].y); int x2 = Mathf.RoundToInt((float)mesh.vertices[edge.P1].x); int y2 = Mathf.RoundToInt((float)mesh.vertices[edge.P1].y); RectInt room1 = new RectInt(0, 0, 0, 0); RectInt room2 = new RectInt(0, 0, 0, 0); foreach (RectInt room in rooms) { if (x1 > room.xMin && x1 < room.xMax && y1 > room.yMin && y1 < room.yMax) { room1 = room; } if (x2 > room.xMin && x2 < room.xMax && y2 > room.yMin && y2 < room.yMax) { room2 = room; } } CreateTTunnel(x1, x2, y1, y2, room1, room2); } }
public static int GetFlagsX(int x, RectInt clip_box) { return ((x > clip_box.Right ? 1 : 0) | ((x < clip_box.Left ? 1 : 0) << 2)); }
// Determine how to place L shaped hallways (multiple overlapping L shaped hallways makes a T shape, hence the "T" in "CreatTTunnel") // Needs refactoring or an algorithm change as it does not always generate appropriate hallways // TODO: // Refactor, // or // replace with A* algorithm private void CreateTTunnel(int x1, int x2, int y1, int y2, RectInt room1, RectInt room2) { int yMid = y2; int xMid = x1; // yMid/xMid dtermines which orientation the L hallway ("H") will go when connecting rooms A <-> B without hitting room C // What this methods aims to do with this spaghetti code (avoid room C): // . . . . . . B B B // . H H H H H B B B // . H . . . . B B B // . H . . . . . . . // . H . . . . . . . // . H . . . . . . . // . H . . . . . . . // A A A . . . C C C // A A A . . . C C C // A A A . . . C C C // // Instead of this (going through room C): // . . . . . . B B B // . . . . . . B B B // . . . . . . . H . // . . . . . . . H . // . . . . . . . H . // . . . . . . . H . // A A A . . . C H C // A A A H H H H H C // A A A . . . C C C if ((room2.yMin < room1.yMax && room1.yMax < room2.yMax)) { yMid = y1; xMid = x2; } else if ((room1.yMin < room2.yMax && room2.yMax < room1.yMax)) { yMid = y2; xMid = x1; } else if ((room2.xMin < room1.xMax && room1.xMax < room2.xMax)) { yMid = y2; xMid = x1; } else if (room1.xMin < room2.xMax && room2.xMax < room1.xMax) { yMid = y1; xMid = x2; } else { bool swap = false; for (int x = Mathf.Min(room2.xMax, room1.xMax) + 1; x < xMid; x++) { if ((this.level[x, yMid - 3] == 1 || this.level[x, yMid - 2] == 1 || this.level[x, yMid - 1] == 1 || this.level[x, yMid] == 1 || this.level[x, yMid + 1] == 1 || this.level[x, yMid + 2] == 1)) { swap = true; } } for (int y = Mathf.Min(room2.yMax, room1.yMax) + 1; y < yMid; y++) { if (this.level[xMid - 3, y] == 1 || this.level[xMid - 2, y] == 1 || this.level[xMid - 1, y] == 1 || this.level[xMid, y] == 1 || this.level[xMid + 1, y] == 1 || this.level[xMid + 2, y] == 1) { swap = true; } } for (int x = Mathf.Max(room2.xMin, room1.xMin) - 1; x >= xMid; x--) { if ((this.level[x, yMid - 3] == 1 || this.level[x, yMid - 2] == 1 || this.level[x, yMid - 1] == 1 || this.level[x, yMid] == 1 || this.level[x, yMid + 1] == 1 || this.level[x, yMid + 2] == 1)) { swap = true; } } for (int y = Mathf.Max(room2.yMin, room1.yMin) - 1; y >= yMid; y--) { if (this.level[xMid - 3, y] == 1 || this.level[xMid - 2, y] == 1 || this.level[xMid - 1, y] == 1 || this.level[xMid, y] == 1 || this.level[xMid + 1, y] == 1 || this.level[xMid + 2, y] == 1) { swap = true; } } if (swap) { yMid = y1; xMid = x2; } else { yMid = y2; xMid = x1; } } for (int x = Mathf.Min(x1, x2) - 2; x <= Mathf.Max(x1, x2) + 1; x++) { if (!(this.hallways[x, yMid - 3] == 1 || this.hallways[x, yMid - 2] == 1 || this.hallways[x, yMid - 1] == 1 || this.hallways[x, yMid] == 1 || this.hallways[x, yMid + 1] == 1 || this.hallways[x, yMid + 2] == 1)) { this.hallwaysT[x, yMid - 2] = 1; this.hallwaysT[x, yMid - 1] = 1; this.hallwaysT[x, yMid] = 1; this.hallwaysT[x, yMid + 1] = 1; if (!(this.level[x, yMid - 3] == 1 && this.level[x, yMid - 2] == 1 && this.level[x, yMid - 1] == 1 && this.level[x, yMid] == 1 && this.level[x, yMid + 1] == 1 && this.level[x, yMid + 2] == 1) || !(this.level[x, yMid - 3] == 0 && this.level[x, yMid - 2] == 0 && this.level[x, yMid - 1] == 0 && this.level[x, yMid] == 0 && this.level[x, yMid + 1] == 0 && this.level[x, yMid + 2] == 0)) { if ((Mathf.RoundToInt(room1.yMin) >= yMid - 2 && Mathf.RoundToInt(room1.yMin) <= yMid + 2) || (Mathf.RoundToInt(room1.yMax) >= yMid - 2 && Mathf.RoundToInt(room1.yMax) <= yMid + 2)) { for (int i = room1.xMin; i <= room1.xMax; i++) { for (int j = yMid - 2; j <= yMid + 1; j++) { this.level[i, j] = 1; } } } if ((Mathf.RoundToInt(room2.yMin) >= yMid - 2 && Mathf.RoundToInt(room2.yMin) <= yMid + 2) || (Mathf.RoundToInt(room2.yMax) >= yMid - 2 && Mathf.RoundToInt(room2.yMax) <= yMid + 2)) { for (int i = room2.xMin; i <= room2.xMax; i++) { for (int j = yMid - 2; j <= yMid + 1; j++) { this.level[i, j] = 1; } } } } } else { // Depcrated method to remove excess hallways //if (x < (Mathf.Max(x1, x2) - 2) && this.hallways[x, yMid - 2] == 1) //{ // this.hallwaysT[x, yMid - 2] = 0; // this.hallwaysT[x, yMid - 1] = 0; // this.hallwaysT[x, yMid] = 0; // this.hallwaysT[x, yMid + 1] = 0; //} } } for (int y = Mathf.Min(y1, y2) - 2; y <= Mathf.Max(y1, y2) + 1; y++) { if (!(this.hallways[xMid - 3, y] == 1 || this.hallways[xMid - 2, y] == 1 || this.hallways[xMid - 1, y] == 1 || this.hallways[xMid, y] == 1 || this.hallways[xMid + 1, y] == 1 || this.hallways[xMid + 2, y] == 1)) { this.hallwaysT[xMid - 2, y] = 1; this.hallwaysT[xMid - 1, y] = 1; this.hallwaysT[xMid, y] = 1; this.hallwaysT[xMid + 1, y] = 1; if (!(this.level[xMid - 2, y] == 1 && this.level[xMid - 1, y] == 1 && this.level[xMid, y] == 1 && this.level[xMid + 1, y] == 1 && this.level[xMid - 3, y] == 1 && this.level[xMid + 2, y] == 1) || !(this.level[xMid - 2, y] == 0 && this.level[xMid - 1, y] == 0 && this.level[xMid, y] == 0 && this.level[xMid + 1, y] == 0) && this.level[xMid - 3, y] == 0 && this.level[xMid + 2, y] == 0) { if ((Mathf.RoundToInt(room1.xMin) >= xMid - 2 && Mathf.RoundToInt(room1.xMin) <= xMid + 2) || (Mathf.RoundToInt(room1.xMax) >= xMid - 2 && Mathf.RoundToInt(room1.xMax) <= xMid + 2)) { for (int j = room1.yMin; j <= room1.yMax; j++) { for (int i = xMid - 2; i <= xMid + 1; i++) { this.level[i, j] = 1; } } } if ((Mathf.RoundToInt(room2.xMin) >= xMid - 2 && Mathf.RoundToInt(room2.xMin) <= xMid + 2) || (Mathf.RoundToInt(room2.xMax) >= xMid - 2 && Mathf.RoundToInt(room2.xMax) <= xMid + 2)) { for (int j = room2.yMin; j <= room2.yMax; j++) { for (int i = xMid - 2; i <= xMid + 1; i++) { this.level[i, j] = 1; } } } } } else { // Depcrated method to remove excess hallways //if (y < (Mathf.Max(y1, y2) - 2) && this.hallways[xMid - 2, y] == 1) //{ // this.hallwaysT[xMid - 2, y] = 0; // this.hallwaysT[xMid - 1, y] = 0; // this.hallwaysT[xMid, y] = 0; // this.hallwaysT[xMid + 1, y] = 0; //} } } }
public static int DoClipLiangBarsky(int x1, int y1, int x2, int y2, RectInt clip_box, int[] x, int[] y) { int xIndex = 0; int yIndex = 0; double nearzero = 1e-30; double deltax = x2 - x1; double deltay = y2 - y1; double xin; double xout; double yin; double yout; double tinx; double tiny; double toutx; double touty; double tin1; double tin2; double tout1; int np = 0; if (deltax == 0.0) { // bump off of the vertical deltax = (x1 > clip_box.Left) ? -nearzero : nearzero; } if (deltay == 0.0) { // bump off of the horizontal deltay = (y1 > clip_box.Bottom) ? -nearzero : nearzero; } if (deltax > 0.0) { // points to right xin = clip_box.Left; xout = clip_box.Right; } else { xin = clip_box.Right; xout = clip_box.Left; } if (deltay > 0.0) { // points up yin = clip_box.Bottom; yout = clip_box.Top; } else { yin = clip_box.Top; yout = clip_box.Bottom; } tinx = (xin - x1) / deltax; tiny = (yin - y1) / deltay; if (tinx < tiny) { // hits x first tin1 = tinx; tin2 = tiny; } else { // hits y first tin1 = tiny; tin2 = tinx; } if (tin1 <= 1.0) { if (0.0 < tin1) { x[xIndex++] = (int)xin; y[yIndex++] = (int)yin; ++np; } if (tin2 <= 1.0) { toutx = (xout - x1) / deltax; touty = (yout - y1) / deltay; tout1 = (toutx < touty) ? toutx : touty; if (tin2 > 0.0 || tout1 > 0.0) { if (tin2 <= tout1) { if (tin2 > 0.0) { if (tinx > tiny) { x[xIndex++] = (int)xin; y[yIndex++] = (int)(y1 + tinx * deltay); } else { x[xIndex++] = (int)(x1 + tiny * deltax); y[yIndex++] = (int)yin; } ++np; } if (tout1 < 1.0) { if (toutx < touty) { x[xIndex++] = (int)xout; y[yIndex++] = (int)(y1 + toutx * deltay); } else { x[xIndex++] = (int)(x1 + touty * deltax); y[yIndex++] = (int)yout; } } else { x[xIndex++] = x2; y[yIndex++] = y2; } ++np; } else { if (tinx > tiny) { x[xIndex++] = (int)xin; y[yIndex++] = (int)yout; } else { x[xIndex++] = (int)xout; y[yIndex++] = (int)yin; } ++np; } } } } return np; }
//--------------------------------------------------------------------- public OutlineRenderer(IImageReaderWriter destImage, IPixelBlender destPixelBlender, LineProfileAnitAlias profile) { destImageSurface = destImage; lineProfile = profile; clippingRectangle = new RectInt(0, 0, 0, 0); doClipping = false; this.destPixelBlender = destPixelBlender; }