Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix various NREs. Calculate vessel orientation without using the NavBall, which doesn't exist in IVA mode. #133

Merged
merged 8 commits into from
May 3, 2022
11 changes: 7 additions & 4 deletions FerramAerospaceResearch/FARAeroComponents/FARAeroSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,13 @@ Dictionary<Part, PartTransformInfo> partWorldToLocalMatrixDict

Vector3 worldSpaceAvgPos = Vector3.zero;
float totalDragFactor = 0;
PartTransformInfo partTransformInfo;
for (int i = 0; i < moduleList.Count; i++)
{
Part p = moduleList[i].part;
if (!partWorldToLocalMatrixDict.ContainsKey(p))
if (!partWorldToLocalMatrixDict.TryGetValue(p, out partTransformInfo))
continue;
worldSpaceAvgPos += partWorldToLocalMatrixDict[p].worldPosition * dragFactor[i];
worldSpaceAvgPos += partTransformInfo.worldPosition * dragFactor[i];
totalDragFactor += dragFactor[i];
}

Expand All @@ -160,8 +161,10 @@ Dictionary<Part, PartTransformInfo> partWorldToLocalMatrixDict

for (int i = 0; i < moduleList.Count; i++)
{
var data = new PartData {aeroModule = moduleList[i]};
Matrix4x4 transformMatrix = partWorldToLocalMatrixDict[data.aeroModule.part].worldToLocalMatrix;
var data = new PartData { aeroModule = moduleList[i] };
if (!partWorldToLocalMatrixDict.TryGetValue(data.aeroModule.part, out partTransformInfo))
continue;
Matrix4x4 transformMatrix = partTransformInfo.worldToLocalMatrix;

Vector3 forceCenterWorldSpace = centroidLocationAlongxRef +
Vector3.ProjectOnPlane(partWorldToLocalMatrixDict[data.aeroModule.part]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ internal class VehicleAerodynamics
private readonly List<float> weighting = new List<float>();

private VehicleVoxel _voxel;
private VoxelCrossSection[] _vehicleCrossSection = new VoxelCrossSection[1];
private VoxelCrossSection[] _vehicleCrossSection = Array.Empty<VoxelCrossSection>();
private double[] _ductedAreaAdjustment = new double[1];

private int _voxelCount;
Expand Down Expand Up @@ -1651,7 +1651,7 @@ double sectionThickness
}
else if (i == back)
{
firstDerivArea = vehicleCrossSection[i].area - vehicleCrossSection[i + 1].area;
firstDerivArea = vehicleCrossSection[i - 1].area - vehicleCrossSection[i].area;
firstDerivArea /= sectionThickness;
}
else
Expand Down Expand Up @@ -1692,7 +1692,7 @@ double sectionThickness
}
else if (i == back)
{
firstDerivArea = vehicleCrossSection[i].area - vehicleCrossSection[i + 1].area;
firstDerivArea = vehicleCrossSection[i - 1].area - vehicleCrossSection[i].area;
firstDerivArea /= -sectionThickness;
}
else
Expand Down
58 changes: 42 additions & 16 deletions FerramAerospaceResearch/FARGUI/FARFlightGUI/PhysicsCalcs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ internal class PhysicsCalcs
private readonly FARCenterQuery aeroForces = new FARCenterQuery();
private readonly int intakeAirId;
private readonly double intakeAirDensity = 1;
private NavBall _navball;
// private NavBall _navball;

private List<FARAeroPartModule> _currentAeroModules;
private List<FARWingAerodynamicModel> _LEGACY_currentWingAeroModel = new List<FARWingAerodynamicModel>();
Expand Down Expand Up @@ -188,11 +188,11 @@ private void CalculateForceBreakdown(Vector3d velVectorNorm)
vesselInfo.liftToDragRatio = vesselInfo.liftForce / vesselInfo.dragForce;
}

private void GetNavball()
{
if (HighLogic.LoadedSceneIsFlight)
_navball = Object.FindObjectOfType<NavBall>();
}
// private void GetNavball()
// {
// if (HighLogic.LoadedSceneIsFlight)
// _navball = Object.FindObjectOfType<NavBall>();
// }

private void CalculateVesselOrientation(Vector3d velVectorNorm)
{
Expand All @@ -215,17 +215,43 @@ private void CalculateVesselOrientation(Vector3d velVectorNorm)
if (double.IsNaN(vesselInfo.sideslipAngle))
vesselInfo.sideslipAngle = 0;

if (_navball == null)
GetNavball();
if (!_navball)
return;
Quaternion vesselRot = Quaternion.Inverse(_navball.relativeGymbal);
// if (_navball == null)
// GetNavball();
// if (!_navball)
// return;
// Quaternion vesselRot = Quaternion.Inverse(_navball.relativeGymbal);

// vesselInfo.headingAngle = vesselRot.eulerAngles.y;
// vesselInfo.pitchAngle =
// vesselRot.eulerAngles.x > 180 ? 360 - vesselRot.eulerAngles.x : -vesselRot.eulerAngles.x;
// vesselInfo.rollAngle =
// vesselRot.eulerAngles.z > 180 ? 360 - vesselRot.eulerAngles.z : -vesselRot.eulerAngles.z;

// Gives the same numbers as the above, but also works in IVA mode which doesn't have a NavBall instance.
var localUp = (_vessel.transform.position - _vessel.mainBody.transform.position).normalized;
var east = Vector3.Cross(localUp, _vessel.mainBody.RotationAxis).normalized;
var north = Vector3.Cross(east, localUp).normalized;
vesselInfo.headingAngle = (SignedAngle(north, Vector3.ProjectOnPlane(up, localUp).normalized, localUp) + 360f) % 360f;
vesselInfo.pitchAngle = 90f - SignedAngle(localUp, up, Vector3.Cross(localUp, up).normalized);
vesselInfo.rollAngle = SignedAngle(Vector3.Cross(localUp, up).normalized, right, -up);
dkavolis marked this conversation as resolved.
Show resolved Hide resolved
}

vesselInfo.headingAngle = vesselRot.eulerAngles.y;
vesselInfo.pitchAngle =
vesselRot.eulerAngles.x > 180 ? 360 - vesselRot.eulerAngles.x : -vesselRot.eulerAngles.x;
vesselInfo.rollAngle =
vesselRot.eulerAngles.z > 180 ? 360 - vesselRot.eulerAngles.z : -vesselRot.eulerAngles.z;
/// <summary>
/// A more precise version of Vector3.SignedAngle at low angles.
/// From https://www.reddit.com/r/Unity3D/comments/aruqz9/if_vector3angle_is_too_imprecise_or_jittery_at/
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <param name="axis"></param>
/// <returns></returns>
float SignedAngle(Vector3 from, Vector3 to, Vector3 axis)
{
var cross = Vector3.Cross(from, to);
var dot = Vector3.Dot(from, to);
var angle = Mathf.Atan2(cross.magnitude, dot) * Mathf.Rad2Deg;
if (Vector3.Dot(axis, cross) < 0.0f)
angle = -angle;
return angle;
}

private void CalculateEngineAndIntakeBasedParameters(double vesselSpeed)
Expand Down
3 changes: 2 additions & 1 deletion FerramAerospaceResearch/FARPartGeometry/VehicleVoxel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ private void BuildVoxel(List<GeometryPartModule> geoModules, bool multiThreaded,
threadsQueued = Environment.ProcessorCount - 1;

if (!multiThreaded)
//Go through it backwards; this ensures that children (and so interior to cargo bay parts) are handled first
//Go through it backwards; this ensures that children (and so interior to cargo bay parts) are handled first
{
foreach (GeometryPartModule m in geoModules)
{
Expand Down Expand Up @@ -1354,6 +1354,7 @@ public void ClearVisualVoxels()
return;
VoxelizationThreadpool.Instance.RunOnMainThread(() =>
{
if (voxelMesh == null) { FARLogger.Debug($"Visual voxel has disappeared!"); return; }
FARLogger.Debug("Clearing visual voxels");
voxelMesh.gameObject.SetActive(false);
voxelMesh.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,10 @@ public override void Initialization()
public override void FixedUpdate()
{
if (justStarted)
{
UpdateShipPartsList();
CalculateSurfaceFunctions();
}

if (HighLogic.LoadedSceneIsFlight && !(part is null) && !(vessel is null))
{
Expand Down
2 changes: 1 addition & 1 deletion FerramAerospaceResearch/LEGACYferram4/FARPartModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public Collider[] PartColliders

public void ForceOnVesselPartsChange()
{
UpdateShipPartsList();
OnVesselPartsChange?.Invoke();
}

Expand All @@ -78,7 +79,6 @@ public void Start()

public virtual void Initialization()
{
OnVesselPartsChange = UpdateShipPartsList;
UpdateShipPartsList();
}

Expand Down
3 changes: 3 additions & 0 deletions FerramAerospaceResearch/RealChuteLite/ChuteCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ private void Start()
DragCube semi = prefab.DragCubes.Cubes.Find(c => c.Name == "SEMIDEPLOYED"),
deployed = prefab.DragCubes.Cubes.Find(c => c.Name == "DEPLOYED");
if (semi == null || deployed == null)
{
FARLogger.Info("" + part.title + " cannot find drag cube for RealChuteLite");
continue;
}
module.preDeployedDiameter = GetApparentDiameter(semi);
module.deployedDiameter = GetApparentDiameter(deployed);
part.moduleInfos.Find(m => m.moduleName == "RealChute").info = module.GetInfo();
Expand Down
16 changes: 8 additions & 8 deletions FerramAerospaceResearch/RealChuteLite/RealChuteFAR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,21 +443,21 @@ public void AssumeDragCubePosition(string cubeName)
case "STOWED":
{
parachute.gameObject.SetActive(false);
cap.gameObject.SetActive(true);
cap?.gameObject.SetActive(true);
break;
}

case "RCDEPLOYED": //This is not a predeployed state, no touchy
{
parachute.gameObject.SetActive(false);
cap.gameObject.SetActive(false);
cap?.gameObject.SetActive(false);
break;
}

case "SEMIDEPLOYED": // stock
{
parachute.gameObject.SetActive(true);
cap.gameObject.SetActive(false);
cap?.gameObject.SetActive(false);
// to the end of the animation
part.SkipToAnimationTime(semiDeployedAnimation, 0, 1);
break;
Expand All @@ -466,7 +466,7 @@ public void AssumeDragCubePosition(string cubeName)
case "DEPLOYED": // stock
{
parachute.gameObject.SetActive(true);
cap.gameObject.SetActive(false);
cap?.gameObject.SetActive(false);
// to the end of the animation
part.SkipToAnimationTime(fullyDeployedAnimation, 0, 1);
break;
Expand Down Expand Up @@ -580,7 +580,7 @@ public void GUIRepack()
DeploymentState = DeploymentStates.STOWED;
randomTimer.Reset();
time = 0;
cap.gameObject.SetActive(true);
cap?.gameObject.SetActive(true);
part.DragCubes.SetCubeWeight("PACKED", 1);
part.DragCubes.SetCubeWeight("RCDEPLOYED", 0);
}
Expand Down Expand Up @@ -727,7 +727,7 @@ public void PreDeploy()
part.Effect("rcpredeploy");
DeploymentState = DeploymentStates.PREDEPLOYED;
parachute.gameObject.SetActive(true);
cap.gameObject.SetActive(false);
cap?.gameObject.SetActive(false);
part.PlayAnimation(semiDeployedAnimation, semiDeploymentSpeed);
dragTimer.Start();
part.DragCubes.SetCubeWeight("PACKED", 0);
Expand Down Expand Up @@ -1184,7 +1184,7 @@ public override void OnStart(StartState startState)
initiated = true;
armed = false;
chuteCount = maxSpares;
cap.gameObject.SetActive(true);
cap?.gameObject.SetActive(true);
}

float tmpPartMass = TotalMass;
Expand Down Expand Up @@ -1213,7 +1213,7 @@ public override void OnStart(StartState startState)
if (DeploymentState != DeploymentStates.STOWED)
{
part.stackIcon.SetIconColor(XKCDColors.Red);
cap.gameObject.SetActive(false);
cap?.gameObject.SetActive(false);
}

if (staged && IsDeployed)
Expand Down