Пример #1
0
    /// <summary>
    /// Calculate an array of points that describe the specified orbit
    /// </summary>
    /// <returns>The positions.</returns>
    /// <param name="numPoints">Number points.</param>
    public Vector3[] OrbitPositions(int numPoints, Vector3 centerPos, bool doSceneMapping)
    {
        GravityEngine ge = GravityEngine.Instance();

        Vector3[] points = new Vector3[numPoints];

        UpdateOrbitParams();
        CalculateRotation();

        float dtheta = 2f * Mathf.PI / numPoints;
        float theta  = 0;

        // add a fudge factor to ensure we go all the way around the circle
        for (int i = 0; i < numPoints; i++)
        {
            points[i] = PositionForTheta(theta, centerPos);
            if (NUtils.VectorNaN(points[i]))
            {
                Debug.LogError("Vector NaN + " + points[i]);
                points[i] = Vector3.zero;
            }
            else if (doSceneMapping && ge.mapToScene)
            {
                points[i] = ge.MapToScene(points[i]);
            }
            theta += dtheta;
        }
        // close the path (credit for fix to R. Vincent)
        points[numPoints - 1] = points[0];
        return(points);
    }
Пример #2
0
    /// <summary>
    /// Calculate an array of orbit positions. Used by the OrbitPredictor, OrbitRenderer and Editor
    /// Gimzo to illustrate the hyperbola.
    /// </summary>
    /// <returns>The positions.</returns>
    /// <param name="numPoints">Number points.</param>
    public Vector3[] OrbitPositions(int numPoints, Vector3 centerPos, bool doSceneMapping)
    {
        CalculateRotation();

        Vector3[] emptyArray = { new Vector3(0, 0, 0), new Vector3(0, 0, 0) };
        // need to have a center to create positions.
        if (centerObject == null)
        {
            centerObject = transform.parent.gameObject;
            if (centerObject == null)
            {
                return(emptyArray);
            }
        }
        Vector3[]     points = new Vector3[numPoints];
        float         theta  = -1f * branchDisplayFactor * Mathf.PI;
        float         dTheta = 2f * Mathf.Abs(theta) / (float)numPoints;
        GravityEngine ge     = GravityEngine.Instance();

        for (int i = 0; i < numPoints; i++)
        {
            points[i] = PositionForThetaLeftBranch(theta, centerPos);
            if (NUtils.VectorNaN(points[i]))
            {
                points[i] = Vector3.zero;
            }
            else if (doSceneMapping && ge.mapToScene)
            {
                points[i] = ge.MapToScene(points[i]);
            }
            theta += dTheta;
        }
        return(points);
    }
Пример #3
0
    /// <summary>
    /// Determine points from body through closest approach the same distance on the other side
    /// </summary>
    /// <param name="numPoints"></param>
    /// <param name="centerPos"></param>
    /// <param name="startPos"></param>
    /// <returns></returns>
    public Vector3[] OrbitSegmentSymmetricPositions(int numPoints, Vector3 centerPos,
                                                    Vector3 startPos)
    {
        GravityEngine ge = GravityEngine.Instance();

        CalculateRotation();

        // map points into xy plane
        Vector3 start_xy = Quaternion.Inverse(hyper_orientation) * (startPos - centerPos);

        // symmetric around origin
        float start_y = -start_xy.y;
        float end_y   = start_xy.y;

        if (start_y > end_y)
        {
            float temp = start_y;
            start_y = end_y;
            end_y   = temp;
        }

        float dy = Mathf.Abs(end_y - start_y) / (float)numPoints;
        float y  = start_y;
        int   i  = 0;

        Vector3[] points = new Vector3[numPoints];
        while (y < end_y)
        {
            points[i] = PositionForY(y, centerPos);
            if (NUtils.VectorNaN(points[i]))
            {
                Debug.LogError(string.Format("Vector NaN = {0} y={1} ecc={2} ", points[i], y, ecc));
                points[i] = Vector3.zero;
            }
            else if (ge.mapToScene)
            {
                points[i] = ge.MapToScene(points[i]);
            }
            y += dy;
            i++;
            if (i > numPoints - 1)
            {
                break;
            }
        }
        // fill to end with last point
        int last = i - 1;

        if (last < 0)
        {
            last = 0;
        }
        while (i < numPoints)
        {
            points[i++] = points[last];
        }
        return(points);
    }
Пример #4
0
 /// <summary>
 /// Update called from GE to set new position/velocity based on gravity evolution.
 /// The NBody referance frame moves so that the local axis points along the path.
 /// </summary>
 ///
 /// <param name="position">The position</param>
 /// <param name="velocity">The velocity</param>
 public void GEUpdate(Vector3 position, Vector3 velocity, GravityEngine ge)
 {
     transform.position = ge.MapToScene(position);
     vel_phys           = velocity;
     if (rotateFrame)
     {
         Quaternion q = new Quaternion();
         q.SetFromToRotation(lastVelocity, velocity);
         transform.rotation = transform.rotation * q;
     }
     lastVelocity = velocity;
 }
Пример #5
0
 private void UpdateLineRenderer()
 {
     if (points != null)
     {
         // TODO - performance. Specify a point limit and allocate once
         positions = new Vector3[points.Count];
         for (int i = 0; i < points.Count; i++)
         {
             positions[i] = ge.MapToScene(points[i].p);
         }
         lineRenderer.positionCount = points.Count;
         lineRenderer.SetPositions(positions);
     }
 }
        #pragma warning restore 414

    /// <summary>
    /// Updates the particles positions in world space.
    ///
    /// UpdateParticles is called from the GravityEngine. Do not call from other scripts.
    /// </summary>
    /// <param name="physicalScale">Physical scale.</param>
    public void UpdateParticles(float physicalScale, GravityEngine ge)
    {
        if (allInactive)
        {
            return;
        }
        for (int i = 0; i < lastParticleCount; i++)
        {
            particles[i].position = ge.MapToScene(new Vector3((float)r[i, 0] * physicalScale,
                                                              (float)r[i, 1] * physicalScale,
                                                              (float)r[i, 2] * physicalScale));
        }
        gravityParticles.SetParticles(particles, particleCount);
        // must be after display - so final inactivated particles are removed
        if (oneTimeBurst && burstDone && ((ejectCount + inactiveCount) >= particleCount))
        {
            allInactive = true;
                        #pragma warning disable 162             // disable unreachable code warning
            if (debugLogs)
            {
                Debug.Log("All particles inactive! time = " + Time.time + " ejected=" + ejectCount + " inactive=" + inactiveCount +
                          " remaining=" + (particleCount - inactiveCount - ejectCount));
            }
                        #pragma warning restore 162
        }
                #pragma warning disable 162, 429                // disable unreachable code warning
        if (debugLogs && debugCnt++ > 30)
        {
            debugCnt = 0;
            string log = "time = " + Time.time + " ejected=" + ejectCount + " inactive=" + inactiveCount +
                         " remaining=" + (particleCount - inactiveCount - ejectCount);
            log += " is Stopped " + gravityParticles.isStopped + " num=" + gravityParticles.particleCount + " pcount=" + particleCount + "\n";
            int logTo = (gravityParticles.main.maxParticles < 10) ? gravityParticles.main.maxParticles : 10;
            for (int i = 0; i < logTo; i++)
            {
                log += string.Format("{0}  rand={1} life={2} inactive={3} ", i, particles[i].randomSeed, particles[i].remainingLifetime, inactive[i]);
                log += " pos=" + particles[i].position;
                log += " phyPos= " + r[i, 0] + " " + r[i, 1] + " " + r[i, 2];
                log += "\n";
            }
            Debug.Log(log);
        }
                #pragma warning restore 162, 429
    }
Пример #7
0
 public void GEUpdate(GravityEngine ge)
 {
     // MapToScene may change things,so need to map every frame
     transform.position = ge.MapToScene(phyPosition);
 }
Пример #8
0
    /// <summary>
    /// Generate the points for an orbit segment given the start and end positions. If shortPath then
    /// the short path between the points will be shown, otherwise the long way around.
    ///
    /// The points are used to determine an angle from the main axis of the ellipse and although they
    /// should be on the ellipse for best results, the code will do it's best if they are not.
    /// </summary>
    /// <param name="numPoints"></param>
    /// <param name="centerPos"></param>
    /// <param name="startPos"></param>
    /// <param name="endPos"></param>
    /// <param name="shortPath"></param>
    /// <returns></returns>
    public Vector3[] OrbitSegmentPositions(int numPoints,
                                           Vector3 centerPos,
                                           Vector3 startPos,
                                           Vector3 endPos,
                                           bool shortPath)
    {
        GravityEngine ge = GravityEngine.Instance();

        Vector3[] points = new Vector3[numPoints];

        UpdateOrbitParams();
        CalculateRotation();

        float dtheta = 2f * Mathf.PI / numPoints;
        float theta  = 0;

        // find the vector to theta=0 on the ellipse, with no offset
        Vector3 ellipseAxis = PositionForTheta(0f, Vector3.zero);
        Vector3 normal      = ellipse_orientation * Vector3.forward;
        float   theta1      = NUtils.AngleFullCircleRadians(ellipseAxis, startPos - centerPos, normal);
        float   theta2      = NUtils.AngleFullCircleRadians(ellipseAxis, endPos - centerPos, normal);

        if (inclination > 90)
        {
            float temp = theta1;
            theta1 = theta2;
            theta2 = temp;
        }
        if (theta1 > theta2)
        {
            float temp = theta1;
            theta1 = theta2;
            theta2 = temp;
        }
        if (!shortPath)
        {
            float temp = theta1;
            theta1 = theta2;
            // ok to go beyond 2 Pi, since will increment to theta2
            theta2 = temp + 2f * Mathf.PI;
        }
        // Debug.LogFormat("theta1={0} theta2={1} start={2} end={3} axis={4}", theta1, theta2, startPos, endPos, ellipseAxis);

        int i = 0;

        for (theta = theta1; theta < theta2; theta += dtheta)
        {
            points[i] = PositionForTheta(theta, centerPos);
            if (NUtils.VectorNaN(points[i]))
            {
                Debug.LogError("Vector NaN + " + points[i]);
                points[i] = Vector3.zero;
            }
            else if (ge.mapToScene)
            {
                points[i] = ge.MapToScene(points[i]);
            }
            i++;
            if (i > numPoints - 1)
            {
                break;
            }
        }
        // fill to end with last point
        int last = i - 1;

        if (last < 0)
        {
            last = 0;
        }
        while (i < numPoints)
        {
            points[i++] = points[last];
        }

        return(points);
    }