public static bool checkAxis(OBBHull2D a, AABBHull2D b, Vector2 norm) { Vector2 aProjValues = getMinMaxProjectionValuesOnNorm(a, norm); Vector2 bProjValues = getMinMaxProjectionValuesOnNorm(b, norm); Debug.DrawLine(aProjValues.x * norm, aProjValues.y * norm, Color.blue); //this is dumb useful, the projected line Debug.DrawLine(bProjValues.x * norm, bProjValues.y * norm, Color.red); //this is dumb useful, the projected line return(detectCollisionFromMinMax(aProjValues, bProjValues)); }
/* * Circle V OBB */ public static bool detectCollision(CircleHull2D circle, OBBHull2D square) { Vector2 closestPoint = square.GetClosestPoint(circle.position); Debug.DrawLine(new Vector3(closestPoint.x, closestPoint.y, 0), circle.position); if (circle.radius > Vector2.Distance(circle.position, closestPoint)) { return(true); } return(false); }
/* * VERIFIED WORKING, based off OBB v OBB Collision */ public static bool detectCollision(OBBHull2D a, AABBHull2D b) { if (checkAxis(a, b, a.getXNormal()) && checkAxis(a, b, a.getYNormal()) && checkAxis(a, b, Vector2.left) && checkAxis(a, b, Vector2.up)) { return(true); } return(false); }
/* * Verified Working, possible error in using 4 checkaxis, i think i missed a check somewhere deeper in the code */ public static bool detectCollision(OBBHull2D lft, OBBHull2D rgt) { //check each axis on each side, need to make better if (checkAxis(lft, rgt, lft.getXNormal()) && checkAxis(lft, rgt, lft.getYNormal()) && checkAxis(lft, rgt, rgt.getXNormal()) && checkAxis(lft, rgt, rgt.getYNormal())) { return(true); } return(false); }
public static Vector2 getMinMaxProjectionValuesOnNorm(OBBHull2D box, Vector2 norm) { float a, b, c, d; int axis = norm.x != 0 ? 0 : 1; //just to make a scaler, but in case the x axis is zero, and if they are both zero then what the hell u doing with a normal (0,0) a = proj(box.getTopLeftPos(), norm)[axis] / norm[axis]; b = proj(box.getTopRightPos(), norm)[axis] / norm[axis]; c = proj(box.getBottomLeftPos(), norm)[axis] / norm[axis]; d = proj(box.getBottomRightPos(), norm)[axis] / norm[axis]; float min = Mathf.Min(new float[] { a, b, c, d }); float max = Mathf.Max(new float[] { a, b, c, d }); return(new Vector2(min, max)); }
public static float checkAxisPenetration(OBBHull2D a, AABBHull2D b, Vector2 norm) { Vector2 aProjValues = getMinMaxProjectionValuesOnNorm(a, norm); Vector2 bProjValues = getMinMaxProjectionValuesOnNorm(b, norm); Debug.DrawLine(aProjValues.x * norm, aProjValues.y * norm, Color.blue); //this is dumb useful, the projected line Debug.DrawLine(bProjValues.x * norm, bProjValues.y * norm, Color.red); //this is dumb useful, the projected line if (!detectCollisionFromMinMax(aProjValues, bProjValues)) { return(0.0f); } else { return(calculateMinMaxCollisionOverlap(aProjValues, bProjValues)); } }
public static HullCollision2D detectCollisionResponse(OBBHull2D a, OBBHull2D b) { Dictionary <Vector2, float> axisValues = new Dictionary <Vector2, float>(); //norm to the overlap value axisValues.Add(a.getXNormal(), checkAxisPenetration(a, b, a.getXNormal())); axisValues.Add(a.getYNormal(), checkAxisPenetration(a, b, a.getYNormal())); if (a.rotation != b.rotation) { axisValues.Add(b.getXNormal(), checkAxisPenetration(a, b, b.getXNormal())); axisValues.Add(b.getYNormal(), checkAxisPenetration(a, b, b.getYNormal())); } Dictionary <Vector2, float> .Enumerator enumerator = axisValues.GetEnumerator(); enumerator.MoveNext(); Vector2 pos = a.position; KeyValuePair <Vector2, float> bestPenetration = enumerator.Current; //need to set one to compare too, no null value to just allow all checking in the for loop if (bestPenetration.Value == 0.0f) { return(null); } while (enumerator.MoveNext()) { if (Mathf.Abs(enumerator.Current.Value) < Mathf.Abs(bestPenetration.Value)) { bestPenetration = enumerator.Current; } if (bestPenetration.Value == 0.0f) { return(null); } } HullCollision2D collision; Vector2 norm = bestPenetration.Key; if (bestPenetration.Value <= 0.0f) //ooh this was an easy thing to miss { norm *= -1.0f; } collision = new HullCollision2D(a, b, norm, Mathf.Abs(bestPenetration.Value)); //collision.contactPoint = pos; return(collision); }
public static HullCollision2D detectCollisionResponse(OBBHull2D a, AABBHull2D b) { Dictionary <Vector2, float> axisValues = new Dictionary <Vector2, float>(); //norm to the overlap value axisValues.Add(Vector2.up, checkAxisPenetration(a, b, Vector2.up)); axisValues.Add(Vector2.right, checkAxisPenetration(a, b, Vector2.right)); if (a.rotation != 0.0f) { axisValues.Add(a.getXNormal(), checkAxisPenetration(a, b, a.getXNormal())); axisValues.Add(a.getYNormal(), checkAxisPenetration(a, b, a.getYNormal())); } Dictionary <Vector2, float> .Enumerator enumerator = axisValues.GetEnumerator(); enumerator.MoveNext(); KeyValuePair <Vector2, float> bestPenetration = enumerator.Current; //need to set one to compare too, no null value to just allow all checking in the for loop if (bestPenetration.Value == 0.0f) { return(null); } while (enumerator.MoveNext()) { if (Mathf.Abs(enumerator.Current.Value) < Mathf.Abs(bestPenetration.Value)) { bestPenetration = enumerator.Current; } if (bestPenetration.Value == 0.0f) { return(null); } } HullCollision2D collision; Vector2 norm = bestPenetration.Key; if (Vector2.Dot(a.velocity, norm) >= 0.0f) { norm *= -1.0f; } collision = new HullCollision2D(a, b, norm, Mathf.Abs(bestPenetration.Value)); return(collision); }
//TODO public static HullCollision2D detectCollisionResponse(CircleHull2D circle, OBBHull2D square) { Vector2 closestPointSquare = square.GetClosestPoint(circle.position); Vector2 closestPointCircle = circle.GetClosestPoint(closestPointSquare); Debug.DrawLine(new Vector3(closestPointSquare.x, closestPointSquare.y, 0), new Vector3(closestPointCircle.x, closestPointCircle.y, 0)); if (circle.radius > Vector2.Distance(circle.position, closestPointSquare)) { Vector2 penNorm = closestPointSquare - closestPointCircle; HullCollision2D collision; if (penNorm.x > 0.0f) { collision = new HullCollision2D(circle, square, penNorm.normalized, penNorm.magnitude); } else { collision = new HullCollision2D(circle, square, penNorm.normalized, penNorm.magnitude); } return(collision); } return(null); }