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.
217 lines
6.2 KiB
217 lines
6.2 KiB
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace CharacterEngine.Primitives
|
|
{
|
|
public class CEProjection
|
|
{
|
|
public Vector2 axis;
|
|
public float max;
|
|
public float min;
|
|
|
|
public CEProjection() { }
|
|
|
|
public CEProjection (CECollider coll, Vector2 axis)
|
|
{
|
|
Project(coll, axis);
|
|
}
|
|
|
|
public void Project(CECollider coll, Vector2 axis)
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
Vector2 p = Vector3.Project(coll.GetPoint(i), axis);
|
|
float distance = p.magnitude * Mathf.Sign(Vector2.Dot(p, axis));
|
|
if (i == 0)
|
|
{
|
|
max = min = distance;
|
|
}
|
|
else
|
|
{
|
|
if (distance > max) max = distance;
|
|
else if (distance < min) min = distance;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CECollider
|
|
{
|
|
public static int[,] edges = new int[,]
|
|
{
|
|
{0, 2}, {0, 3}, {1, 2},{1, 3}
|
|
};
|
|
|
|
public static int[,] pointsNeighbours = new int[,]
|
|
{
|
|
{2, 3}, {3, 2}, {0, 1},{1, 0}
|
|
};
|
|
|
|
private BoxCollider2D collider;
|
|
public BoxCollider2D Coll
|
|
{
|
|
get { return collider; }
|
|
}
|
|
|
|
public virtual Vector2 position
|
|
{
|
|
get { return collider.bounds.center; }
|
|
}
|
|
|
|
public float Height
|
|
{
|
|
get { return (GetPoint(0) - GetPoint(3)).magnitude; }
|
|
}
|
|
public float Width
|
|
{
|
|
get { return (GetPoint(0) - GetPoint(2)).magnitude; }
|
|
}
|
|
|
|
public Vector2 Max
|
|
{
|
|
get { return GetPoint(0); }
|
|
}
|
|
public Vector2 Min
|
|
{
|
|
get { return GetPoint(1); }
|
|
}
|
|
|
|
public Vector2 AABBMax
|
|
{
|
|
get { return GetAABBPoint(0); }
|
|
}
|
|
public Vector2 AABBMin
|
|
{
|
|
get { return GetAABBPoint(1); }
|
|
}
|
|
|
|
public readonly Vector2[] localPoints;
|
|
|
|
public CECollider (BoxCollider2D coll)
|
|
{
|
|
collider = coll;
|
|
|
|
///COLLIDER CONSTANT RELATIVE POINTS
|
|
localPoints = new Vector2[]
|
|
{
|
|
coll.size * 0.5f, //max
|
|
-coll.size * 0.5f, //min
|
|
new Vector2(-coll.size.x * 0.5f, coll.size.y * 0.5f),
|
|
new Vector2(coll.size.x * 0.5f, -coll.size.y * 0.5f)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// GET REAL WORLD POINT OF COLLIDER
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
public Vector2 GetPoint (int index)
|
|
{
|
|
return position + (Vector2)(collider.transform.rotation * Vector2.Scale(localPoints[index], collider.transform.lossyScale));
|
|
}
|
|
public Vector2 GetPoint(int index, Vector2 position)
|
|
{
|
|
return position + (Vector2)(collider.transform.rotation * Vector2.Scale(localPoints[index], collider.transform.lossyScale));
|
|
}
|
|
public Vector2 GetAABBPoint(int index)
|
|
{
|
|
return position + (Vector2)(Vector2.Scale(localPoints[index], collider.transform.lossyScale));
|
|
}
|
|
public Vector2 GetAABBPoint(int index, Vector2 position)
|
|
{
|
|
return position + (Vector2)(Vector2.Scale(localPoints[index], collider.transform.lossyScale));
|
|
}
|
|
public Vector2 GetNormal(int index)
|
|
{
|
|
return Vector3.Cross(GetPoint(edges[index, 0]) - GetPoint(edges[index, 1]), Vector3.forward).normalized;
|
|
}
|
|
public Vector2 GetNormal(int index, Vector2 position)
|
|
{
|
|
return Vector3.Cross(GetPoint(edges[index, 0], position) - GetPoint(edges[index, 1], position), Vector3.forward).normalized;
|
|
}
|
|
|
|
public bool ContainsPoint (Vector2 p)
|
|
{
|
|
p = position + (Vector2)(Quaternion.Inverse(collider.transform.rotation) * (p - position));
|
|
bool insideX = p.x > AABBMin.x && p.x < AABBMax.x;
|
|
bool insideY = p.y > AABBMin.y && p.y < AABBMax.y;
|
|
|
|
return insideX && insideY;
|
|
}
|
|
|
|
public void Project(Vector2 normal, Vector2 p)
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Collision test along a path
|
|
/// </summary>
|
|
public CECollision SweepTest(Vector2 dir, float distance)
|
|
{
|
|
CECollision hit = new CECollision();
|
|
|
|
for (int i = 0; i <= CEPrimitives.sweepResolution; i++)
|
|
{
|
|
Vector2 currentDistance = dir.normalized * (distance * (i / CEPrimitives.sweepResolution));
|
|
hit = BoxCast(position + currentDistance);
|
|
|
|
if (hit.impulse.magnitude != 0.0f) break;
|
|
}
|
|
|
|
return hit;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Collision test in an specific point
|
|
/// </summary>
|
|
public CECollision BoxCast(Vector2 position)
|
|
{
|
|
int mask = LayerMask.GetMask("Default");
|
|
|
|
CECollision collision = new CECollision();
|
|
RaycastHit2D outHit = new RaycastHit2D();
|
|
|
|
|
|
for (int i = 0; i < edges.GetLength(0); i++)
|
|
{
|
|
outHit = Physics2D.Linecast(GetPoint(edges[i, 0], position), GetPoint(edges[i, 1], position), mask);
|
|
|
|
if (!outHit)
|
|
{
|
|
outHit = Physics2D.Linecast(GetPoint(edges[i, 1], position), GetPoint(edges[i, 0], position), mask);
|
|
}
|
|
|
|
if (outHit) break;
|
|
}
|
|
|
|
if (outHit)
|
|
{
|
|
CECollider agent = new CECollider((BoxCollider2D)outHit.collider);
|
|
CECollider myAgent = new CEVirtualCollider(position, collider);
|
|
collision = CECollision.ResolveCollision(myAgent, agent);
|
|
}
|
|
|
|
return collision;
|
|
}
|
|
}
|
|
|
|
public class CEVirtualCollider : CECollider
|
|
{
|
|
protected Vector2 virtualPosition;
|
|
public override Vector2 position
|
|
{
|
|
get
|
|
{
|
|
return virtualPosition;
|
|
}
|
|
}
|
|
|
|
public CEVirtualCollider (Vector2 pos, BoxCollider2D coll) : base(coll)
|
|
{
|
|
virtualPosition = pos;
|
|
}
|
|
}
|
|
}
|
|
|