Compare commits
6 Commits
a1f63d2728
...
ab0e868d52
Author | SHA1 | Date | |
---|---|---|---|
ab0e868d52 | |||
0257911018 | |||
2b19b24a26 | |||
2f4137dae2 | |||
4ce9c8e0d9 | |||
3e9c393817 |
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignable
|
public interface IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
|
/// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignable>? OnUnassigned { get; set; }
|
Action<IAssignable>? OnUnassigned { get; set; }
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignableBehaviourController : IAssignable
|
public interface IAssignableBehaviourController : IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; }
|
Action<IAssignableBehaviourController>? OnBehaviourControllerAssigned { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public interface IAssignableBehaviourController : IAssignable
|
|||||||
IBehaviourController BehaviourController { get; }
|
IBehaviourController BehaviourController { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign a value to the <see cref="IBehaviourController"/> field of this object
|
/// Assign a value to the <see cref="IBehaviourController"/> field of this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="behaviourController">New <see cref="IBehaviourController"/> to assign.</param>
|
/// <param name="behaviourController">New <see cref="IBehaviourController"/> to assign.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignableEntity : IAssignable
|
public interface IAssignableEntity : IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IEntity"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableEntity>? OnEntityAssigned { get; set; }
|
Action<IAssignableEntity>? OnEntityAssigned { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public interface IAssignableEntity : IAssignable
|
|||||||
IEntity Entity { get; }
|
IEntity Entity { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign a value to the <see cref="IEntity"/> field of this object
|
/// Assign a value to the <see cref="IEntity"/> field of this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">New <see cref="IEntity"/> to assign.</param>
|
/// <param name="entity">New <see cref="IEntity"/> to assign.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignableGameManager : IAssignable
|
public interface IAssignableGameManager : IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IGameManager"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; }
|
Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public interface IAssignableGameManager : IAssignable
|
|||||||
IGameManager GameManager { get; }
|
IGameManager GameManager { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign a value to the <see cref="IGameManager"/> field of this object
|
/// Assign a value to the <see cref="IGameManager"/> field of this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gameManager">New <see cref="IGameManager"/> to assign.</param>
|
/// <param name="gameManager">New <see cref="IGameManager"/> to assign.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignableGameObject : IAssignable
|
public interface IAssignableGameObject : IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IGameObject"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IGameObject"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; }
|
Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public interface IAssignableGameObject : IAssignable
|
|||||||
IGameObject GameObject { get; }
|
IGameObject GameObject { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign a value to the <see cref="IGameObject"/> field of this object
|
/// Assign a value to the <see cref="IGameObject"/> field of this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gameObject">New <see cref="IGameObject"/> to assign.</param>
|
/// <param name="gameObject">New <see cref="IGameObject"/> to assign.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignableStateEnable : IAssignable
|
public interface IAssignableStateEnable : IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; }
|
Action<IAssignableStateEnable>? OnStateEnableAssigned { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public interface IAssignableStateEnable : IAssignable
|
|||||||
IStateEnable StateEnable { get; }
|
IStateEnable StateEnable { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign a value to the <see cref="IStateEnable"/> field of this object
|
/// Assign a value to the <see cref="IStateEnable"/> field of this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stateEnable">New <see cref="IStateEnable"/> to assign.</param>
|
/// <param name="stateEnable">New <see cref="IStateEnable"/> to assign.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@@ -8,7 +8,7 @@ namespace Syntriax.Engine.Core.Abstract;
|
|||||||
public interface IAssignableTransform : IAssignable
|
public interface IAssignableTransform : IAssignable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="ITransform"/> value has has been assigned a new value.
|
/// Event triggered when the <see cref="ITransform"/> value has has been assigned a new value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IAssignableTransform>? OnTransformAssigned { get; set; }
|
Action<IAssignableTransform>? OnTransformAssigned { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ public interface IAssignableTransform : IAssignable
|
|||||||
ITransform Transform { get; }
|
ITransform Transform { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign a value to the <see cref="ITransform"/> field of this object
|
/// Assign a value to the <see cref="ITransform"/> field of this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="transform">New <see cref="ITransform"/> to assign.</param>
|
/// <param name="transform">New <see cref="ITransform"/> to assign.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@@ -3,22 +3,22 @@ using System;
|
|||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Responsible for every behaviour an object in the game might have, controlled by <see cref="IBehaviourController"/>.
|
/// Represents a behaviour that any object in the game might use to interact with itself or other objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignableStateEnable, IInitialize
|
public interface IBehaviour : IEntity, IAssignableBehaviourController, IAssignableStateEnable, IInitialize
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="Priority"/> has changed.
|
/// Event triggered when the priority of the <see cref="IBehaviour"/> changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviour>? OnPriorityChanged { get; set; }
|
Action<IBehaviour>? OnPriorityChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call priority of the <see cref="IBehaviour"/>.
|
/// The priority of the <see cref="IBehaviour"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int Priority { get; set; }
|
int Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the <see cref="IBehaviour"/> is active.
|
/// The value indicating whether the <see cref="IBehaviour"/> is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsActive { get; }
|
bool IsActive { get; }
|
||||||
}
|
}
|
||||||
|
@@ -5,102 +5,101 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Responsible for controlling <see cref="IBehaviour"/>s and notify them accordingly about the engine's updates. Connected to an <see cref="IGameObject"/>.
|
/// Represents a controller for managing <see cref="IBehaviour"/>s and notify them accordingly about the engine's updates. Connected to an <see cref="IGameObject"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBehaviourController : IAssignableGameObject, IEnumerable<IBehaviour>
|
public interface IBehaviourController : IAssignableGameObject, IEnumerable<IBehaviour>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="Update()"/> is called but right before the <see cref="OnUpdate"/> action is triggered.
|
/// Event triggered before the update of <see cref="IBehaviour"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController>? OnPreUpdate { get; set; }
|
Action<IBehaviourController>? OnPreUpdate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="Update()"/> is called.
|
/// Event triggered during the update of <see cref="IBehaviour"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController>? OnUpdate { get; set; }
|
Action<IBehaviourController>? OnUpdate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="OnPreDraw()"/> is called.
|
/// Event triggered before the drawing phase.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController>? OnPreDraw { get; set; }
|
Action<IBehaviourController>? OnPreDraw { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IBehaviourController"/> has been registered a new <see cref="IBehaviour"/>.
|
/// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController, IBehaviour>? OnBehaviourAdded { get; set; }
|
Action<IBehaviourController, IBehaviour>? OnBehaviourAdded { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback triggered when the <see cref="IBehaviourController"/> has been removed an existing <see cref="IBehaviour"/>.
|
/// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action<IBehaviourController, IBehaviour>? OnBehaviourRemoved { get; set; }
|
Action<IBehaviourController, IBehaviour>? OnBehaviourRemoved { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers the provided <see cref="IBehaviour"/> to be controlled by the <see cref="IBehaviourController"/>.
|
/// Adds a <see cref="IBehaviour"/> to the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="behaviour">Uninitialized <see cref="IBehaviour"/> to be registered.</param>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to add.</typeparam>
|
||||||
/// <typeparam name="T">An implemented class of <see cref="IBehaviour"/></typeparam>
|
/// <param name="behaviour">The <see cref="IBehaviour"/> to add.</param>
|
||||||
/// <returns>The provided <see cref="IBehaviour"/> class after initialization.</returns>
|
/// <returns>The added <see cref="IBehaviour"/>.</returns>
|
||||||
T AddBehaviour<T>(T behaviour) where T : class, IBehaviour;
|
T AddBehaviour<T>(T behaviour) where T : class, IBehaviour;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates the provided <see cref="IBehaviour"/> type and registers it to the <see cref="IBehaviourController"/>.
|
/// Adds a <see cref="IBehaviour"/> of the specified type to the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">Constructor parameters for the given <see cref="IBehaviour"/> class.</param>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to add.</typeparam>
|
||||||
/// <typeparam name="T">An implemented class of <see cref="IBehaviour"/></typeparam>
|
/// <param name="args">Construction parameters for the <see cref="IBehaviour"/>.</param>
|
||||||
/// <returns>The instantiated <see cref="IBehaviour"/> class after initialization.</returns>
|
/// <returns>The added <see cref="IBehaviour"/>.</returns>
|
||||||
T AddBehaviour<T>(params object?[]? args) where T : class, IBehaviour;
|
T AddBehaviour<T>(params object?[]? args) where T : class, IBehaviour;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up and returns the <see cref="IBehaviour"/> that is controlled by the <see cref="IBehaviourController"/>.
|
/// Gets a <see cref="IBehaviour"/> of the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">An implemented class or <see cref="interface"/></typeparam>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
||||||
/// <returns>
|
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, <see cref="null"/>.</returns>
|
||||||
/// <see cref="T"/>, if the type of <see cref="IBehaviour"/> is present in the <see cref="IBehaviourController"/>, <see cref="null"/> if not.
|
|
||||||
/// </returns>
|
|
||||||
T? GetBehaviour<T>();
|
T? GetBehaviour<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up and tries to get the <see cref="IBehaviour"/> that is controlled by the <see cref="IBehaviourController"/>.
|
/// Tries to get a <see cref="IBehaviour"/> of the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="behaviour">If return value is <see cref="true"/> outputs the class found in the <see cref="IBehaviourController"/>. If the return value is falls, this parameter is <see cref="null"/></param>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
|
||||||
/// <typeparam name="T">An implemented class or <see cref="interface"/></typeparam>
|
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, see.</param>
|
||||||
/// <returns>
|
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found; otherwise, <see cref="false"/>.</returns>
|
||||||
/// <see cref="true"/>, if the type of <see cref="IBehaviour"/> is present in the <see cref="IBehaviourController"/>, <see cref="false"/> if not.
|
|
||||||
/// </returns>
|
|
||||||
bool TryGetBehaviour<T>([NotNullWhen(returnValue: true)] out T? behaviour);
|
bool TryGetBehaviour<T>([NotNullWhen(returnValue: true)] out T? behaviour);
|
||||||
|
|
||||||
/// <typeparam name="T">An implemented class or <see cref="interface"/>.</typeparam>
|
/// <summary>
|
||||||
/// <returns>Returns a list of all the matching <see cref="IBehaviour"/>s found in the <see cref="IBehaviourController"/>.</returns>
|
/// Gets all <see cref="IBehaviour"/>s of the specified type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/>s to get.</typeparam>
|
||||||
|
/// <returns>A list of <see cref="IBehaviour"/>s of the specified type.</returns>
|
||||||
IList<T> GetBehaviours<T>();
|
IList<T> GetBehaviours<T>();
|
||||||
|
|
||||||
/// <typeparam name="T">An implemented class or <see cref="interface"/>.</typeparam>
|
/// <summary>
|
||||||
/// <returns>Fills the provided list parameter all the matching <see cref="IBehaviour"/>s found in the <see cref="IBehaviourController"/>.</returns>
|
/// Gets all <see cref="IBehaviour"/>s of the specified type and stores them in the provided list.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/>s to get.</typeparam>
|
||||||
|
/// <param name="behaviours">The list to store the <see cref="IBehaviour"/>s.</param>
|
||||||
void GetBehaviours<T>(List<T> behaviours);
|
void GetBehaviours<T>(List<T> behaviours);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the <see cref="IBehaviour"/> found in the <see cref="IBehaviourController"/>.
|
/// Removes <see cref="IBehaviour"/>s of the specified type from the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="removeAll">If all of the instances of the given Type is to be removed or not.</param>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/>s to remove.</typeparam>
|
||||||
/// <typeparam name="T">An implemented class or <see cref="interface"/> of <see cref="IBehaviour"/></typeparam>
|
/// <param name="removeAll">A flag indicating whether to remove all <see cref="IBehaviour"/>s of the specified type.</param>
|
||||||
void RemoveBehaviour<T>(bool removeAll = false) where T : class, IBehaviour;
|
void RemoveBehaviour<T>(bool removeAll = false) where T : class, IBehaviour;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the <see cref="IBehaviour"/> found in the <see cref="IBehaviourController"/>.
|
/// Removes the specified <see cref="IBehaviour"/> from the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="removeAll">If all of the instances of the given Type is to be removed or not.</param>
|
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to remove.</typeparam>
|
||||||
/// <typeparam name="T">An implemented class or <see cref="interface"/> of <see cref="IBehaviour"/></typeparam>
|
/// <param name="behaviour">The <see cref="IBehaviour"/> to remove.</param>
|
||||||
void RemoveBehaviour<T>(T behaviour) where T : class, IBehaviour;
|
void RemoveBehaviour<T>(T behaviour) where T : class, IBehaviour;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// To be called in every frame of the engine. Responsible for notifying <see cref="IBehaviour"/>'s under the <see cref="IBehaviourController"/>'s control that a new frame is happening.
|
/// Updates all <see cref="IBehaviour"/>s in the <see cref="IBehaviourController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name=""><see cref=""/> information from the game.</param>
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// To be called before every draw call from the engine. Responsible for notifying <see cref="IBehaviour"/>'s under the <see cref="IBehaviourController"/>'s control that the engine is about to start drawing into the screen.
|
/// Performs pre-draw operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name=""><see cref=""/> information from the game.</param>
|
|
||||||
void UpdatePreDraw();
|
void UpdatePreDraw();
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,26 @@
|
|||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D camera in the engine.
|
||||||
|
/// </summary>
|
||||||
public interface ICamera2D : IBehaviour, IAssignableTransform
|
public interface ICamera2D : IBehaviour, IAssignableTransform
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The zoom level of the camera.
|
||||||
|
/// </summary>
|
||||||
float Zoom { get; set; }
|
float Zoom { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a position from screen coordinates to world coordinates.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="screenPosition">The position in screen coordinates.</param>
|
||||||
|
/// <returns>The position in world coordinates.</returns>
|
||||||
Vector2D ScreenToWorldPosition(Vector2D screenPosition);
|
Vector2D ScreenToWorldPosition(Vector2D screenPosition);
|
||||||
Vector2D WorldToScreenPosition(Vector2D screenPosition);
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a position from world coordinates to screen coordinates.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="worldPosition">The position in world coordinates.</param>
|
||||||
|
/// <returns>The position in screen coordinates.</returns>
|
||||||
|
Vector2D WorldToScreenPosition(Vector2D worldPosition);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a basic entity in the engine.
|
||||||
|
/// </summary>
|
||||||
public interface IEntity : IInitialize, IAssignableStateEnable
|
public interface IEntity : IInitialize, IAssignableStateEnable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -3,19 +3,55 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a game world responsible for managing <see cref="IGameObject"/>s.
|
||||||
|
/// </summary>
|
||||||
public interface IGameManager : IEntity, IEnumerable<IGameObject>
|
public interface IGameManager : IEntity, IEnumerable<IGameObject>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when a <see cref="IGameObject"/> is registered to the <see cref="IGameManager"/>.
|
||||||
|
/// </summary>
|
||||||
Action<IGameManager, IGameObject>? OnGameObjectRegistered { get; set; }
|
Action<IGameManager, IGameObject>? OnGameObjectRegistered { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when a <see cref="IGameObject"/> is unregistered from the <see cref="IGameManager"/>.
|
||||||
|
/// </summary>
|
||||||
Action<IGameManager, IGameObject>? OnGameObjectUnRegistered { get; set; }
|
Action<IGameManager, IGameObject>? OnGameObjectUnRegistered { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a read-only list of <see cref="IGameObject"/>s managed by the <see cref="IGameManager"/>.
|
||||||
|
/// </summary>
|
||||||
IReadOnlyList<IGameObject> GameObjects { get; }
|
IReadOnlyList<IGameObject> GameObjects { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a <see cref="IGameObject"/> to the <see cref="IGameManager"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The <see cref="IGameObject"/> to register.</param>
|
||||||
void RegisterGameObject(IGameObject gameObject);
|
void RegisterGameObject(IGameObject gameObject);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a <see cref="IGameObject"/> of type T with the given arguments and registers it to the <see cref="IGameManager"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of <see cref="IGameObject"/> to instantiate.</typeparam>
|
||||||
|
/// <param name="args">Constructor parameters for the given type of <see cref="IGameObject"/>.</param>
|
||||||
|
/// <returns>The instantiated <see cref="IGameObject"/>.</returns>
|
||||||
T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject;
|
T InstantiateGameObject<T>(params object?[]? args) where T : class, IGameObject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a <see cref="IGameObject"/> from the <see cref="IGameManager"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The <see cref="IGameObject"/> to remove.</param>
|
||||||
|
/// <returns>The removed <see cref="IGameObject"/>.</returns>
|
||||||
IGameObject RemoveGameObject(IGameObject gameObject);
|
IGameObject RemoveGameObject(IGameObject gameObject);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the <see cref="IGameManager"/> with the given engine time data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The engine time.</param>
|
||||||
void Update(EngineTime time);
|
void Update(EngineTime time);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs operations that should be done before the draw calls.
|
||||||
|
/// </summary>
|
||||||
void PreDraw();
|
void PreDraw();
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,18 @@ using System;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a game object with various properties and functionalities.
|
||||||
|
/// </summary>
|
||||||
public interface IGameObject : IEntity, IAssignableGameManager, IAssignableTransform, IAssignableBehaviourController, INameable, IInitialize
|
public interface IGameObject : IEntity, IAssignableGameManager, IAssignableTransform, IAssignableBehaviourController, INameable, IInitialize
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Update"/> method is called.
|
||||||
|
/// </summary>
|
||||||
Action<IGameObject>? OnUpdated { get; set; }
|
Action<IGameObject>? OnUpdated { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the game object.
|
||||||
|
/// </summary>
|
||||||
void Update();
|
void Update();
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,35 @@ using System;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an entity that can be initialized and finalized. This information is useful for objects we know that are not in use and can be either recycled or dropped for garbage collection.
|
||||||
|
/// </summary>
|
||||||
public interface IInitialize
|
public interface IInitialize
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Initialize"/> method is called successfully.
|
||||||
|
/// </summary>
|
||||||
Action<IInitialize>? OnInitialized { get; set; }
|
Action<IInitialize>? OnInitialized { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Finalize"/> method is called successfully.
|
||||||
|
/// </summary>
|
||||||
Action<IInitialize>? OnFinalized { get; set; }
|
Action<IInitialize>? OnFinalized { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The value indicating whether the entity has been initialized.
|
||||||
|
/// </summary>
|
||||||
bool Initialized { get; }
|
bool Initialized { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see cref="true"/> if initialization is successful, otherwise <see cref="false"/>.</returns>
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes the entity so it can either be recycled or garbage collected.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see cref="true"/> if finalization is successful, otherwise <see cref="false"/>.</returns>
|
||||||
bool Finalize();
|
bool Finalize();
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,18 @@ using System;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an entity with a name.
|
||||||
|
/// </summary>
|
||||||
public interface INameable
|
public interface INameable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the name of the entity changes.
|
||||||
|
/// </summary>
|
||||||
Action<IEntity>? OnNameChanged { get; set; }
|
Action<IEntity>? OnNameChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the entity.
|
||||||
|
/// </summary>
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,18 @@ using System;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an entity with an enable state that can be toggled.
|
||||||
|
/// </summary>
|
||||||
public interface IStateEnable : IAssignableEntity
|
public interface IStateEnable : IAssignableEntity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes.
|
||||||
|
/// </summary>
|
||||||
Action<IStateEnable>? OnEnabledChanged { get; set; }
|
Action<IStateEnable>? OnEnabledChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The value indicating whether the <see cref="IStateEnable"/> is enabled.
|
||||||
|
/// </summary>
|
||||||
bool Enabled { get; set; }
|
bool Enabled { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -2,14 +2,38 @@ using System;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
||||||
|
/// </summary>
|
||||||
public interface ITransform
|
public interface ITransform
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
||||||
|
/// </summary>
|
||||||
Action<ITransform>? OnPositionChanged { get; set; }
|
Action<ITransform>? OnPositionChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform"/> changes.
|
||||||
|
/// </summary>
|
||||||
Action<ITransform>? OnScaleChanged { get; set; }
|
Action<ITransform>? OnScaleChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes.
|
||||||
|
/// </summary>
|
||||||
Action<ITransform>? OnRotationChanged { get; set; }
|
Action<ITransform>? OnRotationChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The position of the <see cref="ITransform"/> in 2D space.
|
||||||
|
/// </summary>
|
||||||
Vector2D Position { get; set; }
|
Vector2D Position { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The scale of the <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
Vector2D Scale { get; set; }
|
Vector2D Scale { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The rotation of the <see cref="ITransform"/> in degrees.
|
||||||
|
/// </summary>
|
||||||
float Rotation { get; set; }
|
float Rotation { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,18 @@ using Syntriax.Engine.Physics2D.Primitives;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a <see cref="ICollider2D"/> with the shape of a <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public interface ICircleCollider2D : ICollider2D
|
public interface ICircleCollider2D : ICollider2D
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The local <see cref="Circle"/> shape of the <see cref="ICollider2D"/>.
|
||||||
|
/// </summary>
|
||||||
Circle CircleLocal { get; set; }
|
Circle CircleLocal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The world space representation of the <see cref="Circle"/> shape.
|
||||||
|
/// </summary>
|
||||||
Circle CircleWorld { get; }
|
Circle CircleWorld { get; }
|
||||||
}
|
}
|
||||||
|
@@ -4,15 +4,38 @@ using Syntriax.Engine.Core.Abstract;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D collider.
|
||||||
|
/// </summary>
|
||||||
public interface ICollider2D : IBehaviour, IAssignableTransform
|
public interface ICollider2D : IBehaviour, IAssignableTransform
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when a collision is detected.
|
||||||
|
/// </summary>
|
||||||
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionDetected { get; set; }
|
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionDetected { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when a collision is resolved.
|
||||||
|
/// </summary>
|
||||||
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionResolved { get; set; }
|
Action<ICollider2D, CollisionDetectionInformation>? OnCollisionResolved { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>.
|
||||||
|
/// </summary>
|
||||||
Action<ICollider2D, ICollider2D>? OnTriggered { get; set; }
|
Action<ICollider2D, ICollider2D>? OnTriggered { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="IRigidBody2D"/> associated with the <see cref="ICollider2D"/>.
|
||||||
|
/// </summary>
|
||||||
IRigidBody2D? RigidBody2D { get; }
|
IRigidBody2D? RigidBody2D { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The value indicating whether the <see cref="ICollider2D"/> is a trigger.
|
||||||
|
/// </summary>
|
||||||
bool IsTrigger { get; set; }
|
bool IsTrigger { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Recalculates <see cref="ICollider2D"/> properties.
|
||||||
|
/// </summary>
|
||||||
void Recalculate();
|
void Recalculate();
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,19 @@ using Syntriax.Engine.Physics2D.Abstract;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D collision detector.
|
||||||
|
/// </summary>
|
||||||
public interface ICollisionDetector2D
|
public interface ICollisionDetector2D
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to detect a collision between two <see cref="ICollider2D"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T1">Type of the first <see cref="ICollider2D"/>.</typeparam>
|
||||||
|
/// <typeparam name="T2">Type of the second <see cref="ICollider2D"/>.</typeparam>
|
||||||
|
/// <param name="left">The first <see cref="ICollider2D"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="ICollider2D"/>.</param>
|
||||||
|
/// <param name="collisionInformation">Information about the collision.</param>
|
||||||
|
/// <returns><see cref="true"/> if a collision is detected, otherwise <see cref="false"/>.</returns>
|
||||||
bool TryDetect<T1, T2>(T1 left, T2 right, out CollisionDetectionInformation collisionInformation) where T1 : ICollider2D where T2 : ICollider2D;
|
bool TryDetect<T1, T2>(T1 left, T2 right, out CollisionDetectionInformation collisionInformation) where T1 : ICollider2D where T2 : ICollider2D;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,13 @@
|
|||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D collision resolver.
|
||||||
|
/// </summary>
|
||||||
public interface ICollisionResolver2D
|
public interface ICollisionResolver2D
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves collisions based on collision detection information provided.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collisionInformation">Information about the collision.</param>
|
||||||
void Resolve(CollisionDetectionInformation collisionInformation);
|
void Resolve(CollisionDetectionInformation collisionInformation);
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,18 @@
|
|||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D physics engine.
|
||||||
|
/// </summary>
|
||||||
public interface IPhysicsEngine2D
|
public interface IPhysicsEngine2D
|
||||||
{
|
{
|
||||||
int IterationCount { get; set; }
|
/// <summary>
|
||||||
|
/// The number of iterations the <see cref="IPhysicsEngine2D"/> performs per step.
|
||||||
|
/// </summary>
|
||||||
|
int IterationPerStep { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advances the physics simulation by the specified time.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">The time step.</param>
|
||||||
void Step(float deltaTime);
|
void Step(float deltaTime);
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,17 @@
|
|||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D physics object's responsive attributes.
|
||||||
|
/// </summary>
|
||||||
public interface IPhysicsMaterial2D
|
public interface IPhysicsMaterial2D
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The friction coefficient of the physics object.
|
||||||
|
/// </summary>
|
||||||
float Friction { get; }
|
float Friction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The restitution (bounciness) coefficient of the physics object.
|
||||||
|
/// </summary>
|
||||||
float Restitution { get; }
|
float Restitution { get; }
|
||||||
}
|
}
|
||||||
|
@@ -3,13 +3,33 @@ using Syntriax.Engine.Core.Abstract;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D rigid body in the engine.
|
||||||
|
/// </summary>
|
||||||
public interface IRigidBody2D : IBehaviour, IAssignableTransform
|
public interface IRigidBody2D : IBehaviour, IAssignableTransform
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The physics material of the <see cref="IRigidBody2D"/>.
|
||||||
|
/// </summary>
|
||||||
IPhysicsMaterial2D Material { get; set; }
|
IPhysicsMaterial2D Material { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The velocity of the <see cref="IRigidBody2D"/>.
|
||||||
|
/// </summary>
|
||||||
Vector2D Velocity { get; set; }
|
Vector2D Velocity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The angular velocity (rotation rate) of the <see cref="IRigidBody2D"/>.
|
||||||
|
/// </summary>
|
||||||
float AngularVelocity { get; set; }
|
float AngularVelocity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The mass of the <see cref="IRigidBody2D"/>.
|
||||||
|
/// </summary>
|
||||||
float Mass { get; set; }
|
float Mass { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The value indicating whether the <see cref="IRigidBody2D"/> is static/immovable.
|
||||||
|
/// </summary>
|
||||||
bool IsStatic { get; set; }
|
bool IsStatic { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,19 @@ using Syntriax.Engine.Physics2D.Primitives;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Abstract;
|
namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a <see cref="ICollider2D"/> with a custom <see cref="Shape"/>.
|
||||||
|
/// </summary>
|
||||||
public interface IShapeCollider2D : ICollider2D
|
public interface IShapeCollider2D : ICollider2D
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the local <see cref="Shape"/> of the <see cref="ICollider2D"/>.
|
||||||
|
/// </summary>
|
||||||
Shape ShapeLocal { get; set; }
|
Shape ShapeLocal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the world space representation of the <see cref="Shape"/>.
|
||||||
|
/// </summary>
|
||||||
Shape ShapeWorld { get; }
|
Shape ShapeWorld { get; }
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
|||||||
private readonly ICollisionDetector2D collisionDetector = null!;
|
private readonly ICollisionDetector2D collisionDetector = null!;
|
||||||
private readonly ICollisionResolver2D collisionResolver = null!;
|
private readonly ICollisionResolver2D collisionResolver = null!;
|
||||||
|
|
||||||
public int IterationCount { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; }
|
public int IterationPerStep { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; }
|
||||||
|
|
||||||
public void AddRigidBody(IRigidBody2D rigidBody)
|
public void AddRigidBody(IRigidBody2D rigidBody)
|
||||||
{
|
{
|
||||||
@@ -39,9 +39,9 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
|||||||
|
|
||||||
public void Step(float deltaTime)
|
public void Step(float deltaTime)
|
||||||
{
|
{
|
||||||
float intervalDeltaTime = deltaTime / IterationCount;
|
float intervalDeltaTime = deltaTime / IterationPerStep;
|
||||||
|
|
||||||
for (int iterationIndex = 0; iterationIndex < IterationCount; iterationIndex++)
|
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
||||||
{
|
{
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
for (int i = 0; i < rigidBodies.Count; i++)
|
for (int i = 0; i < rigidBodies.Count; i++)
|
||||||
|
@@ -12,7 +12,7 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
private int _iterationCount = 1;
|
private int _iterationPerStep = 1;
|
||||||
|
|
||||||
protected readonly ICollisionDetector2D collisionDetector = null!;
|
protected readonly ICollisionDetector2D collisionDetector = null!;
|
||||||
protected readonly ICollisionResolver2D collisionResolver = null!;
|
protected readonly ICollisionResolver2D collisionResolver = null!;
|
||||||
@@ -21,14 +21,14 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
|||||||
protected BehaviourCacher<ICollider2D> colliderCacher = new();
|
protected BehaviourCacher<ICollider2D> colliderCacher = new();
|
||||||
|
|
||||||
|
|
||||||
public int IterationCount { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; }
|
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
||||||
public IGameManager GameManager { get; private set; } = null!;
|
public IGameManager GameManager { get; private set; } = null!;
|
||||||
|
|
||||||
public void Step(float deltaTime)
|
public void Step(float deltaTime)
|
||||||
{
|
{
|
||||||
float intervalDeltaTime = deltaTime / IterationCount;
|
float intervalDeltaTime = deltaTime / IterationPerStep;
|
||||||
|
|
||||||
for (int iterationIndex = 0; iterationIndex < IterationCount; iterationIndex++)
|
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
||||||
{
|
{
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var rigidBody in rigidBodyCacher)
|
foreach (var rigidBody in rigidBodyCacher)
|
||||||
|
@@ -4,16 +4,47 @@ using Syntriax.Engine.Core;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an Axis-Aligned Bounding Box (AABB) in 2D space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lowerBoundary">The lower boundary of the <see cref="AABB"/>.</param>
|
||||||
|
/// <param name="upperBoundary">The upper boundary of the <see cref="AABB"/>.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="AABB"/> struct with the specified lower and upper boundaries.
|
||||||
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")]
|
[System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")]
|
||||||
public readonly struct AABB(Vector2D LowerBoundary, Vector2D UpperBoundary)
|
public readonly struct AABB(Vector2D lowerBoundary, Vector2D upperBoundary)
|
||||||
{
|
{
|
||||||
public readonly Vector2D LowerBoundary { get; init; } = LowerBoundary;
|
/// <summary>
|
||||||
public readonly Vector2D UpperBoundary { get; init; } = UpperBoundary;
|
/// The lower boundary of the <see cref="AABB"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Vector2D LowerBoundary = lowerBoundary;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The upper boundary of the <see cref="AABB"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Vector2D UpperBoundary = upperBoundary;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the center point of the <see cref="AABB"/>.
|
||||||
|
/// </summary>
|
||||||
public readonly Vector2D Center => (LowerBoundary + UpperBoundary) * .5f;
|
public readonly Vector2D Center => (LowerBoundary + UpperBoundary) * .5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the size of the <see cref="AABB"/>.
|
||||||
|
/// </summary>
|
||||||
public readonly Vector2D Size => LowerBoundary.FromTo(UpperBoundary).Abs();
|
public readonly Vector2D Size => LowerBoundary.FromTo(UpperBoundary).Abs();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets half the size of the <see cref="AABB"/>.
|
||||||
|
/// </summary>
|
||||||
public readonly Vector2D SizeHalf => Size * .5f;
|
public readonly Vector2D SizeHalf => Size * .5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an <see cref="AABB"/> from a collection of <see cref="Vector2D"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vectors">The collection of <see cref="Vector2D"/>s.</param>
|
||||||
|
/// <returns>An <see cref="AABB"/> that bounds all the <see cref="Vector2D"/>s.</returns>
|
||||||
public static AABB FromVectors(IEnumerable<Vector2D> vectors)
|
public static AABB FromVectors(IEnumerable<Vector2D> vectors)
|
||||||
{
|
{
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
@@ -34,13 +65,33 @@ public readonly struct AABB(Vector2D LowerBoundary, Vector2D UpperBoundary)
|
|||||||
return new(lowerBoundary, upperBoundary);
|
return new(lowerBoundary, upperBoundary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two <see cref="AABB"/>s are approximately equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="AABB"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="AABB"/>.</param>
|
||||||
|
/// <returns><see cref="true"/> if the <see cref="AABB"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
|
||||||
public static bool ApproximatelyEquals(AABB left, AABB right)
|
public static bool ApproximatelyEquals(AABB left, AABB right)
|
||||||
=> left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary);
|
=> left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for the <see cref="AABB"/> struct.
|
||||||
|
/// </summary>
|
||||||
public static class AABBExtensions
|
public static class AABBExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a collection of <see cref="Vector2D"/>s to an <see cref="AABB"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vectors">The collection of <see cref="Vector2D"/>s.</param>
|
||||||
|
/// <returns>An <see cref="AABB"/> that bounds all the <see cref="Vector2D"/>s.</returns>
|
||||||
public static AABB ToAABB(this IEnumerable<Vector2D> vectors) => AABB.FromVectors(vectors);
|
public static AABB ToAABB(this IEnumerable<Vector2D> vectors) => AABB.FromVectors(vectors);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two <see cref="AABB"/>s are approximately equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first <see cref="AABB"/>.</param>
|
||||||
|
/// <param name="right">The second <see cref="AABB"/>.</param>
|
||||||
|
/// <returns><see cref="true"/> if the <see cref="AABB"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
|
||||||
public static bool ApproximatelyEquals(this AABB left, AABB right) => AABB.ApproximatelyEquals(left, right);
|
public static bool ApproximatelyEquals(this AABB left, AABB right) => AABB.ApproximatelyEquals(left, right);
|
||||||
}
|
}
|
||||||
|
@@ -1,47 +1,115 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Center: {Center.ToString(), nq}, Radius: {Radius}")]
|
/// <summary>
|
||||||
public readonly struct Circle(Vector2D Center, float Radius)
|
/// Represents a 2D circle.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="center">The center of the circle.</param>
|
||||||
|
/// <param name="radius">The radius of the circle.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the Circle struct with the specified center and radius.
|
||||||
|
/// </remarks>
|
||||||
|
[DebuggerDisplay("Center: {Center.ToString(),nq}, Radius: {Radius}")]
|
||||||
|
public readonly struct Circle(Vector2D center, float radius)
|
||||||
{
|
{
|
||||||
public static readonly Circle UnitCircle = new(Vector2D.Zero, 1f);
|
/// <summary>
|
||||||
|
/// The center of the circle.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Vector2D Center = center;
|
||||||
|
|
||||||
public readonly Vector2D Center { get; init; } = Center;
|
/// <summary>
|
||||||
public readonly float Radius { get; init; } = Radius;
|
/// The radius of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly float Radius = radius;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the squared radius of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public readonly float RadiusSquared => Radius * Radius;
|
public readonly float RadiusSquared => Radius * Radius;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the diameter of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public readonly float Diameter => 2f * Radius;
|
public readonly float Diameter => 2f * Radius;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A predefined unit <see cref="Circle"/> with a center at the origin and a radius of 1.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Circle UnitCircle = new(Vector2D.Zero, 1f);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the center of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle SetCenter(Circle circle, Vector2D center) => new(center, circle.Radius);
|
public static Circle SetCenter(Circle circle, Vector2D center) => new(center, circle.Radius);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the radius of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle SetRadius(Circle circle, float radius) => new(circle.Center, radius);
|
public static Circle SetRadius(Circle circle, float radius) => new(circle.Center, radius);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displaces the <see cref="Circle"/> by the specified <see cref="Vector2D"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle Displace(Circle circle, Vector2D displaceVector) => new(circle.Center + displaceVector, circle.Radius);
|
public static Circle Displace(Circle circle, Vector2D displaceVector) => new(circle.Center + displaceVector, circle.Radius);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Projects the <see cref="Circle"/> onto the specified <see cref="Vector2D"/>.
|
||||||
|
/// </summary>
|
||||||
public static Projection Project(Circle circle, Vector2D projectionVector)
|
public static Projection Project(Circle circle, Vector2D projectionVector)
|
||||||
{
|
{
|
||||||
float projectedCenter = circle.Center.Dot(projectionVector);
|
float projectedCenter = circle.Center.Dot(projectionVector);
|
||||||
return new(projectedCenter - circle.Radius, projectedCenter + circle.Radius);
|
return new(projectedCenter - circle.Radius, projectedCenter + circle.Radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms the <see cref="Circle"/> by the specified <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle TransformCircle(ITransform transform, Circle circle)
|
public static Circle TransformCircle(ITransform transform, Circle circle)
|
||||||
=> new(transform.TransformVector2D(circle.Center), circle.Radius * transform.Scale.Magnitude);
|
=> new(transform.TransformVector2D(circle.Center), circle.Radius * transform.Scale.Magnitude);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two <see cref="Circle"/>s are approximately equal.
|
||||||
|
/// </summary>
|
||||||
public static bool ApproximatelyEquals(Circle left, Circle right)
|
public static bool ApproximatelyEquals(Circle left, Circle right)
|
||||||
=> left.Center.ApproximatelyEquals(right.Center) && left.Radius.ApproximatelyEquals(right.Radius);
|
=> left.Center.ApproximatelyEquals(right.Center) && left.Radius.ApproximatelyEquals(right.Radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for the <see cref="Circle"/> struct.
|
||||||
|
/// </summary>
|
||||||
public static class CircleExtensions
|
public static class CircleExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the center of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle SetCenter(this Circle circle, Vector2D center) => Circle.SetCenter(circle, center);
|
public static Circle SetCenter(this Circle circle, Vector2D center) => Circle.SetCenter(circle, center);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the radius of the <see cref="Circle"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle SetRadius(this Circle circle, float radius) => Circle.SetRadius(circle, radius);
|
public static Circle SetRadius(this Circle circle, float radius) => Circle.SetRadius(circle, radius);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the <see cref="Circle"/> by the specified <see cref="Vector2D"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle Displace(this Circle circle, Vector2D displaceVector) => Circle.Displace(circle, displaceVector);
|
public static Circle Displace(this Circle circle, Vector2D displaceVector) => Circle.Displace(circle, displaceVector);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Projects the <see cref="Circle"/> onto the specified <see cref="Vector2D"/>.
|
||||||
|
/// </summary>
|
||||||
public static Projection ToProjection(this Circle circle, Vector2D projectionVector) => Circle.Project(circle, projectionVector);
|
public static Projection ToProjection(this Circle circle, Vector2D projectionVector) => Circle.Project(circle, projectionVector);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms the <see cref="Circle"/> by the specified <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
public static Circle TransformCircle(this ITransform transform, Circle circle) => Circle.TransformCircle(transform, circle);
|
public static Circle TransformCircle(this ITransform transform, Circle circle) => Circle.TransformCircle(transform, circle);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two <see cref="Circle"/>s are approximately equal.
|
||||||
|
/// </summary>
|
||||||
public static bool ApproximatelyEquals(this Circle left, Circle right) => Circle.ApproximatelyEquals(left, right);
|
public static bool ApproximatelyEquals(this Circle left, Circle right) => Circle.ApproximatelyEquals(left, right);
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +1,54 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a 2D line segment defined by two endpoints.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the Line struct with the specified endpoints.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="from">The starting point of the <see cref="Line"/> segment.</param>
|
||||||
|
/// <param name="to">The ending point of the <see cref="Line"/> segment.</param>
|
||||||
[System.Diagnostics.DebuggerDisplay("From: {From.ToString(),nq}, To: {To.ToString(),nq}, Direction: {Direction.ToString(),nq}, Length: {Length}")]
|
[System.Diagnostics.DebuggerDisplay("From: {From.ToString(),nq}, To: {To.ToString(),nq}, Direction: {Direction.ToString(),nq}, Length: {Length}")]
|
||||||
public readonly struct Line(Vector2D From, Vector2D To)
|
public readonly struct Line(Vector2D from, Vector2D to)
|
||||||
{
|
{
|
||||||
public readonly Vector2D From { get; init; } = From;
|
/// <summary>
|
||||||
public readonly Vector2D To { get; init; } = To;
|
/// The starting point of the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Vector2D From = from;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ending point of the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Vector2D To = to;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The reversed <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public readonly Line Reversed => new(To, From);
|
public readonly Line Reversed => new(To, From);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The normalized direction <see cref="Vector2D"/> of the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public readonly Vector2D Direction => From.FromTo(To).Normalize();
|
public readonly Vector2D Direction => From.FromTo(To).Normalize();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The length of the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public readonly float Length => From.FromTo(To).Length();
|
public readonly float Length => From.FromTo(To).Length();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The squared length of the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public readonly float LengthSquared => From.FromTo(To).LengthSquared();
|
public readonly float LengthSquared => From.FromTo(To).LengthSquared();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The equation of the <see cref="Line"/> defined by this <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public static LineEquation GetLineEquation(Line line)
|
public static LineEquation GetLineEquation(Line line)
|
||||||
{
|
{
|
||||||
Vector2D slopeVector = line.From.FromTo(line.To);
|
Vector2D slopeVector = line.From.FromTo(line.To);
|
||||||
@@ -27,9 +59,15 @@ public readonly struct Line(Vector2D From, Vector2D To)
|
|||||||
return new LineEquation(slope, yOffset);
|
return new LineEquation(slope, yOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="Vector2D"/> lies on the <see cref="Line"/>.
|
||||||
|
/// </summary>
|
||||||
public static bool Intersects(Line line, Vector2D point)
|
public static bool Intersects(Line line, Vector2D point)
|
||||||
=> LineEquation.Resolve(GetLineEquation(line), point.X).ApproximatelyEquals(point.Y);
|
=> LineEquation.Resolve(GetLineEquation(line), point.X).ApproximatelyEquals(point.Y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the parameter 't' representing the point's position on the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public static float GetT(Line line, Vector2D point)
|
public static float GetT(Line line, Vector2D point)
|
||||||
{
|
{
|
||||||
float fromX = MathF.Abs(line.From.X);
|
float fromX = MathF.Abs(line.From.X);
|
||||||
@@ -52,23 +90,63 @@ public readonly struct Line(Vector2D From, Vector2D To)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Exist(Line line, List<Vector2D> vertices)
|
/// <summary>
|
||||||
|
/// Checks if the <see cref="Line"/> segment intersects with another <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
|
public static bool Intersects(Line left, Line right)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < vertices.Count - 1; i++)
|
int o1 = Vector2D.Orientation(left.From, left.To, right.From);
|
||||||
{
|
int o2 = Vector2D.Orientation(left.From, left.To, right.To);
|
||||||
Vector2D vertexCurrent = vertices[i];
|
int o3 = Vector2D.Orientation(right.From, right.To, left.From);
|
||||||
Vector2D vertexNext = vertices[i];
|
int o4 = Vector2D.Orientation(right.From, right.To, left.To);
|
||||||
if (line.From == vertexCurrent && line.To == vertexNext) return true;
|
|
||||||
if (line.From == vertexNext && line.To == vertexCurrent) return true;
|
if (o1 != o2 && o3 != o4)
|
||||||
}
|
return true;
|
||||||
|
|
||||||
|
if (o1 == 0 && OnSegment(left, right.From)) return true;
|
||||||
|
if (o2 == 0 && OnSegment(left, right.To)) return true;
|
||||||
|
if (o3 == 0 && OnSegment(right, left.From)) return true;
|
||||||
|
if (o4 == 0 && OnSegment(right, left.To)) return true;
|
||||||
|
|
||||||
Vector2D vertexFirst = vertices[0];
|
|
||||||
Vector2D vertexLast = vertices[^1];
|
|
||||||
if (line.From == vertexFirst && line.To == vertexLast) return true;
|
|
||||||
if (line.From == vertexLast && line.To == vertexFirst) return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the point lies within the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
|
public static bool OnSegment(Line line, Vector2D point)
|
||||||
|
{
|
||||||
|
if (point.X <= MathF.Max(line.From.X, line.To.X) && point.X >= MathF.Min(line.From.X, line.To.X) &&
|
||||||
|
point.Y <= MathF.Max(line.From.Y, line.To.Y) && point.Y >= MathF.Min(line.From.Y, line.To.Y))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether two <see cref="Line"/> segments intersect.
|
||||||
|
/// </summary>
|
||||||
|
public static bool Intersects(Line left, Line right, [NotNullWhen(returnValue: true)] out Vector2D? point)
|
||||||
|
{
|
||||||
|
point = null;
|
||||||
|
|
||||||
|
bool result = Intersects(left, right);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
point = IntersectionPoint(left, right);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the point of intersection between two <see cref="Line"/> segments.
|
||||||
|
/// </summary>
|
||||||
|
public static Vector2D IntersectionPoint(Line left, Line right)
|
||||||
|
=> Vector2D.Lerp(left.From, left.To, IntersectionParameterT(left, right));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the parameter 't' representing the intersection point's position on the <see cref="Line"/> segment.
|
||||||
|
/// </summary>
|
||||||
public static float IntersectionParameterT(Line left, Line right)
|
public static float IntersectionParameterT(Line left, Line right)
|
||||||
{
|
{
|
||||||
float numerator = (left.From.X - right.From.X) * (right.From.Y - right.To.Y) - (left.From.Y - right.From.Y) * (right.From.X - right.To.X);
|
float numerator = (left.From.X - right.From.X) * (right.From.Y - right.To.Y) - (left.From.Y - right.From.Y) * (right.From.X - right.To.X);
|
||||||
@@ -81,12 +159,18 @@ public readonly struct Line(Vector2D From, Vector2D To)
|
|||||||
return numerator / denominator;
|
return numerator / denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Linearly interpolates between the two endpoints of the <see cref="Line"/> segment using parameter 't'.
|
||||||
|
/// </summary>
|
||||||
public static Vector2D Lerp(Line line, float t)
|
public static Vector2D Lerp(Line line, float t)
|
||||||
=> new Vector2D(
|
=> new(
|
||||||
line.From.X + (line.To.X - line.From.X) * t,
|
line.From.X + (line.To.X - line.From.X) * t,
|
||||||
line.From.Y + (line.To.Y - line.From.Y) * t
|
line.From.Y + (line.To.Y - line.From.Y) * t
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the closest point on the <see cref="Line"/> segment to the specified point.
|
||||||
|
/// </summary>
|
||||||
public static Vector2D ClosestPointTo(Line line, Vector2D point)
|
public static Vector2D ClosestPointTo(Line line, Vector2D point)
|
||||||
{
|
{
|
||||||
// Convert edge points to vectors
|
// Convert edge points to vectors
|
||||||
@@ -106,53 +190,20 @@ public readonly struct Line(Vector2D From, Vector2D To)
|
|||||||
return new Vector2D((float)closestX, (float)closestY);
|
return new Vector2D((float)closestX, (float)closestY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector2D IntersectionPoint(Line left, Line right)
|
/// <summary>
|
||||||
=> Vector2D.Lerp(left.From, left.To, IntersectionParameterT(left, right));
|
/// Checks if two <see cref="Line"/> segments are approximately equal.
|
||||||
|
/// </summary>
|
||||||
public static bool Intersects(Line left, Line right)
|
|
||||||
{
|
|
||||||
int o1 = Vector2D.Orientation(left.From, left.To, right.From);
|
|
||||||
int o2 = Vector2D.Orientation(left.From, left.To, right.To);
|
|
||||||
int o3 = Vector2D.Orientation(right.From, right.To, left.From);
|
|
||||||
int o4 = Vector2D.Orientation(right.From, right.To, left.To);
|
|
||||||
|
|
||||||
if (o1 != o2 && o3 != o4)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (o1 == 0 && OnSegment(left, right.From)) return true;
|
|
||||||
if (o2 == 0 && OnSegment(left, right.To)) return true;
|
|
||||||
if (o3 == 0 && OnSegment(right, left.From)) return true;
|
|
||||||
if (o4 == 0 && OnSegment(right, left.To)) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool OnSegment(Line line, Vector2D point)
|
|
||||||
{
|
|
||||||
if (point.X <= MathF.Max(line.From.X, line.To.X) && point.X >= MathF.Min(line.From.X, line.To.X) &&
|
|
||||||
point.Y <= MathF.Max(line.From.Y, line.To.Y) && point.Y >= MathF.Min(line.From.Y, line.To.Y))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Intersects(Line left, Line right, [NotNullWhen(returnValue: true)] out Vector2D? point)
|
|
||||||
{
|
|
||||||
point = null;
|
|
||||||
|
|
||||||
bool result = Intersects(left, right);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
point = IntersectionPoint(left, right);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ApproximatelyEquals(Line left, Line right)
|
public static bool ApproximatelyEquals(Line left, Line right)
|
||||||
=> left.From.ApproximatelyEquals(right.From) && left.To.ApproximatelyEquals(right.To);
|
=> left.From.ApproximatelyEquals(right.From) && left.To.ApproximatelyEquals(right.To);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for the Line struct.
|
||||||
|
/// </summary>
|
||||||
public static class LineExtensions
|
public static class LineExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two <see cref="Line"/>s are approximately equal.
|
||||||
|
/// </summary>
|
||||||
public static bool ApproximatelyEquals(this Line left, Line right) => Line.ApproximatelyEquals(left, right);
|
public static bool ApproximatelyEquals(this Line left, Line right) => Line.ApproximatelyEquals(left, right);
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,63 @@ using Syntriax.Engine.Core;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a line equation in the form y = mx + b.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="slope">The slope of the line.</param>
|
||||||
|
/// <param name="offsetY">The y-intercept of the line.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="LineEquation"/> struct with the specified slope and y-intercept.
|
||||||
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")]
|
[System.Diagnostics.DebuggerDisplay("y = {Slope}x + {OffsetY}")]
|
||||||
public readonly struct LineEquation(float Slope, float OffsetY)
|
public readonly struct LineEquation(float slope, float offsetY)
|
||||||
{
|
{
|
||||||
public readonly float Slope { get; init; } = Slope;
|
/// <summary>
|
||||||
public readonly float OffsetY { get; init; } = OffsetY;
|
/// The slope of the line equation.
|
||||||
|
/// </summary>
|
||||||
|
public readonly float Slope = slope;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The y-intercept of the line equation.
|
||||||
|
/// </summary>
|
||||||
|
public readonly float OffsetY = offsetY;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves the y-coordinate for a given x-coordinate using the line equation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lineEquation">The line equation to resolve.</param>
|
||||||
|
/// <param name="x">The x-coordinate for which to resolve the y-coordinate.</param>
|
||||||
|
/// <returns>The y-coordinate resolved using the line equation.</returns>
|
||||||
public static float Resolve(LineEquation lineEquation, float x) => lineEquation.Slope * x + lineEquation.OffsetY; // y = mx + b
|
public static float Resolve(LineEquation lineEquation, float x) => lineEquation.Slope * x + lineEquation.OffsetY; // y = mx + b
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two line equations are approximately equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first line equation to compare.</param>
|
||||||
|
/// <param name="right">The second line equation to compare.</param>
|
||||||
|
/// <returns>True if the line equations are approximately equal; otherwise, false.</returns>
|
||||||
public static bool ApproximatelyEquals(LineEquation left, LineEquation right)
|
public static bool ApproximatelyEquals(LineEquation left, LineEquation right)
|
||||||
=> left.Slope.ApproximatelyEquals(right.Slope) && left.OffsetY.ApproximatelyEquals(right.OffsetY);
|
=> left.Slope.ApproximatelyEquals(right.Slope) && left.OffsetY.ApproximatelyEquals(right.OffsetY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for the LineEquation struct.
|
||||||
|
/// </summary>
|
||||||
public static class LineEquationExtensions
|
public static class LineEquationExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves the y-coordinate for a given x-coordinate using the line equation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lineEquation">The line equation to resolve.</param>
|
||||||
|
/// <param name="x">The x-coordinate for which to resolve the y-coordinate.</param>
|
||||||
|
/// <returns>The y-coordinate resolved using the line equation.</returns>
|
||||||
public static float Resolve(this LineEquation lineEquation, float x) => LineEquation.Resolve(lineEquation, x);
|
public static float Resolve(this LineEquation lineEquation, float x) => LineEquation.Resolve(lineEquation, x);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two line equations are approximately equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first line equation to compare.</param>
|
||||||
|
/// <param name="right">The second line equation to compare.</param>
|
||||||
|
/// <returns>True if the line equations are approximately equal; otherwise, false.</returns>
|
||||||
public static bool ApproximatelyEquals(this LineEquation left, LineEquation right) => LineEquation.ApproximatelyEquals(left, right);
|
public static bool ApproximatelyEquals(this LineEquation left, LineEquation right) => LineEquation.ApproximatelyEquals(left, right);
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,41 @@
|
|||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a range of values along a single axis.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="min">The minimum value of the projection.</param>
|
||||||
|
/// <param name="max">The maximum value of the projection.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="Projection"/> struct with the specified minimum and maximum values.
|
||||||
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("Min: {Min}, Max: {Max}")]
|
[System.Diagnostics.DebuggerDisplay("Min: {Min}, Max: {Max}")]
|
||||||
public readonly struct Projection(float Min, float Max)
|
public readonly struct Projection(float min, float max)
|
||||||
{
|
{
|
||||||
public readonly float Min { get; init; } = Min;
|
/// <summary>
|
||||||
public readonly float Max { get; init; } = Max;
|
/// Gets the minimum value of the projection.
|
||||||
|
/// </summary>
|
||||||
|
public readonly float Min = min;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum value of the projection.
|
||||||
|
/// </summary>
|
||||||
|
public readonly float Max = max;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two projections overlap.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first projection to check.</param>
|
||||||
|
/// <param name="right">The second projection to check.</param>
|
||||||
|
/// <returns><see cref="true"/> if the projections overlap; otherwise, <see cref="false"/>.</returns>
|
||||||
public static bool Overlaps(Projection left, Projection right) => Overlaps(left, right, out var _);
|
public static bool Overlaps(Projection left, Projection right) => Overlaps(left, right, out var _);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two projections overlap and calculates the depth of the overlap.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first projection to check.</param>
|
||||||
|
/// <param name="right">The second projection to check.</param>
|
||||||
|
/// <param name="depth">The depth of the overlap, if any.</param>
|
||||||
|
/// <returns><see cref="true"/> if the projections overlap; otherwise, <see cref="false"/>.</returns>
|
||||||
public static bool Overlaps(Projection left, Projection right, out float depth)
|
public static bool Overlaps(Projection left, Projection right, out float depth)
|
||||||
{
|
{
|
||||||
// TODO Try to improve this
|
// TODO Try to improve this
|
||||||
@@ -42,8 +71,26 @@ public readonly struct Projection(float Min, float Max)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for the <see cref="Projection"/> struct.
|
||||||
|
/// </summary>
|
||||||
public static class ProjectionExtensions
|
public static class ProjectionExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two projections overlap.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first projection to check.</param>
|
||||||
|
/// <param name="right">The second projection to check.</param>
|
||||||
|
/// <returns><see cref="true"/> if the projections overlap; otherwise, <see cref="false"/>.</returns>
|
||||||
public static bool Overlaps(this Projection left, Projection right) => Projection.Overlaps(left, right);
|
public static bool Overlaps(this Projection left, Projection right) => Projection.Overlaps(left, right);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if two projections overlap and calculates the depth of the overlap.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first projection to check.</param>
|
||||||
|
/// <param name="right">The second projection to check.</param>
|
||||||
|
/// <param name="depth">The depth of the overlap, if any.</param>
|
||||||
|
/// <returns><see cref="true"/> if the projections overlap; otherwise, <see cref="false"/>.</returns>
|
||||||
public static bool Overlaps(this Projection left, Projection right, out float depth) => Projection.Overlaps(left, right, out depth);
|
public static bool Overlaps(this Projection left, Projection right, out float depth) => Projection.Overlaps(left, right, out depth);
|
||||||
}
|
}
|
||||||
|
@@ -6,22 +6,55 @@ using Syntriax.Engine.Core.Abstract;
|
|||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D.Primitives;
|
namespace Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a shape defined by a collection of vertices.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertices">The vertices of the shape.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="Shape"/> struct with the specified vertices.
|
||||||
|
/// </remarks>
|
||||||
[System.Diagnostics.DebuggerDisplay("Vertices Count: {Vertices.Count}")]
|
[System.Diagnostics.DebuggerDisplay("Vertices Count: {Vertices.Count}")]
|
||||||
public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
public readonly struct Shape(List<Vector2D> vertices) : IEnumerable<Vector2D>
|
||||||
{
|
{
|
||||||
public static readonly Shape Triangle = CreateNgon(3, Vector2D.Up);
|
public static readonly Shape Triangle = CreateNgon(3, Vector2D.Up);
|
||||||
public static readonly Shape Box = CreateNgon(4, Vector2D.One);
|
public static readonly Shape Box = CreateNgon(4, Vector2D.One);
|
||||||
public static readonly Shape Pentagon = CreateNgon(5, Vector2D.Up);
|
public static readonly Shape Pentagon = CreateNgon(5, Vector2D.Up);
|
||||||
public static readonly Shape Hexagon = CreateNgon(6, Vector2D.Right);
|
public static readonly Shape Hexagon = CreateNgon(6, Vector2D.Right);
|
||||||
|
|
||||||
public readonly IList<Vector2D> Vertices { get; init; } = Vertices;
|
private readonly List<Vector2D> _verticesList = vertices;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the vertices of the shape.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<Vector2D> Vertices => _verticesList;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The vertex at the specified index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The zero-based index of the vertex to get or set.</param>
|
||||||
|
/// <returns>The vertex at the specified index.</returns>
|
||||||
public Vector2D this[System.Index index] => Vertices[index];
|
public Vector2D this[System.Index index] => Vertices[index];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a copy of the current shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to copy.</param>
|
||||||
|
/// <returns>A copy of the input shape.</returns>
|
||||||
public static Shape CreateCopy(Shape shape) => new(new List<Vector2D>(shape.Vertices));
|
public static Shape CreateCopy(Shape shape) => new(new List<Vector2D>(shape.Vertices));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a regular polygon (ngon) with the specified number of vertices.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexCount">The number of vertices in the polygon.</param>
|
||||||
|
/// <returns>A regular polygon with the specified number of vertices.</returns>
|
||||||
public static Shape CreateNgon(int vertexCount) => CreateNgon(vertexCount, Vector2D.Up);
|
public static Shape CreateNgon(int vertexCount) => CreateNgon(vertexCount, Vector2D.Up);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a regular polygon (ngon) with the specified number of vertices and a rotation position.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertexCount">The number of vertices in the polygon.</param>
|
||||||
|
/// <param name="positionToRotate">The position to use for rotation.</param>
|
||||||
|
/// <returns>A regular polygon with the specified number of vertices and rotation position.</returns>
|
||||||
public static Shape CreateNgon(int vertexCount, Vector2D positionToRotate)
|
public static Shape CreateNgon(int vertexCount, Vector2D positionToRotate)
|
||||||
{
|
{
|
||||||
if (vertexCount < 3)
|
if (vertexCount < 3)
|
||||||
@@ -37,6 +70,11 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
return new(vertices);
|
return new(vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the super triangle that encloses the given shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to enclose.</param>
|
||||||
|
/// <returns>The super triangle that encloses the given shape.</returns>
|
||||||
public static Triangle GetSuperTriangle(Shape shape)
|
public static Triangle GetSuperTriangle(Shape shape)
|
||||||
{
|
{
|
||||||
float minX = float.MaxValue, minY = float.MaxValue;
|
float minX = float.MaxValue, minY = float.MaxValue;
|
||||||
@@ -63,6 +101,11 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
return new Triangle(p1, p2, p3);
|
return new Triangle(p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the lines that form the edges of the shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to get lines from.</param>
|
||||||
|
/// <param name="lines">The list to populate with lines.</param>
|
||||||
public static void GetLines(Shape shape, IList<Line> lines)
|
public static void GetLines(Shape shape, IList<Line> lines)
|
||||||
{
|
{
|
||||||
lines.Clear();
|
lines.Clear();
|
||||||
@@ -71,6 +114,11 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
lines.Add(new(shape.Vertices[^1], shape.Vertices[0]));
|
lines.Add(new(shape.Vertices[^1], shape.Vertices[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of lines that form the edges of the shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to get lines from.</param>
|
||||||
|
/// <returns>A list of lines that form the edges of the shape.</returns>
|
||||||
public static List<Line> GetLines(Shape shape)
|
public static List<Line> GetLines(Shape shape)
|
||||||
{
|
{
|
||||||
List<Line> lines = new(shape.Vertices.Count - 1);
|
List<Line> lines = new(shape.Vertices.Count - 1);
|
||||||
@@ -78,6 +126,12 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Projects the shape onto a vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to project.</param>
|
||||||
|
/// <param name="projectionVector">The vector to project onto.</param>
|
||||||
|
/// <param name="list">The list to populate with projected values.</param>
|
||||||
public static void Project(Shape shape, Vector2D projectionVector, IList<float> list)
|
public static void Project(Shape shape, Vector2D projectionVector, IList<float> list)
|
||||||
{
|
{
|
||||||
list.Clear();
|
list.Clear();
|
||||||
@@ -87,6 +141,12 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
list.Add(projectionVector.Dot(shape[i]));
|
list.Add(projectionVector.Dot(shape[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Projects the shape onto a vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to project.</param>
|
||||||
|
/// <param name="projectionVector">The vector to project onto.</param>
|
||||||
|
/// <returns>The projection of the shape onto the vector.</returns>
|
||||||
public static Projection Project(Shape shape, Vector2D projectionVector)
|
public static Projection Project(Shape shape, Vector2D projectionVector)
|
||||||
{
|
{
|
||||||
float min = float.MaxValue;
|
float min = float.MaxValue;
|
||||||
@@ -102,6 +162,12 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
return new(min, max);
|
return new(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms the shape using the specified transform.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to transform.</param>
|
||||||
|
/// <param name="transform">The transform to apply.</param>
|
||||||
|
/// <returns>The transformed shape.</returns>
|
||||||
public static Shape TransformShape(Shape shape, ITransform transform)
|
public static Shape TransformShape(Shape shape, ITransform transform)
|
||||||
{
|
{
|
||||||
List<Vector2D> vertices = new(shape.Vertices.Count);
|
List<Vector2D> vertices = new(shape.Vertices.Count);
|
||||||
@@ -113,15 +179,27 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
return new Shape(vertices);
|
return new Shape(vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms the shape using the specified transform.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">The shape to transform.</param>
|
||||||
|
/// <param name="transform">The transform to apply.</param>
|
||||||
|
/// <param name="to">The transformed shape.</param>
|
||||||
public static void TransformShape(Shape from, ITransform transform, ref Shape to)
|
public static void TransformShape(Shape from, ITransform transform, ref Shape to)
|
||||||
{
|
{
|
||||||
to.Vertices.Clear();
|
to._verticesList.Clear();
|
||||||
|
|
||||||
int count = from.Vertices.Count;
|
int count = from._verticesList.Count;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
to.Vertices.Add(transform.TransformVector2D(from[i]));
|
to._verticesList.Add(transform.TransformVector2D(from[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether two shapes are approximately equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first shape to compare.</param>
|
||||||
|
/// <param name="right">The second shape to compare.</param>
|
||||||
|
/// <returns><c>true</c> if the shapes are approximately equal; otherwise, <c>false</c>.</returns>
|
||||||
public static bool ApproximatelyEquals(Shape left, Shape right)
|
public static bool ApproximatelyEquals(Shape left, Shape right)
|
||||||
{
|
{
|
||||||
if (left.Vertices.Count != right.Vertices.Count)
|
if (left.Vertices.Count != right.Vertices.Count)
|
||||||
@@ -134,22 +212,83 @@ public readonly struct Shape(IList<Vector2D> Vertices) : IEnumerable<Vector2D>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public IEnumerator<Vector2D> GetEnumerator() => Vertices.GetEnumerator();
|
public IEnumerator<Vector2D> GetEnumerator() => Vertices.GetEnumerator();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
IEnumerator IEnumerable.GetEnumerator() => Vertices.GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => Vertices.GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for the <see cref="Shape"/> struct.
|
||||||
|
/// </summary>
|
||||||
public static class ShapeExtensions
|
public static class ShapeExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a copy of the shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to copy.</param>
|
||||||
|
/// <returns>A copy of the input shape.</returns>
|
||||||
public static Shape CreateCopy(this Shape shape) => Shape.CreateCopy(shape);
|
public static Shape CreateCopy(this Shape shape) => Shape.CreateCopy(shape);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the super triangle that encloses the shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to enclose.</param>
|
||||||
|
/// <returns>The super triangle that encloses the shape.</returns>
|
||||||
public static Triangle ToSuperTriangle(this Shape shape) => Shape.GetSuperTriangle(shape);
|
public static Triangle ToSuperTriangle(this Shape shape) => Shape.GetSuperTriangle(shape);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the lines that form the edges of the shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to get lines from.</param>
|
||||||
|
/// <param name="lines">The list to populate with lines.</param>
|
||||||
public static void ToLines(this Shape shape, IList<Line> lines) => Shape.GetLines(shape, lines);
|
public static void ToLines(this Shape shape, IList<Line> lines) => Shape.GetLines(shape, lines);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of lines that form the edges of the shape.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to get lines from.</param>
|
||||||
|
/// <returns>A list of lines that form the edges of the shape.</returns>
|
||||||
public static List<Line> ToLines(this Shape shape) => Shape.GetLines(shape);
|
public static List<Line> ToLines(this Shape shape) => Shape.GetLines(shape);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Projects the shape onto a vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to project.</param>
|
||||||
|
/// <param name="projectionVector">The vector to project onto.</param>
|
||||||
|
/// <param name="list">The list to populate with projected values.</param>
|
||||||
public static void ToProjection(this Shape shape, Vector2D projectionVector, IList<float> list) => Shape.Project(shape, projectionVector, list);
|
public static void ToProjection(this Shape shape, Vector2D projectionVector, IList<float> list) => Shape.Project(shape, projectionVector, list);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Projects the shape onto a vector.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shape">The shape to project.</param>
|
||||||
|
/// <param name="projectionVector">The vector to project onto.</param>
|
||||||
|
/// <returns>The projection of the shape onto the vector.</returns>
|
||||||
public static Projection ToProjection(this Shape shape, Vector2D projectionVector) => Shape.Project(shape, projectionVector);
|
public static Projection ToProjection(this Shape shape, Vector2D projectionVector) => Shape.Project(shape, projectionVector);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms the shape using the specified transform.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The transform to apply.</param>
|
||||||
|
/// <param name="shape">The shape to transform.</param>
|
||||||
|
/// <returns>The transformed shape.</returns>
|
||||||
public static Shape TransformShape(this ITransform transform, Shape shape) => Shape.TransformShape(shape, transform);
|
public static Shape TransformShape(this ITransform transform, Shape shape) => Shape.TransformShape(shape, transform);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms the shape using the specified transform.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The transform to apply.</param>
|
||||||
|
/// <param name="from">The shape to transform.</param>
|
||||||
|
/// <param name="to">The transformed shape.</param>
|
||||||
public static void TransformShape(this ITransform transform, Shape from, ref Shape to) => Shape.TransformShape(from, transform, ref to);
|
public static void TransformShape(this ITransform transform, Shape from, ref Shape to) => Shape.TransformShape(from, transform, ref to);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether two shapes are approximately equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first shape to compare.</param>
|
||||||
|
/// <param name="right">The second shape to compare.</param>
|
||||||
|
/// <returns><c>true</c> if the shapes are approximately equal; otherwise, <c>false</c>.</returns>
|
||||||
public static bool ApproximatelyEquals(this Shape left, Shape right) => Shape.ApproximatelyEquals(left, right);
|
public static bool ApproximatelyEquals(this Shape left, Shape right) => Shape.ApproximatelyEquals(left, right);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user