public static void drawLandingArea(CelestialBody body, double minLatitude, double maxLatitude,
                                           double minLongitude, double maxLongitude,
                                           Color c, double rotation = 0)
        {
            double dlat = (maxLatitude - minLatitude) / 10.0;
            double dlog = (maxLongitude - minLongitude) / 10.0;

            List <Vector3d[]> quads = new List <Vector3d[]> ();

            for (double lat = minLatitude; lat + dlat < maxLatitude; lat += dlat)
            {
                for (double log = minLongitude; log + dlog < maxLongitude; log += dlog)
                {
                    Vector3d up1     = body.GetSurfaceNVector(lat, log);
                    Vector3d center1 = body.position + body.Radius * up1;

                    Vector3d up2     = body.GetSurfaceNVector(lat, log + dlog);
                    Vector3d center2 = body.position + body.Radius * up2;

                    Vector3d up3     = body.GetSurfaceNVector(lat + dlat, log + dlog);
                    Vector3d center3 = body.position + body.Radius * up3;

                    Vector3d up4     = body.GetSurfaceNVector(lat + dlat, log);
                    Vector3d center4 = body.position + body.Radius * up4;

                    if (!IsOccluded(center1, body))
                    {
                        quads.Add(new Vector3d[] { center1, center2, center3, center4 });
                    }
                }
            }

            GLQuadMap(quads, c);
        }
        public static void drawLandingArea(CelestialBody body, double minLatitude, double maxLatitude, 
                                            double minLongitude, double maxLongitude, 
                                            Color c, double rotation = 0)
        {
            double dlat = (maxLatitude - minLatitude) / 10.0;
            double dlog = (maxLongitude - minLongitude) / 10.0;

            List<Vector3d[]> quads = new List<Vector3d[]> ();

            for (double lat = minLatitude; lat + dlat < maxLatitude; lat += dlat) {
                for (double log = minLongitude; log + dlog < maxLongitude; log += dlog) {
                    Vector3d up1 = body.GetSurfaceNVector (lat, log);
                    Vector3d center1 = body.position + body.Radius * up1;

                    Vector3d up2 = body.GetSurfaceNVector (lat, log + dlog);
                    Vector3d center2 = body.position + body.Radius * up2;

                    Vector3d up3 = body.GetSurfaceNVector (lat + dlat, log + dlog);
                    Vector3d center3 = body.position + body.Radius * up3;

                    Vector3d up4 = body.GetSurfaceNVector (lat + dlat, log);
                    Vector3d center4 = body.position + body.Radius * up4;

                    if (!IsOccluded (center1, body)) {
                        quads.Add (new Vector3d[] { center1, center2, center3, center4});
                    }
                }
            }

            GLQuadMap (quads, c);
        }
Example #3
0
        public static ReferenceFrame CreateAtCurrentTime(CelestialBody referenceBody)
        {
            ReferenceFrame ret = new ReferenceFrame();

            ret.lat0lon0AtStart  = referenceBody.GetSurfaceNVector(0, 0);
            ret.lat0lon90AtStart = referenceBody.GetSurfaceNVector(0, 90);
            ret.lat90AtStart     = referenceBody.GetSurfaceNVector(90, 0);
            ret.epoch            = Planetarium.GetUniversalTime();
            ret.referenceBody    = referenceBody;
            return(ret);
        }
        //Computes the time until the phase angle between the launchpad and the target equals the given angle.
        //The convention used is that phase angle is the angle measured starting at the target and going east until
        //you get to the launchpad.
        //The time returned will not be exactly accurate unless the target is in an exactly circular orbit. However,
        //the time returned will go to exactly zero when the desired phase angle is reached.
        public static double TimeToPhaseAngle(double phaseAngle, CelestialBody launchBody, double launchLongitude, Orbit target)
        {
            double launchpadAngularRate = 360 / launchBody.rotationPeriod;
            double targetAngularRate = 360.0 / target.period;
            if (Vector3d.Dot(target.SwappedOrbitNormal(), launchBody.angularVelocity) < 0) targetAngularRate *= -1; //retrograde target

            Vector3d currentLaunchpadDirection = launchBody.GetSurfaceNVector(0, launchLongitude);
            Vector3d currentTargetDirection = target.SwappedRelativePositionAtUT(Planetarium.GetUniversalTime());
            currentTargetDirection = Vector3d.Exclude(launchBody.angularVelocity, currentTargetDirection);

            double currentPhaseAngle = Math.Abs(Vector3d.Angle(currentLaunchpadDirection, currentTargetDirection));
            if (Vector3d.Dot(Vector3d.Cross(currentTargetDirection, currentLaunchpadDirection), launchBody.angularVelocity) < 0)
            {
                currentPhaseAngle = 360 - currentPhaseAngle;
            }

            double phaseAngleRate = launchpadAngularRate - targetAngularRate;

            double phaseAngleDifference = MuUtils.ClampDegrees360(phaseAngle - currentPhaseAngle);

            if (phaseAngleRate < 0)
            {
                phaseAngleRate *= -1;
                phaseAngleDifference = 360 - phaseAngleDifference;
            }

            return phaseAngleDifference / phaseAngleRate;
        }
Example #5
0
        //Computes the time until the phase angle between the launchpad and the target equals the given angle.
        //The convention used is that phase angle is the angle measured starting at the target and going east until
        //you get to the launchpad.
        //The time returned will not be exactly accurate unless the target is in an exactly circular orbit. However,
        //the time returned will go to exactly zero when the desired phase angle is reached.
        public static double TimeToPhaseAngle(double phaseAngle, CelestialBody launchBody, double launchLongitude, Orbit target)
        {
            double launchpadAngularRate = 360 / launchBody.rotationPeriod;
            double targetAngularRate    = 360.0 / target.period;

            if (Vector3d.Dot(target.SwappedOrbitNormal(), launchBody.angularVelocity) < 0)
            {
                targetAngularRate *= -1;                                                                            //retrograde target
            }
            Vector3d currentLaunchpadDirection = launchBody.GetSurfaceNVector(0, launchLongitude);
            Vector3d currentTargetDirection    = target.SwappedRelativePositionAtUT(Planetarium.GetUniversalTime());

            currentTargetDirection = Vector3d.Exclude(launchBody.angularVelocity, currentTargetDirection);

            double currentPhaseAngle = Math.Abs(Vector3d.Angle(currentLaunchpadDirection, currentTargetDirection));

            if (Vector3d.Dot(Vector3d.Cross(currentTargetDirection, currentLaunchpadDirection), launchBody.angularVelocity) < 0)
            {
                currentPhaseAngle = 360 - currentPhaseAngle;
            }

            double phaseAngleRate = launchpadAngularRate - targetAngularRate;

            double phaseAngleDifference = MuUtils.ClampDegrees360(phaseAngle - currentPhaseAngle);

            if (phaseAngleRate < 0)
            {
                phaseAngleRate      *= -1;
                phaseAngleDifference = 360 - phaseAngleDifference;
            }


            return(phaseAngleDifference / phaseAngleRate);
        }
Example #6
0
        //Interprets a given AbsoluteVector as a velocity, and returns the corresponding Vector3d velocity
        //in world coordinates.
        public Vector3d WorldVelocityAtCurrentTime(AbsoluteVector absolute)
        {
            double now = Planetarium.GetUniversalTime();
            double unrotatedLongitude = MuUtils.ClampDegrees360(absolute.longitude - 360 * (now - absolute.UT) / referenceBody.rotationPeriod);

            return(absolute.radius * referenceBody.GetSurfaceNVector(absolute.latitude, unrotatedLongitude));
        }
Example #7
0
        public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0)
        {
            Vector3d up = body.GetSurfaceNVector(latitude, longitude);
            Vector3d center = body.position + body.Radius * up;

            if (IsOccluded(center, body)) return;

            Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

            double radius = body.Radius / 15;

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
            }, c);
        }
Example #8
0
            public Vector3d Up()
            {
                double lat = body.GetLatitude(center);
                double lon = body.GetLongitude(center);

                return(body.GetSurfaceNVector(lat, lon));
            }
Example #9
0
        private int GetHeading()
        {
            body     = staticInstance.CelestialBody;
            upVector = body.GetSurfaceNVector(staticInstance.RefLatitude, staticInstance.RefLongitude).normalized;
            north    = Vector3.ProjectOnPlane(body.transform.up, upVector).normalized;
            east     = Vector3.Cross(upVector, north).normalized;
            forward  = Vector3.ProjectOnPlane(gameObject.transform.forward, upVector);

            float heading = Vector3.Angle(forward, north);

            if (Vector3.Dot(forward, east) < 0)
            {
                heading = 360 - heading;
            }

            heading = (heading + headingAdj + 360) % 360;

            if (heading % 10 > 5)
            {
                heading += 10 - heading % 10;
            }
            if (heading < 6)
            {
                heading = 360; // There are no 00 runways, they all are 36!
            }

            return((int)heading);
        }
Example #10
0
        public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0, double radius = 0)
        {
            Vector3d up = body.GetSurfaceNVector(latitude, longitude);
            var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right);
            if (height < body.Radius) { height = body.Radius; }
            Vector3d center = body.position + height * up;

            if (IsOccluded(center, body)) return;

            Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

            if (radius <= 0) { radius = body.Radius / 15; }

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
            }, c);
        }
Example #11
0
 public static Vector3 GetNorthVector(Vector3 position, CelestialBody body)
 {
     Vector3 geoPosA = VectorUtils.WorldPositionToGeoCoords(position, body);
     Vector3 geoPosB = new Vector3(geoPosA.x+1, geoPosA.y, geoPosA.z);
     Vector3 north = GetWorldSurfacePostion(geoPosB, body)-GetWorldSurfacePostion(geoPosA, body);
     return Vector3.ProjectOnPlane(north, body.GetSurfaceNVector(geoPosA.x, geoPosA.y)).normalized;
 }
Example #12
0
    public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, double radius, Color c, double rotation = 0)
    {
        Vector3d up     = body.GetSurfaceNVector(latitude, longitude);
        Vector3d center = body.position + body.Radius * up;

        if (IsOccluded(center, body))
        {
            return;
        }

        Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

        //double radius = body.Radius / 15;

        GLTriangleMap(new Vector3d[] {
            center,
            center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
            center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
        }, c);

        GLTriangleMap(new Vector3d[] {
            center,
            center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
            center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
        }, c);

        GLTriangleMap(new Vector3d[] {
            center,
            center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
            center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
        }, c);
    }
Example #13
0
        public static bool DrawCBMarker(CelestialBody body, Coordinates pos, Color color, out Vector3d worldPos,
                                        Texture2D texture = null, float size = DefaultIconSize)
        {
            worldPos = Vector3d.zero;
            Camera   camera;
            Vector3d point;

            if (MapView.MapIsEnabled)
            {
                //TODO: cache local center coordinates of the marker
                camera   = PlanetariumCamera.Camera;
                worldPos = body.position + (pos.Alt + body.Radius) * body.GetSurfaceNVector(pos.Lat, pos.Lon);
                point    = ScaledSpace.LocalToScaledSpace(worldPos);
                if (IsOccluded(worldPos, body))
                {
                    return(false);
                }
            }
            else
            {
                camera   = FlightCamera.fetch.mainCamera;
                worldPos = body.GetWorldSurfacePosition(pos.Lat, pos.Lon, pos.Alt);
                point    = worldPos;
                if (camera.transform.InverseTransformPoint(worldPos).z <= 0)
                {
                    return(false);
                }
            }
            return(color.a > 0 && DrawMarker(camera.WorldToScreenPoint(point), color, texture, size));
        }
        public double GroundDistanceFromMark()
        {
            CelestialBody markBody     = FlightGlobals.Bodies[markBodyIndex];
            Vector3d      markVector   = markBody.GetSurfaceNVector(markLatitude, markLongitude);
            Vector3d      vesselVector = vesselState.CoM - markBody.transform.position;

            return(markBody.Radius * Vector3d.Angle(markVector, vesselVector) * UtilMath.Deg2Rad);
        }
Example #15
0
        public static Vector3 GetNorthVector(Vector3 position, CelestialBody body)
        {
            Vector3 geoPosA = WorldPositionToGeoCoords(position, body);
            Vector3 geoPosB = new Vector3(geoPosA.x + 1, geoPosA.y, geoPosA.z);
            Vector3 north   = GetWorldSurfacePostion(geoPosB, body) - GetWorldSurfacePostion(geoPosA, body);

            return(Vector3.ProjectOnPlane(north, body.GetSurfaceNVector(geoPosA.x, geoPosA.y)).normalized);
        }
Example #16
0
        public Vector3d GetSurfaceNormalVector()
        {
            CelestialBody body = ParentBody ? ParentBody : ParentVessel?.mainBody;

            if (body == null)
            {
                return(Vector3d.zero);
            }
            body.GetLatLonAlt(position, out double lat, out double lon, out double _);
            return(body.GetSurfaceNVector(lat, lon));
        }
Example #17
0
        private static float GetHeading(Transform transform)
        {
            CelestialBody body     = FlightGlobals.ActiveVessel.mainBody;
            Vector3       upVector = body.GetSurfaceNVector(body.GetLatitude((Vector3d)transform.position),
                                                            body.GetLongitude((Vector3d)transform.position)).normalized;
            Vector3 north   = Vector3.ProjectOnPlane(body.transform.up, upVector).normalized;
            Vector3 east    = Vector3.Cross(upVector, north).normalized;
            Vector3 forward = Vector3.ProjectOnPlane(transform.forward, upVector);

            return(Vector3.Angle(forward, north));
        }
Example #18
0
        public static DMPRaycastPair RaycastGround(double latitude, double longitude, CelestialBody body)
        {
            //We can only find the ground on bodies that actually *have* ground and if we are in flight near the origin
            if (!HighLogic.LoadedSceneIsFlight || FlightGlobals.fetch.activeVessel == null || body.pqsController == null)
            {
                return(new DMPRaycastPair(-1f, Vector3.up));
            }
            //Math functions take radians.
            double latRadians  = latitude * Mathf.Deg2Rad;
            double longRadians = longitude * Mathf.Deg2Rad;
            //Radial vector
            Vector3d surfaceRadial = new Vector3d(Math.Cos(latRadians) * Math.Cos(longRadians), Math.Sin(latRadians), Math.Cos(latRadians) * Math.Sin(longRadians));
            double   surfaceHeight = body.pqsController.GetSurfaceHeight(surfaceRadial) - body.pqsController.radius;
            Vector3d origin        = body.GetWorldSurfacePosition(latitude, longitude, surfaceHeight + 500);
            //Only return the surface if it's really close.
            double  highestHit    = double.NegativeInfinity;
            Vector3 rotatedVector = Vector3.up;

            if (Vector3d.Distance(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), origin) < 2500)
            {
                //Down vector
                Vector3d downVector = -body.GetSurfaceNVector(latitude, longitude);
                //Magic numbers, comes from Vessel.GetHeightFromTerrain
                LayerMask    groundMask  = 32768;
                RaycastHit[] raycastHits = Physics.RaycastAll(origin, downVector, 1000f, groundMask);
                foreach (RaycastHit raycastHit in raycastHits)
                {
                    if (raycastHit.collider == null)
                    {
                        //I don't think this is technically possible, but unity's weird enough that we should probably check this anyway.
                        continue;
                    }
                    if (raycastHit.collider.name == body.name)
                    {
                        continue;
                    }
                    double hitAltitude = body.GetAltitude(raycastHit.point);
                    if ((hitAltitude > highestHit) && (!body.ocean || hitAltitude > 0))
                    {
                        highestHit    = hitAltitude;
                        rotatedVector = Quaternion.Inverse(body.rotation) * raycastHit.normal;
                    }
                }
            }
            if (double.IsNegativeInfinity(highestHit))
            {
                return(new DMPRaycastPair(-1f, Vector3.up));
            }
            else
            {
                return(new DMPRaycastPair(highestHit, rotatedVector));
            }
        }
Example #19
0
        public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, Color c, bool map, double rotation = 0, double radius = 0)
        {
            Vector3d up     = body.GetSurfaceNVector(latitude, longitude);
            var      height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right);

            if (height < body.Radius)
            {
                height = body.Radius;
            }
            Vector3d center = body.position + height * up;

            Vector3d camPos = map ? ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position) : (Vector3d)FlightCamera.fetch.mainCamera.transform.position;

            if (IsOccluded(center, body, camPos))
            {
                return;
            }

            Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

            if (radius <= 0)
            {
                radius = map ? body.Radius / 15 : 5;
            }

            if (!map)
            {
                Vector3 centerPoint = FlightCamera.fetch.mainCamera.WorldToViewportPoint(center);
                if (centerPoint.z < 0)
                {
                    return;
                }
            }

            GLTriangle(
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
                , c, map);

            GLTriangle(
                center,
                center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
                , c, map);

            GLTriangle(
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
                , c, map);
        }
Example #20
0
 public static DMPRaycastPair RaycastGround(double latitude, double longitude, CelestialBody body)
 {
     //We can only find the ground on bodies that actually *have* ground and if we are in flight near the origin
     if (!HighLogic.LoadedSceneIsFlight || FlightGlobals.fetch.activeVessel == null || body.pqsController == null)
     {
         return new DMPRaycastPair(-1f, Vector3.up);
     }
     //Math functions take radians.
     double latRadians = latitude * Mathf.Deg2Rad;
     double longRadians = longitude * Mathf.Deg2Rad;
     //Radial vector
     Vector3d surfaceRadial = new Vector3d(Math.Cos(latRadians) * Math.Cos(longRadians), Math.Sin(latRadians), Math.Cos(latRadians) * Math.Sin(longRadians));
     double surfaceHeight = body.pqsController.GetSurfaceHeight(surfaceRadial) - body.pqsController.radius;
     Vector3d origin = body.GetWorldSurfacePosition(latitude, longitude, surfaceHeight + 500);
     //Only return the surface if it's really close.
     double highestHit = double.NegativeInfinity;
     Vector3 rotatedVector = Vector3.up;
     if (Vector3d.Distance(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), origin) < 2500)
     {
         //Down vector
         Vector3d downVector = -body.GetSurfaceNVector(latitude, longitude);
         //Magic numbers!
         LayerMask groundMask = 33792;
         RaycastHit[] raycastHits = Physics.RaycastAll(origin, downVector, 1000f, groundMask);
         foreach (RaycastHit raycastHit in raycastHits)
         {
             if (raycastHit.collider == null)
             {
                 //I don't think this is technically possible, but unity's weird enough that we should probably check this anyway.
                 continue;
             }
             if (raycastHit.collider.name == body.name)
             {
                 continue;
             }
             double hitAltitude = body.GetAltitude(raycastHit.point);
             if ((hitAltitude > highestHit) && (!body.ocean || hitAltitude > 0))
             {
                 highestHit = hitAltitude;
                 rotatedVector = Quaternion.Inverse(body.rotation) * raycastHit.normal;
             }
         }
     }
     if (highestHit == double.NegativeInfinity)
     {
         return new DMPRaycastPair(-1f, Vector3.up);
     }
     else
     {
         return new DMPRaycastPair(highestHit, rotatedVector);
     }
 }
        public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, Color c, bool map, double rotation = 0, double radius = 0)
        {
            Vector3d up     = body.GetSurfaceNVector(latitude, longitude);
            var      height = 1 + body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right);

            if (height < body.Radius + 1)
            {
                height = body.Radius + 1;
            }
            Vector3d center = body.position + height * up;
            Vector3d north  = Vector3d.Exclude(up, body.transform.up).normalized;

            if (map)   //grr
            {
                Vector3d camPos = ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position);
                if (IsOccluded(center, body, camPos))
                {
                    return;
                }
            }

            if (radius <= 0)
            {
                radius = map ? body.Radius / 50 : 15;
            }

            List <Vector3d> Verts = new List <Vector3d>();

            int num = 64;

            for (int i = 0; i <= num; i++)
            {
                Verts.Add(center + radius * 0.85 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north));
                Verts.Add(center + radius * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north));
            }
            GLTriangleStrip(Verts, c, map);

            for (int i = 0; i <= num; i++)
            {
                Verts.Add(center + radius * 0.45 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north));
                Verts.Add(center + radius * 0.6 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north));
            }
            GLTriangleStrip(Verts, c, map);


            for (int i = 0; i <= num; i++)
            {
                Verts.Add(center);
                Verts.Add(center + radius * 0.2 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north));
            }
            GLTriangleStrip(Verts, c, map);
        }
Example #22
0
        protected override bool VesselMeetsCondition(Vessel vessel)
        {
            if (!triggered)
            {
                return(false);
            }

            // The following distance calculation code is from MechJebModuleFlightRecorder
            CelestialBody markBody     = FlightGlobals.GetHomeBody();
            Vector3d      markVector   = markBody.GetSurfaceNVector(markLatitude, markLongitude);
            Vector3d      vesselVector = vessel.CoMD - markBody.transform.position;

            curDist = markBody.Radius * Vector3d.Angle(markVector, vesselVector) * UtilMath.Deg2Rad;

            return(curDist > distance);
        }
Example #23
0
        private int getHeading()
        {
            CelestialBody body     = FlightGlobals.ActiveVessel.mainBody;
            Vector3       upVector = body.GetSurfaceNVector(
                FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude).normalized;
            Vector3 north   = Vector3.ProjectOnPlane(body.transform.up, upVector).normalized;
            Vector3 east    = Vector3.Cross(upVector, north).normalized;
            Vector3 forward = Vector3.ProjectOnPlane(gameObject.transform.forward, upVector);
            float   heading = Vector3.Angle(forward, north);

            if (Vector3.Dot(forward, east) < 0)
            {
                heading = 360 - heading;
            }
            return((int)heading);
        }
Example #24
0
        public IEnumerator <YieldInstruction> Burninator()
        {
            LoggingUtil.LogDebug(this, "burninating");
            while (burninating && FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.state != Vessel.State.DEAD)
            {
                Vessel v = FlightGlobals.ActiveVessel;
                v.srf_velocity        = -jool.GetSurfaceNVector(v.latitude, v.longitude);
                v.externalTemperature = 1000f;
                v.atmDensity          = 1.0f;
                v.speed = 3000f;
                v.mach  = 4f;

                yield return(new WaitForFixedUpdate());
            }
            LoggingUtil.LogDebug(this, "burninating done");
        }
Example #25
0
        public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0, double radius = 0)
        {
            Vector3d up     = body.GetSurfaceNVector(latitude, longitude);
            var      height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right);

            if (height < body.Radius)
            {
                height = body.Radius;
            }
            Vector3d center = body.position + height * up;

            if (IsOccluded(center, body))
            {
                return;
            }

            Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

            if (radius <= 0)
            {
                radius = body.Radius / 15;
            }

            GLTriangleMap(new Vector3d[] {
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[] {
                center,
                center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[] {
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
            }, c);
        }
        //From MechJeb2
        //Computes the time required for the given launch location to rotate under the target orbital plane.
        //If the latitude is too high for the launch location to ever actually rotate under the target plane,
        //returns the time of closest approach to the target plane.
        //I have a wonderful proof of this formula which this comment is too short to contain.
        private double[] CalcAngleToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target)
        {
            double[] o = new double[2];

            double   inc = Math.Abs(Vector3d.Angle(SwappedOrbitNormal(target), launchBody.angularVelocity));
            Vector3d b   = Vector3d.Exclude(launchBody.angularVelocity, SwappedOrbitNormal(target)).normalized; // I don't understand the sign here, but this seems to work

            b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc);
            Vector3d c = Vector3d.Cross(SwappedOrbitNormal(target), launchBody.angularVelocity).normalized;
            double   cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude;

            if (cMagnitudeSquared < 0)
            {
                cMagnitudeSquared = 0;
            }
            c *= Math.Sqrt(cMagnitudeSquared);
            Vector3d a1 = b + c;
            Vector3d a2 = b - c;

            Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude);

            double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1));

            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0)
            {
                angle1 = 360 - angle1;
            }

            double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2));

            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0)
            {
                angle2 = 360 - angle2;
            }

            o[0] = Math.Min(angle1, angle2);
            o[1] = Math.Max(angle1, angle2) - 360;

            return(o);
        }
Example #27
0
        public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, Color c, bool map, double rotation = 0, double radius = 0)
        {
            Vector3d up = body.GetSurfaceNVector(latitude, longitude);
            var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right);
            if (height < body.Radius) { height = body.Radius; }
            Vector3d center = body.position + height * up;

            Vector3d camPos = map ? ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position) : (Vector3d)FlightCamera.fetch.mainCamera.transform.position;

            if (IsOccluded(center, body, camPos)) return;

            Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

            if (radius <= 0) { radius = map ? body.Radius / 15 : 5; }

            if (!map)
            {
                Vector3 centerPoint = FlightCamera.fetch.mainCamera.WorldToViewportPoint(center);
                if (centerPoint.z < 0)
                    return;
            }

            GLTriangle(
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
            , c, map);

            GLTriangle(
                center,
                center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
            , c, map);

            GLTriangle(
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
            , c, map);
        }
Example #28
0
        public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, double alt, Color c, bool map, double rotation = 0, double radius = 0)
        {
            Vector3d up     = body.GetSurfaceNVector(latitude, longitude);
            Vector3d center = body.GetWorldSurfacePosition(latitude, longitude, alt + 0.5f);
            Vector3d north  = Vector3d.Exclude(up, body.transform.up).normalized;

            if (!map)
            {
                Vector3 centerPoint = FlightCamera.fetch.mainCamera.WorldToViewportPoint(center);
                if ((centerPoint.z < 0) || (centerPoint.x < -1) || (centerPoint.x > 1) || (centerPoint.y < -1) || (centerPoint.y > 1))
                {
                    return;
                }
            }

            GLTriangle(center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                       center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north), c, map);
            GLTriangle(center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                       center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north), c, map);
            GLTriangle(center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                       center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north), c, map);
        }
        //From MechJeb2
        //Computes the time required for the given launch location to rotate under the target orbital plane.
        //If the latitude is too high for the launch location to ever actually rotate under the target plane,
        //returns the time of closest approach to the target plane.
        //I have a wonderful proof of this formula which this comment is too short to contain.
        internal static double TimeToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target)
        {
            double inc = Math.Abs(Vector3d.Angle(target.SwappedOrbitNormal(), launchBody.angularVelocity));
            Vector3d b = Vector3d.Exclude(launchBody.angularVelocity, target.SwappedOrbitNormal()).normalized; // I don't understand the sign here, but this seems to work
            b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc);
            Vector3d c = Vector3d.Cross(target.SwappedOrbitNormal(), launchBody.angularVelocity).normalized;
            double cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude;
            if (cMagnitudeSquared < 0) cMagnitudeSquared = 0;
            c *= Math.Sqrt(cMagnitudeSquared);
            Vector3d a1 = b + c;
            Vector3d a2 = b - c;

            Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude);

            double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1));
            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0) angle1 = 360 - angle1;
            double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2));
            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0) angle2 = 360 - angle2;

            double angle = Math.Min(angle1, angle2);
            return (angle / 360) * launchBody.rotationPeriod;
        }
Example #30
0
        //Computes the time required for the given launch location to rotate under the target orbital plane.
        //If the latitude is too high for the launch location to ever actually rotate under the target plane,
        //returns the time of closest approach to the target plane.
        //I have a wonderful proof of this formula which this comment is too short to contain.
        public static double TimeToPlane(double LANDifference, CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target)
        {
            double   inc = Math.Abs(Vector3d.Angle(-target.GetOrbitNormal().Reorder(132).normalized, launchBody.angularVelocity));
            Vector3d b   = Vector3d.Exclude(launchBody.angularVelocity, -target.GetOrbitNormal().Reorder(132).normalized).normalized; // I don't understand the sign here, but this seems to work

            b *= launchBody.Radius * Math.Sin(UtilMath.Deg2Rad * launchLatitude) / Math.Tan(UtilMath.Deg2Rad * inc);
            Vector3d c = Vector3d.Cross(-target.GetOrbitNormal().Reorder(132).normalized, launchBody.angularVelocity).normalized;
            double   cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(UtilMath.Deg2Rad * launchLatitude), 2) - b.sqrMagnitude;

            if (cMagnitudeSquared < 0)
            {
                cMagnitudeSquared = 0;
            }
            c *= Math.Sqrt(cMagnitudeSquared);
            Vector3d a1 = b + c;
            Vector3d a2 = b - c;

            Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude);

            double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1));

            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0)
            {
                angle1 = 360 - angle1;
            }
            double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2));

            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0)
            {
                angle2 = 360 - angle2;
            }

            double angle = Math.Min(angle1, angle2) - LANDifference;

            return((angle / 360) * launchBody.rotationPeriod);
        }
Example #31
0
        //Computes the time required for the given launch location to rotate under the target orbital plane.
        //If the latitude is too high for the launch location to ever actually rotate under the target plane,
        //returns the time of closest approach to the target plane.
        //I have a wonderful proof of this formula which this comment is too short to contain.
        public static double TimeToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target)
        {
            double   inc = Math.Abs(Vector3d.Angle(target.SwappedOrbitNormal(), launchBody.angularVelocity));
            Vector3d b   = Vector3d.Exclude(launchBody.angularVelocity, -target.SwappedOrbitNormal()).normalized;

            b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc);
            Vector3d c = Vector3d.Cross(target.SwappedOrbitNormal(), launchBody.angularVelocity).normalized;
            double   cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude;

            if (cMagnitudeSquared < 0)
            {
                cMagnitudeSquared = 0;
            }
            c *= cMagnitudeSquared;
            Vector3d a1 = b + c;
            Vector3d a2 = b - c;

            Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude);

            double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1));

            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0)
            {
                angle1 = 360 - angle1;
            }
            double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2));

            if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0)
            {
                angle2 = 360 - angle2;
            }

            double angle = Math.Min(angle1, angle2);

            return((angle / 360) * launchBody.rotationPeriod);
        }
 public Vector3d Up(CelestialBody body)
 {
     return(body.GetSurfaceNVector(latitude, longitude));
 }
Example #33
0
 public Vector3d Normal(CelestialBody body)
 {
     return(body.GetSurfaceNVector(Lat, Lon));
 }
Example #34
0
        public static void updatePlanetaryResourceMap()
        {
            if (FlightGlobals.currentMainBody.flightGlobalsIndex != current_body)
            {
                loadPlanetaryResourceData(FlightGlobals.currentMainBody.flightGlobalsIndex);
            }

            if (body_resource_maps.ContainsKey(displayed_resource) && (FlightGlobals.currentMainBody.flightGlobalsIndex != map_body || displayed_resource != map_resource))
            {
                foreach (ORSHeatMapOverlay abundance_marker in abundance_markers)
                {
                    removeAbundanceSphere(abundance_marker.getPlanetarySphere());
                    removeAbundanceSphere(abundance_marker.getScaledSphere());
                }
                abundance_markers.Clear();
                CelestialBody celbody = FlightGlobals.currentMainBody;
                sphere_texture = body_resource_maps[displayed_resource].getDisplayTexturePath();
                Vector2d[] abundance_points_list = body_abudnance_angles[displayed_resource];
                if (abundance_points_list != null && celbody.pqsController != null)
                {
                    foreach (Vector2d abundance_point in abundance_points_list)
                    {
                        //double theta = abundance_point.x;
                        //double phi = abundance_point.y;
                        Vector3d up = celbody.GetSurfaceNVector(0, 0).normalized;
                        //double surface_height = celbody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(0, Vector3d.down) * QuaternionD.AngleAxis(0, Vector3d.forward) * Vector3d.right);
                        GameObject resource_prim        = createAbundanceSphere();
                        GameObject resource_prim_scaled = createAbundanceSphere();

                        //Vector3d center = celbody.position + surface_height * up;
                        Vector3d center = celbody.position;
                        //Vector3d scaledcenter = ScaledSpace.LocalToScaledSpace(celbody.position) + surface_height * up * ScaledSpace.InverseScaleFactor;
                        Vector3d scaledcenter = ScaledSpace.LocalToScaledSpace(celbody.position);

                        Transform scaled_trans = ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == celbody.name);
                        resource_prim_scaled.transform.position      = scaledcenter;
                        resource_prim_scaled.transform.localScale    = sphere_scale_scaled * (FlightGlobals.currentMainBody.Radius / FlightGlobals.Bodies[ORSGameConstants.REF_BODY_KERBIN].Radius);
                        resource_prim_scaled.transform.localRotation = Quaternion.identity;
                        resource_prim_scaled.transform.parent        = scaled_trans;
                        resource_prim_scaled.layer = 10;

                        resource_prim.transform.position      = center;
                        resource_prim.transform.parent        = celbody.transform;
                        resource_prim.transform.localScale    = sphere_scale * (FlightGlobals.currentMainBody.Radius / FlightGlobals.Bodies[ORSGameConstants.REF_BODY_KERBIN].Radius);
                        resource_prim.transform.localRotation = Quaternion.identity;

                        ORSHeatMapOverlay abundance_marker = new ORSHeatMapOverlay(resource_prim_scaled);
                        abundance_markers.Add(abundance_marker);
                    }
                    map_body     = current_body;
                    map_resource = displayed_resource;
                    stored_scale = ScaledSpace.ScaleFactor;
                }
            }
            else
            {
                if (body_resource_maps.ContainsKey(displayed_resource) && FlightGlobals.currentMainBody.flightGlobalsIndex == map_body && displayed_resource == map_resource)
                {
                    CelestialBody celbody = FlightGlobals.currentMainBody;
                    foreach (ORSHeatMapOverlay abundance_marker in abundance_markers)
                    {
                        //if (lineOfSightToPosition(abundance_marker.getPlanetarySphere().transform.position, celbody))
                        //{
                        if (MapView.MapIsEnabled)
                        {
                            abundance_marker.getScaledSphere().renderer.enabled = true;
                            abundance_marker.getPlanetarySphere().renderer.enabled = false;
                        }
                        else
                        {
                            abundance_marker.getScaledSphere().renderer.enabled = false;
                            abundance_marker.getPlanetarySphere().renderer.enabled = true;
                        }
                        //}
                        //else
                        //{
                        //    abundance_marker.getScaledSphere().renderer.enabled = false;
                        //    //abundance_marker.getPlanetarySphere().renderer.enabled = false;
                        //}
                    }
                }
            }
        }
 static bool DrawGroundMarker(CelestialBody body, Coordinates pos, Color c, float r = IconSize, Texture2D texture = null)
 {
     Vector3d center;
     Camera camera;
     if(MapView.MapIsEnabled)
     {
         //TODO: cache local center coordinates of the marker
         camera = PlanetariumCamera.Camera;
         center = body.position + (body.TerrainAltitude(pos.Lat, pos.Lon)+body.Radius) * body.GetSurfaceNVector(pos.Lat, pos.Lon);
     }
     else
     {
         camera = FlightCamera.fetch.mainCamera;
         center = body.GetWorldSurfacePosition(pos.Lat, pos.Lon, body.TerrainAltitude(pos.Lat, pos.Lon)+GLB.WaypointHeight);
         if(camera.transform.InverseTransformPoint(center).z <= 0) return false;
     }
     return !IsOccluded(center, body) &&
         DrawMarker(camera.WorldToScreenPoint(MapView.MapIsEnabled ? ScaledSpace.LocalToScaledSpace(center) : center), c, r, texture);
 }
Example #36
0
 public static ReferenceFrame CreateAtCurrentTime(CelestialBody referenceBody)
 {
     ReferenceFrame ret = new ReferenceFrame();
     ret.lat0lon0AtStart = referenceBody.GetSurfaceNVector(0, 0);
     ret.lat0lon90AtStart = referenceBody.GetSurfaceNVector(0, 90);
     ret.lat90AtStart = referenceBody.GetSurfaceNVector(90, 0);
     ret.epoch = Planetarium.GetUniversalTime();
     ret.referenceBody = referenceBody;
     return ret;
 }
        protected bool CheckParameters(MonolithState paramState)
        {
            if (paramState < currentState)
            {
                return(true);
            }

            // StarJeb not active vessel
            if (starJeb != null && FlightGlobals.ActiveVessel != starJeb ||
                candidate != null && FlightGlobals.ActiveVessel != candidate)
            {
                stepTime = Time.fixedTime;
                return(false);
            }

            // Create the velocity change handler
            if (velHdlr == null)
            {
                LoggingUtil.LogDebug(this, "Adding VelocityHandler");
                velHdlr       = MapView.MapCamera.gameObject.AddComponent <VelocityHandler>();
                velHdlr.param = this;
            }

            switch (currentState)
            {
            case MonolithState.STARTED:
                // Look for an eva
                if (FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.vesselType == VesselType.EVA)
                {
                    candidate     = FlightGlobals.ActiveVessel;
                    candidateName = candidate.vesselName;
                    LoggingUtil.LogDebug(this, "Got an eva, starJeb = " + candidate.vesselName);
                    nextState();
                    return(true);
                }
                return(false);

            case MonolithState.EVA:
            {
                Vessel discovery         = ContractVesselTracker.Instance.GetAssociatedVessel("Discovery One");
                float  discoveryDistance = discovery == null ? 10000 : Vector3.Distance(discovery.transform.position, candidate.transform.position);

                if (distance < 10000 && discoveryDistance > distance && Time.fixedTime - stepTime > 10.0f || distance < MONOLITH_TOO_CLOSE)
                {
                    // Store Star Jeb's name
                    starJeb     = candidate;
                    starJebName = candidateName;
                    PersistentDataStore.Instance.Store <string>("starJebName", starJebName);

                    // Store Star Jeb's friend's name
                    ProtoCrewMember protoStarJeb = candidate.GetVesselCrew().First();
                    if (discovery != null)
                    {
                        string          trait      = protoStarJeb.experienceTrait.TypeName == "Scientist" ? "Pilot" : "Scientist";
                        ProtoCrewMember notStarJeb = discovery.GetVesselCrew().Where(pcm => pcm.experienceTrait.TypeName == trait).FirstOrDefault();
                        if (notStarJeb != null)
                        {
                            PersistentDataStore.Instance.Store <string>("notStarJebName", notStarJeb.name);
                        }
                    }
                    candidate = null;
                    nextState();

                    // Set the right image (male vs. female) for the end sequence
                    ConfiguredContract contract  = Root as ConfiguredContract;
                    DialogBox          dialogBox = contract.Behaviours.Select(b => b as DialogBox).Where(b => b != null).FirstOrDefault();
                    if (dialogBox != null)
                    {
                        FieldInfo detailsField = typeof(DialogBox).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).
                                                 Where(fi => fi.FieldType == typeof(List <DialogBox.DialogDetail>)).First();
                        DialogBox.DialogDetail detail       = ((List <DialogBox.DialogDetail>)detailsField.GetValue(dialogBox)).First();
                        DialogBox.ImageSection starJebImage = detail.sections.First() as DialogBox.ImageSection;
                        starJebImage.imageURL = protoStarJeb.gender == ProtoCrewMember.Gender.Male ?
                                                "ContractPacks/AnomalySurveyor/Images/starjeb.dds.noload" :
                                                "ContractPacks/AnomalySurveyor/Images/starjeb_female.dds.noload";
                    }

                    return(true);
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS1:
            {
                // Backup progress tracking
                progressTreeBackup = new ConfigNode("PROGRESS_TREE_BACKUP");
                ProgressTracking.Instance.OnSave(progressTreeBackup);

                // Give the first kick away from Jool - this one using regular velocity change
                CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();

                // Find closest point on the jool-monolith line, and throw us away from that (so we don't hit either)
                Vector3 line    = monolith.transform.position - jool.transform.position;
                float   t       = Vector3.Dot(line, (starJeb.transform.position - jool.transform.position)) / Vector3.Dot(line, line);
                Vector3 closest = jool.transform.position + line * t;

                velocity  = (starJeb.transform.position - (t > 1.0 ? jool.transform.position : closest)).normalized;
                velocity += new Vector3(0.0f, 0.1f, 0.0f);
                velocity *= 15000;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                nextState();

                // Camera to target jool
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition((starJeb.transform.position - jool.transform.position).normalized * 25.0f);
            }
                return(false);

            case MonolithState.FULL_OF_STARS2:
                if (Time.fixedTime - stepTime > 4.0f)
                {
                    // Give the second kick away from Jool - these using anti-kraken velocity change
                    CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();
                    velocity  = (starJeb.transform.position - jool.transform.position).normalized;
                    velocity += new Vector3(0.0f, 0.1f, 0.0f);
                    velocity *= 1500000;
                    LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS3:
                if (Time.fixedTime - stepTime > 3.0f)
                {
                    // Give the third kick away from Jool
                    CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();
                    velocity  = (starJeb.transform.position - jool.transform.position).normalized;
                    velocity *= 20000000;
                    LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS4:
                if (Time.fixedTime - stepTime > 2.0f)
                {
                    // Give the fourth and final kick away from Jool
                    CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();
                    velocity  = (starJeb.transform.position - jool.transform.position).normalized;
                    velocity *= 200000000;
                    LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS5:
                if (Time.fixedTime - stepTime > 2.0f)
                {
                    // Move along
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_DRES1:
            {
                // Visit Dres
                CelestialBody dres = FlightGlobals.Bodies.Where(b => b.name == "Dres").First();

                // Determine which side the sun is on - makes for a better show
                CelestialBody sun       = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       sunnySide = sun.transform.position - dres.transform.position;
                sunnySide.x = 0.0f;
                sunnySide.y = 1;         // Move across the top of the planet
                sunnySide.z = Math.Sign(sunnySide.z);

                // Set position for starjeb
                float distance = 4.0f * (float)dres.Radius;
                starJeb.SetPosition(dres.transform.position + new Vector3(distance, (float)dres.Radius, (float)dres.Radius * sunnySide.z));

                velocity  = (dres.transform.position - starJeb.transform.position + sunnySide * ((float)dres.Radius)).normalized;
                velocity *= distance / 3.0f;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                starJeb.SetWorldVelocity(dres.getRFrmVel(starJeb.transform.position));
                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DRES2:
            {
                // Camera to target Dres - do this on a seperate update to allow KSP to catch up
                CelestialBody dres = FlightGlobals.Bodies.Where(b => b.name == "Dres").First();
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - dres.transform.position).normalized * 10.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DRES3:
                if (Time.fixedTime - stepTime > 5.5f)
                {
                    // Done with Dres
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_DUNA1:
            {
                // Start between the sun and Duna
                CelestialBody duna      = FlightGlobals.Bodies.Where(b => b.name == "Duna").First();
                CelestialBody sun       = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       sunnySide = sun.transform.position - duna.transform.position;
                sunnySide.Normalize();

                // Set us up a nice 4 radiuses away...
                float distance = 4.0f * (float)duna.Radius;
                starJeb.SetPosition(duna.transform.position + sunnySide * distance);

                // Go straight at Duna
                velocity  = (duna.transform.position - starJeb.transform.position).normalized;
                velocity *= distance / 3.0f;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);

                // Now offset him down so he doesn't actually hit Duna...
                starJeb.SetPosition(starJeb.transform.position + new Vector3(0.0f, -((float)duna.Radius + 55000), 0.0f));
                starJeb.SetWorldVelocity(duna.getRFrmVel(starJeb.transform.position));

                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DUNA2:
            {
                // Camera to target Duna - do this on a seperate update to allow KSP to catch up
                CelestialBody duna = FlightGlobals.Bodies.Where(b => b.name == "Duna").First();
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - duna.transform.position).normalized * 25.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DUNA3:
                if (Time.fixedTime - stepTime > 5.5f)
                {
                    // Done with Duna
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EELOO1:
            {
                // Start perpendicular to the sun and Eeloo
                CelestialBody eeloo = FlightGlobals.Bodies.Where(b => b.name == "Eeloo").First();
                CelestialBody sun   = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       perp  = eeloo.transform.position - sun.transform.position;
                float         tmp   = perp.x;
                perp.x = -perp.z;
                perp.z = tmp;
                perp.Normalize();

                // Set us up a nice 4 radiuses away...
                float distance = 4.0f * (float)eeloo.Radius;
                starJeb.SetPosition(eeloo.transform.position + perp * distance);

                // Determine which side the sun is on - makes for a better show
                Vector3 sunnySide = sun.transform.position - eeloo.transform.position;
                sunnySide.Normalize();

                // Go straight at Eeloo
                velocity  = (eeloo.transform.position - starJeb.transform.position).normalized;
                velocity *= distance / 3.0f;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);

                // Now offset him down so he doesn't actually hit Eeloo...
                starJeb.SetPosition(starJeb.transform.position + sunnySide * ((float)eeloo.Radius * 1.5f));
                starJeb.SetWorldVelocity(eeloo.getRFrmVel(starJeb.transform.position));

                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EELOO2:
            {
                // This time won't target directly towards Eeloo, as the player will have some idea
                // what is up by now.
                CelestialBody eeloo       = FlightGlobals.Bodies.Where(b => b.name == "Eeloo").First();
                CelestialBody sun         = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       awayFromSun = sun.transform.position - eeloo.transform.position;
                awayFromSun.Normalize();

                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + awayFromSun * 50.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EELOO3:
                if (Time.fixedTime - stepTime > 5.5f)
                {
                    velocity = null;

                    // Done with Eeloo
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE1:
            {
                CelestialBody eve            = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                Vector3       targetPosition = Destination.Value;
                Vector3       normal         = eve.GetSurfaceNVector(eveLatitude, eveLongitude);
                startDistance = 10000000f;
                Vector3 start = targetPosition + normal * startDistance;

                starJeb.SetPosition(start);
                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE2:
            {
                // Camera straight towards Eve - we're going in!
                CelestialBody eve         = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                Vector3       awayFromEve = starJeb.transform.position - eve.transform.position;
                awayFromEve.Normalize();

                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + awayFromEve * 15.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE3:
                // Wait until we've held the position for a split second
                if (Time.fixedTime - stepTime >= 9.3f)
                {
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE4:
                // Give the player a bit to get settled, then let the fun begins
                if (Time.fixedTime - stepTime >= 15.0f)
                {
                    // Spawn some asteroids
                    CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                    ScenarioDiscoverableObjects asteroidSpawner = (ScenarioDiscoverableObjects)HighLogic.CurrentGame.scenarios.Find(
                        s => s.moduleRef is ScenarioDiscoverableObjects).moduleRef;
                    System.Random random = new System.Random();

                    // Spawn some more asteroids
                    for (int i = 0; i < ASTEROID_COUNT; i++)
                    {
                        asteroidSpawner.SpawnAsteroid();
                    }

                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE5:
                // Wait a full second after spawning the asteroids - we're not allowed to pull
                // them off rails until they've been active a bit
                if (Time.fixedTime - stepTime > 1.0f)
                {
                    // Spawn some asteroids
                    CelestialBody eve    = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                    System.Random random = new System.Random();

                    foreach (Vessel asteroid in FlightGlobals.Vessels.Where(v => v.vesselType == VesselType.SpaceObject).Reverse().Take(ASTEROID_COUNT))
                    {
                        // Set the position
                        double r         = random.NextDouble() * 0.02 + 0.002;
                        double theta     = random.NextDouble() * 2.0 * Math.PI;
                        double latitude  = starJeb.latitude + r * Math.Sin(theta);
                        double longitude = starJeb.longitude + r * Math.Cos(theta);
                        double altitude  = starJeb.altitude + 100 + random.NextDouble() * 200;
                        asteroid.SetPosition(eve.GetWorldSurfacePosition(latitude, longitude, altitude));
                        asteroid.ChangeWorldVelocity(asteroid.GetSrfVelocity());
                        asteroid.Load();
                        asteroid.GoOffRails();
                    }
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE6:
            {
                // Determine if there's an asteroid about to kill us
                CelestialBody eve            = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                bool          killerAsteroid = FlightGlobals.Vessels.Where(v => v.mainBody == eve && v.vesselType == VesselType.SpaceObject &&
                                                                           Vector3.Distance(starJeb.transform.position, v.transform.position) < 5.5 * ((int)v.DiscoveryInfo.objectSize + 1)).Any();

                if (killerAsteroid || Time.fixedTime - stepTime > 20.0f)
                {
                    foreach (Vessel asteroid in FlightGlobals.Vessels.Where(v => v.vesselType == VesselType.SpaceObject).Reverse().Take(ASTEROID_COUNT))
                    {
                        asteroid.Die();
                    }
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN1:
            {
                CheatOptions.NoCrashDamage = false;

                // Start between the sun and Kerbin
                CelestialBody kerbin    = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();
                CelestialBody sun       = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       sunnySide = sun.transform.position - kerbin.transform.position;
                sunnySide.Normalize();

                // Set us up a nice 4 radiuses away...
                float distance = 4.0f * (float)kerbin.Radius;
                starJeb.SetPosition(kerbin.transform.position + sunnySide * distance);

                // Orient him properly
                KerbalEVA  keva           = starJeb.FindPartModulesImplementing <KerbalEVA>().First();
                MethodInfo rotationMethod = typeof(KerbalEVA).GetMethod("correctGroundedRotation", BindingFlags.Instance | BindingFlags.NonPublic);
                starJeb.packed = true;
                rotationMethod.Invoke(keva, new object[] { });
                starJeb.packed = false;

                // Hardcode an orbital velocity, because it's late and I'm tired
                starJeb.SetWorldVelocity(kerbin.getRFrmVel(starJeb.transform.position).normalized * 1085);

                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN2:
            {
                // Camera to target kerbin - do this on a seperate update to allow KSP to catch up
                CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized * 10.0f);

                starJeb.SetRotation(FlightCamera.fetch.transform.rotation * Quaternion.AngleAxis(180.0f, FlightCamera.fetch.transform.up));

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN3:
                if (Time.fixedTime - stepTime > 2.0f)
                {
                    // Turn into star jeb
                    CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();

                    starJeb.vesselName = "The Star Jeb";
                    Undress(starJeb.gameObject);
                    FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized * 1.5f);

                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN4:
                if (Time.fixedTime - stepTime < 15.0f)
                {
                    CelestialBody kerbin       = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();
                    Vector3       camDirection = starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized;
                }
                else
                {
                    nextState();

                    monolith.Die();
                    monolith = null;

                    starJeb.Die();
                    starJeb = null;

                    Vessel discovery = ContractVesselTracker.Instance.GetAssociatedVessel("Discovery One");
                    FlightGlobals.ForceSetActiveVessel(discovery);
                }
                return(false);

            case MonolithState.FULL_OF_STARS_FINAL:
                nextState();
                return(true);

            default:
                return(false);
            }
        }
 public void UpdateAtCurrentTime(CelestialBody body)
 {
     lat0lon0AtStart = body.GetSurfaceNVector(0, 0);
     lat0lon90AtStart = body.GetSurfaceNVector(0, 90);
     lat90AtStart = body.GetSurfaceNVector(90, 0);
     epoch = Planetarium.GetUniversalTime();
     referenceBody = body;
 }
Example #39
0
 public SurfaceNode(WayPoint wp, CelestialBody body)
 {
     position = wp.GetTransform().position;
     up       = body.GetSurfaceNVector(wp.Pos.Lat, wp.Pos.Lon);
 }
Example #40
0
        private bool isInSafetyBubble(Vector3d pos, CelestialBody body, double altitude)
        {
            //Assume Kerbin if body isn't supplied for some reason
            if (body == null)
                body = FlightGlobals.Bodies.Find(b => b.name == "Kerbin");

            //If not at Kerbin or past ceiling we're definitely clear
            if (body.name != "Kerbin" || altitude > SAFETY_BUBBLE_CEILING)
                return false;

            //Cylindrical safety bubble -- project vessel position to a plane positioned at KSC with normal pointed away from surface
            Vector3d kscNormal = body.GetSurfaceNVector(-0.102668048654, -74.5753856554);
            Vector3d kscPosition = body.GetWorldSurfacePosition(-0.102668048654, -74.5753856554, 60);
            Vector3d landingPadPosition = body.GetWorldSurfacePosition(-0.0971978130377757, 285.44237039111, 60);
            Vector3d runwayPosition = body.GetWorldSurfacePosition(-0.0486001121594686, 285.275552559723, 60);
            double projectionDistance = Vector3d.Dot(kscNormal, (pos - kscPosition)) * -1;
            double landingPadDistance = Vector3d.Distance(pos, landingPadPosition);
            double runwayDistance = Vector3d.Distance(pos, runwayPosition);
            Vector3d projectedPos = pos + (Vector3d.Normalize(kscNormal) * projectionDistance);
            return Vector3d.Distance(kscPosition, projectedPos) < safetyBubbleRadius || runwayDistance < MIN_SAFETY_BUBBLE_DISTANCE || landingPadDistance < MIN_SAFETY_BUBBLE_DISTANCE;
        }
        static bool DrawGroundMarker(CelestialBody body, Coordinates pos, Color c, float r = IconSize, Texture2D texture = null)
        {
            Vector3d center;
            Camera   camera;

            if (MapView.MapIsEnabled)
            {
                //TODO: cache local center coordinates of the marker
                camera = PlanetariumCamera.Camera;
                center = body.position + (body.TerrainAltitude(pos.Lat, pos.Lon) + body.Radius) * body.GetSurfaceNVector(pos.Lat, pos.Lon);
            }
            else
            {
                camera = FlightCamera.fetch.mainCamera;
                center = body.GetWorldSurfacePosition(pos.Lat, pos.Lon, body.TerrainAltitude(pos.Lat, pos.Lon) + GLB.WaypointHeight);
                if (camera.transform.InverseTransformPoint(center).z <= 0)
                {
                    return(false);
                }
            }
            return(!IsOccluded(center, body) &&
                   DrawMarker(camera.WorldToScreenPoint(MapView.MapIsEnabled ? ScaledSpace.LocalToScaledSpace(center) : center), c, r, texture));
        }
Example #42
0
		/*These methods borrowed from MechJeb GLUtils: 
		 * https://github.com/MuMech/MechJeb2/blob/master/MechJeb2/GLUtils.cs
		 * 
		*/
		internal static void drawTargetOverlay(CelestialBody body, double latitude, double longitude, Color c)
		{
			double rotation = 0;
			double radius = 0;
			Vector3d up = body.GetSurfaceNVector(latitude, longitude);
			var height = SCANUtil.getElevation(body, longitude, latitude);
			if (height < body.Radius)
				height = body.Radius;
			Vector3d center = body.position + height * up;

			if (occluded(center, body))
				return;

			Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

			if (radius <= 0)
				radius = body.Radius / 15;

			GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 55, up) * north), center + radius * (QuaternionD.AngleAxis(rotation -35, up) * north) }, c);

			GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation + 55, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 35, up) * north) }, c);

			GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 145, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 125, up) * north) }, c);

			GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation + 145, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 125, up) * north) }, c);
		}
Example #43
0
        private bool isInSafetyBubble(Vector3d pos, CelestialBody body, double altitude)
        {
            //Assume Kerbin if body isn't supplied for some reason
            if (body == null) body = FlightGlobals.Bodies.Find(b => b.name == "Kerbin");

            //If KSC out of range, syncing, not at Kerbin, or past ceiling we're definitely clear
            if (kscPosition == Vector3d.zero || syncing || body.name != "Kerbin" || altitude > SAFETY_BUBBLE_CEILING)
                return false;

            //Cylindrical safety bubble -- project vessel position to a plane positioned at KSC with normal pointed away from surface
            Vector3d kscNormal = body.GetSurfaceNVector(-0.102668048654,-74.5753856554);
            double projectionDistance = Vector3d.Dot(kscNormal, (pos - kscPosition)) * -1;
            Vector3d projectedPos = pos + (Vector3d.Normalize(kscNormal)*projectionDistance);

            return Vector3d.Distance(kscPosition, projectedPos) < safetyBubbleRadius;
        }
Example #44
0
 public Vector3d BodyPositionAtCurrentTime(AbsoluteVector absolute)
 {
     return(referenceBody.position + absolute.radius * referenceBody.GetSurfaceNVector(absolute.latitude, absolute.longitude));
 }