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

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);
}
}
}