using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace CharacterEngine.Primitives
{
public class CECollider
{
public static int[,] edges = new int[,]
{
{0, 2}, {0, 3}, {1, 2},{1, 3}
};
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)
};
}
///
/// GET REAL WORLD POINT OF COLLIDER
///
///
///
public virtual Vector2 GetPoint (int index)
{
return position + (Vector2)(collider.transform.rotation * Vector2.Scale(localPoints[index], collider.transform.lossyScale));
}
public virtual Vector2 GetPoint(int index, Vector2 position)
{
return position + (Vector2)(collider.transform.rotation * Vector2.Scale(localPoints[index], collider.transform.lossyScale));
}
public virtual Vector2 GetAABBPoint(int index)
{
return position + (Vector2)(Vector2.Scale(localPoints[index], collider.transform.lossyScale));
}
public virtual Vector2 GetAABBPoint(int index, Vector2 position)
{
return position + (Vector2)(Vector2.Scale(localPoints[index], collider.transform.lossyScale));
}
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;
}
///
/// Collision test along a path
///
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;
}
///
/// Collision test in an specific point
///
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;
}
}
}