Skip to content

Commit

Permalink
Merge branch 'master' into ForkedPrediction
Browse files Browse the repository at this point in the history
  • Loading branch information
pleroy committed Sep 21, 2017
2 parents a548d22 + 6c7b951 commit 62b98b7
Show file tree
Hide file tree
Showing 18 changed files with 185 additions and 405 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ ifeq ($(UNAME_S),Linux)
SHAREDFLAG := -shared
endif
ifeq ($(UNAME_S),Darwin)
SHARED_ARGS += -mmacosx-version-min=10.7 -arch x86_64
SHARED_ARGS += -mmacosx-version-min=10.8 -arch x86_64
MDTOOL ?= "/Applications/Xamarin Studio.app/Contents/MacOS/mdtool"
SHAREDFLAG := -dynamiclib
endif
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Principia

**[Cesàro](https://github.com/mockingbirdnest/Principia/wiki/Change-Log#ces%C3%A0ro), the September version of Principia, is available. It has performance improvements and bug fixes and supports both 1.2.2 and 1.3. Download it [here for 1.2.2](https://goo.gl/8B3Qfm) and [here for 1.3](https://goo.gl/feQStR).**

Principia is a mod for Kerbal Space Program (KSP) which implements N-body and extended body gravitation. Instead of being within the sphere of influence of a single celestial body at any point in time, your vessels are influenced by all the celestials. This makes it possible to implement missions that are more complex and more realistic than in the stock game, especially if used in conjunction with a mod like RealSolarSystem which has real-life celestials.

N-body gravitation is more complex than the toy physics of the stock game. Therefore, before using the mod we recommend that you read the [concepts](https://github.com/mockingbirdnest/Principia/wiki/Concepts) document which explains the most important parts of Principia. In particular, you should learn about the [plotting frame](https://github.com/mockingbirdnest/Principia/wiki/Concepts#plotting-frame) and [flight planning](https://github.com/mockingbirdnest/Principia/wiki/Concepts#flight-planning).
Expand All @@ -14,4 +16,4 @@ The [change log](https://github.com/mockingbirdnest/Principia/wiki/Change-Log) g

Principia is released on every [new moon](https://en.wikipedia.org/wiki/New_moon) with whatever features and bug fixes are ready at the time. This ensures relatively timely improvements and bug fixes.

Download the binary (Ubuntu, macOS, and Windows) [here for 1.2.2](https://goo.gl/pGjxXw), [here for 1.3](https://goo.gl/ycMXJz) or, if you don't trust our binary, build the mod from the [Чебышёв](https://github.com/mockingbirdnest/Principia/releases/tag/2017082119-Чебышёв) release.
Download the binary (Ubuntu, macOS, and Windows) [here for 1.2.2](https://goo.gl/8B3Qfm), [here for 1.3](https://goo.gl/feQStR) or, if you don't trust our binary, build the mod from the [Cesàro](https://github.com/mockingbirdnest/Principia/releases/tag/2017092006-Ces%C3%A0ro) release.
5 changes: 5 additions & 0 deletions base/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ inline void noreturn() { std::exit(0); }
# define UNICODE_PATH(x) u8 ## x
#endif

// Mutex.
#if !OS_MACOSX
# define HAS_SHARED_MUTEX 1
#endif

#define NAMED(expression) #expression << ": " << (expression)

// A macro to allow glog checking within C++11 constexpr code. If |condition|
Expand Down
19 changes: 19 additions & 0 deletions base/shared_lock_guard.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
#pragma once

#include "base/macros.hpp"
#include "base/not_null.hpp"

#if HAS_SHARED_MUTEX
#include <shared_mutex>
#else
#include <mutex>
#endif

namespace principia {
namespace base {

#if HAS_SHARED_MUTEX

using shared_mutex = std::shared_mutex;

// A helper class that the language designer didn't think useful of providing.
template<typename Mutex>
class shared_lock_guard final {
Expand All @@ -16,6 +27,14 @@ class shared_lock_guard final {
not_null<Mutex*> const mutex_;
};

#else

using shared_mutex = std::mutex;
template<typename Mutex>
using shared_lock_guard = std::lock_guard<Mutex>;

#endif

} // namespace base
} // namespace principia

Expand Down
6 changes: 4 additions & 2 deletions base/shared_lock_guard_body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace principia {
namespace base {

#if HAS_SHARED_MUTEX

template<typename Mutex>
shared_lock_guard<Mutex>::shared_lock_guard(Mutex& mutex) : mutex_(&mutex) {
mutex_->lock_shared();
Expand All @@ -15,7 +17,7 @@ shared_lock_guard<Mutex>::~shared_lock_guard() {
mutex_->unlock_shared();
}

#endif

} // namespace base
} // namespace principia

#include "base/shared_lock_guard_body.hpp"
40 changes: 0 additions & 40 deletions ksp_plugin/interface_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,6 @@ NavigationFrame const* principia__GetPlottingFrame(Plugin const* const plugin) {
return m.Return(GetRenderer(plugin).GetPlottingFrame());
}

Iterator* principia__RenderedPrediction(Plugin* const plugin,
char const* const vessel_guid,
XYZ const sun_world_position) {
journal::Method<journal::RenderedPrediction> m({plugin,
vessel_guid,
sun_world_position});
CHECK_NOTNULL(plugin);
auto const& prediction = plugin->GetVessel(vessel_guid)->prediction();
auto rendered_trajectory =
GetRenderer(plugin).RenderBarycentricTrajectoryInWorld(
plugin->CurrentTime(),
prediction.Begin(),
prediction.End(),
FromXYZ<Position<World>>(sun_world_position),
plugin->PlanetariumRotation());
return m.Return(new TypedIterator<DiscreteTrajectory<World>>(
std::move(rendered_trajectory),
plugin));
}

void principia__RenderedPredictionApsides(Plugin const* const plugin,
char const* const vessel_guid,
int const celestial_index,
Expand Down Expand Up @@ -136,26 +116,6 @@ void principia__RenderedPredictionNodes(Plugin const* const plugin,
return m.Return();
}

Iterator* principia__RenderedVesselTrajectory(Plugin const* const plugin,
char const* const vessel_guid,
XYZ const sun_world_position) {
journal::Method<journal::RenderedVesselTrajectory> m({plugin,
vessel_guid,
sun_world_position});
CHECK_NOTNULL(plugin);
auto const& psychohistory = plugin->GetVessel(vessel_guid)->psychohistory();
auto rendered_trajectory =
GetRenderer(plugin).RenderBarycentricTrajectoryInWorld(
plugin->CurrentTime(),
psychohistory.Begin(),
psychohistory.End(),
FromXYZ<Position<World>>(sun_world_position),
plugin->PlanetariumRotation());
return m.Return(new TypedIterator<DiscreteTrajectory<World>>(
std::move(rendered_trajectory),
plugin));
}

// |navigation_frame| must not be null. No transfer of ownership of
// |*navigation_frame|, takes ownership of |**navigation_frame|, nulls
// |*navigation_frame|.
Expand Down
6 changes: 3 additions & 3 deletions ksp_plugin/interface_vessel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ void principia__VesselSetPredictionAdaptiveStepParameters(
journal::Method<journal::VesselSetPredictionAdaptiveStepParameters> m(
{plugin, vessel_guid, adaptive_step_parameters});
CHECK_NOTNULL(plugin);
plugin->GetVessel(vessel_guid)
->set_prediction_adaptive_step_parameters(
FromAdaptiveStepParameters(adaptive_step_parameters));
plugin->SetPredictionAdaptiveStepParameters(
vessel_guid,
FromAdaptiveStepParameters(adaptive_step_parameters));
return m.Return();
}

Expand Down
16 changes: 16 additions & 0 deletions ksp_plugin/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,22 @@ RelativeDegreesOfFreedom<AliceSun> Plugin::CelestialFromParent(
return result;
}

void Plugin::SetPredictionAdaptiveStepParameters(
GUID const& vessel_guid,
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters) const {
// If there is a target vessel, it is integrated with the same parameters as
// the given (current) vessel. This makes it possible to plot the prediction
// of the current vessel.
if (renderer_->HasTargetVessel()) {
renderer_->GetTargetVessel().set_prediction_adaptive_step_parameters(
prediction_adaptive_step_parameters);
}
FindOrDie(vessels_, vessel_guid)
->set_prediction_adaptive_step_parameters(
prediction_adaptive_step_parameters);
}

void Plugin::UpdatePrediction(GUID const& vessel_guid) const {
CHECK(!initializing_);
FindOrDie(vessels_, vessel_guid)->FlowPrediction(InfiniteFuture);
Expand Down
5 changes: 5 additions & 0 deletions ksp_plugin/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ class Plugin {
virtual RelativeDegreesOfFreedom<AliceSun> CelestialFromParent(
Index celestial_index) const;

virtual void SetPredictionAdaptiveStepParameters(
GUID const& vessel_guid,
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters) const;

// Updates the prediction for the vessel with guid |vessel_guid|.
void UpdatePrediction(GUID const& vessel_guid) const;

Expand Down
90 changes: 1 addition & 89 deletions ksp_plugin_adapter/gl_lines.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,74 +19,20 @@ public static void Draw(Action line_vertices) {
line_material.SetPass(0);
UnityEngine.GL.LoadPixelMatrix();
UnityEngine.GL.Begin(UnityEngine.GL.LINES);
rendering_lines_ = true;

Vector3d camera = ScaledSpace.ScaledToLocalSpace(
PlanetariumCamera.Camera.transform.position);
// Only consider bodies with an angular radius greater than arcsin 1e-3.
// From the Earth, this would consider the Moon and the Sun, but ignore
// Jupiter. The map view camera is wide-angle, so this is probably
// overkill.
// In any case we just want to do that in native code reasonably soon, so
// this does the trick for now.
hiding_bodies_ =
(from body in FlightGlobals.Bodies
where body.Radius * body.Radius >
(body.position - camera).sqrMagnitude * 1e-6
select body).ToArray();

line_vertices();

hiding_bodies_ = null;

rendering_lines_ = false;
UnityEngine.GL.End();
UnityEngine.GL.PopMatrix();
} catch (Exception e) {
Log.Fatal("Exception while drawing lines: " + e.ToString());
}
}

private static bool IsHidden(Vector3d point) {
Vector3d camera = ScaledSpace.ScaledToLocalSpace(
PlanetariumCamera.Camera.transform.position);
foreach (CelestialBody body in hiding_bodies_) {
Vector3d camera_to_point = point - camera;
Vector3d camera_to_body = body.position - camera;
double inner_product = Vector3d.Dot(camera_to_point, camera_to_body);
double r_squared = body.Radius * body.Radius;
// The projections on the camera-body axis of |point| and of the horizon
// have lengths |inner_product| / d and d - r^2/d, where d is the distance
// between the camera and the body and r is the body's radius, thus if
// |inner_product| < d^2 - r^2, |point| is above the plane passing
// through the horizon.
// Otherwise, we check whether |point| is within the cone hidden from the
// camera, by comparing the squared cosines multiplied by
// d^2|camera_to_point|^2.
// In addition, we check whether we're inside the body (this covers the
// cap above the horizon plane and below the surface of the body, which
// would otherwise be displayed).
double d_squared_minus_r_squared =
camera_to_body.sqrMagnitude - r_squared;
if ((body.position - point).sqrMagnitude < r_squared ||
(inner_product > d_squared_minus_r_squared &&
inner_product * inner_product >
camera_to_point.sqrMagnitude * d_squared_minus_r_squared)) {
return true;
}
}
return false;
}

public static void AddSegment(Vector3d world_begin,
Vector3d world_end,
bool hide_behind_bodies) {
if (!rendering_lines_) {
Log.Fatal("|AddSegment| outside of |DrawLines|");
}
if (hide_behind_bodies && (IsHidden(world_begin) || IsHidden(world_end))) {
return;
}
Vector3d world_end) {
var begin = WorldToMapScreen(world_begin);
var end = WorldToMapScreen(world_end);
if (begin.z > 0 && end.z > 0) {
Expand All @@ -95,38 +41,6 @@ public static void AddSegment(Vector3d world_begin,
}
}

public static void RenderAndDeleteTrajectory(IntPtr trajectory_iterator,
UnityEngine.Color colour,
Style style) {
try {
Vector3d? previous_point = null;

UnityEngine.GL.Color(colour);
int size = trajectory_iterator.IteratorSize();

for (int i = 0;
!trajectory_iterator.IteratorAtEnd();
trajectory_iterator.IteratorIncrement(), ++i) {
Vector3d current_point =
(Vector3d)trajectory_iterator.IteratorGetDiscreteTrajectoryXYZ();
if (previous_point.HasValue) {
if (style == Style.FADED) {
colour.a = (float)(4 * i + size) / (float)(5 * size);
UnityEngine.GL.Color(colour);
}
if (style != Style.DASHED || i % 2 == 1) {
AddSegment(previous_point.Value,
current_point,
hide_behind_bodies : true);
}
}
previous_point = current_point;
}
} finally {
Interface.IteratorDelete(ref trajectory_iterator);
}
}

public static IntPtr NewPlanetarium(IntPtr plugin,
XYZ sun_world_position) {
UnityEngine.Camera camera = PlanetariumCamera.Camera;
Expand Down Expand Up @@ -242,8 +156,6 @@ private static XY ToScreen(XY rp2_point) {
0.5 * camera.pixelHeight};
}

private static bool rendering_lines_ = false;
private static CelestialBody[] hiding_bodies_;
private static UnityEngine.Material line_material_;
private static UnityEngine.Material line_material {
get {
Expand Down
Loading

0 comments on commit 62b98b7

Please sign in to comment.