예제 #1
0
 protected override bool CheckCollision(JCollider colliderA, JCollider colliderB, out JCollision collision)
 {
     collision = null;
     if (colliderA is T1 && colliderB is T2)
     {
         collision = new JCollision(colliderA, colliderB);
         return(CheckCollision(colliderA as T1, colliderB as T2, out collision));
     }
     else if (colliderB is T1 && colliderA is T2)
     {
         collision = new JCollision(colliderB, colliderA);
         return(CheckCollision(colliderB as T1, colliderA as T2, out collision));
     }
     return(false);
 }
예제 #2
0
 private void OnDrawGizmos()
 {
     Gizmos.color = Color.yellow;
     if (wasHit)
     {
         Gizmos.DrawSphere(testPoint, 0.1f);
     }
     Gizmos.color = Color.blue;
     for (int i = 0; i < _frameCollisions.Count; i++)
     {
         JCollision collision = _frameCollisions[i];
         for (int j = 0; j < collision.collisionPoints.Count; j++)
         {
             Gizmos.DrawSphere(collision.collisionPoints[j], 0.1f);
         }
     }
 }
예제 #3
0
    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return(false);
        }

        JCollision collision = (JCollision)obj;

        if (collision != null)
        {
            bool equal =
                (colliderA == collision.colliderA && colliderB == collision.colliderB) ||
                (colliderA == collision.colliderB && colliderB == collision.colliderA);
            return(equal);
        }
        return(false);
    }
예제 #4
0
    private void CorrectPositions(JCollision collision)
    {
        const float slop    = 0.01f;
        const float percent = 0.6f;

        JRigidbody bodyA = collision.colliderA.owningBody;
        JRigidbody bodyB = collision.colliderB.owningBody;

        Vector3 correction = (Mathf.Max(collision.collisionDepth - slop, 0.0f) / (bodyA.Mass + bodyB.Mass)) * percent * collision.collisionNormal;

        if (!bodyA._isKinematic)
        {
            bodyA.transform.position -= bodyA.Mass * correction;
        }
        if (!bodyB._isKinematic)
        {
            bodyB.transform.position += bodyB.Mass * correction;
        }
        //bodyA.ApplyForce(bodyA.Mass * correction * 200);
        //bodyB.ApplyForce(-bodyB.Mass * correction * 200);
    }
예제 #5
0
    protected override bool CheckCollision(JSphereCollider colliderA, JPlaneCollider colliderB, out JCollision collision)
    {
        Vector3 closestPointA = colliderB.GetClosestPoint(colliderA.transform.position);
        Vector3 closestPointB = colliderA.GetClosestPoint(closestPointA, true);

        Debug.DrawLine(closestPointA, closestPointB);

        if (colliderB.IsPointInside(closestPointB))
        {
            float          collisionDepth  = Vector3.Distance(closestPointA, closestPointB);
            Vector3        collisionNormal = (closestPointA - closestPointB).normalized;
            List <Vector3> contacts        = new List <Vector3>()
            {
                closestPointA + (closestPointB * 0.5f)
            };

            collision = new JCollision(contacts, collisionNormal, collisionDepth, colliderA, colliderB);
            return(true);
        }
        collision = null;
        return(false);
    }
예제 #6
0
    protected override bool CheckCollision(JCuboidCollider colliderA, JCuboidCollider colliderB, out JCollision collision)
    {
        collision = new JCollision();
        Vector3[] axesOfSeperation = GetAxesOfSeperation(colliderA, colliderB);
        Vector3   normal           = Vector3.zero;
        bool      shouldFlip       = false;

        collision.collisionDepth = float.PositiveInfinity;
        collision.colliderA      = colliderA;
        collision.colliderB      = colliderB;

        Vector3[] colliderAVerts = colliderA.GetVertices();
        Vector3[] colliderBVerts = colliderB.GetVertices();

        for (int i = 0; i < axesOfSeperation.Length; i++)
        {
            if (Vector3.SqrMagnitude(axesOfSeperation[i]) < 0.001f)// If out axis has a length of 0, some false positives can happen, soooooo lets just not do that
            {
                continue;
            }
            float depth = FindPenetrationDepth(colliderAVerts, colliderBVerts, axesOfSeperation[i], out shouldFlip);
            if (depth <= 0)
            {
                return(false);
            }
            else if (depth < collision.collisionDepth)
            {
                collision.collisionDepth = depth;
                normal = shouldFlip ? axesOfSeperation[i] * -1.0f :  axesOfSeperation[i];
            }
        }
        if (normal == Vector3.zero)
        {
            return(false);
        }
        Vector3 sharedPlaneAxis = normal.normalized;

        List <Vector3> contacts = new List <Vector3>();

        contacts.AddRange(CuboidIntersectionPoints(colliderB, colliderA));
        contacts.AddRange(CuboidIntersectionPoints(colliderA, colliderB));



        JSegment meshSegment  = JMeshCollider.GetMeshSegmentOnAxis(colliderAVerts, sharedPlaneAxis);
        float    distance     = (meshSegment.Length * 0.5f) - (collision.collisionDepth * 0.5f);
        Vector3  pointOnPlane = colliderA.transform.position + sharedPlaneAxis * distance;

        collision.collisionNormal = sharedPlaneAxis;

        collision.valid = contacts.Count > 0;

        for (int i = 0; i < contacts.Count; i++)
        {
            Vector3 contact = contacts[i];
            contact = contact + (sharedPlaneAxis * Vector3.Dot(sharedPlaneAxis, pointOnPlane - contact));

            bool unique = true;
            for (int j = 0; j < collision.collisionPoints.Count; j++)
            {
                if (Vector3.Distance(contact, collision.collisionPoints[j]) < 0.2f)
                {
                    unique = false;
                }
            }
            if (unique)
            {
                collision.collisionPoints.Add(contact);
            }
        }



        return(collision.valid);
    }
예제 #7
0
    private void SolveFrameCollisions()
    {
        for (int i = 0; i < _frameCollisions.Count; i++)
        {
            JCollision collision = _frameCollisions[i];
            JRigidbody bodyA     = collision.colliderA.owningBody;
            JRigidbody bodyB     = collision.colliderB.owningBody;
            if (bodyA == null || bodyB == null)
            {
                continue;
            }

            Vector3   normal     = collision.collisionNormal.normalized;
            Vector3   velocityA  = bodyA.Velocity;
            Vector3   velocityB  = bodyB.Velocity;
            Matrix4x4 invTensorA = bodyA._colliders[0].GetInverseTensor(bodyA.Mass);
            Matrix4x4 invTensorB = bodyB._colliders[0].GetInverseTensor(bodyB.Mass);

            Debug.DrawLine(bodyA.transform.position, collision.collisionPoints[0], Color.red);

            for (int c = 0; c < collision.collisionPoints.Count; c++)
            {
                Vector3 relativeContactPointA = collision.collisionPoints[c] - bodyA.transform.position;
                Vector3 relativeContactPointB = collision.collisionPoints[c] - bodyB.transform.position;

                Vector3 contactVelocity =
                    ((velocityB + Vector3.Cross(bodyB.AngularVelocity, relativeContactPointB)) -
                     (velocityA + Vector3.Cross(bodyA.AngularVelocity, relativeContactPointA)));
                float reactionForceMagnitude = Vector3.Dot(contactVelocity, normal);

                if (reactionForceMagnitude > 0)
                {
                    continue;
                }

                float numerator = (-(1.0f + epsilon) * reactionForceMagnitude);

                float   d1          = (bodyA.GetInvMass() + bodyB.GetInvMass());
                Vector3 d2          = Vector3.Cross(invTensorA * Vector3.Cross(relativeContactPointA, normal), relativeContactPointA);
                Vector3 d3          = Vector3.Cross(invTensorB * Vector3.Cross(relativeContactPointB, normal), relativeContactPointB);
                float   denominator = d1 + Vector3.Dot(normal, d2 + d3);

                float j = (denominator == 0) ? 0 : (numerator / denominator);
                j /= (float)collision.collisionPoints.Count;

                Vector3 impulseReactionForce = (j * normal);

                bodyA.SetVelocity(velocityA - impulseReactionForce * bodyA.GetInvMass());
                bodyB.SetVelocity(velocityB + impulseReactionForce * bodyB.GetInvMass());

                bodyA.AngularVelocity = bodyA.AngularVelocity - (Vector3)(invTensorA * Vector3.Cross(relativeContactPointA, impulseReactionForce));
                bodyB.AngularVelocity = bodyB.AngularVelocity + (Vector3)(invTensorB * Vector3.Cross(relativeContactPointB, impulseReactionForce));



                //Vector3 tangent = (contactVelocity - (Vector3.Dot(contactVelocity, normal) * normal)).normalized;
                //float staticFrictionAverage = PythSolver(bodyA.StaticFriction, bodyB.StaticFriction);
                //float dynamicFrictionAverage = PythSolver(bodyA.DynamicFriction, bodyB.DynamicFriction);

                //numerator = -Vector3.Dot(contactVelocity, tangent);

                //d1 = (bodyA.GetInvMass() + bodyB.GetInvMass());
                //d2 = Vector3.Cross(invTensorA * Vector3.Cross(relativeContactPointA, tangent), relativeContactPointA);
                //d3 = Vector3.Cross(invTensorB * Vector3.Cross(relativeContactPointB, tangent), relativeContactPointB);
                //denominator = d1 + Vector3.Dot(tangent, d2 + d3);

                //if (denominator == 0)
                //{
                //    continue;
                //}



                //float jt = (numerator / denominator) / (float)collision.collisionPoints.Count;

                //if (jt <= 0)
                //{
                //    continue;
                //}

                //Debug.Log("test");


                //if (jt > j * dynamicFrictionAverage)
                //{
                //    jt = j * dynamicFrictionAverage;
                //}
                //else if (jt < -j * dynamicFrictionAverage)
                //{
                //    jt = -j * dynamicFrictionAverage;
                //}

                //Vector3 tangentImpulse = tangent * jt;

                //bodyA.SetVelocity(bodyA.Velocity - (tangentImpulse * bodyA.GetInvMass()));
                //bodyB.SetVelocity(bodyB.Velocity + (tangentImpulse * bodyB.GetInvMass()));

                //bodyA.AngularVelocity = bodyA.AngularVelocity - (Vector3)(invTensorA * Vector3.Cross(relativeContactPointA, impulseReactionForce));
                //bodyB.AngularVelocity = bodyB.AngularVelocity + (Vector3)(invTensorB * Vector3.Cross(relativeContactPointB, impulseReactionForce));
            }

            if (Mathf.Abs(bodyA.Velocity.magnitude) < 0.1f)
            {
                bodyA.SetVelocity(Vector3.zero);
            }

            if (Mathf.Abs(bodyB.Velocity.magnitude) < 0.1f)
            {
                bodyB.SetVelocity(Vector3.zero);
            }

            if (Mathf.Abs(bodyA.AngularVelocity.magnitude) < 0.1f)
            {
                bodyA.AngularVelocity = (Vector3.zero);
            }

            if (Mathf.Abs(bodyB.AngularVelocity.magnitude) < 0.1f)
            {
                bodyB.AngularVelocity = (Vector3.zero);
            }
        }
    }
예제 #8
0
 protected abstract bool CheckCollision(T1 colliderA, T2 colliderB, out JCollision collision);