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: 3589181ddee0
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bb5029fa2c19
Choose a head ref
  • 9 commits
  • 9 files changed
  • 1 contributor

Commits on Feb 25, 2020

  1. New part constructor.

    pleroy committed Feb 25, 2020
    Copy the full SHA
    a7d83e5 View commit details
  2. loaded_ bit.

    pleroy committed Feb 25, 2020
    Copy the full SHA
    9bde730 View commit details
  3. Expose PartIsLoaded.

    pleroy committed Feb 25, 2020
    Copy the full SHA
    1690e00 View commit details

Commits on Feb 26, 2020

  1. Copy the full SHA
    160541c View commit details
  2. Format.

    pleroy committed Feb 26, 2020
    Copy the full SHA
    1166c50 View commit details
  3. Copy the full SHA
    c4e0de4 View commit details
  4. Save the loaded_ bit.

    pleroy committed Feb 26, 2020
    Copy the full SHA
    26a6b63 View commit details
  5. Truthfulness.

    pleroy committed Feb 26, 2020
    Copy the full SHA
    076e30f View commit details
  6. Merge pull request #2483 from pleroy/UnloadedPart

    Fix the handling of unloaded parts to prevent vessels exploding on "set orbit"
    pleroy authored Feb 26, 2020
    Copy the full SHA
    bb5029f View commit details
4 changes: 4 additions & 0 deletions Principia.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -86,6 +86,10 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_BINARY_EXPRESSIONS/@EntryValue">WRAP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">80</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/ProtobufCodeFormatting/INDENT_SIZE/@EntryValue">2</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/ProtobufCodeFormatting/TAB_WIDTH/@EntryValue">2</s:Int64>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/ProtobufCodeFormatting/USE_INDENT_FROM_VS/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/ProtobufCodeFormatting/WRAP_LIMIT/@EntryValue">80</s:Int64>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseVarWhenEvident</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVarWhenEvident</s:String>
9 changes: 9 additions & 0 deletions ksp_plugin/interface_part.cpp
Original file line number Diff line number Diff line change
@@ -99,6 +99,15 @@ QPRW __cdecl principia__PartGetActualDegreesOfFreedom(
ToXYZ(part_angular_velocity.coordinates() / (Radian / Second))});
}

bool __cdecl principia__PartIsTruthful(
Plugin const* const plugin,
uint32_t const part_id) {
journal::Method<journal::PartIsTruthful> m({plugin, part_id});
CHECK_NOTNULL(plugin);
return m.Return(plugin->PartIsTruthful(part_id));
}


void __cdecl principia__PartSetApparentRigidMotion(
Plugin* const plugin,
PartId const part_id,
92 changes: 67 additions & 25 deletions ksp_plugin/part.cpp
Original file line number Diff line number Diff line change
@@ -32,25 +32,34 @@ using quantities::si::Kilogram;
using quantities::si::Metre;
using quantities::si::Radian;

Part::Part(
PartId const part_id,
std::string const& name,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion,
std::function<void()> deletion_callback)
: part_id_(part_id),
name_(name),
mass_(mass),
inertia_tensor_(inertia_tensor),
rigid_motion_(rigid_motion),
prehistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
subset_node_(make_not_null_unique<Subset<Part>::Node>()),
deletion_callback_(std::move(deletion_callback)) {
prehistory_->Append(astronomy::InfinitePast,
{Barycentric::origin, Barycentric::unmoving});
history_ = prehistory_->NewForkAtLast();
}
constexpr Mass untruthful_part_mass = 1 * Kilogram;

Part::Part(PartId const part_id,
std::string const& name,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion,
std::function<void()> deletion_callback)
: Part(part_id,
name,
/*truthful=*/true,
mass,
inertia_tensor,
rigid_motion,
std::move(deletion_callback)) {}

Part::Part(PartId part_id,
std::string const& name,
DegreesOfFreedom<Barycentric> const& degrees_of_freedom,
std::function<void()> deletion_callback)
: Part(part_id,
name,
/*truthful=*/false,
untruthful_part_mass,
MakeWaterSphereInertiaTensor(untruthful_part_mass),
RigidMotion<RigidPart, Barycentric>::MakeNonRotatingMotion(
degrees_of_freedom),
std::move(deletion_callback)) {}

Part::~Part() {
LOG(INFO) << "Destroying part " << ShortDebugString();
@@ -63,6 +72,14 @@ PartId Part::part_id() const {
return part_id_;
}

bool Part::truthful() const {
return truthful_;
}

void Part::make_truthful() {
truthful_ = true;
}

void Part::set_mass(Mass const& mass) {
mass_change_ = mass - mass_;
mass_ = mass;
@@ -210,6 +227,7 @@ void Part::WriteToMessage(not_null<serialization::Part*> const message,
serialization_index_for_pile_up) const {
message->set_part_id(part_id_);
message->set_name(name_);
message->set_truthful(truthful_);
mass_.WriteToMessage(message->mutable_mass());
inertia_tensor_.WriteToMessage(message->mutable_inertia_tensor());
intrinsic_force_.WriteToMessage(message->mutable_intrinsic_force());
@@ -238,33 +256,36 @@ not_null<std::unique_ptr<Part>> Part::ReadFromMessage(
auto const degrees_of_freedom =
DegreesOfFreedom<Barycentric>::ReadFromMessage(
message.degrees_of_freedom());
part = make_not_null_unique<Part>(
part = std::unique_ptr<Part>(new Part(
message.part_id(),
message.name(),
message.truthful(),
Mass::ReadFromMessage(message.mass()),
MakeWaterSphereInertiaTensor(Mass::ReadFromMessage(message.mass())),
RigidMotion<RigidPart, Barycentric>::MakeNonRotatingMotion(
degrees_of_freedom),
std::move(deletion_callback));
std::move(deletion_callback)));
} else if (is_pre_frenet) {
part = make_not_null_unique<Part>(
part = std::unique_ptr<Part>(new Part(
message.part_id(),
message.name(),
message.truthful(),
Mass::ReadFromMessage(message.pre_frenet_inertia_tensor().mass()),
InertiaTensor<RigidPart>::ReadFromMessage(
message.pre_frenet_inertia_tensor().form()),
RigidMotion<RigidPart, Barycentric>::ReadFromMessage(
message.rigid_motion()),
std::move(deletion_callback));
std::move(deletion_callback)));
} else {
part = make_not_null_unique<Part>(
part = std::unique_ptr<Part>(new Part(
message.part_id(),
message.name(),
message.truthful(),
Mass::ReadFromMessage(message.mass()),
InertiaTensor<RigidPart>::ReadFromMessage(message.inertia_tensor()),
RigidMotion<RigidPart, Barycentric>::ReadFromMessage(
message.rigid_motion()),
std::move(deletion_callback));
std::move(deletion_callback)));
}

part->apply_intrinsic_force(
@@ -317,6 +338,27 @@ std::string Part::ShortDebugString() const {
return name_ + " (" + hex_id.data.get() + ")";
}

Part::Part(PartId const part_id,
std::string const& name,
bool const truthful,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion,
std::function<void()> deletion_callback)
: part_id_(part_id),
name_(name),
truthful_(truthful),
mass_(mass),
inertia_tensor_(inertia_tensor),
rigid_motion_(rigid_motion),
prehistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
subset_node_(make_not_null_unique<Subset<Part>::Node>()),
deletion_callback_(std::move(deletion_callback)) {
prehistory_->Append(astronomy::InfinitePast,
{Barycentric::origin, Barycentric::unmoving});
history_ = prehistory_->NewForkAtLast();
}

InertiaTensor<RigidPart> MakeWaterSphereInertiaTensor(Mass const& mass) {
static constexpr MomentOfInertia zero;
static constexpr Density ρ_of_water = 1000 * Kilogram / Pow<3>(Metre);
19 changes: 19 additions & 0 deletions ksp_plugin/part.hpp
Original file line number Diff line number Diff line change
@@ -43,19 +43,29 @@ using quantities::Torque;
// Represents a KSP part.
class Part final {
public:
// A truthful part.
Part(PartId part_id,
std::string const& name,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion,
std::function<void()> deletion_callback);

// An untruthful part.
Part(PartId part_id,
std::string const& name,
DegreesOfFreedom<Barycentric> const& degrees_of_freedom,
std::function<void()> deletion_callback);

// Calls the deletion callback passed at construction, if any. This part must
// not be piled up.
~Part();

PartId part_id() const;

bool truthful() const;
void make_truthful();

// Sets or returns the mass and inertia tensor. Even though a part is
// massless in the sense that it doesn't exert gravity, it has a mass and an
// inertia used to determine its intrinsic acceleration and rotational
@@ -146,8 +156,17 @@ class Part final {
std::string ShortDebugString() const;

private:
Part(PartId part_id,
std::string const& name,
bool truthful,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion,
std::function<void()> deletion_callback);

PartId const part_id_;
std::string const name_;
bool truthful_;
Mass mass_;
Mass mass_change_;
InertiaTensor<RigidPart> inertia_tensor_;
34 changes: 16 additions & 18 deletions ksp_plugin/plugin.cpp
Original file line number Diff line number Diff line change
@@ -106,7 +106,6 @@ using quantities::Infinity;
using quantities::Length;
using quantities::MomentOfInertia;
using quantities::SIUnit;
using quantities::si::Kilogram;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Radian;
@@ -418,14 +417,7 @@ void Plugin::InsertUnloadedPart(
DegreesOfFreedom<Barycentric> const degrees_of_freedom =
vessel->parent()->current_degrees_of_freedom(current_time_) + relative;

Mass const mass = 1 * Kilogram;
AddPart(vessel,
part_id,
name,
mass,
MakeWaterSphereInertiaTensor(mass),
RigidMotion<RigidPart, Barycentric>::MakeNonRotatingMotion(
degrees_of_freedom));
AddPart(vessel, part_id, name, degrees_of_freedom);
// NOTE(egg): we do not keep the part; it may disappear just as we load, if
// it happens to be a part with no physical significance (rb == null).
}
@@ -484,12 +476,13 @@ void Plugin::InsertOrKeepLoadedPart(
}
vessel->KeepPart(part_id);
not_null<Part*> part = vessel->part(part_id);
part->make_truthful();
part->set_mass(mass);
part->set_inertia_tensor(inertia_tensor);
}

void Plugin::ApplyPartIntrinsicForce(PartId const part_id,
Vector<Force, World> const& force) {
Vector<Force, World> const& force) const {
CHECK(!initializing_);
not_null<Vessel*> const vessel = FindOrDie(part_id_to_vessel_, part_id);
CHECK(is_loaded(vessel));
@@ -501,7 +494,7 @@ void Plugin::ApplyPartIntrinsicForceAtPosition(
PartId const part_id,
Vector<Force, World> const& force,
Position<World> const& point_of_force_application,
Position<World> const& part_position) {
Position<World> const& part_position) const {
CHECK(!initializing_);
not_null<Vessel*> const vessel = FindOrDie(part_id_to_vessel_, part_id);
CHECK(is_loaded(vessel));
@@ -514,14 +507,22 @@ void Plugin::ApplyPartIntrinsicForceAtPosition(

void Plugin::ApplyPartIntrinsicTorque(
PartId const part_id,
Bivector<Torque, World> const& torque) {
Bivector<Torque, World> const& torque) const {
CHECK(!initializing_);
not_null<Vessel*> const vessel = FindOrDie(part_id_to_vessel_, part_id);
CHECK(is_loaded(vessel));
vessel->part(part_id)->apply_intrinsic_torque(
renderer_->WorldToBarycentric(PlanetariumRotation())(torque));
}

bool Plugin::PartIsTruthful(PartId const part_id) const {
auto const it = part_id_to_vessel_.find(part_id);
if (it == part_id_to_vessel_.end()) {
return false;
}
return it->second->part(part_id)->truthful();
}

void Plugin::PrepareToReportCollisions() {
for (auto const& [_, vessel] : vessels_) {
// NOTE(egg): The lifetime requirement on the second argument of
@@ -1544,22 +1545,19 @@ void Plugin::ReadCelestialsFromMessages(
}
}

template<typename... Args>
void Plugin::AddPart(not_null<Vessel*> const vessel,
PartId const part_id,
std::string const& name,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion) {
Args... args) {
auto const [it, inserted] = part_id_to_vessel_.emplace(part_id, vessel);
CHECK(inserted) << NAMED(part_id);
auto deletion_callback = [it = it, &map = part_id_to_vessel_] {
map.erase(it);
};
auto part = make_not_null_unique<Part>(part_id,
name,
mass,
inertia_tensor,
rigid_motion,
std::forward<Args>(args)...,
std::move(deletion_callback));
vessel->AddPart(std::move(part));
}
17 changes: 9 additions & 8 deletions ksp_plugin/plugin.hpp
Original file line number Diff line number Diff line change
@@ -217,15 +217,17 @@ class Plugin {
// relevant part, which must be in a loaded vessel.
virtual void ApplyPartIntrinsicForce(
PartId part_id,
Vector<Force, World> const& force);
Vector<Force, World> const& force) const;
virtual void ApplyPartIntrinsicForceAtPosition(
PartId part_id,
Vector<Force, World> const& force,
Position<World> const& point_of_force_application,
Position<World> const& part_position);
Position<World> const& part_position) const;
virtual void ApplyPartIntrinsicTorque(
PartId part_id,
Bivector<Torque, World> const& torque);
Bivector<Torque, World> const& torque) const;

virtual bool PartIsTruthful(PartId part_id) const;

// Calls |MakeSingleton| for all parts in loaded vessels, enabling the use of
// union-find for pile up construction. This must be called after the calls
@@ -472,14 +474,13 @@ class Plugin {
IndexToOwnedCelestial& celestials,
std::map<std::string, Index>& name_to_index);

// Adds a part to a vessel, recording it in the appropriate map and setting up
// a deletion callback.
// Constructs a part using the constructor arguments, and add it to a vessel,
// recording it in the appropriate map and setting up a deletion callback.
template<typename... Args>
void AddPart(not_null<Vessel*> vessel,
PartId part_id,
std::string const& name,
Mass const& mass,
InertiaTensor<RigidPart> const& inertia_tensor,
RigidMotion<RigidPart, Barycentric> const& rigid_motion);
Args... args);

// Whether |loaded_vessels_| contains |vessel|.
bool is_loaded(not_null<Vessel*> vessel) const;
Loading