Skip to content

Commit

Permalink
Added base physics implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornado-Technology committed Jul 16, 2024
1 parent 4e49054 commit 9969f67
Show file tree
Hide file tree
Showing 25 changed files with 322 additions and 48 deletions.
4 changes: 4 additions & 0 deletions Hypercube.Client/Dependencies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Hypercube.Shared.Entities.Realisation.EventBus;
using Hypercube.Shared.Entities.Realisation.Manager;
using Hypercube.Shared.EventBus;
using Hypercube.Shared.Physics;
using Hypercube.Shared.Resources.Caching;
using Hypercube.Shared.Resources.Manager;
using Hypercube.Shared.Timing;
Expand Down Expand Up @@ -54,6 +55,9 @@ public static void Register(DependenciesContainer rootContainer)
// Camera
rootContainer.Register<ICameraManager, CameraManager>();

// Physics
rootContainer.Register<IPhysicsManager, PhysicsManager>();

// Rendering
rootContainer.Register<IRenderer, Renderer>();

Expand Down
32 changes: 32 additions & 0 deletions Hypercube.Client/Entities/Systems/Physics/PhysicsSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Hypercube.Client.Graphics.Events;
using Hypercube.Client.Graphics.Rendering;
using Hypercube.Math;
using Hypercube.Math.Shapes;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.Entities.Systems.Physics;
using SharedPhysicsSystem = Hypercube.Shared.Entities.Systems.Physics.PhysicsSystem;

namespace Hypercube.Client.Entities.Systems.Physics;

public class PhysicsSystem : SharedPhysicsSystem
{
[Dependency] private readonly IRenderer _renderer = default!;

public override void Initialize()
{
base.Initialize();

Subscribe<RenderDrawingEvent>(OnRenderDrawing);
}

private void OnRenderDrawing(ref RenderDrawingEvent args)
{
foreach (var entity in GetEntities<PhysicsComponent>())
{
var shape = entity.Component.Shape;
var circle = new Circle(shape.Position + entity.Component.Position, shape.Radius);

_renderer.DrawCircle(circle, Color.Green);
}
}
}
2 changes: 1 addition & 1 deletion Hypercube.Client/Entities/Systems/Sprite/SpriteSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Hypercube.Client.Graphics.Events;
using Hypercube.Client.Graphics.Rendering;
using Hypercube.Client.Graphics.Texturing;
using Hypercube.Math.Boxs;
using Hypercube.Math.Shapes;
using Hypercube.Math.Transforms;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Dependency;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Hypercube.Client.Graphics.Drawing;
using Hypercube.Client.Graphics.Texturing;
using Hypercube.Math;
using Hypercube.Math.Boxs;
using Hypercube.Math.Matrixs;
using Hypercube.Math.Vectors;
using Hypercube.Math.Shapes;
using OpenTK.Mathematics;
using OpenToolkit.Graphics.OpenGL4;
using Box2 = Hypercube.Math.Shapes.Box2;
using Vector2 = Hypercube.Math.Vectors.Vector2;

namespace Hypercube.Client.Graphics.Realisation.OpenGL.Rendering;

Expand Down Expand Up @@ -61,6 +63,23 @@ public void DrawLine(Box2 box, Color color, Matrix4X4 model)
AddLineBatch(startIndex, box, color);
}

public void DrawCircle(Circle circle, Color color)
{
DrawCircle(circle, color, Matrix4X4.Identity);
}

public void DrawCircle(Circle circle, Color color, Matrix3X3 model)
{
DrawCircle(circle, color, Matrix4X4.CreateIdentity(model));
}

public void DrawCircle(Circle circle, Color color, Matrix4X4 model)
{
var startIndex = (uint)_batchVertexIndex;
_batches.Add(new Batch(_batchIndexIndex, 20, null, PrimitiveType.LineLoop, model));
AddCircleBatch(startIndex, circle, color, 20);
}

public void DrawRectangle(Box2 box, Color color)
{
DrawRectangle(box, color, Matrix4X4.Identity);
Expand Down Expand Up @@ -113,6 +132,20 @@ private void AddLineBatch(uint startIndex, Box2 box2, Color color)
_batchIndices[_batchIndexIndex++] = startIndex + 1;
}

private void AddCircleBatch(uint startIndex, Circle circle, Color color, int segments)
{
var total = HyperMathF.TwoPI / segments;
for (var i = 0; i < segments; i++)
{
var theta = total * i;
var x = circle.Position.X + circle.Radius * MathF.Cos(theta);
var y = circle.Position.Y + circle.Radius * MathF.Sin(theta);

_batchVertices[_batchVertexIndex++] = new Vertex(new Vector2(x, y), Vector2.Zero, color);
_batchIndices[_batchIndexIndex++] = startIndex + (uint)i;
}
}

private void AddQuadBatch(uint startIndex, Box2 quad, Box2 uv, Color color)
{
_batchVertices[_batchVertexIndex++] = new Vertex(quad.TopRight, uv.TopRight, color);
Expand Down
25 changes: 18 additions & 7 deletions Hypercube.Client/Graphics/Realisation/OpenGL/Texturing/Texture.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
using Hypercube.Client.Graphics.Texturing;
using Hypercube.Math.Boxs;
using Hypercube.Math.Shapes;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Resources;

namespace Hypercube.Client.Graphics.Realisation.OpenGL.Texturing;

public readonly struct Texture(ResourcePath path, Vector2Int size, byte[] data) : ITexture
public readonly struct Texture : ITexture
{
public ResourcePath Path { get; } = path;
public int Width { get; } = size.X;
public int Height { get; } = size.Y;
public byte[] Data { get; } = data;
public ResourcePath Path { get; }
public Vector2Int Size { get; }
public byte[] Data { get; }

public int Width => Size.X;
public int Height => Size.Y;

public Texture(ResourcePath path, Vector2Int size, byte[] data)
{
Path = path;
Size = size;
Data = data;
}

public Box2 QuadCrateTranslated(Vector2 position)
{
return new Box2(position, position + (Vector2)size);
var size = (Vector2)Size / 2;
return new Box2(position - size / 2, position + size / 2);
}
}
5 changes: 4 additions & 1 deletion Hypercube.Client/Graphics/Rendering/IRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using Hypercube.Client.Graphics.Texturing;
using Hypercube.Client.Graphics.Windows;
using Hypercube.Math;
using Hypercube.Math.Boxs;
using Hypercube.Math.Matrixs;
using Hypercube.Math.Shapes;
using Hypercube.Math.Vectors;

namespace Hypercube.Client.Graphics.Rendering;
Expand Down Expand Up @@ -34,6 +34,9 @@ public interface IRenderer
void DrawLine(Box2 box, Color color);
void DrawLine(Box2 box, Color color, Matrix3X3 model);
void DrawLine(Box2 box, Color color, Matrix4X4 model);
void DrawCircle(Circle circle, Color color);
void DrawCircle(Circle circle, Color color, Matrix3X3 model);
void DrawCircle(Circle circle, Color color, Matrix4X4 model);
void DrawRectangle(Box2 box, Color color);
void DrawRectangle(Box2 box, Color color, Matrix3X3 model);
void DrawRectangle(Box2 box, Color color, Matrix4X4 model);
Expand Down
2 changes: 1 addition & 1 deletion Hypercube.Client/Graphics/Texturing/ITexture.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Hypercube.Math.Boxs;
using Hypercube.Math.Shapes;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Resources;

Expand Down
1 change: 0 additions & 1 deletion Hypercube.Client/Hypercube.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="Entities\Systems\" />
<Folder Include="Input\Binding\" />
</ItemGroup>

Expand Down
6 changes: 4 additions & 2 deletions Hypercube.Example/Example.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
using Hypercube.Client.Graphics.Events;
using Hypercube.Client.Graphics.Rendering;
using Hypercube.Math;
using Hypercube.Math.Boxs;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.Entities.Realisation.Manager;
using Hypercube.Shared.Entities.Systems.Physics;
using Hypercube.Shared.Entities.Systems.Transform.Coordinates;
using Hypercube.Shared.EventBus;
using Hypercube.Shared.Resources;
Expand Down Expand Up @@ -50,7 +50,7 @@ private void OnRenderDrawing(ref RenderDrawingEvent ev)

private void Startup(ref RuntimeStartupEvent args)
{
for (var i = 0; i < 100; i++)
for (var i = 0; i < 400; i++)
{
var x = _random.NextSingle() * 800 - 400;
var y = _random.NextSingle() * 800 - 400;
Expand All @@ -72,6 +72,8 @@ private void Startup(ref RuntimeStartupEvent args)
private void CreateEntity(SceneCoordinates coordinates)
{
var entityUid = _entitiesManager.Create("Fuck", coordinates);

_entitiesComponentManager.AddComponent<PhysicsComponent>(entityUid);

_entitiesComponentManager.AddComponent<SpriteComponent>(entityUid, entity =>
{
Expand Down
2 changes: 1 addition & 1 deletion Hypercube.Math/Matrixs/Matrix4X4.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Hypercube.Math.Boxs;
using Hypercube.Math.Shapes;
using Hypercube.Math.Transforms;
using Hypercube.Math.Vectors;

Expand Down
6 changes: 2 additions & 4 deletions Hypercube.Math/Boxs/Box2.cs → Hypercube.Math/Shapes/Box2.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Hypercube.Math.Vectors;
using Hypercube.Math.Vectors;

namespace Hypercube.Math.Boxs;
namespace Hypercube.Math.Shapes;

[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public readonly struct Box2
{
public static readonly Box2 UV = new(0.0f, 1.0f, 1.0f, 0.0f);
Expand Down
11 changes: 11 additions & 0 deletions Hypercube.Math/Shapes/Circle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Hypercube.Math.Vectors;

namespace Hypercube.Math.Shapes;

public readonly struct Circle(Vector2 position, float radius)
{
public readonly Vector2 Position = position;
public readonly float Radius = radius;

public float Area => Radius * Radius * HyperMathF.PI;
}
18 changes: 18 additions & 0 deletions Hypercube.Math/Vectors/Vector2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,22 @@ public override string ToString()
{
return !a.Equals(b);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float DistanceSquared(Vector2 a, Vector2 b)
{
return (a - b).LengthSquared;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Distance(Vector2 a, Vector2 b)
{
return MathF.Sqrt(DistanceSquared(a, b));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Dot(Vector2 a, Vector2 b)
{
return a.X * b.X + a.Y * b.Y;
}
}
31 changes: 31 additions & 0 deletions Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Hypercube.Math.Vectors;
using Hypercube.Shared.Entities.Realisation.Components;
using Hypercube.Shared.Entities.Systems.Transform;
using Hypercube.Shared.Physics;
using Hypercube.Shared.Physics.Shapes;

namespace Hypercube.Shared.Entities.Systems.Physics;

public sealed class PhysicsComponent : Component, IBody
{
// Caching
public TransformComponent TransformComponent;

Check warning on line 12 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformComponent' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 12 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformComponent' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 12 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformComponent' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 12 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformComponent' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
public TransformSystem TransformSystem;

Check warning on line 13 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformSystem' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 13 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformSystem' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 13 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformSystem' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 13 in Hypercube.Shared/Entities/Systems/Physics/PhysicsComponent.cs

View workflow job for this annotation

GitHub Actions / Windows Build

Non-nullable field 'TransformSystem' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

public CircleShape Shape { get; private set; } = new();

public Vector2 Velocity { get; private set; }

public Vector2 Position
{
get => TransformComponent.Transform.Position;
set => TransformSystem.SetPosition(TransformComponent, value);
}

public Vector2 PreviousPosition { get; private set; }

public void Move(Vector2 position)
{
Position += position;
}
}
46 changes: 46 additions & 0 deletions Hypercube.Shared/Entities/Systems/Physics/PhysicsSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Hypercube.Shared.Dependency;
using Hypercube.Shared.Entities.Realisation;
using Hypercube.Shared.Entities.Realisation.Events;
using Hypercube.Shared.Entities.Realisation.Systems;
using Hypercube.Shared.Entities.Systems.Transform;
using Hypercube.Shared.Physics;
using Hypercube.Shared.Runtimes.Loop.Event;

namespace Hypercube.Shared.Entities.Systems.Physics;

public abstract class PhysicsSystem : EntitySystem
{
[Dependency] private readonly IPhysicsManager _physicsManager = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!;

public override void Initialize()
{
base.Initialize();

Subscribe<PhysicsComponent, ComponentAdded>(OnBodyAdded);
Subscribe<PhysicsComponent, ComponentRemoved>(OnBodyRemoved);
}

public override void FrameUpdate(UpdateFrameEvent args)
{
base.FrameUpdate(args);

foreach (var physics in GetEntities<PhysicsComponent>())
{
_transformSystem.SetPosition(physics.Owner, physics.Component.Position);
}
}

private void OnBodyAdded(Entity<PhysicsComponent> entity, ref ComponentAdded args)
{
entity.Component.TransformComponent = GetComponent<TransformComponent>(entity);
entity.Component.TransformSystem = _transformSystem;

_physicsManager.AddBody(entity.Component);
}

private void OnBodyRemoved(Entity<PhysicsComponent> entity, ref ComponentRemoved args)
{
_physicsManager.RemoveBody(entity.Component);
}
}
15 changes: 13 additions & 2 deletions Hypercube.Shared/Entities/Systems/Transform/TransformSystem.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
using Hypercube.Shared.Entities.Realisation.Systems;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Entities.Realisation;
using Hypercube.Shared.Entities.Realisation.Systems;

namespace Hypercube.Shared.Entities.Systems.Transform;

public class TransformSystem : EntitySystem
{

public void SetPosition(TransformComponent transform, Vector2 position)
{
transform.Transform.SetPosition(position);
}

public void SetPosition(Entity<TransformComponent?> entity, Vector2 position)
{
var transform = entity.Component ?? GetComponent<TransformComponent>(entity);
transform.Transform.SetPosition(position);
}
}
3 changes: 0 additions & 3 deletions Hypercube.Shared/Hypercube.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
<ItemGroup>
<ProjectReference Include="..\Hypercube.Math\Hypercube.Math.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Entities\Systems\" />
</ItemGroup>
<ItemGroup>
<ContentWithTargetPath Include="..\Resources\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand Down
Loading

0 comments on commit 9969f67

Please sign in to comment.