Пример #1
0
    private static bool ApplyCollision(PhysicsPlane plane, PhysicsSphere sphere)
    {
        Vector3 planeOffset = plane.GetPositionOffset();
        Vector3 planePos = plane.physicsObject.state.position + planeOffset;
        Vector3 planeLastPos = plane.physicsObject.state.lastPosition + planeOffset;

        Vector3 sphereOffset = sphere.GetPositionOffset();
        Vector3 spherePos = sphere.physicsObject.state.position + sphereOffset;
        Vector3 sphereLastPos = sphere.physicsObject.state.lastPosition + sphereOffset;
        //Debug.LogError("Object Pos: " + sphere.physicsObject.state.position + " Offset Pos: " + spherePos);

        float distanceCur = plane.GetDistanceToPoint(spherePos);
        float distanceLast = plane.GetDistanceToPoint(sphereLastPos);

        //Check if there could be a collision - fast check
        if (distanceCur >= sphere.Radius && distanceLast >= sphere.Radius) {
            float dotCur = Vector3.Dot(plane.Normal, (planePos - spherePos).normalized);
            float dotLast = Vector3.Dot(plane.Normal, (planeLastPos - sphereLastPos).normalized);

            if ((dotCur > 0) == (dotLast > 0)) { return false; }
        }

        //Now check step by step
        int steps = 10;
        Vector3 planePath = planePos - planeLastPos;
        Vector3 spherePath = spherePos - sphereLastPos;
        for (int i = 0; i <= steps; i++) {
            Vector3 planeStepPos = planeLastPos + ((planePath / (float)steps) * i);
            Vector3 sphereStepPos = sphereLastPos + ((spherePath / (float)steps) * i);
            //Debug.Log("SpherePos: " + spherePos + "SpereLastPos: " + sphereLastPos);
            if (plane.GetDistanceToPoint(planeStepPos, sphereStepPos) <= (sphere.Radius + 0.01)) {
                Vector3 newVelocity = Vector3.Reflect(sphere.physicsObject.state.velocity, plane.Normal);
                newVelocity *= sphere.GetCombinedBounciness(plane);
                plane.physicsObject.state.position = planeLastPos - planeOffset;
                sphere.physicsObject.state.position = sphereLastPos - sphereOffset;
                sphere.physicsObject.state.velocity = newVelocity;
                //Debug.LogError("new Velo: " + newVelocity + " Plane: " + plane.name + " Sphere: " + sphere.name);
                return true;
            }
            planeLastPos = planeStepPos;
            sphereLastPos = sphereStepPos;
        }
        return false;
    }
Пример #2
0
    private static bool ApplyCollision(PhysicsSphere sphereA, PhysicsSphere sphereB)
    {
        Vector3 sphereAOffset = sphereA.GetPositionOffset();
        Vector3 sphereAPos = sphereA.physicsObject.state.position + sphereAOffset;
        Vector3 sphereALastPos = sphereA.physicsObject.state.lastPosition + sphereAOffset;

        Vector3 sphereBOffset = sphereB.GetPositionOffset();
        Vector3 sphereBPos = sphereB.physicsObject.state.position + sphereBOffset;
        Vector3 sphereBLastPos = sphereB.physicsObject.state.lastPosition + sphereBOffset;

        float distance = GeometryHelper.DistanceSegmentSegment(sphereAPos, sphereALastPos, sphereBPos, sphereBLastPos);
        if (distance >= sphereA.Radius + sphereB.Radius) { return false; }

        Vector3 spherePathA = sphereAPos - sphereALastPos;
        Vector3 spherePathB = sphereBPos - sphereBLastPos;

        int steps = 10;
        for (int i = 0; i <= steps; i++) {

            Vector3 spherePosA = sphereALastPos + ((spherePathA / (float)steps) * i);
            Vector3 spherePosB = sphereBLastPos + ((spherePathB / (float)steps) * i);

            if ((spherePosB - spherePosA).magnitude <= sphereA.Radius + sphereB.Radius) {

                float massA = 1, massB = 1;

                Vector3 collisionNormal = spherePosA - spherePosB;
                collisionNormal.Normalize();

                if (Vector3.Dot(collisionNormal, sphereA.physicsObject.state.velocity) < 0 || Vector3.Dot(collisionNormal, sphereB.physicsObject.state.velocity) > 0) {

                    float tempFactorA = Vector3.Dot(sphereA.physicsObject.state.velocity, collisionNormal);
                    float tempFactorB = Vector3.Dot(sphereB.physicsObject.state.velocity, collisionNormal);

                    Vector3 AxisVelocityA = tempFactorA * collisionNormal;
                    Vector3 AxisVelocityB = tempFactorB * collisionNormal;

                    sphereA.physicsObject.state.velocity -= AxisVelocityA;
                    sphereB.physicsObject.state.velocity -= AxisVelocityB;

                    float tempFactor3 = massA + massB;
                    float tempFactor4 = massA - massB;

                    float tempFactor5 = (2.0f * massB * tempFactorB + tempFactorA * tempFactor4) / tempFactor3;
                    float tempFactor6 = (2.0f * massA * tempFactorA - tempFactorB * tempFactor4) / tempFactor3;

                    AxisVelocityA = tempFactor5 * collisionNormal;
                    AxisVelocityB = tempFactor6 * collisionNormal;
                    AxisVelocityA *= sphereA.GetCombinedBounciness(sphereB);
                    AxisVelocityB *= sphereB.GetCombinedBounciness(sphereA);

                    sphereA.physicsObject.state.velocity += AxisVelocityA;
                    sphereB.physicsObject.state.velocity += AxisVelocityB;

                    sphereA.physicsObject.state.position = sphereALastPos - sphereAOffset;
                    sphereB.physicsObject.state.position = sphereBLastPos - sphereBOffset;
                    return true;
                }
            }

            sphereALastPos = spherePosA;
            sphereBLastPos = spherePosB;
        }
        return false;
    }