/// <summary> /// See individual fields for explanation on what they are and how to use them. /// </summary> public View(string id, Rectangle area, Rectangle viewport, bool active = true) : base(id) { GameArea = area; Viewport = viewport; Active = active; }
protected override void Recalculate() { float minX = float.PositiveInfinity, minY = float.PositiveInfinity, maxX = float.NegativeInfinity, maxY = float.NegativeInfinity; for (int i = 0; i < _basePoints.Length; i++) { Points[i] = _Position + _basePoints[i].RotateOverOrigin(Point.Zero, _Rotation) * _Size; if (Points[i].X < minX) minX = Points[i].X; if (Points[i].Y < minY) minY = Points[i].Y; if (Points[i].X > maxX) maxX = Points[i].X; if (Points[i].Y > maxY) maxY = Points[i].Y; if (i < _basePoints.Length - 1) BoundLines[i] = new Line(Points[i], Points[i + 1]); else BoundLines[i] = new Line(Points[i], Points[0]); PerpAxes[i] = BoundLines[i].GetPerpAxes()[0]; } EnclosingRectangle = new Rectangle(minX, minY, maxX - minX, maxY - minY); Changed = false; }
/// <summary> /// Draw the sprite projected on a rectangle. /// </summary> public void Draw(ComplexRectangle rect, int frameIndex = 0, int depth = 0) { if (!Loaded) throw new NotLoadedException(); Rectangle sourceRect = new Rectangle(GetIndexLocation(frameIndex), FrameSize); DrawX.DrawJobs.Add(new TextureDrawJob(depth, rect.GetEnclosingRectangle(), TextureHandle, sourceRect, rect)); }
/// <summary> /// Texture job. /// </summary> public TextureDrawJob(int depth, Rectangle area, IntPtr texture, Rectangle sourceRect, ComplexRectangle destRect) : this() { Texture = texture; SourceRect = sourceRect; DestRect = destRect; Depth = depth; Area = area; }
/// <summary> /// A teensy quadtree baby. /// </summary> private QuadTree(byte level, Rectangle bounds, List<PhysicalObject> objects) { byte level1 = level; Rectangle bounds1 = bounds; _center = bounds.Position + bounds.Size / 2f; Point childSize = bounds.Size / 2f; if (objects.Count > MaxObjects) { //decide in what childtree an object would fit and add it there List<PhysicalObject> childObjects0 = new List<PhysicalObject>(); List<PhysicalObject> childObjects1 = new List<PhysicalObject>(); List<PhysicalObject> childObjects2 = new List<PhysicalObject>(); List<PhysicalObject> childObjects3 = new List<PhysicalObject>(); foreach (PhysicalObject obj in objects) { bool[] fits = FitObject(obj); if (!fits[4]) { if (fits[0]) childObjects0.Add(obj); else if (fits[1]) childObjects1.Add(obj); else if (fits[2]) childObjects2.Add(obj); else childObjects3.Add(obj); } else _objects.Add(obj); } //create subtrees and add everything that fits inside of em _children[0] = new QuadTree((byte)(level1 + 1), new Rectangle(bounds1.Position, childSize), childObjects0); _children[1] = new QuadTree((byte)(level1 + 1), new Rectangle(new Point(_center.X, bounds1.Position.Y), childSize), childObjects1); _children[2] = new QuadTree((byte)(level1 + 1), new Rectangle(new Point(bounds1.Position.X, _center.Y), childSize), childObjects2); _children[3] = new QuadTree((byte)(level1 + 1), new Rectangle(_center, childSize), childObjects3); } else _objects = objects; }
private static void Draw() { //collect drawjobs foreach (GameObject obj in Resources.Objects) { if (!obj.Destroyed) obj.Draw(); } DrawX.DrawJobs = DrawX.DrawJobs.OrderBy(job => job.Depth).ToList(); SDL.SDL_SetRenderDrawColor(RendererHandle, DrawX.BackgroundColor.R, DrawX.BackgroundColor.G, DrawX.BackgroundColor.B, DrawX.BackgroundColor.A); SDL.SDL_RenderClear(RendererHandle); foreach (View view in Resources.Get<View>()) { if (!view.Active) continue; Rectangle absoluteGameArea = view.GetAbsoluteGameArea(); Rectangle absoluteViewport = view.GetAbsoluteViewport(); Point scale = view.GetScale(); SDL.SDL_RenderSetScale(RendererHandle, scale.X, scale.Y); //viewport is affected by scale for whatever reason, correct it Rectangle scaledViewport = new Rectangle(absoluteViewport); scaledViewport.Position /= scale; scaledViewport.Size /= scale; SDL.SDL_Rect sdlViewport = (SDL.SDL_Rect)scaledViewport; SDL.SDL_RenderSetViewport(RendererHandle, ref sdlViewport); //get all jobs that will draw inside this view foreach (IDrawJob job in DrawX.GetDrawJobsByArea(absoluteGameArea)) { Type jobType = job.GetType(); if (jobType == typeof(TextureDrawJob)) //draw a texture { TextureDrawJob textureDrawJob = (TextureDrawJob)job; SDL.SDL_Rect sourceRect = (SDL.SDL_Rect)textureDrawJob.SourceRect; SDL.SDL_Rect destRect = (SDL.SDL_Rect)new Rectangle(textureDrawJob.DestRect.Position - absoluteGameArea.Position - textureDrawJob.DestRect.Origin, textureDrawJob.DestRect.Size); if (textureDrawJob.DestRect.Rotation == 0f) SDL.SDL_RenderCopy(RendererHandle, textureDrawJob.Texture, ref sourceRect, ref destRect); else { SDL.SDL_Point origin = (SDL.SDL_Point)textureDrawJob.DestRect.Origin; SDL.SDL_RenderCopyEx(RendererHandle, textureDrawJob.Texture, ref sourceRect, ref destRect, textureDrawJob.DestRect.Rotation, ref origin, SDL.SDL_RendererFlip.SDL_FLIP_NONE); } } else if (jobType == typeof(LineDrawJob)) //draw line(s) { LineDrawJob lineDrawJob = (LineDrawJob)job; //transform all points according to view and cast em SDL.SDL_Point[] sdlPoints = Array.ConvertAll(lineDrawJob.Points, point => (SDL.SDL_Point)(point - absoluteGameArea.Position)); SDL.SDL_SetRenderDrawColor(RendererHandle, lineDrawJob.Color.R, lineDrawJob.Color.G, lineDrawJob.Color.B, lineDrawJob.Color.A); SDL.SDL_RenderDrawLines(RendererHandle, sdlPoints, lineDrawJob.PointCount); } else //draw filledrect { FilledRectDrawJob rectDrawJob = (FilledRectDrawJob)job; SDL.SDL_Rect rect = (SDL.SDL_Rect)(rectDrawJob.Area - absoluteGameArea.Position); SDL.SDL_SetRenderDrawColor(RendererHandle, rectDrawJob.Color.R, rectDrawJob.Color.G, rectDrawJob.Color.B, rectDrawJob.Color.A); SDL.SDL_RenderFillRect(RendererHandle, ref rect); } } } DrawX.DrawJobs.Clear(); //threadpool should take care of actually swapping the frames (RenderPresent may wait for things like Fraps or VSync) RenderframeReady = true; ThreadPool.QueueUserWorkItem(PresentRender); }
protected override void Recalculate() { Points[0] = new Point(_Position.X - _origin.X, _Position.Y - _origin.Y).RotateOverOrigin(_Position, _Rotation); Points[1] = new Point(_Position.X - _origin.X + _Size.X, _Position.Y - _origin.Y).RotateOverOrigin(_Position, _Rotation); Points[2] = new Point(_Position.X - _origin.X + _Size.X, _Position.Y - _origin.Y + _Size.Y).RotateOverOrigin(_Position, _Rotation); Points[3] = new Point(_Position.X - _origin.X, _Position.Y - _origin.Y + _Size.Y).RotateOverOrigin(_Position, _Rotation); PerpAxes[0] = new Point((-Points[1].Y + Points[0].Y) / _Size.X, (Points[1].X - Points[0].X) / _Size.X); PerpAxes[1] = new Point((-Points[2].Y + Points[1].Y) / _Size.Y, (Points[2].X - Points[1].X) / _Size.Y); PerpAxes[2] = PerpAxes[0]; PerpAxes[3] = PerpAxes[1]; float minX = float.PositiveInfinity, minY = float.PositiveInfinity, maxX = float.NegativeInfinity, maxY = float.NegativeInfinity; foreach (Point p in Points) { if (p.X < minX) minX = p.X; if (p.Y < minY) minY = p.Y; if (p.X > maxX) maxX = p.X; if (p.Y > maxY) maxY = p.Y; } EnclosingRectangle = new Rectangle(minX, minY, maxX - minX, maxY - minY); BoundLines = new Line[] { new Line(Points[0], Points[1]), new Line(Points[1], Points[2]), new Line(Points[2], Points[3]), new Line(Points[3], Points[0]) }; Changed = false; }
public Rectangle(Rectangle rect) : this(rect._Position, rect._Size) { }
/// <summary> /// The mother of all quadtrees. /// </summary> public QuadTree(Rectangle bounds) : this(0, bounds, Resources.PhysicalObjects) { }
/// <summary> /// Sets the area the bounds could maximally cover with the current SpeedVelocity (any direction). /// Rectangle on x and y axes. /// </summary> internal void UpdateCoverableArea() { float minX = float.PositiveInfinity; float minY = float.PositiveInfinity; float maxX = float.NegativeInfinity; float maxY = float.NegativeInfinity; float speed = SpeedVelocity; foreach (Point pnt in Bounds.GetPoints()) { if (pnt.X < minX) minX = pnt.X; if (pnt.X > maxX) maxX = pnt.X; if (pnt.Y < minY) minY = pnt.Y; if (pnt.Y > maxY) maxY = pnt.Y; } CoverableArea = new Rectangle(minX - speed, minY - speed, maxX - minX + speed, maxY - minY + speed); }
protected override void Recalculate() { Points[0] = _Position; Points[1] = _Position + _Size; PerpAxes[0] = new Point((-Point2.Y + Point1.Y) / Length, (Point2.X - Point1.X) / Length); float minX = float.PositiveInfinity, minY = float.PositiveInfinity, maxX = float.NegativeInfinity, maxY = float.NegativeInfinity; foreach (Point p in Points) { if (p.X < minX) minX = p.X; if (p.Y < minY) minY = p.Y; if (p.X > maxX) maxX = p.X; if (p.Y > maxY) maxY = p.Y; } EnclosingRectangle = new Rectangle(minX, minY, maxX - minX, maxY - minY); Changed = false; }
internal static List<IDrawJob> GetDrawJobsByArea(Rectangle area) { return DrawJobs.FindAll(j => j.Area.IntersectsWith(area)); }
public static void DrawFilledRect(Rectangle rect, Color color, int depth = 0) { DrawJobs.Add(new FilledRectDrawJob(depth, rect, color)); }