Beispiel #1
0
    bool IsSphereStatic(PhysicsSphere sphere)
    {
        bool lowVelocity      = sphere.Velocity.magnitude < 0.2f;
        bool touchingThePlane = (CorrectedPosition(sphere) - sphere.transform.position).magnitude < 0.02f;

        return(lowVelocity && touchingThePlane);
    }
Beispiel #2
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="sphere"></param>
    /// <param name="energyDissipation" the impact of the energy dissipation on the reflected velocity></param>
    protected override void Choc(PhysicsSphere sphere, float energyDissipation = 0f)
    {
        //Debug.Log("choc: " + name);
        if (IsColliding(sphere) == false)
        {
            return;
        }

        //Debug.Log("Sphere plane collision on: " + name);
        //Debug.Log("Velocity Error: isVerlet: " + sphere.isVerlet + " " + sphere.ErrorVelocityOnTheGround());

        //sphere.Velocity = Vector3.Reflect(sphere.Velocity, Normal);

        if (IsSphereStaticOnPlane(sphere))
        {
            sphere.transform.position = CorrectedPosition(sphere);
            sphere.ApplyForce(-sphere.mass * Physics.gravity);
        }
        else // sphere is dynamic
        {
            sphere.transform.position = CorrectedPosition(sphere);
            InverseRelativeVelocity(sphere, Reflect(RelativeVelocity(sphere), energyDissipation));
            //sphere.Velocity = Reflect(RelativeVelocity(sphere), energyDissipation);
        }
    }
Beispiel #3
0
    protected override void Choc(PhysicsSphere sphere, float energyDissipation = 0f)
    {
        //Debug.Log("choc: " + name);
        if (IsColliding(sphere) == false)
        {
            return;
        }

        if (spaced) // Yeet the ball
        {
            sphere.transform.position = CorrectedPosition(sphere);

            sphere.Velocity = Normal * ballPushForce;
            return;
        }


        if (IsSphereStaticOnBox(sphere))
        {
            sphere.transform.position = CorrectedPosition(sphere);
            sphere.ApplyForce(-sphere.mass * Physics.gravity);
        }
        else
        {
            sphere.transform.position = CorrectedPosition(sphere);
            InverseRelativeVelocity(sphere, Reflect(RelativeVelocity(sphere)));
        }
    }
Beispiel #4
0
 public bool isColliding(PhysicsSphere sphere)
 {
     if (WillBeCollision(sphere) == false)
     {
         return(false);
     }
     return(Distance(sphere) >= 0 || Mathf.Abs(Distance(sphere)) <= sphere.Radius);
 }
Beispiel #5
0
    bool TouchingThePlane(PhysicsSphere sphere)
    {
        // sphere speed
        // deltaTime
        float deltaMove = Mathf.Max(deltaMoveCoef * sphere.Radius, RelativeVelocity(sphere).magnitude *Time.deltaTime);

        return((CorrectedPosition(sphere) - sphere.transform.position).magnitude <= correctedPostionCoef * deltaMove);
    }
        private void CounterSlopes(Vector3 groundNormal)
        {
            Vector3 carForward             = transform.right;
            Vector3 gravity                = Physics.gravity;
            Vector3 directionOfFlat        = Vector3.Cross(-gravity, groundNormal).normalized;     //the direction that if you head in you wouldnt change altitude
            Vector3 directionOfSlope       = Vector3.Cross(directionOfFlat, groundNormal);         //the direction down the slope
            float   affectOfGravity        = Vector3.Dot(gravity, directionOfSlope);               // returns 1 on a cliff face, 0 on a plane
            float   affectOfWheelAlignment = Mathf.Abs(Vector3.Dot(carForward, directionOfSlope)); // returns 1 if facing down or up the slope, 0 if 90 degrees to slope

            PhysicsSphere.AddForce(-directionOfSlope * affectOfWheelAlignment * affectOfGravity, ForceMode.Acceleration);
        }
Beispiel #7
0
        // тут просто захардкожено добавление физических моделей к определённым ячейкам
        public void AddPhysicsModel(IRenderPrimitive initPrimitive)
        {
            var cellWithPhysics = new MapObject
            {
                Position = initPrimitive.Position,
                Size     = initPrimitive.Size
            };

            var PhysicModel = new PhysicsSphere
            {
                IsSatatic = true,
                Radius    = cellWithPhysics.Size.Length() / 2.0f,
                MapObject = cellWithPhysics
            };

            World.PhysicsManager.Models.Add(PhysicModel);
        }
    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;
    }
Beispiel #9
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="sphere"></param>
    /// <param name="energyDissipation" the impact of the energy dissapation on the reflected velocity></param>
    public void Chock(PhysicsSphere sphere, float energyDissipation = 0)
    {
        if (isColliding(sphere) == false)
        {
            return;
        }

        //Debug.Log("Velocity Error: isVerlet " + sphere.isVerlet + " " + sphere.ErrorVelocityOnGround());

        if (IsSphereStatic(sphere))
        {
            sphere.transform.position = CorrectedPosition(sphere);
            sphere.ApplyForce(-sphere.Mass * Physics.gravity);
        }
        else //sphere is dynamic
        {
            sphere.Velocity = Reflect(sphere.Velocity, energyDissipation);
        }
    }
Beispiel #10
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="sphere"></param>
    /// <param name="energyDissipation" the impact of the energy dissipation on the reflected velocity></param>
    protected override void Choc(PhysicsSphere sphere, float energyDissipation = 0f)
    {
        if (IsColliding(sphere) == false)
        {
            return;
        }

        InverseRelativeVelocity(sphere, Reflect(RelativeVelocity(sphere), energyDissipation));
        //if (IsSphereStaticOnPlane(sphere))
        //{
        //    //sphere.transform.position = CorrectedPosition(sphere);
        //    sphere.ApplyForce(-sphere.mass * Physics.gravity);
        //}
        //else // sphere is dynamic
        //{
        //    //sphere.transform.position = CorrectedPosition(sphere);

        //}
    }
        private void FixedUpdate()
        {
            RaycastHit hitOn;
            RaycastHit hitNear;

            OnGround   = Physics.Raycast(transform.position, Vector3.down, out hitOn, rayMaxDistance);
            NearGround = Physics.Raycast(transform.position, Vector3.down, out hitNear, rayMaxDistance + 0.8f);

            VehicleModel.up = Vector3.Lerp(VehicleModel.up, hitNear.normal, Time.deltaTime * 8.0f);
            VehicleModel.Rotate(0, transform.eulerAngles.y, 0);

            if (NearGround)
            {
                PhysicsSphere.AddForce(transform.forward * speedTarget, ForceMode.Acceleration);
                PhysicsSphere.AddForce(transform.right * strafeTarget, ForceMode.Acceleration);
            }
            else
            {
                PhysicsSphere.AddForce(transform.forward * (speedTarget / 10), ForceMode.Acceleration);
                PhysicsSphere.AddForce(Vector3.down * Gravity, ForceMode.Acceleration);
            }

            Vector3 localVelocity = transform.InverseTransformVector(physicsSphere.velocity);

            localVelocity.x *= 0.9f + (Drift / 10);

            if (NearGround)
            {
                PhysicsSphere.velocity = transform.TransformVector(localVelocity);
            }

            if (StopSlopeSlide)
            {
                CounterSlopes(hitNear.normal);
            }
        }
Beispiel #12
0
    public float Distance(PhysicsSphere sphere)
    {
        Vector3 sphereToPlane = Position - sphere.transform.position;

        return(Vector3.Dot(sphereToPlane, Normal));
    }
Beispiel #13
0
 public Vector3 CorrectedPosition(PhysicsSphere sphere)
 {
     return(Projection(sphere) + Normal * sphere.Radius);
 }
Beispiel #14
0
 private bool WillBeCollision(PhysicsSphere sphere)
 {
     return(Vector3.Dot(sphere.Velocity, Normal) < 0);
 }
Beispiel #15
0
    public Vector3 Projection(PhysicsSphere sphere)
    {
        Vector3 sphereToProjection = Distance(sphere) * Normal;

        return(sphere.transform.position + sphereToProjection);
    }
Beispiel #16
0
    bool IsSphereStaticOnBox(PhysicsSphere sphere)
    {
        bool lowVelocity = RelativeVelocity(sphere).magnitude < staticVelocityLimit;

        return(lowVelocity && TouchingThePlane(sphere));
    }
    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;
    }