Skip to content

Commit

Permalink
Merge pull request #3803 from pleroy/3230c
Browse files Browse the repository at this point in the history
Optimize the code in the adapter
  • Loading branch information
pleroy authored Nov 19, 2023
2 parents b9a621c + 3bc2fd8 commit be6820c
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 75 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ temp/
# Generated files
*.generated.*

# Unity
unity/

# Vagrant
.vagrant/

Expand Down
160 changes: 85 additions & 75 deletions ksp_plugin_adapter/ksp_plugin_adapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using KSP.Localization;

using static principia.ksp_plugin_adapter.FrameType;

namespace principia {
Expand Down Expand Up @@ -426,10 +424,14 @@ private void ApplyToBodyTree(BodyProcessor process_body) {
}

private void ApplyToVesselsOnRails(VesselProcessor process_vessel) {
// |process_vessels| may touch |Transform|s, so disable syncing.
UnityEngine.Physics.autoSyncTransforms = false;
foreach (Vessel vessel in FlightGlobals.Vessels.Where(
is_manageable_on_rails)) {
process_vessel(vessel);
}
UnityEngine.Physics.SyncTransforms();
UnityEngine.Physics.autoSyncTransforms = true;
}

private void UpdateBody(CelestialBody body, double universal_time) {
Expand Down Expand Up @@ -504,9 +506,19 @@ private void UpdateVessel(Vessel vessel, double universal_time) {
refBody : vessel.orbit.referenceBody,
UT : universal_time);
if (vessel.loaded) {
Part root_part = vessel.rootPart;
UnityEngine.Rigidbody root_part_rb = root_part.rb;
var origin = new Origin{
reference_part_is_at_origin = true,
reference_part_is_unmoving = true,
main_body_centre_in_world =
(XYZ)FlightGlobals.ActiveVessel.mainBody.position,
reference_part_id = root_part.flightID
};
foreach (Part part in vessel.parts.Where(part => part.rb != null &&
plugin_.PartIsTruthful(
part.flightID))) {
UnityEngine.Rigidbody part_rb = part.rb;
// TODO(egg): What if the plugin doesn't have the part? this seems
// brittle.
// NOTE(egg): I am not sure what the origin is here, as we are
Expand All @@ -516,25 +528,19 @@ private void UpdateVessel(Vessel vessel, double universal_time) {
// TODO(egg): check that the vessel is moved *after* this. Shouldn't
// we be calling vessel.orbitDriver.updateFromParameters() after
// setting the orbit anyway?
QPRW part_actual_motion = plugin_.PartGetActualRigidMotion(
part.flightID,
new Origin{
reference_part_is_at_origin = true,
reference_part_is_unmoving = true,
main_body_centre_in_world =
(XYZ)FlightGlobals.ActiveVessel.mainBody.position,
reference_part_id = vessel.rootPart.flightID
});
part.rb.position = vessel.rootPart.rb.position +
(Vector3d)part_actual_motion.qp.q;
part.rb.transform.position = vessel.rootPart.rb.position +
(Vector3d)part_actual_motion.qp.q;
part.rb.rotation = (UnityEngine.QuaternionD)part_actual_motion.r;
part.rb.transform.rotation =
(UnityEngine.QuaternionD)part_actual_motion.r;
part.rb.velocity = vessel.rootPart.rb.velocity +
(Vector3d)part_actual_motion.qp.p;
part.rb.angularVelocity = (Vector3d)part_actual_motion.w;
QPRW part_actual_motion =
plugin_.PartGetActualRigidMotion(part.flightID, origin);
QP part_actual_degrees_of_freedom = part_actual_motion.qp;
var part_position = (Vector3d)part_actual_degrees_of_freedom.q;
var part_velocity = (Vector3d)part_actual_degrees_of_freedom.p;
var part_rotation = (UnityEngine.QuaternionD)part_actual_motion.r;
var part_angular_velocity = (Vector3d)part_actual_motion.w;
part_rb.position = root_part_rb.position + part_position;
part_rb.transform.position = root_part_rb.position + part_position;
part_rb.rotation = part_rotation;
part_rb.transform.rotation = part_rotation;
part_rb.velocity = root_part_rb.velocity + part_velocity;
part_rb.angularVelocity = part_angular_velocity;
}
}
}
Expand Down Expand Up @@ -1177,6 +1183,7 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
out bool inserted);
if (!vessel.packed) {
foreach (Part part in vessel.parts.Where(PartIsFaithful)) {
UnityEngine.Rigidbody part_rb = part.rb;
QP degrees_of_freedom;
if (part_id_to_degrees_of_freedom_.ContainsKey(part.flightID)) {
degrees_of_freedom =
Expand All @@ -1190,9 +1197,9 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
"WaitForFixedUpdate. Linearly extrapolating its " +
"position at the previous frame.");
degrees_of_freedom = new QP{
q = (XYZ)((Vector3d)part.rb.position -
Δt * (Vector3d)part.rb.velocity),
p = (XYZ)(Vector3d)part.rb.velocity
q = (XYZ)((Vector3d)part_rb.position -
Δt * (Vector3d)part_rb.velocity),
p = (XYZ)(Vector3d)part_rb.velocity
};
}
// In the first few frames after spawning a Kerbal, its physicsMass is
Expand All @@ -1203,18 +1210,18 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
plugin_.InsertOrKeepLoadedPart(
part.flightID,
part.name,
part.physicsMass == 0 ? part.rb.mass : part.physicsMass,
(XYZ)(Vector3d)part.rb.centerOfMass,
(XYZ)(Vector3d)part.rb.inertiaTensor,
(WXYZ)(UnityEngine.QuaternionD)part.rb.inertiaTensorRotation,
part.physicsMass == 0 ? part_rb.mass : part.physicsMass,
(XYZ)(Vector3d)part_rb.centerOfMass,
(XYZ)(Vector3d)part_rb.inertiaTensor,
(WXYZ)(UnityEngine.QuaternionD)part_rb.inertiaTensorRotation,
(from PartModule module in part.Modules
select module as ModuleEngines).Any(is_lit_solid_booster),
vessel.id.ToString(),
vessel.mainBody.flightGlobalsIndex,
main_body_degrees_of_freedom,
degrees_of_freedom,
(WXYZ)(UnityEngine.QuaternionD)part.rb.rotation,
(XYZ)(Vector3d)part.rb.angularVelocity,
(WXYZ)(UnityEngine.QuaternionD)part_rb.rotation,
(XYZ)(Vector3d)part_rb.angularVelocity,
Δt);
if (part_id_to_intrinsic_torque_.ContainsKey(part.flightID)) {
plugin_.PartApplyIntrinsicTorque(part.flightID,
Expand Down Expand Up @@ -1279,7 +1286,7 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
// Here, the |CollisionReporter.collisions| are the collisions that occurred
// in the physics simulation.
foreach (Vessel vessel1 in FlightGlobals.Vessels.Where(
v => !v.packed && is_manageable(v))) {
v => !v.packed && is_manageable(v))) {
if (plugin_.HasVessel(vessel1.id.ToString())) {
if (vessel1.isEVA &&
(vessel1.evaController.OnALadder ||
Expand Down Expand Up @@ -1384,13 +1391,14 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
foreach (Part part in vessel.parts.Where(PartIsFaithful)) {
if (main_body_change_countdown_ == 0 &&
last_main_body_ == FlightGlobals.ActiveVessel?.mainBody) {
UnityEngine.Rigidbody part_rb = part.rb;
plugin_.PartSetApparentRigidMotion(
part.flightID,
// TODO(egg): use the centre of mass.
new QP{q = (XYZ)(Vector3d)part.rb.position,
p = (XYZ)(Vector3d)part.rb.velocity},
(WXYZ)(UnityEngine.QuaternionD)part.rb.rotation,
(XYZ)(Vector3d)part.rb.angularVelocity);
new QP{q = (XYZ)(Vector3d)part_rb.position,
p = (XYZ)(Vector3d)part_rb.velocity},
(WXYZ)(UnityEngine.QuaternionD)part_rb.rotation,
(XYZ)(Vector3d)part_rb.angularVelocity);
}
}
}
Expand All @@ -1416,34 +1424,42 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
if (has_active_manageable_vessel() &&
!FlightGlobals.ActiveVessel.packed &&
plugin_.HasVessel(FlightGlobals.ActiveVessel.id.ToString())) {
// We are going to touch plenty of |Transform|s, so we will prevent
// Unity from syncing with the physics system all the time.
UnityEngine.Physics.autoSyncTransforms = false;

Vector3d q_correction_at_root_part = Vector3d.zero;
Vector3d v_correction_at_root_part = Vector3d.zero;
CelestialBody main_body = FlightGlobals.ActiveVessel.mainBody;
Part root_part = FlightGlobals.ActiveVessel.rootPart;
Origin origin = new Origin{
reference_part_is_at_origin = FloatingOrigin.fetch.continuous,
reference_part_is_unmoving =
krakensbane_.FrameVel != Vector3d.zero,
main_body_centre_in_world = (XYZ)main_body.position,
reference_part_id = root_part.flightID
};

foreach (Vessel vessel in FlightGlobals.Vessels.Where(v => !v.packed)) {
// TODO(egg): if I understand anything, there should probably be a
// special treatment for loaded packed vessels. I don't understand
// anything though.
if (!plugin_.HasVessel(vessel.id.ToString())) {
continue;
}

foreach (Part part in vessel.parts.Where(PartIsFaithful)) {
QPRW part_actual_motion = plugin_.PartGetActualRigidMotion(
part.flightID,
new Origin{
reference_part_is_at_origin =
FloatingOrigin.fetch.continuous,
reference_part_is_unmoving =
krakensbane_.FrameVel != Vector3d.zero,
main_body_centre_in_world = (XYZ)FlightGlobals.ActiveVessel.
mainBody.position,
reference_part_id =
FlightGlobals.ActiveVessel.rootPart.flightID
});
if (part == FlightGlobals.ActiveVessel.rootPart) {
QP part_actual_degrees_of_freedom = part_actual_motion.qp;
q_correction_at_root_part =
(Vector3d)part_actual_degrees_of_freedom.q - part.rb.position;
v_correction_at_root_part =
(Vector3d)part_actual_degrees_of_freedom.p - part.rb.velocity;
UnityEngine.Rigidbody part_rb = part.rb;
QPRW part_actual_motion =
plugin_.PartGetActualRigidMotion(part.flightID, origin);
QP part_actual_degrees_of_freedom = part_actual_motion.qp;
var part_position = (Vector3d)part_actual_degrees_of_freedom.q;
var part_velocity = (Vector3d)part_actual_degrees_of_freedom.p;
var part_rotation = (UnityEngine.QuaternionD)part_actual_motion.r;
var part_angular_velocity = (Vector3d)part_actual_motion.w;
if (part == root_part) {
q_correction_at_root_part = part_position - part_rb.position;
v_correction_at_root_part = part_velocity - part_rb.velocity;
}

// TODO(egg): use the centre of mass. Here it's a bit tedious, some
Expand All @@ -1453,37 +1469,29 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
// performing this correction after the physics step.
// See https://github.com/mockingbirdnest/Principia/pull/1427,
// https://github.com/mockingbirdnest/Principia/issues/1307#issuecomment-478337241.
part.rb.position = (Vector3d)part_actual_motion.qp.q;
part.rb.transform.position = (Vector3d)part_actual_motion.qp.q;
part.rb.rotation = (UnityEngine.QuaternionD)part_actual_motion.r;
part.rb.transform.rotation =
(UnityEngine.QuaternionD)part_actual_motion.r;

part.rb.velocity = (Vector3d)part_actual_motion.qp.p;
part.rb.angularVelocity = (Vector3d)part_actual_motion.w;
part_rb.position = part_position;
part_rb.transform.position = part_position;
part_rb.rotation = part_rotation;
part_rb.transform.rotation = part_rotation;

part_rb.velocity = part_velocity;
part_rb.angularVelocity = part_angular_velocity;
}
}
foreach (physicalObject physical_object in FlightGlobals.
physicalObjects.Where(o => o != null && o.rb != null)) {
// TODO(egg): This is no longer sensible.
physical_object.rb.position += q_correction_at_root_part;
physical_object.rb.transform.position += q_correction_at_root_part;
physical_object.rb.velocity += v_correction_at_root_part;
UnityEngine.Rigidbody physical_object_rb = physical_object.rb;
physical_object_rb.position += q_correction_at_root_part;
physical_object_rb.transform.position += q_correction_at_root_part;
physical_object_rb.velocity += v_correction_at_root_part;
}
QP main_body_dof = plugin_.CelestialWorldDegreesOfFreedom(
FlightGlobals.ActiveVessel.mainBody.flightGlobalsIndex,
new Origin{
reference_part_is_at_origin = FloatingOrigin.fetch.continuous,
reference_part_is_unmoving =
krakensbane_.FrameVel != Vector3d.zero,
main_body_centre_in_world =
(XYZ)FlightGlobals.ActiveVessel.mainBody.position,
reference_part_id = FlightGlobals.ActiveVessel.rootPart.flightID
},
main_body.flightGlobalsIndex,
origin,
plugin_.CurrentTime());
krakensbane.FrameVel = -(Vector3d)main_body_dof.p;
Vector3d offset = (Vector3d)main_body_dof.q -
FlightGlobals.ActiveVessel.mainBody.position;
Vector3d offset = (Vector3d)main_body_dof.q - main_body.position;
// We cannot use FloatingOrigin.SetOffset to move the world here, because
// as far as I can tell, that does not move the bubble relative to the
// rest of the universe.
Expand All @@ -1499,6 +1507,8 @@ private System.Collections.IEnumerator WaitedForFixedUpdate() {
// them at the previous instant, and will propagate them at the beginning
// of the next frame...
}
UnityEngine.Physics.SyncTransforms();
UnityEngine.Physics.autoSyncTransforms = true;

if (last_main_body_ != FlightGlobals.ActiveVessel?.mainBody) {
main_body_change_countdown_ = 1;
Expand Down

0 comments on commit be6820c

Please sign in to comment.