Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 14ee57622a10
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4de322598208
Choose a head ref
  • 14 commits
  • 7 files changed
  • 1 contributor

Commits on Nov 30, 2019

  1. prototyping

    eggrobin committed Nov 30, 2019
    Copy the full SHA
    55a6c97 View commit details

Commits on Dec 1, 2019

  1. Copy the full SHA
    638b245 View commit details

Commits on Dec 2, 2019

  1. CameraReference

    eggrobin committed Dec 2, 2019
    Copy the full SHA
    2193ad4 View commit details

Commits on Dec 6, 2019

  1. Copy the full SHA
    18a0d97 View commit details

Commits on Dec 7, 2019

  1. Copy the full SHA
    ab6000a View commit details
  2. Copy the full SHA
    08925aa View commit details
  3. remove traces, add comment

    eggrobin committed Dec 7, 2019
    Copy the full SHA
    38ee704 View commit details
  4. roll

    eggrobin committed Dec 7, 2019
    Copy the full SHA
    5f35d2c View commit details
  5. cleanup

    eggrobin committed Dec 7, 2019
    Copy the full SHA
    4327508 View commit details
  6. Copy the full SHA
    84678f8 View commit details
  7. a new tag

    eggrobin committed Dec 7, 2019
    Copy the full SHA
    c2d6ae8 View commit details
  8. better comment

    eggrobin committed Dec 7, 2019
    Copy the full SHA
    129ddd6 View commit details

Commits on Dec 8, 2019

  1. after pleroy's review

    eggrobin committed Dec 8, 2019
    Copy the full SHA
    7a75f59 View commit details
  2. Merge pull request #2393 from eggrobin/camera-rotation

    Camera rotation
    eggrobin authored Dec 8, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4de3225 View commit details
Showing with 146 additions and 3 deletions.
  1. +15 −2 ksp_plugin/frames.hpp
  2. +10 −0 ksp_plugin/interface_renderer.cpp
  3. +15 −0 ksp_plugin/renderer.cpp
  4. +4 −0 ksp_plugin/renderer.hpp
  5. +86 −0 ksp_plugin_adapter/ksp_plugin_adapter.cs
  6. +1 −0 serialization/geometry.proto
  7. +15 −1 serialization/journal.proto
17 changes: 15 additions & 2 deletions ksp_plugin/frames.hpp
Original file line number Diff line number Diff line change
@@ -43,7 +43,8 @@ using ApparentBubble = Frame<serialization::Frame::PluginTag,

// |Barycentric|, with its y and z axes swapped; the basis is left-handed.
using CelestialSphere = Frame<serialization::Frame::PluginTag,
serialization::Frame::CELESTIAL_SPHERE, true>;
serialization::Frame::CELESTIAL_SPHERE,
true>;

// The surface frame of a celestial, with the x axis pointing to the origin of
// latitude and longitude, the y axis pointing to the pole with positive
@@ -59,7 +60,18 @@ using Navball = Frame<serialization::Frame::PluginTag,
// The frame used for trajectory plotting and manœuvre planning. Its definition
// depends on the choice of a subclass of DynamicFrame.
using Navigation = Frame<serialization::Frame::PluginTag,
serialization::Frame::NAVIGATION, false>;
serialization::Frame::NAVIGATION,
false>;

// The plotting frame, but with the y and z axes swapped compared to
// |Navigation| (the basis is left-handed). This frame defines the camera
// horizontal, and its angular velocity defines the angular velocity of the
// camera (note that the linear motion of the camera is defined in-game by
// following a specific target, which may be in motion with respect to
// |CameraReference|, so the camera is not necessarily at rest in that frame).
using CameraReference = Frame<serialization::Frame::PluginTag,
serialization::Frame::CAMERA_REFERENCE,
false>;

// A nonrotating referencence frame comoving with the sun with the same axes as
// |AliceWorld|. Since it is nonrotating (though not inertial), differences
@@ -104,6 +116,7 @@ using internal_frames::ApparentBubble;
using internal_frames::Barycentric;
using internal_frames::BodyWorld;
using internal_frames::Camera;
using internal_frames::CameraReference;
using internal_frames::CelestialSphere;
using internal_frames::MainBodyCentred;
using internal_frames::Navball;
10 changes: 10 additions & 0 deletions ksp_plugin/interface_renderer.cpp
Original file line number Diff line number Diff line change
@@ -137,5 +137,15 @@ void __cdecl principia__SetTargetVessel(Plugin* const plugin,
return m.Return();
}

WXYZ __cdecl principia__CameraReferenceRotation(Plugin* const plugin) {
journal::Method<journal::CameraReferenceRotation> m({plugin});
CHECK_NOTNULL(plugin);
return m.Return(
ToWXYZ(GetRenderer(plugin)
.CameraReferenceRotation(plugin->CurrentTime(),
plugin->PlanetariumRotation())
.quaternion()));
}

} // namespace interface
} // namespace principia
15 changes: 15 additions & 0 deletions ksp_plugin/renderer.cpp
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ namespace internal_renderer {

using base::make_not_null_unique;
using geometry::AngularVelocity;
using geometry::Permutation;
using geometry::RigidTransformation;
using geometry::Vector;
using geometry::Velocity;
@@ -265,6 +266,20 @@ RigidTransformation<World, Navigation> Renderer::WorldToPlotting(
WorldToBarycentric(time, sun_world_position, planetarium_rotation);
}

Rotation<CameraReference, World> Renderer::CameraReferenceRotation(
Instant const& time,
Rotation<Barycentric, AliceSun> const& planetarium_rotation) const {
Permutation<CameraReference, Navigation> const celestial_mirror(
Permutation<CameraReference, Navigation>::XZY);
auto const result =
OrthogonalMap<WorldSun, World>::Identity() *
sun_looking_glass.Inverse().Forget() * planetarium_rotation.Forget() *
plotting_frame_->FromThisFrameAtTime(time).orthogonal_map() *
celestial_mirror.Forget();
CHECK(result.Determinant().is_positive());
return result.rotation();
}

void Renderer::WriteToMessage(
not_null<serialization::Renderer*> message) const {
plotting_frame_->WriteToMessage(message->mutable_plotting_frame());
4 changes: 4 additions & 0 deletions ksp_plugin/renderer.hpp
Original file line number Diff line number Diff line change
@@ -159,6 +159,10 @@ class Renderer {
Position<World> const& sun_world_position,
Rotation<Barycentric, AliceSun> const& planetarium_rotation) const;

virtual Rotation<CameraReference, World> CameraReferenceRotation(
Instant const& time,
Rotation<Barycentric, AliceSun> const& planetarium_rotation) const;

virtual void WriteToMessage(not_null<serialization::Renderer*> message) const;

static not_null<std::unique_ptr<Renderer>> ReadFromMessage(
86 changes: 86 additions & 0 deletions ksp_plugin_adapter/ksp_plugin_adapter.cs
Original file line number Diff line number Diff line change
@@ -83,6 +83,18 @@ internal IntPtr Plugin() {

private bool time_is_advancing_;

// True if a discontinuous change to the camera reference rotation occurred
// (due to a change in plotting frame), in which case we need special handling
// to keep the motion of the camera continuous.
bool should_transfer_camera_coordinates_ = false;
// The camera reference rotation applied during the previous frame; this is
// used when transfering camera coordinates to preserve continuity.
UnityEngine.QuaternionD previous_camera_reference_rotation_;
// The roll of the camera; this is set when transferring camera coordinates to
// preserve continuity of orientation, and gradually brought down to 0 so that
// the camera is horizontal in the new reference frame.
double camera_roll_ = 0;

private RenderingActions map_renderer_;
private RenderingActions galaxy_cube_rotator_;

@@ -690,6 +702,72 @@ private void OnGUI() {
}
}

private void OrientPlanetariumCamera() {
const double degree = Math.PI / 180;
var reference_rotation =
(UnityEngine.QuaternionD)plugin_.CameraReferenceRotation();
var camera_roll = UnityEngine.QuaternionD.AngleAxis(camera_roll_ / degree,
Vector3d.forward);
if (should_transfer_camera_coordinates_) {
UnityEngine.QuaternionD previous_referenced_pivot =
previous_camera_reference_rotation_ *
(UnityEngine.QuaternionD)PlanetariumCamera.fetch.GetPivot().rotation *
camera_roll;
// Note that we use a single-precision quaternion here because the
// double-precision one that comes with KSP does not implement Euler
// angles.
UnityEngine.Quaternion new_dereferenced_pivot =
UnityEngine.QuaternionD.Inverse(reference_rotation) *
previous_referenced_pivot;
double new_heading = (new_dereferenced_pivot.eulerAngles.y -
Planetarium.InverseRotAngle) * degree;
double new_pitch = new_dereferenced_pivot.eulerAngles.x * degree;
// The camera cannot be given nonzero roll by camera controls, but we
// smoothly bring its roll to 0 over the course of a few frames to make
// the change in orientation continuous, and thus easier to follow:
// instantly flipping can be confusing if it is a large change, e.g. Earth
// equator to Uranus equator.
camera_roll_ =
((new_dereferenced_pivot.eulerAngles.z + 180) % 360 - 180) * degree;
// Unity has a very mad Euler angle convention that has pitch in
// [0, π/2] ∪ [3π/2, 2π].
if (new_pitch > Math.PI) {
new_pitch -= 2 * Math.PI;
}
PlanetariumCamera.fetch.camHdg = (float)new_heading;
PlanetariumCamera.fetch.camPitch = (float)new_pitch;
// Use the old reference rotation for this frame: since the change to
// camera heading and pitch has yet to take effect, the new one would
// result in a weird orientation for one frame. Similarly, we keep the
// existing |camera_roll|.
reference_rotation = previous_camera_reference_rotation_;
should_transfer_camera_coordinates_ = false;
}
previous_camera_reference_rotation_ = reference_rotation;
PlanetariumCamera.fetch.GetPivot().rotation =
reference_rotation *
(UnityEngine.QuaternionD)PlanetariumCamera.fetch.GetPivot().rotation *
camera_roll;
// The galaxy camera also renders the galaxy cube outside map view; it
// should not be rotated there.
if (MapView.MapIsEnabled) {
ScaledCamera.Instance.galaxyCamera.transform.rotation =
reference_rotation *
(UnityEngine.QuaternionD)ScaledCamera.Instance.galaxyCamera.transform.rotation *
camera_roll;
}
if (camera_roll_ != 0) {
// TODO(egg): Should we be doing this in LateUpdate?
const double roll_change_per_frame = 0.1 /*radians*/;
if (Math.Abs(camera_roll_) < roll_change_per_frame) {
camera_roll_ = 0;
} else {
camera_roll_ += camera_roll_ > 0 ? -roll_change_per_frame
: roll_change_per_frame;
}
}
}

private void LateUpdate() {
if (map_renderer_ == null) {
map_renderer_ =
@@ -1412,6 +1490,9 @@ private void BetterLateThanNever() {
}

private void BetterLateThanNeverLateUpdate() {
// We need to correct the orientation of the cameras after KSP has set it
// (and before we update the map nodes below).
OrientPlanetariumCamera();
// While we draw the trajectories directly (and thus do so after everything
// else has been rendered), we rely on the game to render its map nodes.
// Since the screen position is determined in |MapNode.NodeUpdate|, it must
@@ -1435,6 +1516,10 @@ private void BetterLateThanNeverLateUpdate() {
RenderFlightPlanMarkers(main_vessel_guid, sun_world_position);
}
}
foreach (var node in KSP.UI.Screens.Mapview.MapNode.AllMapNodes) {
node.NodeUpdate();
}
// TODO(egg): redundant NodeUpdate calls.
map_node_pool_.Update();
}

@@ -2127,6 +2212,7 @@ private void UpdateRenderingFrame(
}
navball_changed_ = true;
reset_rsas_target_ = true;
should_transfer_camera_coordinates_ = true;
}

private static void InitializeIntegrators(
1 change: 1 addition & 0 deletions serialization/geometry.proto
Original file line number Diff line number Diff line change
@@ -145,6 +145,7 @@ message Frame {
BODY_WORLD = 9;
// BUBBLE = 13;
CAMERA = 14;
CAMERA_REFERENCE = 17;
CELESTIAL_SPHERE = 8;
MAIN_BODY_CENTRED = 15;
NAVBALL = 10;
16 changes: 15 additions & 1 deletion serialization/journal.proto
Original file line number Diff line number Diff line change
@@ -213,7 +213,7 @@ message OrbitAnalysis {
}

message Method {
extensions 5000 to 5999; // Last used: 5162.
extensions 5000 to 5999; // Last used: 5163.
}

message AdvanceTime {
@@ -228,6 +228,20 @@ message AdvanceTime {
optional In in = 1;
}

message CameraReferenceRotation {
extend Method {
optional CameraReferenceRotation extension = 5163;
}
message In {
required fixed64 plugin = 1 [(pointer_to) = "Plugin", (is_subject) = true];
}
message Return {
required WXYZ result = 1;
}
optional In in = 1;
optional Return return = 3;
}

message CatchUpLaggingVessels {
extend Method {
optional CatchUpLaggingVessels extension = 5120;