public override void CheckForCollisions(List <LPhysicsObject2D> objs, float deltaTime) { base.CheckForCollisions(objs, deltaTime); for (int i = objs.Count - 1; i >= 1; i--) { for (int j = i - 1; j >= 0; j--) { LPhysicsObject2D objA = objs[i]; LPhysicsObject2D objB = objs[j]; if (objA.collider != null && objB.collider != null && objA.collider.bounds.Intersects(objB.collider.bounds)) { simplex.Clear(); direction = Vector2.one; epa.Clear(); closestFace = null; safety.Clear(); LContactConstraint2D constraint = CollisionDetect(objA, objB); if (constraint != null) { contactConstraints.Add(constraint); } } } } }
/// <summary> /// 寻找距离原点最近的face /// </summary> /// <returns></returns> public EPAFace2D FindClosestFace() { EPAFace2D minFace = null; for (int i = faces.Count - 1; i >= 0; i--) { if (minFace == null || faces[i].sqrMagnitude < minFace.sqrMagnitude) { minFace = faces[i]; } } return(minFace); }
/// <summary> /// <para>EPA判断渗透方向和深度</para> /// <para>1.找到list中离原点最近的face</para> /// <para>2.如果与上一次找到的相同,直接返回</para> /// <para>3.否则找face.normal的最远点A</para> /// <para>4.移除使A看不到的原点的face,将(A, face.A)和(A, face.B)构建为新的face添加到list中,返回第一步</para> /// </summary> /// <returns></returns> private void PenetrationDetect(LPhysicsObject2D objA, LPhysicsObject2D objB) { EPAFace2D face = epa.FindClosestFace(); if (closestFace == null || Mathf.Abs(closestFace.sqrMagnitude - face.sqrMagnitude) > EPAFace2D.Threshold) { closestFace = face; safety.Add(closestFace); Vector2 a = objA.collider.GetFurtherPointInDirection(closestFace.direction); Vector2 b = objB.collider.GetFurtherPointInDirection(-closestFace.direction); SimplexPoint2D sp = new SimplexPoint2D(a, b); epa.ImportNewSupportPoint(sp); PenetrationDetect(objA, objB); } }
public void Add(EPAFace2D face) { faces.Add(face); }