moar shit

This commit is contained in:
Marquitos
2016-05-15 20:21:29 -03:00
parent 8a4ae25e04
commit e7f07a6e53
59 changed files with 800 additions and 505 deletions

View File

@@ -1,73 +1,114 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace CharacterEngine.Primitives
{
public sealed class CECollider
public class CECollider
{
public static int[,] edges = new int[,]
{
{0, 4}, {0, 2}, {0, 6},
{1, 7}, {1, 5}, {1, 3},
{3, 4}, {3, 2}, {6, 5},
{6, 7}, {7, 2}, {5, 4}
{0, 2}, {0, 3}, {1, 2},{1, 3}
};
public static int[,] faces = new int[,]
{
{0, 3}, {0, 5}, {0, 7},
{1, 6}, {1, 4}, {1, 2}
};
private Collider collider;
public Collider Coll
private BoxCollider2D collider;
public BoxCollider2D Coll
{
get { return collider; }
}
public Vector3 position
public virtual Vector2 position
{
get { return collider.bounds.center; }
}
public readonly Vector3[] localPoints;
public float Height
{
get { return (GetPoint(0) - GetPoint(3)).magnitude; }
}
public float Width
{
get { return (GetPoint(0) - GetPoint(2)).magnitude; }
}
public CECollider (Collider coll)
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 Vector3[]
localPoints = new Vector2[]
{
coll.bounds.size * 0.5f, //max
-coll.bounds.size * 0.5f, //min
new Vector3(-coll.bounds.extents.x, coll.bounds.extents.y, coll.bounds.extents.z),
new Vector3(-coll.bounds.extents.x, coll.bounds.extents.y, -coll.bounds.extents.z),
new Vector3(coll.bounds.extents.x, coll.bounds.extents.y, -coll.bounds.extents.z),
new Vector3(coll.bounds.extents.x, -coll.bounds.extents.y, -coll.bounds.extents.z),
new Vector3(coll.bounds.extents.x, -coll.bounds.extents.y, coll.bounds.extents.z),
new Vector3(-coll.bounds.extents.x, -coll.bounds.extents.y, coll.bounds.extents.z)
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)
};
}
public Vector3 GetPoint (int index)
/// <summary>
/// GET REAL WORLD POINT OF COLLIDER
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public virtual Vector2 GetPoint (int index)
{
return position + localPoints[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;
}
/// <summary>
/// Collision test along a path
/// </summary>
public RaycastHit SweepTest(Vector3 dir, float distance, float skinWidth = 1.0f)
public CECollision SweepTest(Vector2 dir, float distance)
{
RaycastHit hit = new RaycastHit();
CECollision hit = new CECollision();
for (int i = 0; i <= CEPrimitives.sweepResolution; i++)
{
Vector3 currentDistance = dir.normalized * (distance * (i / CEPrimitives.sweepResolution));
hit = BoxCast(position + currentDistance, skinWidth);
Vector2 currentDistance = dir.normalized * (distance * (i / CEPrimitives.sweepResolution));
hit = BoxCast(position + currentDistance);
if (hit.distance != 0.0f) break;
if (hit.impulse.magnitude != 0.0f) break;
}
return hit;
@@ -76,45 +117,51 @@ namespace CharacterEngine.Primitives
/// <summary>
/// Collision test in an specific point
/// </summary>
public RaycastHit BoxCast(Vector3 position, float skinWidth = 1.0f)
public CECollision BoxCast(Vector2 position)
{
int mask = LayerMask.GetMask("Default");
RaycastHit outHit = new RaycastHit();
CECollision collision = new CECollision();
RaycastHit2D outHit = new RaycastHit2D();
///FACE CAST
for (int i = 0; i < faces.GetLength(0); i++)
for (int i = 0; i < edges.GetLength(0); i++)
{
//Debug.DrawLine(points[faces[i, 0]], points[faces[i, 1]], Color.blue);
outHit = Physics2D.Linecast(GetPoint(edges[i, 0], position), GetPoint(edges[i, 1], position), mask);
if (!Physics.Linecast(position + localPoints[faces[i, 0]] * skinWidth, position + localPoints[faces[i, 1]] * skinWidth, out outHit, mask, QueryTriggerInteraction.Ignore))
if (!outHit)
{
continue;
outHit = Physics2D.Linecast(GetPoint(edges[i, 1], position), GetPoint(edges[i, 0], position), mask);
}
///RETURN DISTANCE FROM CENTER
return outHit;
if (outHit) break;
}
///EDGE CAST
for (int i = 0; i < CECollider.edges.GetLength(0); i++)
if (outHit)
{
//Debug.DrawLine(points[edges[i, 0]], points[edges[i, 1]], Color.red);
if (!Physics.Linecast(position + localPoints[edges[i, 0]] * skinWidth, position + localPoints[edges[i, 1]] * skinWidth, out outHit, mask, QueryTriggerInteraction.Ignore))
{
if (!Physics.Linecast(position + localPoints[edges[i, 1]] * skinWidth, position + localPoints[edges[i, 0]] * skinWidth, out outHit, mask, QueryTriggerInteraction.Ignore))
{
continue;
}
}
///RETURN DISTANCE FROM CENTER
return outHit;
CECollider agent = new CECollider((BoxCollider2D)outHit.collider);
CECollider myAgent = new CEVirtualCollider(position, collider);
collision = CECollision.ResolveCollision(myAgent, agent);
}
///IF REACH HERE DIDNT FOUND SHIT
return outHit;
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;
}
}
}

View File

@@ -0,0 +1,93 @@
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();
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);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 348109b22797c724282c6d7807b00b73
timeCreated: 1463330859
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -24,8 +24,8 @@ namespace CharacterEngine.Primitives
private CEController controller;
public readonly CECollider collider;
private Vector3 velocity;
public Vector3 Velocity
private Vector2 velocity;
public Vector2 Velocity
{
get { return velocity; }
}
@@ -42,7 +42,7 @@ namespace CharacterEngine.Primitives
public CEPrimitives (CEController controller)
{
this.controller = controller;
collider = new CECollider(controller.GetComponent<Collider>());
collider = new CECollider(controller.GetComponent<BoxCollider2D>());
}
#endregion
@@ -89,20 +89,22 @@ namespace CharacterEngine.Primitives
bool CollideAndSlide()
{
Vector3 oldPos = transform.position;
Vector3 predictedPos = oldPos + velocity * Time.fixedDeltaTime;
Vector3 correctedPos = predictedPos;
RaycastHit hit = collider.SweepTest(velocity, velocity.magnitude * Time.fixedDeltaTime, controller.skinWidth);
Vector2 oldPos = transform.position;
Vector2 predictedPos = oldPos + velocity * Time.fixedDeltaTime;
Vector2 correctedPos = predictedPos;
if (hit.collider == null) { return false; }
CECollision hit = collider.SweepTest(velocity, velocity.magnitude * Time.fixedDeltaTime);
Vector3 obstacleHitPoint = hit.point;
Vector3 obstacleNormal = hit.normal;
Vector3 obstacleTangent = Vector3.Cross(obstacleNormal, Vector3.forward);
if (hit.normal == Vector2.zero) { return false; }
Vector2 obstacleHitPoint = hit.point;
Vector2 obstacleNormal = hit.normal;
Vector2 obstacleTangent = Vector3.Cross(obstacleNormal, Vector3.forward);
if (obstacleTangent.magnitude == 0)
obstacleTangent = Vector3.Cross(obstacleNormal, Vector3.up);
Debug.DrawRay(hit.point, hit.normal);
/*
Plane obstaclePlane = new Plane(obstacleNormal, obstacleHitPoint);
Ray velRay = new Ray(oldPos, velocity);
@@ -112,12 +114,11 @@ namespace CharacterEngine.Primitives
Vector3 vectorFromCenter = obstacleHitPoint - Coll.bounds.center ;
*/
correctedPos = oldPos + velocity.normalized * hit.distance;
/*
GameObject a = Instantiate(this.gameObject, correctedPos, transform.rotation) as GameObject;
a.GetComponent<EntityController>().enabled = false;
*/
correctedPos = predictedPos + hit.impulse;
//GameObject a = CEController.Instantiate(controller.gameObject, correctedPos, transform.rotation) as GameObject;
//a.GetComponent<CEController>().enabled = false;
Vector3 epsilon = correctedPos - predictedPos;
@@ -129,9 +130,7 @@ namespace CharacterEngine.Primitives
*/
Vector3 projectedForce = Vector3.Project(velocity, obstacleTangent);
velocity = projectedForce;
velocity.z = 0.0f;
return true;
}
@@ -143,7 +142,7 @@ namespace CharacterEngine.Primitives
void Move()
{
transform.position += velocity * Time.deltaTime;
transform.position += (Vector3)velocity * Time.deltaTime;
}
#endregion

View File

@@ -0,0 +1,22 @@
using UnityEngine;
using System.Collections;
using CharacterEngine.Primitives;
public class test : MonoBehaviour {
public BoxCollider2D coll;
protected CECollider ce;
// Use this for initialization
void Start () {
ce = new CECollider(coll);
}
// Update is called once per frame
void Update () {
if (ce.ContainsPoint(transform.position))
{
Vector2 p = CECollision.ClosestPointInBounds(ce, transform.position);
Debug.DrawLine(p, transform.position, Color.red);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f0ed370640e457f4ca5447af56a3319c
timeCreated: 1463341313
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: