// Credits to https://github.com/jrossignol/WaypointManager/blob/master/source/WaypointManager/CustomWaypointGUI.cs // for this code public static bool GetBodyRayIntersect(CelestialBody targetBody, bool map, out double latitude, out double longitude, out double altitude) { latitude = 0; longitude = 0; altitude = 0; if (targetBody.pqsController == null) { return(false); } Ray mouseRay = map ? PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition) : FlightCamera.fetch.mainCamera.ScreenPointToRay(Input.mousePosition); if (map) // use scaled space { mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); } var bodyToOrigin = mouseRay.origin - targetBody.position; double curRadius = targetBody.pqsController.radiusMax; double lastRadius = 0; int loops = 0; while (loops < 10) { Vector3d relSurfacePosition; if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { var surfacePoint = targetBody.position + relSurfacePosition; double alt = targetBody.pqsController.GetSurfaceHeight( QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right); double error = Math.Abs(curRadius - alt); if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 500) { latitude = targetBody.GetLatitude(surfacePoint); longitude = targetBody.GetLongitude(surfacePoint); altitude = targetBody.TerrainAltitude(latitude, longitude); return(true); } else { lastRadius = curRadius; curRadius = 0.5 * alt + 0.5 * curRadius; loops++; } } else { if (loops == 0) { break; } // Went too low, needs to try higher else { curRadius = (lastRadius * 9 + curRadius) / 10; loops++; } } } return(true); }
} // So many ifs..... // Cinically stolen from Waypoint Manager source code :D private void PlaceTargetAtCursor() { CelestialBody targetBody = this.vessel.mainBody; if (targetBody.pqsController == null) { return; } Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); var bodyToOrigin = mouseRay.origin - targetBody.position; double curRadius = targetBody.pqsController.radiusMax; double lastRadius = 0; int loops = 0; while (loops < 50) { Vector3d relSurfacePosition; if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { var surfacePoint = targetBody.position + relSurfacePosition; double alt = targetBody.pqsController.GetSurfaceHeight( QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right); double error = Math.Abs(curRadius - alt); if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 100) { targetLatitude = (targetBody.GetLatitude(surfacePoint) + 360) % 360; targetLongitude = (targetBody.GetLongitude(surfacePoint) + 360) % 360; /* this.distanceToTarget = GeoUtils.GetDistance( * this.vessel.latitude, this.vessel.longitude, this.targetLatitude, this.targetLongitude, this.vessel.mainBody.Radius * ); * this.distanceTravelled = 0;*/ return; } else { lastRadius = curRadius; curRadius = alt; loops++; } } else { if (loops == 0) { break; } // Went too low, needs to try higher else { curRadius = (lastRadius * 9 + curRadius) / 10; loops++; } } } }
/// <summary> /// Place target at cursor in the map mode. Borrowed Waypoint Manager and changed. /// Returns latitude and longitude of a target or double.MinValue, if target is not valid /// </summary> /// <param name="targetBody"></param> /// <returns>[latitude, longitude]</returns> internal static double[] PlaceTargetAtCursor(CelestialBody targetBody) { if (targetBody.pqsController == null) { return new double[2] { double.MinValue, double.MinValue } } ; Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); var bodyToOrigin = mouseRay.origin - targetBody.position; double curRadius = targetBody.pqsController.radiusMax; double lastRadius = 0; int loops = 0; while (loops < 50) { Vector3d relSurfacePosition; if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { var surfacePoint = targetBody.position + relSurfacePosition; double alt = targetBody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right); double error = Math.Abs(curRadius - alt); if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 100) { return(new double[2] { (targetBody.GetLatitude(surfacePoint) + 360) % 360, (targetBody.GetLongitude(surfacePoint) + 360) % 360 }); } else { lastRadius = curRadius; curRadius = alt; loops++; } } else { if (loops == 0) { break; } else // Went too low, needs to try higher { curRadius = (lastRadius * 9 + curRadius) / 10; loops++; } } } return(new double[2] { double.MinValue, double.MinValue }); }
private static void PlaceWaypointAtCursor() { if (targetBody.pqsController == null) { return; } Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); var bodyToOrigin = mouseRay.origin - targetBody.position; double curRadius = targetBody.pqsController.radiusMax; double lastRadius = 0; int loops = 0; while (loops < 50) { Vector3d relSurfacePosition; if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { var surfacePoint = targetBody.position + relSurfacePosition; double alt = targetBody.pqsController.GetSurfaceHeight( QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right); double error = Math.Abs(curRadius - alt); if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 100) { latitude = targetBody.GetLatitude(surfacePoint).ToString(); longitude = targetBody.GetLongitude(surfacePoint).ToString(); return; } else { lastRadius = curRadius; curRadius = alt; loops++; } } else { if (loops == 0) { break; } // Went too low, needs to try higher else { curRadius = (lastRadius * 9 + curRadius) / 10; loops++; } } } }
static Coordinates Search(CelestialBody body, Ray mouseRay) { if (body == null || body.pqsController == null) { return(null); } Vector3d relSurfacePosition; Vector3d relOrigin = mouseRay.origin - body.position; double curRadius = body.pqsController.radiusMax; double lastRadius = 0; double error = 0; int loops = 0; float st = Time.time; while (loops < 50) { if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { var alt = body.pqsController.GetSurfaceHeight(relSurfacePosition); if (body.ocean && alt < body.Radius) { alt = body.Radius; } error = Math.Abs(curRadius - alt); if (error < (body.pqsController.radiusMax - body.pqsController.radiusMin) / 100) { return(Coordinates.SurfacePoint(body.position + relSurfacePosition, body)); } else { lastRadius = curRadius; curRadius = alt; loops++; } } else { if (loops == 0) { break; } else { // Went too low, needs to try higher curRadius = (lastRadius * 9 + curRadius) / 10; loops++; } } } return(null); }
public static Coordinates GetMouseCoordinates(CelestialBody body) { Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); Vector3d relOrigin = mouseRay.origin - body.position; Vector3d relSurfacePosition; double curRadius = body.pqsController.radiusMax; double lastRadius = 0; double error = 0; int loops = 0; float st = Time.time; while (loops < 50) { if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { Vector3d surfacePoint = body.position + relSurfacePosition; double alt = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(body.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(body.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right); error = Math.Abs(curRadius - alt); if (error < (body.pqsController.radiusMax - body.pqsController.radiusMin) / 100) { return(new Coordinates(body.GetLatitude(surfacePoint), MuUtils.ClampDegrees180(body.GetLongitude(surfacePoint)))); } else { lastRadius = curRadius; curRadius = alt; loops++; } } else { if (loops == 0) { break; } else { // Went too low, needs to try higher curRadius = (lastRadius * 9 + curRadius) / 10; loops++; } } } return(null); }
public static Coordinates GetMouseCoordinates(CelestialBody body) { Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); Vector3d relOrigin = mouseRay.origin - body.position; Vector3d relSurfacePosition; if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, body.Radius, out relSurfacePosition)) { Vector3d surfacePoint = body.position + relSurfacePosition; return(new Coordinates(body.GetLatitude(surfacePoint), MuUtils.ClampDegrees180(body.GetLongitude(surfacePoint)))); } else { return(null); } }
public override void OnUpdate() { if (picking_waypoint) { if (!HighLogic.LoadedSceneIsFlight || !MapView.MapIsEnabled) { // we left map without picking MessageManager.post_quick_message("Cancelled"); picking_waypoint = false; AtmosphereAutopilot.Instance.mainMenuGUIUpdate(); return; } // Thanks MechJeb! if (Input.GetMouseButtonDown(0) && !window.Contains(Input.mousePosition)) { Ray mouseRay = PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); Vector3d relOrigin = mouseRay.origin - vessel.mainBody.position; Vector3d relSurfacePosition; double curRadius = vessel.mainBody.pqsController.radiusMax; if (PQS.LineSphereIntersection(relOrigin, mouseRay.direction, curRadius, out relSurfacePosition)) { Vector3d surfacePoint = vessel.mainBody.position + relSurfacePosition; current_waypt.longitude = vessel.mainBody.GetLongitude(surfacePoint); current_waypt.latitude = vessel.mainBody.GetLatitude(surfacePoint); picking_waypoint = false; desired_latitude.Value = (float)current_waypt.latitude; desired_longitude.Value = (float)current_waypt.longitude; dist_to_dest = Vector3d.Distance(surfacePoint, vessel.ReferenceTransform.position); AtmosphereAutopilot.Instance.mainMenuGUIUpdate(); WaypointMode = true; MessageManager.post_quick_message("Picked"); } else { MessageManager.post_quick_message("Missed"); } } } else { if (Input.GetKeyDown(switch_key_mode)) { use_keys = !use_keys; MessageManager.post_status_message(use_keys ? "CF key input mode enabled" : "CF key input mode disabled"); } if (Input.GetKeyDown(vertical_control_key)) { vertical_control = !vertical_control; MessageManager.post_status_message(use_keys ? "Vertical motion control enabled" : "Vertical motion control disabled"); } if (Input.GetKeyDown(toggle_vertical_setpoint_type_key)) { AltitudeMode = !AltitudeMode; MessageManager.post_status_message(AltitudeMode ? "Altitude control" : "Vertical speed control"); } // input shenanigans if (use_keys && !FlightDriver.Pause && InputLockManager.IsUnlocked(ControlTypes.PITCH) && InputLockManager.IsUnlocked(ControlTypes.YAW)) { bool pitch_key_pressed = false; float pitch_change_sign = 0.0f; // Pitch if (GameSettings.PITCH_UP.GetKey() && !GameSettings.MODIFIER_KEY.GetKey()) { pitch_change_sign = 1.0f; pitch_key_pressed = true; } else if (GameSettings.PITCH_DOWN.GetKey() && !GameSettings.MODIFIER_KEY.GetKey()) { pitch_change_sign = -1.0f; pitch_key_pressed = true; } if (pitch_key_pressed) { if (height_mode == HeightMode.Altitude) { float setpoint = desired_altitude; float new_setpoint = setpoint + pitch_change_sign * hotkey_altitude_sens * Time.deltaTime * setpoint; desired_altitude.Value = new_setpoint; } else { float setpoint = desired_vertspeed; float magnetic_mult = Mathf.Abs(desired_vertspeed) < 10.0f ? 0.3f : 1.0f; float new_setpoint = setpoint + pitch_change_sign * hotkey_vertspeed_sens * Time.deltaTime * magnetic_mult; desired_vertspeed.Value = new_setpoint; } need_to_show_altitude = true; altitude_change_counter = 0.0f; AtmosphereAutopilot.Instance.mainMenuGUIUpdate(); } // Yaw (Course) bool yaw_key_pressed = false; float yaw_change_sign = 0.0f; if (GameSettings.YAW_RIGHT.GetKey() && !GameSettings.MODIFIER_KEY.GetKey()) { yaw_key_pressed = true; yaw_change_sign = 1.0f; } else if (GameSettings.YAW_LEFT.GetKey() && !GameSettings.MODIFIER_KEY.GetKey()) { yaw_key_pressed = true; yaw_change_sign = -1.0f; } if (yaw_key_pressed) { float setpoint = desired_course; float new_setpoint = setpoint + yaw_change_sign * hotkey_course_sens * Time.deltaTime; if (new_setpoint > 360.0f) { new_setpoint -= 360.0f; } if (new_setpoint < 0.0f) { new_setpoint = 360.0f + new_setpoint; } desired_course.Value = new_setpoint; need_to_show_course = true; course_change_counter = 0.0f; } if (need_to_show_course) { course_change_counter += Time.deltaTime; } if (course_change_counter > 1.0f) { course_change_counter = 0; need_to_show_course = false; } if (need_to_show_altitude) { altitude_change_counter += Time.deltaTime; if (height_mode == HeightMode.VerticalSpeed && altitude_change_counter > 0.2f) { if (Mathf.Abs(desired_vertspeed) < hotkey_vertspeed_snap) { desired_vertspeed.Value = 0.0f; } } } if (altitude_change_counter > 1.0f) { altitude_change_counter = 0; need_to_show_altitude = false; } } else { need_to_show_altitude = false; altitude_change_counter = 0; need_to_show_course = false; course_change_counter = 0; } } }
public void OnGUI() { if (Event.current.type == EventType.MouseDown) { PluginLogger.logDebug("OnGUI"); PluginLogger.logDebug("removing old"); removeGameObject("MouseRayLine"); Camera camera = Camera.main; Ray mouseRay; Vector3 worldStart; Vector3 worldDirection; if (MapView.MapIsEnabled) { body = Planetarium.fetch.CurrentMainBody; camera = PlanetariumCamera.Camera; mouseRay = camera.ScreenPointToRay(Input.mousePosition); mouseRay.origin = mouseRay.origin; PluginLogger.logDebug(mouseRay); Vector3 toDrawStart = mouseRay.origin; Vector3 toDrawEnd = mouseRay.origin + mouseRay.direction * (float)body.Radius; PluginLogger.logDebug(toDrawStart + "->" + toDrawEnd); PluginLogger.logDebug(ScaledSpace.LocalToScaledSpace(body.position)); GameObject lineObj = addGameObject(new GameObject("MouseRayLine")); lineObj.layer = 9; LineRenderer line = lineObj.AddComponent <LineRenderer>(); line.useWorldSpace = true; line.transform.localPosition = Vector3.zero; line.transform.localEulerAngles = Vector3.zero; // Make it render a red to yellow triangle, 1 meter wide and 2 meters long line.material = new Material(Shader.Find("Particles/Additive")); line.SetColors(Color.green, Color.red); line.SetWidth((float)10 / 1000 * PlanetariumCamera.fetch.Distance, (float)10 / 1000 * PlanetariumCamera.fetch.Distance); line.SetVertexCount(2); //line.SetPosition(0, ScaledSpace.LocalToScaledSpace(body.position + new Vector3(1, 0, 0) * (float)body.Radius *5)); //line.SetPosition(1, ScaledSpace.LocalToScaledSpace(body.position)); //line.SetPosition(0, toDrawStart); line.SetPosition(0, toDrawStart + new Vector3(0, -1, 0)); line.SetPosition(1, toDrawEnd); worldStart = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); worldDirection = mouseRay.direction; } else { //Input.mousePosition = new Vector2(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y) mouseRay = camera.ScreenPointToRay(Input.mousePosition); PluginLogger.logDebug(Input.mousePosition); PluginLogger.logDebug(camera.ScreenToWorldPoint(Event.current.mousePosition)); PluginLogger.logDebug(mouseRay); PluginLogger.logDebug(camera.transform.position); //mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); GameObject lineObj = addGameObject(new GameObject("MouseRayLine")); LineRenderer line = lineObj.AddComponent <LineRenderer>(); line.useWorldSpace = true; line.transform.localPosition = Vector3.zero; line.transform.localEulerAngles = Vector3.zero; // Make it render a red to yellow triangle, 1 meter wide and 2 meters long line.material = new Material(Shader.Find("Particles/Additive")); line.SetColors(Color.red, Color.red); line.SetWidth(1, 1); line.SetVertexCount(2); line.SetPosition(0, mouseRay.origin); line.SetPosition(1, mouseRay.origin + mouseRay.direction * 1000); worldStart = mouseRay.origin; worldDirection = mouseRay.direction; } Vector3d intersectionPoint = new Vector3d(); Vector3d bodyToMouse = worldStart - body.position; float radius = (float)body.pqsController.radiusMax; //if (body.pqsController.RayIntersection(worldStart, worldDirection, out intersectionPoint)) { if (PQS.LineSphereIntersection(bodyToMouse, mouseRay.direction, radius, out intersectionPoint)) { PluginLogger.logDebug("intersect!"); } else { PluginLogger.logDebug("No hit!"); } //mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin); } }