From ba284a199a3e3ed5880d4bd6885382a6e1318039 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 23 Jan 2024 12:16:58 +0300 Subject: [PATCH] Engine DeMonoGame #2 --- Engine | 2 +- Game/Behaviours/MovementBallBehaviour.cs | 6 +-- Game/Behaviours/MovementBoxBehaviour.cs | 24 ++++++------ Game/EngineConverted.cs | 11 ++++++ Game/Game.csproj | 1 - Game/Game1.cs | 47 ++++++++++++----------- Game/Physics2D/Abstract/ICollider2D.cs | 7 ++-- Game/Physics2D/Abstract/IRigidBody2D.cs | 5 +-- Game/Physics2D/Collider2DAABBBehaviour.cs | 18 ++++----- Game/Physics2D/PhysicsEngine2D.cs | 20 +++++----- Game/Physics2D/PhysicsMath.cs | 32 ++++++++------- Game/Physics2D/Primitives/AABB.cs | 6 +-- Game/Physics2D/Primitives/Circle.cs | 6 +-- Game/Physics2D/Primitives/Line.cs | 44 ++++++++++----------- Game/Physics2D/Primitives/Shape.cs | 12 +++--- Game/Physics2D/Primitives/Triangle.cs | 16 ++++---- Game/Physics2D/RigidBody2D.cs | 2 +- 17 files changed, 135 insertions(+), 124 deletions(-) create mode 100644 Game/EngineConverted.cs diff --git a/Engine b/Engine index 485dfcc..39e553e 160000 --- a/Engine +++ b/Engine @@ -1 +1 @@ -Subproject commit 485dfcc51ea548a50eec57b003bc3cb31cfdf579 +Subproject commit 39e553ebbf61f398a3ed9a96b20f6819a197cd86 diff --git a/Game/Behaviours/MovementBallBehaviour.cs b/Game/Behaviours/MovementBallBehaviour.cs index ddfe614..063c79e 100644 --- a/Game/Behaviours/MovementBallBehaviour.cs +++ b/Game/Behaviours/MovementBallBehaviour.cs @@ -6,12 +6,12 @@ using Syntriax.Engine.Input; using Syntriax.Engine.Physics2D.Abstract; namespace Pong.Behaviours; -public class MovementBallBehaviour(Vector2 StartDirection, float Speed) : BehaviourOverride +public class MovementBallBehaviour(Vector2D StartDirection, float Speed) : BehaviourOverride { - public Vector2 StartDirection { get; private set; } = Vector2.Normalize(StartDirection); + public Vector2D StartDirection { get; private set; } = Vector2D.Normalize(StartDirection); public float Speed { get; set; } = Speed; - protected override void OnFirstActiveFrame(GameTime time) + protected override void OnFirstActiveFrame() { if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody)) throw new Exception($"Where's my {nameof(IRigidBody2D)}????"); diff --git a/Game/Behaviours/MovementBoxBehaviour.cs b/Game/Behaviours/MovementBoxBehaviour.cs index a2ebebc..fd9468a 100644 --- a/Game/Behaviours/MovementBoxBehaviour.cs +++ b/Game/Behaviours/MovementBoxBehaviour.cs @@ -17,25 +17,25 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo private bool isUpPressed = false; private bool isDownPressed = false; - private IKeyboardInputs inputs = null!; + private IButtonInputs inputs = null!; - protected override void OnUpdate(GameTime time) + protected override void OnUpdate() { if (isUpPressed && isDownPressed) return; if (isUpPressed) - GameObject.Transform.Position = GameObject.Transform.Position + Vector2.UnitY * (float)time.ElapsedGameTime.TotalSeconds * Speed; + GameObject.Transform.Position = GameObject.Transform.Position + Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed; else if (isDownPressed) - GameObject.Transform.Position = GameObject.Transform.Position + -Vector2.UnitY * (float)time.ElapsedGameTime.TotalSeconds * Speed; + GameObject.Transform.Position = GameObject.Transform.Position + -Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed; - GameObject.Transform.Position = new Vector2(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low)); + GameObject.Transform.Position = new Vector2D(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low)); } - protected override void OnFirstActiveFrame(GameTime time) + protected override void OnFirstActiveFrame() { - if (!BehaviourController.TryGetBehaviour(out var behaviourResult)) - throw new Exception($"{nameof(IKeyboardInputs)} is missing on ${GameObject.Name}."); + if (!BehaviourController.TryGetBehaviour>(out var behaviourResult)) + throw new Exception($"{nameof(IButtonInputs)} is missing on ${GameObject.Name}."); inputs = behaviourResult; @@ -55,8 +55,8 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo inputs.UnregisterOnRelease(Down, OnDownReleased); } - private void OnUpPressed(IKeyboardInputs inputs, Keys keys) => isUpPressed = true; - private void OnUpReleased(IKeyboardInputs inputs, Keys keys) => isUpPressed = false; - private void OnDownPressed(IKeyboardInputs inputs, Keys keys) => isDownPressed = true; - private void OnDownReleased(IKeyboardInputs inputs, Keys keys) => isDownPressed = false; + private void OnUpPressed(IButtonInputs inputs, Keys keys) => isUpPressed = true; + private void OnUpReleased(IButtonInputs inputs, Keys keys) => isUpPressed = false; + private void OnDownPressed(IButtonInputs inputs, Keys keys) => isDownPressed = true; + private void OnDownReleased(IButtonInputs inputs, Keys keys) => isDownPressed = false; } diff --git a/Game/EngineConverted.cs b/Game/EngineConverted.cs new file mode 100644 index 0000000..1a4173f --- /dev/null +++ b/Game/EngineConverted.cs @@ -0,0 +1,11 @@ +using System.Runtime.CompilerServices; +using Microsoft.Xna.Framework; +using Syntriax.Engine.Core; + +namespace Pong; + +public static class EngineConverted +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EngineTime ToEngineTime(this GameTime gameTime) => new(gameTime.TotalGameTime, gameTime.ElapsedGameTime); +} diff --git a/Game/Game.csproj b/Game/Game.csproj index 9b23577..323a3f6 100644 --- a/Game/Game.csproj +++ b/Game/Game.csproj @@ -26,7 +26,6 @@ - diff --git a/Game/Game1.cs b/Game/Game1.cs index f8aff67..7e06d96 100644 --- a/Game/Game1.cs +++ b/Game/Game1.cs @@ -1,5 +1,4 @@ using System; - using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; @@ -19,7 +18,9 @@ public class Game1 : Game private PhysicsEngine2D engine; private SpriteBatch _spriteBatch = null!; public static GameManager gameManager = null!; - public static Sprite spriteBox = null!; + // public static Sprite spriteBox = null!; + private MonoGameCameraBehaviour cameraBehaviour; + public Game1() { @@ -49,16 +50,16 @@ public class Game1 : Game { _spriteBatch = new SpriteBatch(GraphicsDevice); - spriteBox = new Sprite() { Texture2D = Content.Load("Sprites/Pixel") }; - Sprite spriteBall = new Sprite() { Texture2D = Content.Load("Sprites/Circle") }; + // spriteBox = new Sprite() { Texture2D = Content.Load("Sprites/Pixel") }; + // Sprite spriteBall = new Sprite() { Texture2D = Content.Load("Sprites/Circle") }; IGameObject gameObjectCamera = gameManager.InstantiateGameObject(); gameObjectCamera.Name = "Camera"; gameObjectCamera.Transform.Position = Vector2D.Zero; - MonoGameCameraBehaviour monoGameCameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour(); - monoGameCameraBehaviour.Viewport = GraphicsDevice.Viewport; - gameManager.Camera = monoGameCameraBehaviour; + cameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour(); + cameraBehaviour.Viewport = GraphicsDevice.Viewport; + gameManager.Camera = cameraBehaviour; GameObject gameObjectBall = gameManager.InstantiateGameObject(); gameObjectBall.Name = "Ball"; @@ -67,7 +68,7 @@ public class Game1 : Game engine.AddRigidBody(gameObjectBall.BehaviourController.AddBehaviour()); gameObjectBall.BehaviourController.AddBehaviour(new Vector2D(.1f, .1f), 500f); // gameObjectBall.BehaviourController.AddBehaviour().Assign(spriteBall); - gameObjectBall.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2.One * 512f * .5f, Vector2.One * 512f * .5f); + gameObjectBall.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * 512f * .5f, Vector2D.One * 512f * .5f); // gameObjectBall = gameManager.InstantiateGameObject(); // gameObjectBall.Name = "Ball"; // gameObjectBall.Transform.Position = Vector2D.UnitY * 30f; @@ -102,26 +103,26 @@ public class Game1 : Game goPlayAreaTop.Transform.Position = new Vector2D(0f, 288f + 20f); goPlayAreaTop.Transform.Scale = new Vector2D(10240f, 40f); // goPlayAreaTop.BehaviourController.AddBehaviour().Assign(spriteBox); - goPlayAreaTop.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); + // goPlayAreaTop.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); engine.AddRigidBody(goPlayAreaTop.BehaviourController.AddBehaviour()); IGameObject goPlayAreaBottom = gameManager.InstantiateGameObject(); goPlayAreaBottom.Transform.Position = new Vector2D(0f, -(288f + 20f)); goPlayAreaBottom.Transform.Scale = new Vector2D(10240f, 40f); // goPlayAreaBottom.BehaviourController.AddBehaviour().Assign(spriteBox); - goPlayAreaBottom.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); + // goPlayAreaBottom.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); engine.AddRigidBody(goPlayAreaBottom.BehaviourController.AddBehaviour()); IGameObject goPlayAreaRight = gameManager.InstantiateGameObject(); goPlayAreaRight.Transform.Position = new Vector2D(512f + 20f, 0f); goPlayAreaRight.Transform.Scale = new Vector2D(40f, 5760f); // goPlayAreaRight.BehaviourController.AddBehaviour().Assign(spriteBox); - goPlayAreaRight.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); + // goPlayAreaRight.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); engine.AddRigidBody(goPlayAreaRight.BehaviourController.AddBehaviour()); IGameObject goPlayAreaLeft = gameManager.InstantiateGameObject(); goPlayAreaLeft.Transform.Position = new Vector2D(-(512f + 20f), 0f); goPlayAreaLeft.Transform.Scale = new Vector2D(40f, 5760f); // goPlayAreaLeft.BehaviourController.AddBehaviour().Assign(spriteBox); - goPlayAreaLeft.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); + // goPlayAreaLeft.BehaviourController.AddBehaviour().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); engine.AddRigidBody(goPlayAreaLeft.BehaviourController.AddBehaviour()); // IGameObject goPlayAreaCenter = gameManager.InstantiateGameObject(); @@ -132,7 +133,7 @@ public class Game1 : Game // TODO: use this.Content to load your game content here } - protected override void Update(Microsoft.Xna.Framework.GameTime gameTime) + protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); @@ -148,21 +149,21 @@ public class Game1 : Game _graphics.IsFullScreen = true; _graphics.ApplyChanges(); - float previousScreenSize = MathF.Sqrt(MathF.Pow(gameManager.Camera.Viewport.Width, 2f) + MathF.Pow(gameManager.Camera.Viewport.Height, 2f)); + float previousScreenSize = MathF.Sqrt(MathF.Pow(cameraBehaviour.Viewport.Width, 2f) + MathF.Pow(cameraBehaviour.Viewport.Height, 2f)); float currentScreenSize = MathF.Sqrt(MathF.Pow(GraphicsDevice.Viewport.Width, 2f) + MathF.Pow(GraphicsDevice.Viewport.Height, 2f)); - gameManager.Camera.Zoom /= previousScreenSize / currentScreenSize; - gameManager.Camera.Viewport = GraphicsDevice.Viewport; + cameraBehaviour.Zoom /= previousScreenSize / currentScreenSize; + cameraBehaviour.Viewport = GraphicsDevice.Viewport; } if (Keyboard.GetState().IsKeyDown(Keys.U)) - gameManager.Camera.Zoom += gameTime.ElapsedGameTime.Nanoseconds * 0.00025f; + cameraBehaviour.Zoom += gameTime.ElapsedGameTime.Nanoseconds * 0.00025f; if (Keyboard.GetState().IsKeyDown(Keys.J)) - gameManager.Camera.Zoom -= gameTime.ElapsedGameTime.Nanoseconds * 0.00025f; + cameraBehaviour.Zoom -= gameTime.ElapsedGameTime.Nanoseconds * 0.00025f; if (Keyboard.GetState().IsKeyDown(Keys.Q)) - gameManager.Camera.Transform.Rotation += gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; + cameraBehaviour.BehaviourController.GameObject.Transform.Rotation += gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; if (Keyboard.GetState().IsKeyDown(Keys.E)) - gameManager.Camera.Transform.Rotation -= gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; + cameraBehaviour.BehaviourController.GameObject.Transform.Rotation -= gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; if (Keyboard.GetState().IsKeyDown(Keys.N)) { @@ -210,7 +211,7 @@ public class Game1 : Game // physicsTimer += 0.01f; // engine.Step(.01f); // } - gameManager.Update(gameTime); + gameManager.Update(gameTime.ToEngineTime()); base.Update(gameTime); } static float physicsTimer = 0f; @@ -224,9 +225,9 @@ public class Game1 : Game // Console.WriteLine($"Pos: {gameManager.Camera.Position}"); // TODO: Add your drawing code here - gameManager.PreDraw(gameTime); + gameManager.PreDraw(); gameManager.Camera.Update(); - gameManager.Draw(_spriteBatch); + // gameManager.Draw(_spriteBatch); base.Draw(gameTime); } diff --git a/Game/Physics2D/Abstract/ICollider2D.cs b/Game/Physics2D/Abstract/ICollider2D.cs index 64eba9b..a88a19f 100644 --- a/Game/Physics2D/Abstract/ICollider2D.cs +++ b/Game/Physics2D/Abstract/ICollider2D.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; -using Microsoft.Xna.Framework; - +using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; namespace Syntriax.Engine.Physics2D.Abstract; @@ -13,8 +12,8 @@ public interface ICollider2D : IBehaviour, IAssignableTransform IRigidBody2D? RigidBody2D { get; } - IList Vertices { get; } + IList Vertices { get; } - bool CheckCollision(Vector2 point); + bool CheckCollision(Vector2D point); void Recalculate(); } diff --git a/Game/Physics2D/Abstract/IRigidBody2D.cs b/Game/Physics2D/Abstract/IRigidBody2D.cs index 0881c48..820caa6 100644 --- a/Game/Physics2D/Abstract/IRigidBody2D.cs +++ b/Game/Physics2D/Abstract/IRigidBody2D.cs @@ -1,5 +1,4 @@ -using Microsoft.Xna.Framework; - +using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; namespace Syntriax.Engine.Physics2D.Abstract; @@ -8,7 +7,7 @@ public interface IRigidBody2D : IBehaviour, IAssignableTransform { IPhysicsMaterial2D Material { get; set; } - Vector2 Velocity { get; set; } + Vector2D Velocity { get; set; } float AngularVelocity { get; set; } float Mass { get; set; } diff --git a/Game/Physics2D/Collider2DAABBBehaviour.cs b/Game/Physics2D/Collider2DAABBBehaviour.cs index ccb59d2..79fc368 100644 --- a/Game/Physics2D/Collider2DAABBBehaviour.cs +++ b/Game/Physics2D/Collider2DAABBBehaviour.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using Microsoft.Xna.Framework; - using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Physics2D.Abstract; @@ -16,7 +14,7 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D public AABB AABBWorld { get; private set; } = null!; private IRigidBody2D? _rigidBody2D = null; - private List _vertices = new List(4); + private List _vertices = new List(4); public IRigidBody2D? RigidBody2D { @@ -35,9 +33,9 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D ITransform IAssignableTransform.Transform => Transform; public bool Assign(ITransform transform) => GameObject.Assign(transform); - public IList Vertices => _vertices; + public IList Vertices => _vertices; - public bool CheckCollision(Vector2 point) + public bool CheckCollision(Vector2D point) { return AABBWorld.Overlaps(point); } @@ -51,11 +49,11 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D Vertices.Clear(); Vertices.Add(AABBWorld.LowerBoundary); - Vertices.Add(new Vector2(AABBWorld.LowerBoundary.X, AABBWorld.UpperBoundary.Y)); + Vertices.Add(new Vector2D(AABBWorld.LowerBoundary.X, AABBWorld.UpperBoundary.Y)); Vertices.Add(AABBWorld.UpperBoundary); - Vertices.Add(new Vector2(AABBWorld.UpperBoundary.X, AABBWorld.LowerBoundary.Y)); + Vertices.Add(new Vector2D(AABBWorld.UpperBoundary.X, AABBWorld.LowerBoundary.Y)); } - public Collider2DAABBBehaviour(Vector2 lowerBoundary, Vector2 upperBoundary) + public Collider2DAABBBehaviour(Vector2D lowerBoundary, Vector2D upperBoundary) { AABBLocal = new AABB(lowerBoundary, upperBoundary); AABBWorld = new AABB(lowerBoundary, upperBoundary); @@ -63,7 +61,7 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D public Collider2DAABBBehaviour() { - AABBLocal = new(Vector2.Zero, Vector2.Zero); - AABBWorld = new(Vector2.Zero, Vector2.Zero); + AABBLocal = new(Vector2D.Zero, Vector2D.Zero); + AABBWorld = new(Vector2D.Zero, Vector2D.Zero); } } diff --git a/Game/Physics2D/PhysicsEngine2D.cs b/Game/Physics2D/PhysicsEngine2D.cs index e1acfb6..4c0bb66 100644 --- a/Game/Physics2D/PhysicsEngine2D.cs +++ b/Game/Physics2D/PhysicsEngine2D.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using Microsoft.Xna.Framework; - +using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Primitives; @@ -60,7 +60,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D } } - private void ResolveCollision(ICollider2D c1, ICollider2D c2, Vector2 vertex, float intervalDeltaTime) + private void ResolveCollision(ICollider2D c1, ICollider2D c2, Vector2D vertex, float intervalDeltaTime) { if (c1.RigidBody2D is not IRigidBody2D) return; @@ -71,16 +71,16 @@ public class PhysicsEngine2D : IPhysicsEngine2D c2.Vertices.ToLines(lines); - Vector2 normal = Vector2.UnitY; + Vector2D normal = Vector2D.Up; float t = 1f; bool hasIntersectedWithLines = false; foreach (var line in lines) { - if (!vertexTrajectory.Intersects(line, out Vector2? intersectionPoint)) + if (!vertexTrajectory.Intersects(line, out Vector2D? intersectionPoint)) continue; - if (intersectionPoint is not Vector2 ip) + if (intersectionPoint is not Vector2D ip) continue; float tTemp = vertexTrajectory.GetT(ip); @@ -88,7 +88,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D continue; t = tTemp; - Vector2 lineDirection = line.Direction; + Vector2D lineDirection = line.Direction; normal = new(lineDirection.Y, lineDirection.X); hasIntersectedWithLines = true; } @@ -99,11 +99,11 @@ public class PhysicsEngine2D : IPhysicsEngine2D float rewindInterval = intervalDeltaTime - t * intervalDeltaTime; StepRigidBody(c1.RigidBody2D, -rewindInterval); - c1.RigidBody2D.Velocity = Vector2.Reflect(c1.RigidBody2D.Velocity, normal); + c1.RigidBody2D.Velocity = Vector2D.Reflect(c1.RigidBody2D.Velocity, normal); StepRigidBody(c1.RigidBody2D, rewindInterval); } - private void CheckCollisions(ICollider2D collider2D, List collider2Ds, Action OnCollisionDetectedAction) + private void CheckCollisions(ICollider2D collider2D, List collider2Ds, Action OnCollisionDetectedAction) { for (int i = 0; i < collider2Ds.Count; i++) { @@ -113,7 +113,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D for (int y = 0; y < collider2D.Vertices.Count; y++) { - Vector2 vertex = collider2D.Vertices[y]; + Vector2D vertex = collider2D.Vertices[y]; if (collider2DItem.CheckCollision(vertex)) { OnCollisionDetectedAction?.Invoke(collider2D, collider2DItem, vertex); @@ -128,7 +128,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D private void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime) { - Vector2 nextPosition = rigidBody.Transform.Position; + Vector2D nextPosition = rigidBody.Transform.Position; nextPosition += rigidBody.Velocity * intervalDeltaTime; rigidBody.Transform.Position = nextPosition; diff --git a/Game/Physics2D/PhysicsMath.cs b/Game/Physics2D/PhysicsMath.cs index a19f014..7ccd28c 100644 --- a/Game/Physics2D/PhysicsMath.cs +++ b/Game/Physics2D/PhysicsMath.cs @@ -2,22 +2,22 @@ using System; using System.Collections.Generic; using Microsoft.Xna.Framework; - +using Syntriax.Engine.Core; using Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D; public static class PhysicsMath { - public static Vector2 Scale(this Vector2 original, Vector2 scale) - => new Vector2(original.X * scale.X, original.Y * scale.Y); + public static Vector2D Scale(this Vector2D original, Vector2D scale) + => new Vector2D(original.X * scale.X, original.Y * scale.Y); - public static Triangle ToSuperTriangle(this IList vertices) + public static Triangle ToSuperTriangle(this IList vertices) { float minX = float.MaxValue, minY = float.MaxValue; float maxX = float.MinValue, maxY = float.MinValue; - foreach (Vector2 point in vertices) + foreach (Vector2D point in vertices) { minX = MathF.Min(minX, point.X); minY = MathF.Min(minY, point.Y); @@ -31,21 +31,21 @@ public static class PhysicsMath float midX = (minX + maxX) / 2; float midY = (minY + maxY) / 2; - Vector2 p1 = new Vector2((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); - Vector2 p2 = new Vector2((float)midX, (float)midY + 20 * (float)deltaMax); - Vector2 p3 = new Vector2((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); + Vector2D p1 = new Vector2D((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); + Vector2D p2 = new Vector2D((float)midX, (float)midY + 20 * (float)deltaMax); + Vector2D p3 = new Vector2D((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); return new Triangle(p1, p2, p3); } - public static IList ToLines(this IList vertices) + public static IList ToLines(this IList vertices) { List lines = new List(vertices.Count - 1); ToLines(vertices, lines); return lines; } - public static void ToLines(this IList vertices, IList lines) + public static void ToLines(this IList vertices, IList lines) { lines.Clear(); for (int i = 0; i < vertices.Count - 1; i++) @@ -53,13 +53,13 @@ public static class PhysicsMath lines.Add(new(vertices[^1], vertices[0])); } - public static bool LaysOn(this Vector2 point, Line line) + public static bool LaysOn(this Vector2D point, Line line) => line.Resolve(point.X).ApproximatelyEquals(point); // Given three collinear points p, q, r, the function checks if // point q lies on line segment 'pr' - public static bool OnSegment(Vector2 p, Vector2 q, Vector2 r) + public static bool OnSegment(Vector2D p, Vector2D q, Vector2D r) { if (q.X <= MathF.Max(p.X, r.X) && q.X >= MathF.Min(p.X, r.X) && q.Y <= MathF.Max(p.Y, r.Y) && q.Y >= MathF.Min(p.Y, r.Y)) @@ -73,7 +73,7 @@ public static class PhysicsMath // 0 --> p, q and r are collinear // 1 --> Clockwise // 2 --> Counterclockwise - public static int Orientation(Vector2 p, Vector2 q, Vector2 r) + public static int Orientation(Vector2D p, Vector2D q, Vector2D r) { // See https://www.geeksforgeeks.org/orientation-3-ordered-points/ // for details of below formula. @@ -85,7 +85,7 @@ public static class PhysicsMath return (val > 0) ? 1 : 2; // clock or counterclock wise } - public static float IntersectionParameterT(Vector2 p0, Vector2 p1, Vector2 q0, Vector2 q1) + public static float IntersectionParameterT(Vector2D p0, Vector2D p1, Vector2D q0, Vector2D q1) => ((q0.X - p0.X) * (p1.Y - p0.Y) - (q0.Y - p0.Y) * (p1.X - p0.X)) / ((q1.Y - q0.Y) * (p1.X - p0.X) - (q1.X - q0.X) * (p1.Y - p0.Y)); @@ -96,6 +96,10 @@ public static class PhysicsMath => ApproximatelyEquals(a, b, float.Epsilon); public static bool ApproximatelyEquals(this Vector2 a, Vector2 b, float epsilon) => ApproximatelyEquals(a.X, b.X, epsilon) && ApproximatelyEquals(a.Y, b.Y, epsilon); + public static bool ApproximatelyEquals(this Vector2D a, Vector2D b) + => ApproximatelyEquals(a, b, float.Epsilon); + public static bool ApproximatelyEquals(this Vector2D a, Vector2D b, float epsilon) + => ApproximatelyEquals(a.X, b.X, epsilon) && ApproximatelyEquals(a.Y, b.Y, epsilon); public static bool ApproximatelyEquals(this float a, float b, float epsilon) { if (a == b) diff --git a/Game/Physics2D/Primitives/AABB.cs b/Game/Physics2D/Primitives/AABB.cs index e6d3c28..96e1560 100644 --- a/Game/Physics2D/Primitives/AABB.cs +++ b/Game/Physics2D/Primitives/AABB.cs @@ -1,10 +1,10 @@ -using Microsoft.Xna.Framework; +using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D.Primitives; -public record AABB(Vector2 LowerBoundary, Vector2 UpperBoundary) +public record AABB(Vector2D LowerBoundary, Vector2D UpperBoundary) { - public bool Overlaps(Vector2 point) + public bool Overlaps(Vector2D point) => point.X >= LowerBoundary.X && point.X <= UpperBoundary.X && point.Y >= LowerBoundary.Y && point.Y <= UpperBoundary.Y; diff --git a/Game/Physics2D/Primitives/Circle.cs b/Game/Physics2D/Primitives/Circle.cs index 386e651..1d30cf2 100644 --- a/Game/Physics2D/Primitives/Circle.cs +++ b/Game/Physics2D/Primitives/Circle.cs @@ -1,8 +1,8 @@ -using Microsoft.Xna.Framework; +using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D.Primitives; -public record Circle(Vector2 Position, float Radius) +public record Circle(Vector2D Position, float Radius) { public bool Intersects(Circle other) { @@ -12,7 +12,7 @@ public record Circle(Vector2 Position, float Radius) return distanceSquared < radiusSumSquared; } - public bool Overlaps(Vector2 point) => (Position - point).LengthSquared() <= Radius * Radius; + public bool Overlaps(Vector2D point) => (Position - point).LengthSquared() <= Radius * Radius; public bool ApproximatelyEquals(Circle other) => Position.ApproximatelyEquals(other.Position) && Radius.ApproximatelyEquals(other.Radius); } diff --git a/Game/Physics2D/Primitives/Line.cs b/Game/Physics2D/Primitives/Line.cs index 4b61625..bd3162c 100644 --- a/Game/Physics2D/Primitives/Line.cs +++ b/Game/Physics2D/Primitives/Line.cs @@ -2,14 +2,14 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using Microsoft.Xna.Framework; +using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D.Primitives; -public record Line(Vector2 From, Vector2 To) +public record Line(Vector2D From, Vector2D To) { public Line Reversed => new(To, From); - public Vector2 Direction => Vector2.Normalize(To - From); + public Vector2D Direction => Vector2D.Normalize(To - From); public float Length => (From - To).Length(); public float LengthSquared => (From - To).LengthSquared(); @@ -17,7 +17,7 @@ public record Line(Vector2 From, Vector2 To) { get { - Vector2 slopeVector = To - From; + Vector2D slopeVector = To - From; float slope = slopeVector.Y / slopeVector.X; float yOffset = From.Y - (slope * From.X); @@ -26,10 +26,10 @@ public record Line(Vector2 From, Vector2 To) } } - public bool Intersects(Vector2 point) + public bool Intersects(Vector2D point) => Resolve(point.X).ApproximatelyEquals(point); - public float GetT(Vector2 point) + public float GetT(Vector2D point) { float fromX = MathF.Abs(From.X); float toX = MathF.Abs(To.X); @@ -51,18 +51,18 @@ public record Line(Vector2 From, Vector2 To) return t; } - public bool Exist(List vertices) + public bool Exist(List vertices) { for (int i = 0; i < vertices.Count - 1; i++) { - Vector2 vertexCurrent = vertices[i]; - Vector2 vertexNext = vertices[i]; + Vector2D vertexCurrent = vertices[i]; + Vector2D vertexNext = vertices[i]; if (From == vertexCurrent && To == vertexNext) return true; if (From == vertexNext && To == vertexCurrent) return true; } - Vector2 vertexFirst = vertices[0]; - Vector2 vertexLast = vertices[^1]; + Vector2D vertexFirst = vertices[0]; + Vector2D vertexLast = vertices[^1]; if (From == vertexFirst && To == vertexLast) return true; if (From == vertexLast && To == vertexFirst) return true; return false; @@ -80,20 +80,20 @@ public record Line(Vector2 From, Vector2 To) return numerator / denominator; } - public Vector2 Lerp(float t) - => new Vector2( + public Vector2D Lerp(float t) + => new Vector2D( From.X + (To.X - From.X) * t, From.Y + (To.Y - From.Y) * t ); - public Vector2 Resolve(float x) - => new Vector2(x, LineEquation.Resolve(x)); + public Vector2D Resolve(float x) + => new Vector2D(x, LineEquation.Resolve(x)); - public Vector2 ClosestPointTo(Vector2 point) + public Vector2D ClosestPointTo(Vector2D point) { // Convert edge points to vectors - var edgeVector = new Vector2(To.X - From.X, To.Y - From.Y); - var pointVector = new Vector2(point.X - From.X, point.Y - From.Y); + var edgeVector = new Vector2D(To.X - From.X, To.Y - From.Y); + var pointVector = new Vector2D(point.X - From.X, point.Y - From.Y); // Calculate the projection of pointVector onto edgeVector float t = (pointVector.X * edgeVector.X + pointVector.Y * edgeVector.Y) / (edgeVector.X * edgeVector.X + edgeVector.Y * edgeVector.Y); @@ -105,11 +105,11 @@ public record Line(Vector2 From, Vector2 To) float closestX = From.X + t * edgeVector.X; float closestY = From.Y + t * edgeVector.Y; - return new Vector2((float)closestX, (float)closestY); + return new Vector2D((float)closestX, (float)closestY); } - public Vector2 IntersectionPoint(Line other) - => Vector2.Lerp(From, To, IntersectionParameterT(other)); + public Vector2D IntersectionPoint(Line other) + => Vector2D.Lerp(From, To, IntersectionParameterT(other)); public bool Intersects(Line other) { @@ -129,7 +129,7 @@ public record Line(Vector2 From, Vector2 To) return false; } - public bool Intersects(Line other, [NotNullWhen(returnValue: true)] out Vector2? point) + public bool Intersects(Line other, [NotNullWhen(returnValue: true)] out Vector2D? point) { point = null; diff --git a/Game/Physics2D/Primitives/Shape.cs b/Game/Physics2D/Primitives/Shape.cs index f5fa09b..8ba8dbf 100644 --- a/Game/Physics2D/Primitives/Shape.cs +++ b/Game/Physics2D/Primitives/Shape.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; -using Microsoft.Xna.Framework; +using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D.Primitives; -public record Shape(IList Vertices) +public record Shape(IList Vertices) { public Triangle SuperTriangle { @@ -14,7 +14,7 @@ public record Shape(IList Vertices) float minX = float.MaxValue, minY = float.MaxValue; float maxX = float.MinValue, maxY = float.MinValue; - foreach (Vector2 point in Vertices) + foreach (Vector2D point in Vertices) { minX = MathF.Min(minX, point.X); minY = MathF.Min(minY, point.Y); @@ -28,9 +28,9 @@ public record Shape(IList Vertices) float midX = (minX + maxX) / 2; float midY = (minY + maxY) / 2; - Vector2 p1 = new Vector2((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); - Vector2 p2 = new Vector2((float)midX, (float)midY + 20 * (float)deltaMax); - Vector2 p3 = new Vector2((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); + Vector2D p1 = new Vector2D((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); + Vector2D p2 = new Vector2D((float)midX, (float)midY + 20 * (float)deltaMax); + Vector2D p3 = new Vector2D((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); return new Triangle(p1, p2, p3); } diff --git a/Game/Physics2D/Primitives/Triangle.cs b/Game/Physics2D/Primitives/Triangle.cs index 7f01b8b..5ffcd6a 100644 --- a/Game/Physics2D/Primitives/Triangle.cs +++ b/Game/Physics2D/Primitives/Triangle.cs @@ -1,10 +1,10 @@ using System; -using Microsoft.Xna.Framework; +using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D.Primitives; -public record Triangle(Vector2 A, Vector2 B, Vector2 C) +public record Triangle(Vector2D A, Vector2D B, Vector2D C) { public float Area => MathF.Abs(( A.X * (B.Y - C.Y) + @@ -16,27 +16,27 @@ public record Triangle(Vector2 A, Vector2 B, Vector2 C) { get { - Vector2 midAB = (A + B) / 2; - Vector2 midBC = (B + C) / 2; + Vector2D midAB = (A + B) / 2; + Vector2D midBC = (B + C) / 2; float slopeAB = (B.Y - A.Y) / (B.X - A.X); float slopeBC = (C.Y - B.Y) / (C.X - B.X); - Vector2 center; + Vector2D center; if (MathF.Abs(slopeAB - slopeBC) > float.Epsilon) { float x = (slopeAB * slopeBC * (A.Y - C.Y) + slopeBC * (A.X + B.X) - slopeAB * (B.X + C.X)) / (2 * (slopeBC - slopeAB)); float y = -(x - (A.X + B.X) / 2) / slopeAB + (A.Y + B.Y) / 2; - center = new Vector2(x, y); + center = new Vector2D(x, y); } else center = (midAB + midBC) * .5f; - return new(center, Vector2.Distance(center, A)); + return new(center, Vector2D.Distance(center, A)); } } - public bool Overlaps(Vector2 point) + public bool Overlaps(Vector2D point) { float originalTriangleArea = Area; diff --git a/Game/Physics2D/RigidBody2D.cs b/Game/Physics2D/RigidBody2D.cs index efc384d..454a3ab 100644 --- a/Game/Physics2D/RigidBody2D.cs +++ b/Game/Physics2D/RigidBody2D.cs @@ -15,7 +15,7 @@ public class RigidBody2D : BehaviourOverride, IRigidBody2D public IPhysicsMaterial2D Material { get; set; } = null!; - public Vector2 Velocity { get; set; } = Vector2.Zero; + public Vector2D Velocity { get; set; } = Vector2D.Zero; public float AngularVelocity { get; set; } = 0f; public float Mass { get; set; } = 0f; ITransform IAssignableTransform.Transform => Transform;