You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.4 KiB
131 lines
4.4 KiB
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
namespace CharacterEngine.Primitives
|
|
{
|
|
public struct CECollision
|
|
{
|
|
public Vector2 impulse;
|
|
public Vector2 point;
|
|
public Vector2 normal;
|
|
|
|
/// <summary>
|
|
/// RESOLVE THE COLLISION AND RETURN A COLLISION VALUE
|
|
/// a = Collider wich is dynamic
|
|
/// b = static Collider
|
|
/// </summary>
|
|
/// <param name="a"></param>
|
|
/// <param name="b"></param>
|
|
public static CECollision ResolveCollision (CECollider a, CECollider b)
|
|
{
|
|
Vector2 closestPoint = Vector2.zero;
|
|
CECollision collision = new CECollision();
|
|
|
|
///IS NOT MTV THO (music television) is MINIMUN TRANSLATION VECTOR (funny joke uh)
|
|
Vector2 MTV = Vector2.zero;
|
|
float minimunOverlap = 0.0f;
|
|
|
|
Vector2[] axes = new Vector2[8];
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
axes[i] = i < 4 ? a.GetNormal(i) : b.GetNormal(i - 4);
|
|
}
|
|
|
|
for (int i = 0; i < axes.Length; i++)
|
|
{
|
|
CEProjection projectionA = new CEProjection(a, axes[i]);
|
|
CEProjection projectionB = new CEProjection(b, axes[i]);
|
|
|
|
float overlapValue = Mathf.Abs(projectionA.max - projectionB.min);
|
|
|
|
if (i == 0 || overlapValue < minimunOverlap)
|
|
{
|
|
minimunOverlap = overlapValue;
|
|
MTV = axes[i] * minimunOverlap;
|
|
}
|
|
}
|
|
|
|
collision.impulse = MTV;
|
|
collision.normal = collision.impulse.normalized;
|
|
///COULDNT DETRMINE YET HOW TO FIND POINT ILL DO IT ASFASDGSD
|
|
collision.point = Vector2.zero;
|
|
/*
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
Vector2 currentPoint = a.GetPoint(i);
|
|
if (b.ContainsPoint(currentPoint))
|
|
{
|
|
closestPoint = ClosestPointInBounds(b, currentPoint);
|
|
|
|
collision.impulse = closestPoint - currentPoint;
|
|
collision.normal = collision.impulse.normalized;
|
|
collision.point = closestPoint;
|
|
|
|
return collision;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
Vector2 currentPoint = b.GetPoint(i);
|
|
if (a.ContainsPoint(currentPoint))
|
|
{
|
|
closestPoint = ClosestPointInBounds(a, currentPoint);
|
|
|
|
collision.impulse = (closestPoint - currentPoint) * -1;
|
|
collision.normal = collision.impulse.normalized;
|
|
collision.point = closestPoint;
|
|
|
|
return collision;
|
|
}
|
|
}
|
|
*/
|
|
|
|
//IF REACH HERE DIDNT RESOLVE SHIT
|
|
//Debug.Log("Could not resolve collision");
|
|
return collision;
|
|
}
|
|
|
|
/// <summary>
|
|
/// GET CLOSEST CONTACT POINT
|
|
/// </summary>
|
|
/// <param name="coll"></param>
|
|
/// <param name="point"></param>
|
|
/// <returns></returns>
|
|
public static Vector2 ClosestPointInBounds (CECollider coll, Vector2 point)
|
|
{
|
|
Vector2 smallerDelta = Vector2.zero;
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
Vector2 cpis = ClosestVectorToSegment(point, coll.GetPoint(CECollider.edges[i, 0]), coll.GetPoint(CECollider.edges[i, 1]));
|
|
Vector2 delta = cpis - point;
|
|
|
|
if (smallerDelta == Vector2.zero) smallerDelta = delta;
|
|
else
|
|
{
|
|
if (delta.sqrMagnitude < smallerDelta.sqrMagnitude)
|
|
smallerDelta = delta;
|
|
}
|
|
}
|
|
|
|
return point + smallerDelta;
|
|
}
|
|
|
|
public static Vector2 ClosestVectorToSegment (Vector2 p, Vector2 a, Vector2 b)
|
|
{
|
|
Vector2 segmentNormal = Vector3.Cross((a- b).normalized, Vector3.forward);
|
|
Vector2 distanceToPointA = a - p;
|
|
Vector2 distanceToPointB = b - p;
|
|
|
|
return p + (Vector2)Vector3.Project(distanceToPointA, segmentNormal);
|
|
}
|
|
public static Vector2 ClosestVectorToPlane(Vector2 p, Vector2 normal, Vector2 position)
|
|
{
|
|
Vector2 plane = Vector3.Cross(normal, Vector3.forward);
|
|
Vector2 distanceToPosition = position - p;
|
|
|
|
return p + (Vector2)Vector3.Project(distanceToPosition, plane);
|
|
}
|
|
}
|
|
}
|
|
|