Browse Source

- fixed angular drag bug

- game load support (wip)
master
Youen Toupin 9 years ago
parent
commit
7102f572ed
  1. 67
      Plugin/ModuleBalloon.cs
  2. 75
      Plugin/ModuleBalloonCase.cs

67
Plugin/ModuleBalloon.cs

@ -26,9 +26,18 @@ namespace Aerostats
/// <summary>
/// Mass of the empty balloon, in kg
/// </summary>
public float EmptyMass { get; private set; }
[KSPField(isPersistant = true, guiActive = false)]
public float EmptyMass;
[KSPField(isPersistant = true, guiActive = false)]
public float LiftingGasQuantity;
[KSPField(isPersistant = true, guiActive = false)]
public float Scale;
[KSPField(isPersistant = true, guiActive = false)]
public Vector3d Velocity;
public float LiftingGasQuantity { get; private set; }
public float CurrentVolume { get; private set; }
public float Lift { get; private set; }
public bool IsVenting { get; private set; }
@ -50,7 +59,13 @@ namespace Aerostats
AttachedCase = attachedCase;
GasMolarMass = gasDensity / GasUtilities.StpVolumeToMoles;
EmptyMass = part.mass * 1000.0f;
Velocity = initialVelocity;
LiftingGasQuantity = initialGasQuantity;
Initialize();
}
private void Initialize()
{
// replace mesh and collider by a sphere (hack until proper assets are created)
var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
var meshFilter = gameObject.GetComponentInChildren<MeshFilter>();
@ -72,22 +87,49 @@ namespace Aerostats
gameObject.AddComponent<Rigidbody>();
rigidbody.mass = EmptyMass * 0.001f;
part.mass = rigidbody.mass;
rigidbody.velocity = initialVelocity;
rigidbody.velocity = Velocity - Krakensbane.GetFrameVelocity();
rigidbody.position = transform.position;
part.rb = rigidbody;
InjectGas(initialGasQuantity);
float initialQuantity = LiftingGasQuantity;
LiftingGasQuantity = 0;
InjectGas(initialQuantity);
part.OnJustAboutToBeDestroyed += OnPartDestroyed;
}
public override void OnLoad(ConfigNode node)
{
base.OnLoad(node);
if (vessel != null)
{
Debug.Log("Loading Balloon part...");
Initialize();
Vector3d worldPos = vessel.GetWorldPos3D();
CelestialBody body = vessel.mainBody;
float externalPressure = (float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f;
if (externalPressure > 1.0f)
{
vessel.GoOffRails(); // apparently the vessel is on rails on loading, we must take it off rails if it's inside the atmosphere, or it's destroyed by KSP
}
}
}
public override void OnSave(ConfigNode node)
{
base.OnSave(node);
}
public void OnDetached()
{
Debug.Log("Balloon part detached");
AttachedCase = null;
}
private void OnPartDestroyed()
{
Debug.Log("Balloon part destroyed");
if(AttachedCase != null)
AttachedCase.Cut();
@ -135,13 +177,13 @@ namespace Aerostats
// V = 4/3*pi*r^3
Radius = Mathf.Pow(CurrentVolume * 0.75f / Mathf.PI, 0.333f);
float scale = Mathf.Max(Radius * 2.0f, 0.1f);
Scale = Mathf.Max(Radius * 2.0f, 0.1f);
if(AttachedCase != null)
{
float dist = Vector3.Distance(AttachedCase.transform.position, transform.position);
scale = Mathf.Min(Mathf.Max(dist, transform.localScale.x * 0.5f) - 0.005f, scale * 0.5f) * 2.0f; // to prevent physics explosion due to interpenetration of objects, don't scale the balloon more than the space available between the case and the balloon (this happens when expanding fast after deploy in vaccum for example)
Scale = Mathf.Min(Mathf.Max(dist, transform.localScale.x * 0.5f) - 0.005f, Scale * 0.5f) * 2.0f; // to prevent physics explosion due to interpenetration of objects, don't scale the balloon more than the space available between the case and the balloon (this happens when expanding fast after deploy in vaccum for example)
}
transform.localScale = new Vector3(scale, scale, scale);
transform.localScale = new Vector3(Scale, Scale, Scale);
rigidbody.mass = (EmptyMass + balloonGasMass) * 0.001f;
part.mass = rigidbody.mass;
@ -182,8 +224,6 @@ namespace Aerostats
float externalPressure = (float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f;
float airDensity = (float)FlightGlobals.getAtmDensity(externalPressure / 1000.0f, externalTemperature, body);
rigidbody.angularDrag = Mathf.Max(0.5f, 10.0f * externalPressure / GasUtilities.StandardPressure);
if (externalPressure > 0.00001f)
{
// lift
@ -198,5 +238,14 @@ namespace Aerostats
rigidbody.AddForce(-airVelocity.normalized * dragForce / 1000.0f, ForceMode.Force);
}
}
private void Update()
{
Vector3d worldPos = vessel.GetWorldPos3D();
CelestialBody body = vessel.mainBody;
float externalPressure = (float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f;
part.angularDrag = Mathf.Max(0.5f, 10.0f * externalPressure / GasUtilities.StandardPressure);
rigidbody.angularDrag = Mathf.Max(0.5f, 10.0f * externalPressure / GasUtilities.StandardPressure);
}
}
}

75
Plugin/ModuleBalloonCase.cs

@ -8,6 +8,13 @@ namespace Aerostats
{
public class ModuleBalloonCase : PartModule
{
public enum BalloonState
{
Packed,
Deployed,
Detached
}
/// <summary>
/// Maximum rate at which gas can be injected in the balloon to fill it, in m^3/s at stp
/// </summary>
@ -43,11 +50,17 @@ namespace Aerostats
public float MinimumFillQuantity = 10.0f;
/// <summary>
/// Length of spring that can not be extended (no force applied under this length)
/// Length of spring at rest (no force applied under this length)
/// </summary>
[KSPField(isPersistant = false, guiActive = false)]
public float SpringRestLength = 10.0f;
/// <summary>
/// Length at which the spring breaks
/// </summary>
[KSPField(isPersistant = false, guiActive = false)]
public float SpringBreakLength = 50.0f;
/// <summary>
/// Force applied by the spring between the balloon and the vessel, proportional to spring extension, in newton per meter
/// </summary>
@ -57,9 +70,8 @@ namespace Aerostats
[KSPField(isPersistant = false, guiActive = true)]
public string Status;
private bool Deployed;
private bool Destroyed;
[KSPField(isPersistant = true, guiActive = false)]
public BalloonState State;
/// <summary>
/// Gas quantity currently inside the balloon
@ -76,18 +88,18 @@ namespace Aerostats
[KSPEvent(guiActive = true, active = true, externalToEVAOnly = false, guiActiveUnfocused = true, guiName = "Deploy balloon", unfocusedRange = 5)]
public void Deploy()
{
if (Destroyed || Deployed)
if (State != BalloonState.Packed)
return;
Deployed = true;
State = BalloonState.Deployed;
UnityEngine.Debug.Log("Aerostats: staged");
Util.PostDebugScreenMessage("staged");
UnityEngine.Debug.Log("Aerostats: deploying");
Util.PostDebugScreenMessage("deploying");
AvailablePart avPart = PartLoader.Instance.parts.Single(p => p.name == "heliumBalloon");
var balloonPart = (Part)UnityEngine.Object.Instantiate(avPart.partPrefab);
var balloonObject = balloonPart.gameObject;
balloonObject.transform.position = part.Rigidbody.position + part.Rigidbody.transform.up * 3.0f;
balloonObject.transform.position = part.Rigidbody.position + part.Rigidbody.transform.up * 1.0f;
balloonObject.transform.rotation = part.Rigidbody.rotation;
balloonPart.SetHierarchyRoot(balloonPart);
balloonPart.vessel = vessel;
@ -103,7 +115,7 @@ namespace Aerostats
Balloon.part.vessel.vesselName = vessel.vesselName + " balloon";
float initialGasQuantity = Mathf.Min(0.1f, part.RequestResource("Helium", MinimumFillQuantity));
Balloon.Initialize(this, part.rigidbody.velocity, GasDensity, initialGasQuantity);
Balloon.Initialize(this, (Vector3d)part.rigidbody.velocity + Krakensbane.GetFrameVelocity(), GasDensity, initialGasQuantity);
LiftingGasQuantity = Balloon.LiftingGasQuantity;
@ -120,18 +132,19 @@ namespace Aerostats
[KSPEvent(guiActive = true, active = true, externalToEVAOnly = false, guiActiveUnfocused = true, guiName = "Cut rope", unfocusedRange = 5)]
public void Cut()
{
if (Destroyed || !Deployed)
if (State != BalloonState.Deployed)
return;
if (Balloon != null)
{
if(Balloon != null)
Balloon.OnDetached();
Balloon = null;
}
Destroy(Spring);
Balloon = null;
if(Spring != null)
Destroy(Spring);
Spring = null;
part.OnJustAboutToBeDestroyed -= OnPartDestroyed;
Destroyed = true;
State = BalloonState.Detached;
}
public override void OnStart(PartModule.StartState state)
@ -149,7 +162,10 @@ namespace Aerostats
private void FixedUpdate()
{
if (Destroyed)
if (State == BalloonState.Deployed && Balloon == null)
Cut();
if (State == BalloonState.Detached)
{
Status = "separated";
VolumeStatus = "-";
@ -161,7 +177,7 @@ namespace Aerostats
Deploy();
}
if (Deployed)
if (State == BalloonState.Deployed)
{
float currentMaxQuantity = Balloon.GetCurrentMaxQuantity();
@ -203,7 +219,12 @@ namespace Aerostats
float springLength = springVec.magnitude;
float springForceMag = 0;
var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * Balloon.Radius;
if(springLength > restLength)
if(springLength > SpringBreakLength)
{
Cut();
FlightLogger.eventLog.Add("The balloon cable broke due to extreme extension");
}
else if(springLength > restLength)
{
float tensingLength = springLength - restLength;
springForceMag = tensingLength * SpringHardness;
@ -222,16 +243,16 @@ namespace Aerostats
private void LateUpdate()
{
if (Destroyed)
if (State == BalloonState.Deployed && Balloon == null)
Cut();
if (State != BalloonState.Deployed)
return;
if (Deployed)
{
var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * Balloon.Radius;
var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * Balloon.Radius;
Spring.SetPosition(0, part.transform.position);
Spring.SetPosition(1, balloonAttachPoint);
}
Spring.SetPosition(0, part.transform.position);
Spring.SetPosition(1, balloonAttachPoint);
}
}
}

Loading…
Cancel
Save