Skip to content

Commit 3c06940

Browse files
authored
Merge pull request #3198 from pleroy/InGame
Fix problems found in game
2 parents 581a644 + ae77982 commit 3c06940

5 files changed

+62
-12
lines changed

ksp_plugin/pile_up.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -612,12 +612,16 @@ absl::Status PileUp::AdvanceTime(Instant const& t) {
612612
// time we go through this function. It will be re-created as needed.
613613
fixed_instance_ = nullptr;
614614
// We make the |psychohistory_|, if any, authoritative, i.e. append it to
615-
// the end of the |history_|. We integrate on top of it, and it gets
616-
// appended authoritatively to the part tails.
615+
// the end of the |history_|. We integrate on top of it. Note how we skip
616+
// the first point of the psychohistory, which is already present in the
617+
// |trajectory_|.
617618
auto const psychohistory_trajectory =
618619
trajectory_.DetachSegments(psychohistory_);
619-
for (auto const& [time, degrees_of_freedom] : psychohistory_trajectory) {
620-
trajectory_.Append(time, degrees_of_freedom);
620+
CHECK(!psychohistory_trajectory.empty());
621+
for (auto it = std::next(psychohistory_trajectory.begin());
622+
it != psychohistory_trajectory.end();
623+
++it) {
624+
trajectory_.Append(it->time, it->degrees_of_freedom);
621625
}
622626

623627
auto const intrinsic_acceleration =

physics/discrete_traject0ry_body.hpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,23 @@ typename DiscreteTraject0ry<Frame>::SegmentIterator
207207
DiscreteTraject0ry<Frame>::AttachSegments(
208208
DiscreteTraject0ry&& trajectory) {
209209
CHECK(!trajectory.empty());
210-
// NOTE(phl): This check might be too strict, we might want to allow LT as the
211-
// time comparison, and to adjust the first point of trajectory as needed.
212-
// We'll see if the clients need that.
213-
CHECK_EQ(rbegin()->time, trajectory.begin()->time)
214-
<< "Mismatching times when attaching segments";
215-
CHECK_EQ(rbegin()->degrees_of_freedom, trajectory.begin()->degrees_of_freedom)
216-
<< "Mismatching degrees of freedom when attaching segments";
217210

218211
if (empty()) {
219212
*this = DiscreteTraject0ry(uninitialized);
213+
} else if (back().time == trajectory.front().time) {
214+
CHECK_EQ(back().degrees_of_freedom, trajectory.front().degrees_of_freedom)
215+
<< "Mismatching degrees of freedom when attaching segments";
216+
} else {
217+
// If the points are not matching, prepend a matching point to |trajectory|
218+
// and update the time-to-segment map.
219+
CHECK_LT(back().time, trajectory.front().time)
220+
<< "Mismatching times when attaching segments";
221+
trajectory.segments_->begin()->Prepend(back().time,
222+
back().degrees_of_freedom);
223+
auto const leit = trajectory.segment_by_left_endpoint_.cbegin();
224+
auto const sit = leit->second;
225+
trajectory.segment_by_left_endpoint_.erase(leit);
226+
trajectory.segment_by_left_endpoint_.emplace(back().time, sit);
220227
}
221228

222229
// The |end| iterator keeps pointing at the end after the splice. Instead,

physics/discrete_traject0ry_test.cpp

+27-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ TEST_F(DiscreteTraject0ryTest, DetachSegments) {
406406
}
407407
}
408408

409-
TEST_F(DiscreteTraject0ryTest, AttachSegments) {
409+
TEST_F(DiscreteTraject0ryTest, AttachSegmentsMatching) {
410410
auto trajectory1 = MakeTrajectory();
411411
auto trajectory2 = MakeTrajectory(
412412
t0_ + 14 * Second,
@@ -453,6 +453,32 @@ TEST_F(DiscreteTraject0ryTest, AttachSegments) {
453453
}
454454
}
455455

456+
TEST_F(DiscreteTraject0ryTest, AttachSegmentsMismatching) {
457+
auto trajectory1 = MakeTrajectory();
458+
auto trajectory2 = MakeTrajectory(
459+
t0_ + 15 * Second,
460+
DegreesOfFreedom<World>(
461+
World::origin + Displacement<World>({5 * Metre,
462+
5 * Metre,
463+
5 * Metre}),
464+
Velocity<World>({0 * Metre / Second,
465+
0 * Metre / Second,
466+
1 * Metre / Second})));
467+
trajectory1.AttachSegments(std::move(trajectory2));
468+
EXPECT_EQ(6, trajectory1.segments().size());
469+
EXPECT_EQ(t0_, trajectory1.begin()->time);
470+
EXPECT_EQ(t0_ + 29 * Second, trajectory1.rbegin()->time);
471+
472+
EXPECT_EQ(trajectory1.EvaluatePosition(t0_ + 14 * Second),
473+
World::origin + Displacement<World>({4 * Metre,
474+
4 * Metre,
475+
4 * Metre}));
476+
EXPECT_EQ(trajectory1.EvaluatePosition(t0_ + 15 * Second),
477+
World::origin + Displacement<World>({5 * Metre,
478+
5 * Metre,
479+
5 * Metre}));
480+
}
481+
456482
TEST_F(DiscreteTraject0ryTest, DeleteSegments) {
457483
auto trajectory = MakeTrajectory();
458484
auto const first_segment = trajectory.segments().begin();

physics/discrete_trajectory_segment.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ class DiscreteTrajectorySegment : public Trajectory<Frame> {
140140
// segments.
141141
void SetSelf(DiscreteTrajectorySegmentIterator<Frame> self);
142142

143+
void Prepend(Instant const& t,
144+
DegreesOfFreedom<Frame> const& degrees_of_freedom);
145+
143146
absl::Status Append(Instant const& t,
144147
DegreesOfFreedom<Frame> const& degrees_of_freedom);
145148

physics/discrete_trajectory_segment_body.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,16 @@ void DiscreteTrajectorySegment<Frame>::SetSelf(
318318
self_ = self;
319319
}
320320

321+
template<typename Frame>
322+
void DiscreteTrajectorySegment<Frame>::Prepend(
323+
Instant const& t,
324+
DegreesOfFreedom<Frame> const& degrees_of_freedom) {
325+
CHECK(!timeline_.empty() || t < timeline_.cbegin()->time)
326+
<< "Prepend out of order at " << t << ", first time is "
327+
<< timeline_.cbegin()->time;
328+
timeline_.emplace_hint(timeline_.cbegin(), t, degrees_of_freedom);
329+
}
330+
321331
template<typename Frame>
322332
absl::Status DiscreteTrajectorySegment<Frame>::Append(
323333
Instant const& t,

0 commit comments

Comments
 (0)