Esempio n. 1
0
    void Update()
    {
        for (int i = 0; i < bodies.Count - 1; i++)
        {
            for (int j = i + 1; j < bodies.Count; j++)
            {
                VirtualPhysicsTransform bodyA = bodies[i].PhysicsTransform, bodyB = bodies[j].PhysicsTransform;

                decimal squardDist = Vector3.DistanceSquared(bodyA.Position, bodyB.Position);

                decimal forceMagnitude = 0m;

                if (squardDist > 0.001m)
                {
                    forceMagnitude = (G * bodyA.Mass * bodyB.Mass) / squardDist;
                }

                Vector3 force = (bodyA.Position - bodyB.Position).Normalized * forceMagnitude;

                //Two birds with one stone
                bodyA.AddForce(-force);
                Debug.DrawRay(bodyA.Position, -force / bodyA.Mass, Color.green, Time.deltaTime, false);
                bodyB.AddForce(force);
                Debug.DrawRay(bodyB.Position, force / bodyB.Mass, Color.yellow, Time.deltaTime, false);
            }
        }
    }
Esempio n. 2
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="penData"></param>
    /// <returns>bool willPenetrate, float penetrationDepth</returns>
    protected virtual Tuple <bool, float> WillPen(TerminalBallisticsData penData)
    {
        ProjectileData          projData         = penData.projectile.projectileData;
        VirtualPhysicsTransform physicsTransform = penData.projectile.physicsTransform;

        //(assuming 0 degrees is hitting straight on)
        //If angleWeHitTarget >= 80 degrees, then richochet
        if (Vector3.Angle(physicsTransform.Velocity.normalized, -penData.hitInfo.normal) >= 80)
        {
            return(new Tuple <bool, float>(false, 0.0f));           //When Unity supports C#7, switch this to the new syntax
        }
        //Otherwise, do some more testing

        float targetDensity = 1000.0f;         //{TODO} Hook this up

        //tex:
        //$$stoppingDist=\sqrt[3]{\frac{projMass * initVel^2}{targetDensity*projCrossArea * projDragCoefficient}} $$
        //Heavily simplified model

        float stoppingDist =
            Mathf.Pow(                                                                                                                    //3rd root
                (projData.bulletMass * physicsTransform.VelocityMagnitude * physicsTransform.VelocityMagnitude)                           //{TODO} Make velocity relative to target
                /
                (targetDensity * projData.CrossSectionalArea * projData.GetDragCoefficient(physicsTransform.Velocity.magnitude / 343.0f)) //{TODO} Rewrite correctly!
                , (1.0f / 3.0f)
                );

        return(new Tuple <bool, float>(stoppingDist >= projData.noseLength, stoppingDist));
    }
Esempio n. 3
0
    public void Initialise(VirtualPhysicsTransform fromData)
    {
        pos     = fromData.pos;
        vel     = fromData.vel;
        prevPos = fromData.prevPos;
        prevVel = fromData.prevVel;

        rot        = fromData.rot;
        rotVel     = fromData.rotVel;
        prevRot    = fromData.prevRot;
        prevRotVel = fromData.prevRotVel;

        mass = fromData.mass;
    }
Esempio n. 4
0
    //{TODO} Damn this method is long...
    protected virtual void Penetrate(TerminalBallisticsData penData, float stoppingDist)
    {
        ProjectileData          projData         = penData.projectile.projectileData;
        VirtualPhysicsTransform physicsTransform = penData.projectile.physicsTransform;
        float targetDensity = 1000.0f;         //{TODO} Hook this up

        //343.0f - Temporary hardcoded value - 1 mach in air ~= 343 m/s

        ThicknessData objectThickness =
            ProjectileHelper.FindThickness(
                physicsTransform.PrevPosition,
                physicsTransform.Velocity.normalized,
                (rCH) => rCH.collider.gameObject == penData.hitInfo.collider.gameObject);         //Only colliders on this object


        Debug.Log($"Thickness: {objectThickness.thickness}m");

        //{TODO} Add some check to see if the object thickness was even found

        //If the projectile stops mid-object, de-activate it
        if (stoppingDist <= objectThickness.thickness)
        {
            penData.projectile.Active = false;
            Debug.Log($"Stopped after penetrating {stoppingDist}m");
            return;
        }

        //Otherwise, see how fast we come out the other side
        physicsTransform.Position = objectThickness.exitPosition;

        //tex:
        //$$ v=\sqrt{-\frac{ACpx^3}{m}+u^2}$$

        physicsTransform.VelocityMagnitude =
            Mathf.Sqrt(
                -
                (
                    (
                        projData.CrossSectionalArea *
                        projData.GetDragCoefficient(physicsTransform.Velocity.magnitude / 343.0f) *
                        targetDensity *
                        objectThickness.thickness * objectThickness.thickness * objectThickness.thickness
                    )
                    /
                    projData.bulletMass
                )
                + (physicsTransform.VelocityMagnitude * physicsTransform.VelocityMagnitude)
                );

        //Modify the exit direction depending on the projectile velocity
        //{TODO} Rewrite!
        float range = 0.25f;

        physicsTransform.VelocityDirection +=
            Vector3.Lerp(
                new Vector3(
                    CryptoRand.Range(-range, range),
                    CryptoRand.Range(-range, range),
                    CryptoRand.Range(-range, range)),
                Vector3.zero,
                Mathf.Clamp(1 / physicsTransform.VelocityMagnitude, 0, 1)
                );

        Debug.Log($"Stopping distance: {stoppingDist}");
        Debug.Log($"Fully penetrated with an exit velocity of {physicsTransform.Velocity.magnitude}m/s");
    }