Engine DeMonoGame #2
This commit is contained in:
parent
0486b0343a
commit
ba284a199a
2
Engine
2
Engine
|
@ -1 +1 @@
|
||||||
Subproject commit 485dfcc51ea548a50eec57b003bc3cb31cfdf579
|
Subproject commit 39e553ebbf61f398a3ed9a96b20f6819a197cd86
|
|
@ -6,12 +6,12 @@ using Syntriax.Engine.Input;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
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;
|
public float Speed { get; set; } = Speed;
|
||||||
|
|
||||||
protected override void OnFirstActiveFrame(GameTime time)
|
protected override void OnFirstActiveFrame()
|
||||||
{
|
{
|
||||||
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody))
|
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody))
|
||||||
throw new Exception($"Where's my {nameof(IRigidBody2D)}????");
|
throw new Exception($"Where's my {nameof(IRigidBody2D)}????");
|
||||||
|
|
|
@ -17,25 +17,25 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo
|
||||||
private bool isUpPressed = false;
|
private bool isUpPressed = false;
|
||||||
private bool isDownPressed = false;
|
private bool isDownPressed = false;
|
||||||
|
|
||||||
private IKeyboardInputs inputs = null!;
|
private IButtonInputs<Keys> inputs = null!;
|
||||||
|
|
||||||
protected override void OnUpdate(GameTime time)
|
protected override void OnUpdate()
|
||||||
{
|
{
|
||||||
if (isUpPressed && isDownPressed)
|
if (isUpPressed && isDownPressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (isUpPressed)
|
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)
|
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<IKeyboardInputs>(out var behaviourResult))
|
if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult))
|
||||||
throw new Exception($"{nameof(IKeyboardInputs)} is missing on ${GameObject.Name}.");
|
throw new Exception($"{nameof(IButtonInputs<Keys>)} is missing on ${GameObject.Name}.");
|
||||||
|
|
||||||
inputs = behaviourResult;
|
inputs = behaviourResult;
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo
|
||||||
inputs.UnregisterOnRelease(Down, OnDownReleased);
|
inputs.UnregisterOnRelease(Down, OnDownReleased);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUpPressed(IKeyboardInputs inputs, Keys keys) => isUpPressed = true;
|
private void OnUpPressed(IButtonInputs<Keys> inputs, Keys keys) => isUpPressed = true;
|
||||||
private void OnUpReleased(IKeyboardInputs inputs, Keys keys) => isUpPressed = false;
|
private void OnUpReleased(IButtonInputs<Keys> inputs, Keys keys) => isUpPressed = false;
|
||||||
private void OnDownPressed(IKeyboardInputs inputs, Keys keys) => isDownPressed = true;
|
private void OnDownPressed(IButtonInputs<Keys> inputs, Keys keys) => isDownPressed = true;
|
||||||
private void OnDownReleased(IKeyboardInputs inputs, Keys keys) => isDownPressed = false;
|
private void OnDownReleased(IButtonInputs<Keys> inputs, Keys keys) => isDownPressed = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -26,7 +26,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Engine\Engine.Core\Engine.Core.csproj" />
|
<ProjectReference Include="..\Engine\Engine.Core\Engine.Core.csproj" />
|
||||||
<ProjectReference Include="..\Engine\Engine.Input\Engine.Input.csproj" />
|
<ProjectReference Include="..\Engine\Engine.Input\Engine.Input.csproj" />
|
||||||
<ProjectReference Include="..\Engine\Engine.Graphics\Engine.Graphics.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
||||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
<Message Text="Restoring dotnet tools" Importance="High" />
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
@ -19,7 +18,9 @@ public class Game1 : Game
|
||||||
private PhysicsEngine2D engine;
|
private PhysicsEngine2D engine;
|
||||||
private SpriteBatch _spriteBatch = null!;
|
private SpriteBatch _spriteBatch = null!;
|
||||||
public static GameManager gameManager = null!;
|
public static GameManager gameManager = null!;
|
||||||
public static Sprite spriteBox = null!;
|
// public static Sprite spriteBox = null!;
|
||||||
|
private MonoGameCameraBehaviour cameraBehaviour;
|
||||||
|
|
||||||
|
|
||||||
public Game1()
|
public Game1()
|
||||||
{
|
{
|
||||||
|
@ -49,16 +50,16 @@ public class Game1 : Game
|
||||||
{
|
{
|
||||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
|
||||||
spriteBox = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Pixel") };
|
// spriteBox = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Pixel") };
|
||||||
Sprite spriteBall = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Circle") };
|
// Sprite spriteBall = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Circle") };
|
||||||
|
|
||||||
IGameObject gameObjectCamera = gameManager.InstantiateGameObject<GameObject>();
|
IGameObject gameObjectCamera = gameManager.InstantiateGameObject<GameObject>();
|
||||||
gameObjectCamera.Name = "Camera";
|
gameObjectCamera.Name = "Camera";
|
||||||
gameObjectCamera.Transform.Position = Vector2D.Zero;
|
gameObjectCamera.Transform.Position = Vector2D.Zero;
|
||||||
|
|
||||||
MonoGameCameraBehaviour monoGameCameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour<MonoGameCameraBehaviour>();
|
cameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour<MonoGameCameraBehaviour>();
|
||||||
monoGameCameraBehaviour.Viewport = GraphicsDevice.Viewport;
|
cameraBehaviour.Viewport = GraphicsDevice.Viewport;
|
||||||
gameManager.Camera = monoGameCameraBehaviour;
|
gameManager.Camera = cameraBehaviour;
|
||||||
|
|
||||||
GameObject gameObjectBall = gameManager.InstantiateGameObject<GameObject>();
|
GameObject gameObjectBall = gameManager.InstantiateGameObject<GameObject>();
|
||||||
gameObjectBall.Name = "Ball";
|
gameObjectBall.Name = "Ball";
|
||||||
|
@ -67,7 +68,7 @@ public class Game1 : Game
|
||||||
engine.AddRigidBody(gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>());
|
engine.AddRigidBody(gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>());
|
||||||
gameObjectBall.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2D(.1f, .1f), 500f);
|
gameObjectBall.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2D(.1f, .1f), 500f);
|
||||||
// gameObjectBall.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall);
|
// gameObjectBall.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall);
|
||||||
gameObjectBall.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2.One * 512f * .5f, Vector2.One * 512f * .5f);
|
gameObjectBall.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * 512f * .5f, Vector2D.One * 512f * .5f);
|
||||||
// gameObjectBall = gameManager.InstantiateGameObject<GameObject>();
|
// gameObjectBall = gameManager.InstantiateGameObject<GameObject>();
|
||||||
// gameObjectBall.Name = "Ball";
|
// gameObjectBall.Name = "Ball";
|
||||||
// gameObjectBall.Transform.Position = Vector2D.UnitY * 30f;
|
// gameObjectBall.Transform.Position = Vector2D.UnitY * 30f;
|
||||||
|
@ -102,26 +103,26 @@ public class Game1 : Game
|
||||||
goPlayAreaTop.Transform.Position = new Vector2D(0f, 288f + 20f);
|
goPlayAreaTop.Transform.Position = new Vector2D(0f, 288f + 20f);
|
||||||
goPlayAreaTop.Transform.Scale = new Vector2D(10240f, 40f);
|
goPlayAreaTop.Transform.Scale = new Vector2D(10240f, 40f);
|
||||||
// goPlayAreaTop.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
// goPlayAreaTop.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
||||||
goPlayAreaTop.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
// goPlayAreaTop.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
||||||
engine.AddRigidBody(goPlayAreaTop.BehaviourController.AddBehaviour<RigidBody2D>());
|
engine.AddRigidBody(goPlayAreaTop.BehaviourController.AddBehaviour<RigidBody2D>());
|
||||||
IGameObject goPlayAreaBottom = gameManager.InstantiateGameObject<GameObject>();
|
IGameObject goPlayAreaBottom = gameManager.InstantiateGameObject<GameObject>();
|
||||||
goPlayAreaBottom.Transform.Position = new Vector2D(0f, -(288f + 20f));
|
goPlayAreaBottom.Transform.Position = new Vector2D(0f, -(288f + 20f));
|
||||||
goPlayAreaBottom.Transform.Scale = new Vector2D(10240f, 40f);
|
goPlayAreaBottom.Transform.Scale = new Vector2D(10240f, 40f);
|
||||||
// goPlayAreaBottom.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
// goPlayAreaBottom.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
||||||
goPlayAreaBottom.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
// goPlayAreaBottom.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
||||||
engine.AddRigidBody(goPlayAreaBottom.BehaviourController.AddBehaviour<RigidBody2D>());
|
engine.AddRigidBody(goPlayAreaBottom.BehaviourController.AddBehaviour<RigidBody2D>());
|
||||||
|
|
||||||
IGameObject goPlayAreaRight = gameManager.InstantiateGameObject<GameObject>();
|
IGameObject goPlayAreaRight = gameManager.InstantiateGameObject<GameObject>();
|
||||||
goPlayAreaRight.Transform.Position = new Vector2D(512f + 20f, 0f);
|
goPlayAreaRight.Transform.Position = new Vector2D(512f + 20f, 0f);
|
||||||
goPlayAreaRight.Transform.Scale = new Vector2D(40f, 5760f);
|
goPlayAreaRight.Transform.Scale = new Vector2D(40f, 5760f);
|
||||||
// goPlayAreaRight.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
// goPlayAreaRight.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
||||||
goPlayAreaRight.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
// goPlayAreaRight.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
||||||
engine.AddRigidBody(goPlayAreaRight.BehaviourController.AddBehaviour<RigidBody2D>());
|
engine.AddRigidBody(goPlayAreaRight.BehaviourController.AddBehaviour<RigidBody2D>());
|
||||||
IGameObject goPlayAreaLeft = gameManager.InstantiateGameObject<GameObject>();
|
IGameObject goPlayAreaLeft = gameManager.InstantiateGameObject<GameObject>();
|
||||||
goPlayAreaLeft.Transform.Position = new Vector2D(-(512f + 20f), 0f);
|
goPlayAreaLeft.Transform.Position = new Vector2D(-(512f + 20f), 0f);
|
||||||
goPlayAreaLeft.Transform.Scale = new Vector2D(40f, 5760f);
|
goPlayAreaLeft.Transform.Scale = new Vector2D(40f, 5760f);
|
||||||
// goPlayAreaLeft.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
// goPlayAreaLeft.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
|
||||||
goPlayAreaLeft.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
// goPlayAreaLeft.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
|
||||||
engine.AddRigidBody(goPlayAreaLeft.BehaviourController.AddBehaviour<RigidBody2D>());
|
engine.AddRigidBody(goPlayAreaLeft.BehaviourController.AddBehaviour<RigidBody2D>());
|
||||||
|
|
||||||
// IGameObject goPlayAreaCenter = gameManager.InstantiateGameObject<GameObject>();
|
// IGameObject goPlayAreaCenter = gameManager.InstantiateGameObject<GameObject>();
|
||||||
|
@ -132,7 +133,7 @@ public class Game1 : Game
|
||||||
// TODO: use this.Content to load your game content here
|
// 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))
|
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||||
Exit();
|
Exit();
|
||||||
|
@ -148,21 +149,21 @@ public class Game1 : Game
|
||||||
_graphics.IsFullScreen = true;
|
_graphics.IsFullScreen = true;
|
||||||
_graphics.ApplyChanges();
|
_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));
|
float currentScreenSize = MathF.Sqrt(MathF.Pow(GraphicsDevice.Viewport.Width, 2f) + MathF.Pow(GraphicsDevice.Viewport.Height, 2f));
|
||||||
gameManager.Camera.Zoom /= previousScreenSize / currentScreenSize;
|
cameraBehaviour.Zoom /= previousScreenSize / currentScreenSize;
|
||||||
gameManager.Camera.Viewport = GraphicsDevice.Viewport;
|
cameraBehaviour.Viewport = GraphicsDevice.Viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.U))
|
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))
|
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))
|
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))
|
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))
|
if (Keyboard.GetState().IsKeyDown(Keys.N))
|
||||||
{
|
{
|
||||||
|
@ -210,7 +211,7 @@ public class Game1 : Game
|
||||||
// physicsTimer += 0.01f;
|
// physicsTimer += 0.01f;
|
||||||
// engine.Step(.01f);
|
// engine.Step(.01f);
|
||||||
// }
|
// }
|
||||||
gameManager.Update(gameTime);
|
gameManager.Update(gameTime.ToEngineTime());
|
||||||
base.Update(gameTime);
|
base.Update(gameTime);
|
||||||
}
|
}
|
||||||
static float physicsTimer = 0f;
|
static float physicsTimer = 0f;
|
||||||
|
@ -224,9 +225,9 @@ public class Game1 : Game
|
||||||
// Console.WriteLine($"Pos: {gameManager.Camera.Position}");
|
// Console.WriteLine($"Pos: {gameManager.Camera.Position}");
|
||||||
|
|
||||||
// TODO: Add your drawing code here
|
// TODO: Add your drawing code here
|
||||||
gameManager.PreDraw(gameTime);
|
gameManager.PreDraw();
|
||||||
gameManager.Camera.Update();
|
gameManager.Camera.Update();
|
||||||
gameManager.Draw(_spriteBatch);
|
// gameManager.Draw(_spriteBatch);
|
||||||
|
|
||||||
base.Draw(gameTime);
|
base.Draw(gameTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
@ -13,8 +12,8 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
|
||||||
|
|
||||||
IRigidBody2D? RigidBody2D { get; }
|
IRigidBody2D? RigidBody2D { get; }
|
||||||
|
|
||||||
IList<Vector2> Vertices { get; }
|
IList<Vector2D> Vertices { get; }
|
||||||
|
|
||||||
bool CheckCollision(Vector2 point);
|
bool CheckCollision(Vector2D point);
|
||||||
void Recalculate();
|
void Recalculate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
@ -8,7 +7,7 @@ public interface IRigidBody2D : IBehaviour, IAssignableTransform
|
||||||
{
|
{
|
||||||
IPhysicsMaterial2D Material { get; set; }
|
IPhysicsMaterial2D Material { get; set; }
|
||||||
|
|
||||||
Vector2 Velocity { get; set; }
|
Vector2D Velocity { get; set; }
|
||||||
float AngularVelocity { get; set; }
|
float AngularVelocity { get; set; }
|
||||||
|
|
||||||
float Mass { get; set; }
|
float Mass { get; set; }
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
@ -16,7 +14,7 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
|
||||||
public AABB AABBWorld { get; private set; } = null!;
|
public AABB AABBWorld { get; private set; } = null!;
|
||||||
|
|
||||||
private IRigidBody2D? _rigidBody2D = null;
|
private IRigidBody2D? _rigidBody2D = null;
|
||||||
private List<Vector2> _vertices = new List<Vector2>(4);
|
private List<Vector2D> _vertices = new List<Vector2D>(4);
|
||||||
|
|
||||||
public IRigidBody2D? RigidBody2D
|
public IRigidBody2D? RigidBody2D
|
||||||
{
|
{
|
||||||
|
@ -35,9 +33,9 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
|
||||||
ITransform IAssignableTransform.Transform => Transform;
|
ITransform IAssignableTransform.Transform => Transform;
|
||||||
public bool Assign(ITransform transform) => GameObject.Assign(transform);
|
public bool Assign(ITransform transform) => GameObject.Assign(transform);
|
||||||
|
|
||||||
public IList<Vector2> Vertices => _vertices;
|
public IList<Vector2D> Vertices => _vertices;
|
||||||
|
|
||||||
public bool CheckCollision(Vector2 point)
|
public bool CheckCollision(Vector2D point)
|
||||||
{
|
{
|
||||||
return AABBWorld.Overlaps(point);
|
return AABBWorld.Overlaps(point);
|
||||||
}
|
}
|
||||||
|
@ -51,11 +49,11 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
|
||||||
|
|
||||||
Vertices.Clear();
|
Vertices.Clear();
|
||||||
Vertices.Add(AABBWorld.LowerBoundary);
|
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(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);
|
AABBLocal = new AABB(lowerBoundary, upperBoundary);
|
||||||
AABBWorld = new AABB(lowerBoundary, upperBoundary);
|
AABBWorld = new AABB(lowerBoundary, upperBoundary);
|
||||||
|
@ -63,7 +61,7 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
|
||||||
|
|
||||||
public Collider2DAABBBehaviour()
|
public Collider2DAABBBehaviour()
|
||||||
{
|
{
|
||||||
AABBLocal = new(Vector2.Zero, Vector2.Zero);
|
AABBLocal = new(Vector2D.Zero, Vector2D.Zero);
|
||||||
AABBWorld = new(Vector2.Zero, Vector2.Zero);
|
AABBWorld = new(Vector2D.Zero, Vector2D.Zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
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)
|
if (c1.RigidBody2D is not IRigidBody2D)
|
||||||
return;
|
return;
|
||||||
|
@ -71,16 +71,16 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
|
|
||||||
c2.Vertices.ToLines(lines);
|
c2.Vertices.ToLines(lines);
|
||||||
|
|
||||||
Vector2 normal = Vector2.UnitY;
|
Vector2D normal = Vector2D.Up;
|
||||||
float t = 1f;
|
float t = 1f;
|
||||||
bool hasIntersectedWithLines = false;
|
bool hasIntersectedWithLines = false;
|
||||||
|
|
||||||
foreach (var line in lines)
|
foreach (var line in lines)
|
||||||
{
|
{
|
||||||
if (!vertexTrajectory.Intersects(line, out Vector2? intersectionPoint))
|
if (!vertexTrajectory.Intersects(line, out Vector2D? intersectionPoint))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (intersectionPoint is not Vector2 ip)
|
if (intersectionPoint is not Vector2D ip)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float tTemp = vertexTrajectory.GetT(ip);
|
float tTemp = vertexTrajectory.GetT(ip);
|
||||||
|
@ -88,7 +88,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
t = tTemp;
|
t = tTemp;
|
||||||
Vector2 lineDirection = line.Direction;
|
Vector2D lineDirection = line.Direction;
|
||||||
normal = new(lineDirection.Y, lineDirection.X);
|
normal = new(lineDirection.Y, lineDirection.X);
|
||||||
hasIntersectedWithLines = true;
|
hasIntersectedWithLines = true;
|
||||||
}
|
}
|
||||||
|
@ -99,11 +99,11 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
float rewindInterval = intervalDeltaTime - t * intervalDeltaTime;
|
float rewindInterval = intervalDeltaTime - t * intervalDeltaTime;
|
||||||
StepRigidBody(c1.RigidBody2D, -rewindInterval);
|
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);
|
StepRigidBody(c1.RigidBody2D, rewindInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckCollisions(ICollider2D collider2D, List<ICollider2D> collider2Ds, Action<ICollider2D, ICollider2D, Vector2> OnCollisionDetectedAction)
|
private void CheckCollisions(ICollider2D collider2D, List<ICollider2D> collider2Ds, Action<ICollider2D, ICollider2D, Vector2D> OnCollisionDetectedAction)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < collider2Ds.Count; i++)
|
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++)
|
for (int y = 0; y < collider2D.Vertices.Count; y++)
|
||||||
{
|
{
|
||||||
Vector2 vertex = collider2D.Vertices[y];
|
Vector2D vertex = collider2D.Vertices[y];
|
||||||
if (collider2DItem.CheckCollision(vertex))
|
if (collider2DItem.CheckCollision(vertex))
|
||||||
{
|
{
|
||||||
OnCollisionDetectedAction?.Invoke(collider2D, collider2DItem, vertex);
|
OnCollisionDetectedAction?.Invoke(collider2D, collider2DItem, vertex);
|
||||||
|
@ -128,7 +128,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
|
|
||||||
private void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
|
private void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
|
||||||
{
|
{
|
||||||
Vector2 nextPosition = rigidBody.Transform.Position;
|
Vector2D nextPosition = rigidBody.Transform.Position;
|
||||||
nextPosition += rigidBody.Velocity * intervalDeltaTime;
|
nextPosition += rigidBody.Velocity * intervalDeltaTime;
|
||||||
|
|
||||||
rigidBody.Transform.Position = nextPosition;
|
rigidBody.Transform.Position = nextPosition;
|
||||||
|
|
|
@ -2,22 +2,22 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
public static class PhysicsMath
|
public static class PhysicsMath
|
||||||
{
|
{
|
||||||
public static Vector2 Scale(this Vector2 original, Vector2 scale)
|
public static Vector2D Scale(this Vector2D original, Vector2D scale)
|
||||||
=> new Vector2(original.X * scale.X, original.Y * scale.Y);
|
=> new Vector2D(original.X * scale.X, original.Y * scale.Y);
|
||||||
|
|
||||||
public static Triangle ToSuperTriangle(this IList<Vector2> vertices)
|
public static Triangle ToSuperTriangle(this IList<Vector2D> vertices)
|
||||||
{
|
{
|
||||||
float minX = float.MaxValue, minY = float.MaxValue;
|
float minX = float.MaxValue, minY = float.MaxValue;
|
||||||
float maxX = float.MinValue, maxY = float.MinValue;
|
float maxX = float.MinValue, maxY = float.MinValue;
|
||||||
|
|
||||||
foreach (Vector2 point in vertices)
|
foreach (Vector2D point in vertices)
|
||||||
{
|
{
|
||||||
minX = MathF.Min(minX, point.X);
|
minX = MathF.Min(minX, point.X);
|
||||||
minY = MathF.Min(minY, point.Y);
|
minY = MathF.Min(minY, point.Y);
|
||||||
|
@ -31,21 +31,21 @@ public static class PhysicsMath
|
||||||
float midX = (minX + maxX) / 2;
|
float midX = (minX + maxX) / 2;
|
||||||
float midY = (minY + maxY) / 2;
|
float midY = (minY + maxY) / 2;
|
||||||
|
|
||||||
Vector2 p1 = new Vector2((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax);
|
Vector2D p1 = new Vector2D((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax);
|
||||||
Vector2 p2 = new Vector2((float)midX, (float)midY + 20 * (float)deltaMax);
|
Vector2D p2 = new Vector2D((float)midX, (float)midY + 20 * (float)deltaMax);
|
||||||
Vector2 p3 = new Vector2((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax);
|
Vector2D p3 = new Vector2D((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax);
|
||||||
|
|
||||||
return new Triangle(p1, p2, p3);
|
return new Triangle(p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IList<Line> ToLines(this IList<Vector2> vertices)
|
public static IList<Line> ToLines(this IList<Vector2D> vertices)
|
||||||
{
|
{
|
||||||
List<Line> lines = new List<Line>(vertices.Count - 1);
|
List<Line> lines = new List<Line>(vertices.Count - 1);
|
||||||
ToLines(vertices, lines);
|
ToLines(vertices, lines);
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ToLines(this IList<Vector2> vertices, IList<Line> lines)
|
public static void ToLines(this IList<Vector2D> vertices, IList<Line> lines)
|
||||||
{
|
{
|
||||||
lines.Clear();
|
lines.Clear();
|
||||||
for (int i = 0; i < vertices.Count - 1; i++)
|
for (int i = 0; i < vertices.Count - 1; i++)
|
||||||
|
@ -53,13 +53,13 @@ public static class PhysicsMath
|
||||||
lines.Add(new(vertices[^1], vertices[0]));
|
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);
|
=> line.Resolve(point.X).ApproximatelyEquals(point);
|
||||||
|
|
||||||
|
|
||||||
// Given three collinear points p, q, r, the function checks if
|
// Given three collinear points p, q, r, the function checks if
|
||||||
// point q lies on line segment 'pr'
|
// 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) &&
|
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))
|
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
|
// 0 --> p, q and r are collinear
|
||||||
// 1 --> Clockwise
|
// 1 --> Clockwise
|
||||||
// 2 --> Counterclockwise
|
// 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/
|
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
|
||||||
// for details of below formula.
|
// for details of below formula.
|
||||||
|
@ -85,7 +85,7 @@ public static class PhysicsMath
|
||||||
return (val > 0) ? 1 : 2; // clock or counterclock wise
|
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)) /
|
=> ((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));
|
((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);
|
=> ApproximatelyEquals(a, b, float.Epsilon);
|
||||||
public static bool ApproximatelyEquals(this Vector2 a, Vector2 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);
|
=> 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)
|
public static bool ApproximatelyEquals(this float a, float b, float epsilon)
|
||||||
{
|
{
|
||||||
if (a == b)
|
if (a == b)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
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.X >= LowerBoundary.X && point.X <= UpperBoundary.X &&
|
||||||
point.Y >= LowerBoundary.Y && point.Y <= UpperBoundary.Y;
|
point.Y >= LowerBoundary.Y && point.Y <= UpperBoundary.Y;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
public record Circle(Vector2 Position, float Radius)
|
public record Circle(Vector2D Position, float Radius)
|
||||||
{
|
{
|
||||||
public bool Intersects(Circle other)
|
public bool Intersects(Circle other)
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ public record Circle(Vector2 Position, float Radius)
|
||||||
return distanceSquared < radiusSumSquared;
|
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)
|
public bool ApproximatelyEquals(Circle other)
|
||||||
=> Position.ApproximatelyEquals(other.Position) && Radius.ApproximatelyEquals(other.Radius);
|
=> Position.ApproximatelyEquals(other.Position) && Radius.ApproximatelyEquals(other.Radius);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,14 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
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 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 Length => (From - To).Length();
|
||||||
public float LengthSquared => (From - To).LengthSquared();
|
public float LengthSquared => (From - To).LengthSquared();
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public record Line(Vector2 From, Vector2 To)
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Vector2 slopeVector = To - From;
|
Vector2D slopeVector = To - From;
|
||||||
float slope = slopeVector.Y / slopeVector.X;
|
float slope = slopeVector.Y / slopeVector.X;
|
||||||
|
|
||||||
float yOffset = From.Y - (slope * From.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);
|
=> Resolve(point.X).ApproximatelyEquals(point);
|
||||||
|
|
||||||
public float GetT(Vector2 point)
|
public float GetT(Vector2D point)
|
||||||
{
|
{
|
||||||
float fromX = MathF.Abs(From.X);
|
float fromX = MathF.Abs(From.X);
|
||||||
float toX = MathF.Abs(To.X);
|
float toX = MathF.Abs(To.X);
|
||||||
|
@ -51,18 +51,18 @@ public record Line(Vector2 From, Vector2 To)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exist(List<Vector2> vertices)
|
public bool Exist(List<Vector2D> vertices)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < vertices.Count - 1; i++)
|
for (int i = 0; i < vertices.Count - 1; i++)
|
||||||
{
|
{
|
||||||
Vector2 vertexCurrent = vertices[i];
|
Vector2D vertexCurrent = vertices[i];
|
||||||
Vector2 vertexNext = vertices[i];
|
Vector2D vertexNext = vertices[i];
|
||||||
if (From == vertexCurrent && To == vertexNext) return true;
|
if (From == vertexCurrent && To == vertexNext) return true;
|
||||||
if (From == vertexNext && To == vertexCurrent) return true;
|
if (From == vertexNext && To == vertexCurrent) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 vertexFirst = vertices[0];
|
Vector2D vertexFirst = vertices[0];
|
||||||
Vector2 vertexLast = vertices[^1];
|
Vector2D vertexLast = vertices[^1];
|
||||||
if (From == vertexFirst && To == vertexLast) return true;
|
if (From == vertexFirst && To == vertexLast) return true;
|
||||||
if (From == vertexLast && To == vertexFirst) return true;
|
if (From == vertexLast && To == vertexFirst) return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -80,20 +80,20 @@ public record Line(Vector2 From, Vector2 To)
|
||||||
return numerator / denominator;
|
return numerator / denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 Lerp(float t)
|
public Vector2D Lerp(float t)
|
||||||
=> new Vector2(
|
=> new Vector2D(
|
||||||
From.X + (To.X - From.X) * t,
|
From.X + (To.X - From.X) * t,
|
||||||
From.Y + (To.Y - From.Y) * t
|
From.Y + (To.Y - From.Y) * t
|
||||||
);
|
);
|
||||||
|
|
||||||
public Vector2 Resolve(float x)
|
public Vector2D Resolve(float x)
|
||||||
=> new Vector2(x, LineEquation.Resolve(x));
|
=> new Vector2D(x, LineEquation.Resolve(x));
|
||||||
|
|
||||||
public Vector2 ClosestPointTo(Vector2 point)
|
public Vector2D ClosestPointTo(Vector2D point)
|
||||||
{
|
{
|
||||||
// Convert edge points to vectors
|
// Convert edge points to vectors
|
||||||
var edgeVector = new Vector2(To.X - From.X, To.Y - From.Y);
|
var edgeVector = new Vector2D(To.X - From.X, To.Y - From.Y);
|
||||||
var pointVector = new Vector2(point.X - From.X, point.Y - From.Y);
|
var pointVector = new Vector2D(point.X - From.X, point.Y - From.Y);
|
||||||
|
|
||||||
// Calculate the projection of pointVector onto edgeVector
|
// 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);
|
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 closestX = From.X + t * edgeVector.X;
|
||||||
float closestY = From.Y + t * edgeVector.Y;
|
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)
|
public Vector2D IntersectionPoint(Line other)
|
||||||
=> Vector2.Lerp(From, To, IntersectionParameterT(other));
|
=> Vector2D.Lerp(From, To, IntersectionParameterT(other));
|
||||||
|
|
||||||
public bool Intersects(Line other)
|
public bool Intersects(Line other)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +129,7 @@ public record Line(Vector2 From, Vector2 To)
|
||||||
return false;
|
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;
|
point = null;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
public record Shape(IList<Vector2> Vertices)
|
public record Shape(IList<Vector2D> Vertices)
|
||||||
{
|
{
|
||||||
public Triangle SuperTriangle
|
public Triangle SuperTriangle
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ public record Shape(IList<Vector2> Vertices)
|
||||||
float minX = float.MaxValue, minY = float.MaxValue;
|
float minX = float.MaxValue, minY = float.MaxValue;
|
||||||
float maxX = float.MinValue, maxY = float.MinValue;
|
float maxX = float.MinValue, maxY = float.MinValue;
|
||||||
|
|
||||||
foreach (Vector2 point in Vertices)
|
foreach (Vector2D point in Vertices)
|
||||||
{
|
{
|
||||||
minX = MathF.Min(minX, point.X);
|
minX = MathF.Min(minX, point.X);
|
||||||
minY = MathF.Min(minY, point.Y);
|
minY = MathF.Min(minY, point.Y);
|
||||||
|
@ -28,9 +28,9 @@ public record Shape(IList<Vector2> Vertices)
|
||||||
float midX = (minX + maxX) / 2;
|
float midX = (minX + maxX) / 2;
|
||||||
float midY = (minY + maxY) / 2;
|
float midY = (minY + maxY) / 2;
|
||||||
|
|
||||||
Vector2 p1 = new Vector2((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax);
|
Vector2D p1 = new Vector2D((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax);
|
||||||
Vector2 p2 = new Vector2((float)midX, (float)midY + 20 * (float)deltaMax);
|
Vector2D p2 = new Vector2D((float)midX, (float)midY + 20 * (float)deltaMax);
|
||||||
Vector2 p3 = new Vector2((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax);
|
Vector2D p3 = new Vector2D((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax);
|
||||||
|
|
||||||
return new Triangle(p1, p2, p3);
|
return new Triangle(p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
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((
|
public float Area => MathF.Abs((
|
||||||
A.X * (B.Y - C.Y) +
|
A.X * (B.Y - C.Y) +
|
||||||
|
@ -16,27 +16,27 @@ public record Triangle(Vector2 A, Vector2 B, Vector2 C)
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Vector2 midAB = (A + B) / 2;
|
Vector2D midAB = (A + B) / 2;
|
||||||
Vector2 midBC = (B + C) / 2;
|
Vector2D midBC = (B + C) / 2;
|
||||||
|
|
||||||
float slopeAB = (B.Y - A.Y) / (B.X - A.X);
|
float slopeAB = (B.Y - A.Y) / (B.X - A.X);
|
||||||
float slopeBC = (C.Y - B.Y) / (C.X - B.X);
|
float slopeBC = (C.Y - B.Y) / (C.X - B.X);
|
||||||
|
|
||||||
Vector2 center;
|
Vector2D center;
|
||||||
if (MathF.Abs(slopeAB - slopeBC) > float.Epsilon)
|
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 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;
|
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
|
else
|
||||||
center = (midAB + midBC) * .5f;
|
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;
|
float originalTriangleArea = Area;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class RigidBody2D : BehaviourOverride, IRigidBody2D
|
||||||
|
|
||||||
public IPhysicsMaterial2D Material { get; set; } = null!;
|
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 AngularVelocity { get; set; } = 0f;
|
||||||
public float Mass { get; set; } = 0f;
|
public float Mass { get; set; } = 0f;
|
||||||
ITransform IAssignableTransform.Transform => Transform;
|
ITransform IAssignableTransform.Transform => Transform;
|
||||||
|
|
Loading…
Reference in New Issue