예제 #1
0
        public override void Update(double dt)
        {
            base.Update(dt);

            foreach (GridFin gridFin in _gridFins)
            {
                gridFin.Update(dt);
            }

            foreach (LandingLeg landingLeg in _landingLegs)
            {
                landingLeg.Update(dt);
            }

            DVector2 velocity = GetRelativeVelocity();
            double   altitude = GetRelativeAltitude();

            DVector2 normalizedVelocity = velocity.Clone();

            normalizedVelocity.Normalize();

            DVector2 rotation = new DVector2(Math.Cos(Pitch), Math.Sin(Pitch));

            // If we are going retro-grade and firing rockets adds soot
            if (altitude < 70000 && normalizedVelocity.Dot(rotation) < 0 && velocity.Length() > 400)
            {
                foreach (IEngine engine in Engines)
                {
                    if (engine.IsActive && engine.Throttle > 0)
                    {
                        _sootRatio = Math.Min(_sootRatio + 0.015 * dt, 1.0);
                    }
                }
            }
        }
예제 #2
0
    /// <summary>
    /// Find the closet point along this line from a_point
    /// </summary>
    /// <param name="a_point"></param>
    /// <returns></returns>
    public DVector2 ClosestPoint(DVector2 a_point)
    {
        DVector2 delta         = v1 - v0;
        double   lengthSquared = delta.SqrMagnitude();

        if (lengthSquared.Equals(0f))
        {
            return(v0);
        }
        double projection = DVector2.Dot(a_point - v0, delta);
        double scale      = projection / lengthSquared;

        return(v0 + delta * scale);
    }
예제 #3
0
파일: Utility.cs 프로젝트: rbarraud/Blarg2
    public static DVector2 PredictShot(DVector2 origin, DReal projectileSpeed, DVector2 targetPosition, DVector2 targetVelocity)
    {
        var dp = targetPosition - origin;

        // Try to lead the target.
        var a = DVector2.Dot(targetVelocity, targetVelocity) - projectileSpeed * projectileSpeed;
        var b = 2 * DVector2.Dot(targetVelocity, dp);
        var c = DVector2.Dot(dp, dp);

        var p = -b / (2 * a);

        var discriminant = b * b - 4 * a * c;

        if (discriminant <= 0)
        {
            return(targetPosition);
        }

        DReal q;

        try {
            q = DReal.Sqrt(discriminant) / (2 * a);
        } catch (System.ArithmeticException) {
            return(targetPosition);
        }

        var   t1 = p - q;
        var   t2 = p + q;
        DReal t;

        if (t1 > t2 && t2 > 0)
        {
            t = t2;
        }
        else if (t1 > 0)
        {
            t = t1;
        }
        else
        {
            return(targetPosition);
        }

        return(targetPosition + targetVelocity * t);
    }
예제 #4
0
        // Gets bodies sorted by distance that point the direction of the camera normal
        private static List <Tuple <double, int> > GetSortedBodyDistances(int currentIndex, IList <IGravitationalBody> bodies, DVector2 cameraNormal)
        {
            DVector2 targetCenter = bodies[currentIndex].Position;

            var bodiesByDistance = new List <Tuple <double, int> >();

            for (int i = 0; i < bodies.Count; i++)
            {
                if (i == currentIndex)
                {
                    continue;
                }

                var spaceCraft = bodies[i] as ISpaceCraft;

                // Skip terminated bodies
                if (spaceCraft != null && spaceCraft.Terminated)
                {
                    continue;
                }

                DVector2 difference = bodies[i].Position - targetCenter;

                double distance = difference.LengthSquared();

                difference.Normalize();

                // Only add bodies in the same direction as the camera normal
                if (difference.Dot(cameraNormal) > 0)
                {
                    bodiesByDistance.Add(new Tuple <double, int>(distance, i));
                }
            }

            bodiesByDistance.Sort(Compare);

            return(bodiesByDistance);
        }
예제 #5
0
        public static bool IntersectLineCircle(DVector2 circleOrigin, DReal radius, DVector2 lineStart, DVector2 lineEnd, out DVector2 outIp)
        {
            var d = lineEnd - lineStart;      // ray direction.
            var f = lineStart - circleOrigin; // Vector from circle centre to ray start.

            var a = DVector2.Dot(d, d);
            var b = 2 * DVector2.Dot(f, d);
            var c = DVector2.Dot(f, f) - radius * radius;

            if (a == 0)
            {
                // start & end are close enough that distance = 0. Degrade to point/circle test.
                outIp = lineStart;
                return((lineStart - circleOrigin).sqrMagnitude < radius * radius);
            }

            var discriminant = b * b - 4 * a * c;

            if (discriminant < 0)
            {
                outIp = new DVector2();
                return(false);
            }

            // ray didn't totally miss sphere,
            // so there is a solution to
            // the equation.
            discriminant = DReal.Sqrt(discriminant);

            // either solution may be on or off the ray so need to test both
            // t1 is always the smaller value, because BOTH discriminant and
            // a are nonnegative.
            var t1 = (-b - discriminant) / (2 * a);
            var t2 = (-b + discriminant) / (2 * a);

            // 3x HIT cases:
            //          -o->             --|-->  |            |  --|->
            // Impale(t1 hit,t2 hit), Poke(t1 hit,t2>1), ExitWound(t1<0, t2 hit),

            // 3x MISS cases:
            //       ->  o                     o ->              | -> |
            // FallShort (t1>1,t2>1), Past (t1<0,t2<0), CompletelyInside(t1<0, t2>1)
            if (t1 >= 0 && t1 <= 1)
            {
                // t1 is the intersection, and it's closer than t2
                // (since t1 uses -b - discriminant)
                // Impale, Poke
                outIp = circleOrigin + d.normalized * -radius;
                return(true);
            }

            // here t1 didn't intersect so we are either started
            // inside the sphere or completely past it
            if (t2 >= 0 && t2 <= 1)
            {
                // ExitWound
                outIp = circleOrigin + d.normalized * radius;
                return(true);
            }

            // actually completely inside counts as a hit too.
            var startSqrDist = (lineStart - circleOrigin).sqrMagnitude;
            var endSqrDist   = (lineEnd - circleOrigin).sqrMagnitude;
            var sqrRadius    = radius * radius;

            if (startSqrDist < sqrRadius && endSqrDist < sqrRadius)
            {
                outIp = lineStart;
                return(true);
            }

            // no intn: FallShort, Past, CompletelyInside
            outIp = new DVector2();
            return(false);
        }
예제 #6
0
파일: MathOps.cs 프로젝트: vimaec/ara3d-dev
 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double LengthSquared(this DVector2 v) => v.Dot(v);