/
SimulatedVessel.cs
125 lines (98 loc) · 4.08 KB
/
SimulatedVessel.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using System.Collections.Generic;
using Smooth.Pools;
namespace MuMech
{
public class SimulatedVessel
{
public readonly List<SimulatedPart> parts = new List<SimulatedPart>();
private int count;
public double totalMass;
private ReentrySimulation.SimCurves simCurves;
private static readonly Pool<SimulatedVessel> pool = new Pool<SimulatedVessel>(Create, Reset);
public static int PoolSize => pool.Size;
private static SimulatedVessel Create() => new SimulatedVessel();
public void Release() => pool.Release(this);
private static void Reset(SimulatedVessel obj)
{
SimulatedPart.Release(obj.parts);
obj.parts.Clear();
}
public static SimulatedVessel Borrow(Vessel v, ReentrySimulation.SimCurves simCurves, double startTime, int limitChutesStage)
{
SimulatedVessel vessel = pool.Borrow();
vessel.Init(v, simCurves, startTime, limitChutesStage);
return vessel;
}
private void Init(Vessel v, ReentrySimulation.SimCurves _simCurves, double startTime, int limitChutesStage)
{
totalMass = 0;
List<Part> oParts = v.Parts;
count = oParts.Count;
simCurves = _simCurves;
if (parts.Capacity < count)
parts.Capacity = count;
for (int i = 0; i < count; i++)
{
SimulatedPart simulatedPart = null;
bool special = false;
for (int j = 0; j < oParts[i].Modules.Count; j++)
{
var mp = oParts[i].Modules[j] as ModuleParachute;
if (mp != null && v.mainBody.atmosphere)
{
special = true;
simulatedPart = SimulatedParachute.Borrow(mp, simCurves, startTime, limitChutesStage);
}
}
if (!special)
{
simulatedPart = SimulatedPart.Borrow(oParts[i], simCurves);
}
parts.Add(simulatedPart);
totalMass += simulatedPart.totalMass;
}
}
public Vector3d Drag(Vector3d localVelocity, double dynamicPressurekPa, float mach)
{
Vector3d drag = Vector3d.zero;
double dragFactor = dynamicPressurekPa * PhysicsGlobals.DragCubeMultiplier * PhysicsGlobals.DragMultiplier;
for (int i = 0; i < count; i++)
{
drag += parts[i].Drag(localVelocity, dragFactor, mach);
}
return -localVelocity.normalized * drag.magnitude;
}
public Vector3d Lift(Vector3d localVelocity, float dynamicPressurekPa, float mach)
{
Vector3d lift = Vector3d.zero;
double liftFactor = dynamicPressurekPa * simCurves.LiftMachCurve.Evaluate(mach);
for (int i = 0; i < count; i++)
{
lift += parts[i].Lift(localVelocity, liftFactor);
}
return lift;
}
public bool WillChutesDeploy(double altAGL, double altASL, double probableLandingSiteASL, double pressure, double shockTemp, double t,
double parachuteSemiDeployMultiplier)
{
for (int i = 0; i < count; i++)
{
if (parts[i].SimulateAndRollback(altAGL, altASL, probableLandingSiteASL, pressure, shockTemp, t, parachuteSemiDeployMultiplier))
{
return true;
}
}
return false;
}
public bool Simulate(double altATGL, double altASL, double endASL, double pressure, double shockTemp, double time,
double semiDeployMultiplier)
{
bool deploying = false;
for (int i = 0; i < count; i++)
{
deploying |= parts[i].Simulate(altATGL, altASL, endASL, pressure, shockTemp, time, semiDeployMultiplier);
}
return deploying;
}
}
}