Example #1
0
    // Calculates and returns the gravitational force between two physics objects this tick
    public Vector3 CalculateGravitationalForce(PhysicsObjectPair pair)
    {
        //Obtain Direction Vector
        Vector3 pos1 = pair.O1.rb.position; //OPTIMISATION NOTE: These together cause 2x Rigidbody AND 2x Collider Syncs
        Vector3 pos2 = pair.O2.rb.position;
        Vector3 dir  = new Vector3(pos1.x - pos2.x, pos1.y - pos2.y, pos1.z - pos2.z);

        //Obtain Distance, return if 0
        float distSqr = dir.x * dir.x + dir.y * dir.y + dir.z * dir.z;

        if (distSqr == 0.0f)
        {
            return(Vector3.zero);
        }

        //Calculate Magnitude of force
        float forceMagnitude = G * (pair.O1.rb.mass * pair.O2.rb.mass) / distSqr;

        // Compare to current largest force for both objects
        ForceExerter current_max;

        // 1
        if (!strongest_force.TryGetValue(pair.O1.ID, out current_max) || forceMagnitude > current_max.magnitude)
        {
            strongest_force[pair.O1.ID] = new ForceExerter(pair.O2.ID, forceMagnitude);
        }
        // 2
        if (!strongest_force.TryGetValue(pair.O2.ID, out current_max) || forceMagnitude > current_max.magnitude)
        {
            strongest_force[pair.O2.ID] = new ForceExerter(pair.O1.ID, forceMagnitude);
        }

        //Calculate force
        float   dirMag = Mathf.Sqrt(distSqr);
        Vector3 force  = new Vector3(dir.x / dirMag, dir.y / dirMag, dir.z / dirMag) * forceMagnitude;

        return(force);
    }
Example #2
0
    // Adds the given physics object to the physics engine
    // Registers and stores all possible pairs ahead of simulation
    // This is called whenever a new physics object becomes enabled and active.
    public void AddObject(PhysicsObject physicsObject)
    {
        // If pairs list does not exist, create it
        if (ObjectPairs == null)
        {
            ObjectPairs = new List <PhysicsObjectPair>();
        }

        foreach (KeyValuePair <int, PhysicsObject> obj in PhysicsObject.physicsObjects)
        {
            //For every other object
            if (obj.Value != physicsObject)
            {
                // Creat new pair
                PhysicsObjectPair pair = new PhysicsObjectPair();
                pair.O1 = physicsObject;
                pair.O2 = obj.Value;
                //Check if list already contains pair
                bool alreadyInList = false;
                foreach (PhysicsObjectPair objectPair in ObjectPairs.ToList())
                {
                    //If pair already exists
                    if ((objectPair.O1 == pair.O1 && objectPair.O2 == pair.O2) ||
                        (objectPair.O2 == pair.O1 && objectPair.O1 == pair.O2))
                    {
                        alreadyInList = true;
                    }
                }
                //If pair not in list, add pair
                if (!alreadyInList)
                {
                    ObjectPairs.Add(pair);
                }
            }
        }
    }
Example #3
0
    Vector3[] PredictOrbit(PhysicsObject _strongestObject, uint steps)
    {
        try
        {
            Vector3[] positions = new Vector3[steps];

            PhysicsObjectPair pair = new PhysicsObjectPair();
            pair.O1 = this;
            pair.O2 = _strongestObject;


            // Calculate Orbital Period for this
            //float period = (2.0f * Mathf.PI) * Mathf.Sqrt( Mathf.Pow(Vector3.Distance(pair.O1.transform.position, pair.O2.transform.position),3.0f) / G * ( pair.O1.rb.mass + pair.O2.rb.mass)  );



            Vector3 position1 = this.transform.position;
            Vector3 position2 = _strongestObject.transform.position;

            Vector3 velocity1 = this.rb.velocity - _strongestObject.rb.velocity;
            //Vector3 velocity2 = _strongestObject.rb.velocity;
            //Vector3 velocity2 = -velocity1;
            Vector3 velocity2 = Vector3.zero;
            //Vector3 velocity2 = _strongestObject.rb.velocity - this.rb.velocity;


            float mass1 = this.rb.mass;
            float mass2 = _strongestObject.rb.mass;

            // Note, this is flawed as it assumes circular orbit
            float period = (Mathf.PI * 2.0f) * Vector3.Distance(pair.O1.transform.position, pair.O2.transform.position) /
                           velocity1.magnitude;

            float timestep = period / steps;

            for (int i = 0; i < steps; i++)
            {
                positions[i] = position1;

                // Calculate force
                Vector3 force = new Vector3();
                //Obtain Direction Vector
                Vector3 dir = position1 - position2;
                //Obtain Distance, return if 0
                float dist = dir.magnitude;
                if (dist == 0)
                {
                    force = Vector3.zero;
                }
                //Calculate Magnitude of force
                float magnitude = PhysicsEngine.G * (mass1 * mass2) / Mathf.Pow(dist, 2);
                force = dir.normalized * magnitude;

                // Calculate accelerations
                Vector3 a1 = -force / mass1;
                Vector3 a2 = force / mass2;

                // Update positions
                position1 += velocity1 * timestep + 0.5f * a1 * timestep * timestep;
                position2 += velocity2 * timestep + 0.5f * a2 * timestep * timestep;

                // Update velocities
                velocity1 += a1 * timestep;
                velocity2 += a2 * timestep;
            }

            return(positions);
        }
        catch
        {
            lineRenderer.positionCount = 0;
            return(default);