Test pNIADIPSDNIP

This commit is contained in:
2023-12-04 17:48:22 +03:00
parent 84ecc68320
commit def463afcf
5 changed files with 80 additions and 21 deletions

View File

@@ -19,7 +19,7 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
IReadOnlyList<Vector2> Vertices { get; }
bool CheckCollision(Vector2 point, ICollider2D otherCollider, out Vector2 normal);
bool CheckCollision(Vector2 point, ICollider2D otherCollider, out CollisionInformation collisionInformation);
void RecalculateVertices();
}

View File

@@ -3,9 +3,10 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Pong;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Graphics.TwoDimensional;
using Syntriax.Engine.Physics2D.Abstract;
namespace Syntriax.Engine.Physics2D;
@@ -42,9 +43,9 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
public bool Assign(ITransform transform) => GameObject.Assign(transform);
public bool CheckCollision(Vector2 point, ICollider2D otherCollider, out Vector2 normal)
public bool CheckCollision(Vector2 point, ICollider2D otherCollider, out CollisionInformation collisionInformation)
{
normal = Vector2.UnitX;
collisionInformation = new CollisionInformation(Vector2.Zero, Vector2.Zero);
foreach (var triangle in triangles)
{
@@ -59,9 +60,19 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
{
if (!DoIntersect(main, edge))
continue;
normal = edge.A - edge.B;
Vector2 contactPoint = ClosestPointOnEdge(point, edge);
Vector2 normal = contactPoint - point;
normal.Normalize();
normal = new Vector2(normal.Y, normal.X);
collisionInformation = new CollisionInformation(normal, contactPoint);
GameObject gameObject = Game1.gameManager.InstantiateGameObject<GameObject>();
gameObject.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(Game1.spriteBox);
gameObject.Transform.Position = point;
gameObject.Transform.Scale = new Vector2(1f, .01f) * 100f;
gameObject.Transform.Rotation = (float)Math.Atan2(normal.Y, normal.X);
break;
}
return true;
@@ -143,6 +154,25 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
// }
}
private Vector2 ClosestPointOnEdge(Vector2 point, Edge edge)
{
// Convert edge points to vectors
var edgeVector = new Vector2(edge.B.X - edge.A.X, edge.B.Y - edge.A.Y);
var pointVector = new Vector2(point.X - edge.A.X, point.Y - edge.A.Y);
// Calculate the projection of pointVector onto edgeVector
float t = (pointVector.X * edgeVector.X + pointVector.Y * edgeVector.Y) / (edgeVector.X * edgeVector.X + edgeVector.Y * edgeVector.Y);
// Clamp t to the range [0, 1] to ensure the closest point is on the edge
t = Math.Max(0, Math.Min(1, t));
// Calculate the closest point on the edge
float closestX = edge.A.X + t * edgeVector.X;
float closestY = edge.A.Y + t * edgeVector.Y;
return new Vector2(closestX, closestY);
}
private bool DoesEdgeExistInTriangles(Edge edge, List<Triangle> triangles)
{
foreach (var triangle in triangles)

View File

@@ -1,12 +1,9 @@
using Microsoft.Xna.Framework;
using Syntriax.Engine.Physics2D.Abstract;
namespace Syntriax.Engine.Physics2D;
public record CollisionInformation
(
Vector2 Normal,
float Impulse,
IRigidBody2D? RigidBodyX,
IRigidBody2D? RigidBodyY
Vector2 ContactPosition
);

View File

@@ -57,18 +57,39 @@ public class PhysicsEngine2D : IPhysicsEngine2D
{
ICollider2D colliderX = colliders[colliderIX];
for (int colliderIY = colliderIX + 1; colliderIY < colliders.Count; colliderIY++)
foreach (var vertex in colliderX.Vertices)
for (int i1 = 0; i1 < colliderX.Vertices.Count; i1++)
{
if (!colliders[colliderIY].CheckCollision(vertex, colliderX, out var normal))
Vector2 vertex = colliderX.Vertices[i1];
if (!colliders[colliderIY].CheckCollision(vertex, colliderX, out var collisionInformation))
continue;
Console.WriteLine($"normal = {collisionInformation.Normal}");
// // if (colliders[colliderIX].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidX))
// // rigidX.Velocity = Vector2.Reflect(rigidX.Velocity, collisionInformation.Normal);
if (colliders[colliderIX].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidX))
rigidX.Velocity = Vector2.Reflect(rigidX.Velocity, normal);
{
Console.WriteLine($"rigidX.Velocity = {rigidX.Velocity}");
rigidX.Velocity = Vector2.Reflect(rigidX.Velocity, collisionInformation.Normal);
Vector2 vector2 = -new Vector2(collisionInformation.Normal.X * rigidX.Velocity.X, collisionInformation.Normal.Y * rigidX.Velocity.Y);
Console.WriteLine($"Displacement = {vector2}");
rigidX.Transform.Position += vector2 * intervalDeltaTime * 2;
Console.WriteLine($"rigidX.Velocity = {rigidX.Velocity}");
}
if (colliders[colliderIY].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidY))
rigidY.Velocity = Vector2.Reflect(rigidY.Velocity, normal);
{
Console.WriteLine($"rigidY.Velocity = {rigidY.Velocity}");
rigidY.Velocity = Vector2.Reflect(rigidY.Velocity, collisionInformation.Normal);
Vector2 vector2 = -new Vector2(collisionInformation.Normal.X * rigidY.Velocity.X, collisionInformation.Normal.Y * rigidY.Velocity.Y);
Console.WriteLine($"Displacement = {vector2}");
rigidY.Transform.Position += vector2 * intervalDeltaTime * 2;
Console.WriteLine($"rigidY.Velocity = {rigidY.Velocity}");
}
Console.WriteLine($"/////////////////////////////////////////////");
colliders[colliderIY].RecalculateVertices();
colliders[colliderIX].RecalculateVertices();
// Console.WriteLine($"Collision");
break;
}
}
}