示例#1
0
 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);
                 }
             }
         }
     }
 }
示例#2
0
    /// <summary>
    /// <para>GJK判断是否碰撞</para>
    /// <para>1.找direction方向的最远点</para>
    /// <para>2.判断最远点是否与原点在同一方向(是否比原点还远),如果不是则未碰撞</para>
    /// <para>3.将最远点置入simplex,判断simplex是否包围了原点,如果是则碰撞,否则以离原点最近的simplex上的点到原点作为direction回到步骤1</para>
    /// </summary>
    /// <param name="objA"></param>
    /// <param name="objB"></param>
    private LContactConstraint2D CollisionDetect(LPhysicsObject2D objA, LPhysicsObject2D objB)
    {
        Vector2        a  = objA.collider.GetFurtherPointInDirection(direction);
        Vector2        b  = objB.collider.GetFurtherPointInDirection(-direction);
        SimplexPoint2D sp = new SimplexPoint2D(a, b);

        if (simplex.IsSameDirectionWithOrigin(sp, direction))
        {
            simplex.Add(sp);
            if (simplex.DoSimplex2D())
            {
                epa.Add(new EPAFace2D(simplex[0], simplex[1]));
                epa.Add(new EPAFace2D(simplex[1], simplex[2]));
                epa.Add(new EPAFace2D(simplex[2], simplex[0]));
                PenetrationDetect(objA, objB);
                return(ContactConstraintGenerate(objA, objB));
            }
            else
            {
                direction = simplex.FindClosestPointToOriginDirection();
                return(CollisionDetect(objA, objB));
            }
        }
        else
        {
            return(null);
        }
    }
示例#3
0
    /// <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);
        }
    }
示例#4
0
    private LContactConstraint2D ContactConstraintGenerate(LPhysicsObject2D objA, LPhysicsObject2D objB)
    {
        LContactConstraint2D constraint = null;
        Vector2 contactPointsA          = LGeometryUtil2D.CalcBarycentric(closestFace.sp1.a, closestFace.sp2.a);
        Vector2 contactPointsB          = LGeometryUtil2D.CalcBarycentric(closestFace.sp1.b, closestFace.sp2.b);

        if (closestFace.sqrMagnitude > LPhysicsStatic2D.DistanceSqrtThreshold)
        {
            float   penetration = Mathf.Sqrt(closestFace.sqrMagnitude);
            Vector2 normal      = closestFace.direction / penetration;
            if (objA.rigidBody != null ||
                objB.rigidBody != null)
            {
                constraint             = new LContactConstraint2D(objA, objB);
                constraint.anchorA     = contactPointsA;
                constraint.anchorB     = contactPointsB;
                constraint.normal      = normal;
                constraint.penetration = penetration;
            }
        }
        return(constraint);
    }
示例#5
0
    public void Update(Transform trans)
    {
        int instanceID = trans.GetInstanceID();
        int index      = physicsIndexes.IndexOf(instanceID);
        LPhysicsObject2D physicsObj = null;

        if (index == -1)
        {
            physicsObj = new LPhysicsObject2D(trans);
            physicsIndexes.Add(instanceID);
            physicsObjs.Add(physicsObj);
        }
        else
        {
            physicsObj = physicsObjs[index];
        }
        physicsObj.Refresh();
        if (physicsObj.collider == null &&
            physicsObj.rigidBody == null)
        {
            physicsObjs.Remove(physicsObj);
        }
    }
示例#6
0
 public LContactConstraint2D(LPhysicsObject2D objA, LPhysicsObject2D objB)
     : base(objA, objB)
 {
 }
示例#7
0
 public LConstraint2D(LPhysicsObject2D objA, LPhysicsObject2D objB)
 {
     mObjA = objA;
     mObjB = objB;
 }
示例#8
0
 public LGeneralConstraint2D(LPhysicsObject2D objA, LPhysicsObject2D objB)
     : base(objA, objB)
 {
 }