diff --git a/Plugin/ModuleBalloon.cs b/Plugin/ModuleBalloon.cs index 21ebe5e..0b40201 100644 --- a/Plugin/ModuleBalloon.cs +++ b/Plugin/ModuleBalloon.cs @@ -53,17 +53,28 @@ namespace Aerostats // replace mesh and collider by a sphere (hack until proper assets are created) var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); - gameObject.GetComponentInChildren().mesh = sphere.GetComponent().mesh; - Destroy(gameObject.collider); - var collider = gameObject.AddComponent(); - collider.radius = 0.67f; // don't ask me, I don't know why + var meshFilter = gameObject.GetComponentInChildren(); + meshFilter.mesh = sphere.GetComponent().mesh; + var t = meshFilter.transform; + while (t != transform) + { + t.localPosition = new Vector3(0, 0, 0); + t.localRotation = Quaternion.identity; + t.localScale = new Vector3(1, 1, 1); + t = t.parent; + } + var colliderObject = part.collider.gameObject; + Destroy(colliderObject.collider); + var collider = colliderObject.AddComponent(); + collider.radius = 0.5f; Destroy(sphere); gameObject.AddComponent(); rigidbody.mass = EmptyMass * 0.001f; - rigidbody.velocity = initialVelocity; // start with the same velocity or everything explodes when deploying from a moving vessel - rigidbody.angularDrag = 10.0f; + part.mass = rigidbody.mass; + rigidbody.velocity = initialVelocity; rigidbody.position = transform.position; + part.rb = rigidbody; InjectGas(initialGasQuantity); @@ -108,7 +119,7 @@ namespace Aerostats CelestialBody body = vessel.mainBody; float externalTemperature = (float)FlightGlobals.getExternalTemperature(worldPos, body); - float balloonInternalTemperature = externalTemperature; + float balloonInternalTemperature = Mathf.Max(externalTemperature, 20.0f); float externalPressure = Math.Max((float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f, 0.00001f); float currentGasMoles = GasUtilities.StpVolumeToMoles * LiftingGasQuantity; @@ -124,9 +135,15 @@ namespace Aerostats // V = 4/3*pi*r^3 Radius = Mathf.Pow(CurrentVolume * 0.75f / Mathf.PI, 0.333f); - float scale = Radius + 0.1f; + float 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) + } transform.localScale = new Vector3(scale, scale, scale); rigidbody.mass = (EmptyMass + balloonGasMass) * 0.001f; + part.mass = rigidbody.mass; return LiftingGasQuantity; } @@ -140,7 +157,7 @@ namespace Aerostats CelestialBody body = vessel.mainBody; float externalTemperature = (float)FlightGlobals.getExternalTemperature(worldPos, body); - float balloonInternalTemperature = externalTemperature; + float balloonInternalTemperature = Mathf.Max(externalTemperature, 20.0f); float externalPressure = Math.Max((float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f, 0.00001f); Util.PostDebugSingleScreenMessage("external atmo", "Temperature = " + externalTemperature + "K, Pressure=" + externalPressure + "Pa"); @@ -158,23 +175,28 @@ namespace Aerostats InjectGas(0); // update security valve venting - var gravityAccel = FlightGlobals.getGeeForceAtPosition(worldPos); + var gravityAccel = FlightGlobals.getGeeForceAtPosition(rigidbody.position); //Util.PostSingleScreenMessage("gravity", "Gravity accel = (" + gravityAccel.x + ", " + gravityAccel.y + ", " + gravityAccel.z + ")"); float externalTemperature = (float)FlightGlobals.getExternalTemperature(worldPos, body); - float balloonInternalTemperature = externalTemperature; - float externalPressure = Math.Max((float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f, 0.00001f); + float externalPressure = (float)FlightGlobals.getStaticPressure(worldPos, body) * 1000.0f; float airDensity = (float)FlightGlobals.getAtmDensity(externalPressure / 1000.0f, externalTemperature, body); - rigidbody.AddForce(-gravityAccel * Lift / 1000.0f, ForceMode.Force); + rigidbody.angularDrag = Mathf.Max(0.5f, 10.0f * externalPressure / GasUtilities.StandardPressure); - // balloon drag - var airVelocity = rigidbody.velocity + Krakensbane.GetFrameVelocity() /*- vessel.mainBody.getRFrmVel(vessel.GetWorldPos3D())*/; - float sqVel = (float)airVelocity.magnitude; - sqVel *= sqVel; - float dragForce = 0.5f * airDensity * sqVel * DragCoeff * (Mathf.PI * Radius * Radius); - Util.PostDebugSingleScreenMessage("balloon drag", "Drag = " + dragForce + "N"); - rigidbody.AddForce(-airVelocity.normalized * dragForce / 1000.0f, ForceMode.Force); + if (externalPressure > 0.00001f) + { + // lift + rigidbody.AddForce(-gravityAccel * Lift / 1000.0f, ForceMode.Force); + + // balloon drag + var airVelocity = rigidbody.velocity + Krakensbane.GetFrameVelocity() /*- vessel.mainBody.getRFrmVel(vessel.GetWorldPos3D())*/; + float sqVel = (float)airVelocity.magnitude; + sqVel *= sqVel; + float dragForce = 0.5f * airDensity * sqVel * DragCoeff * (Mathf.PI * Radius * Radius); + Util.PostDebugSingleScreenMessage("balloon drag", "Drag = " + dragForce + "N"); + rigidbody.AddForce(-airVelocity.normalized * dragForce / 1000.0f, ForceMode.Force); + } } } } diff --git a/Plugin/ModuleBalloonCase.cs b/Plugin/ModuleBalloonCase.cs index 1e1b1ee..70f8d31 100644 --- a/Plugin/ModuleBalloonCase.cs +++ b/Plugin/ModuleBalloonCase.cs @@ -61,8 +61,6 @@ namespace Aerostats private bool Destroyed; - private Vector3 EstimatedNextFramePosition; - /// /// Gas quantity currently inside the balloon /// @@ -75,18 +73,6 @@ namespace Aerostats private ModuleBalloon Balloon; private LineRenderer Spring; - public static void RemoveAttachJointBetween(Part part1, Part part2) - { - if (part1.attachJoint && ((part1.attachJoint.Host == part1 && part1.attachJoint.Target == part2) || (part1.attachJoint.Host == part2 && part1.attachJoint.Target == part1))) - { - part1.attachJoint.DestroyJoint(); - } - if (part2.attachJoint && ((part2.attachJoint.Host == part2 && part2.attachJoint.Target == part1) || (part2.attachJoint.Host == part1 && part2.attachJoint.Target == part2))) - { - part2.attachJoint.DestroyJoint(); - } - } - [KSPEvent(guiActive = true, active = true, externalToEVAOnly = false, guiActiveUnfocused = true, guiName = "Deploy balloon", unfocusedRange = 5)] public void Deploy() { @@ -109,11 +95,14 @@ namespace Aerostats Balloon = balloonObject.GetComponent(); Balloon.part = balloonPart; - float initialGasQuantity = Mathf.Min(0.1f, part.RequestResource("Helium", MinimumFillQuantity)); balloonObject.SetActive(true); GameEvents.onVesselWasModified.Fire(vessel); + Balloon.part.decouple(); // after that, the balloon becomes an independent vessel + 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); LiftingGasQuantity = Balloon.LiftingGasQuantity; @@ -126,8 +115,6 @@ namespace Aerostats Spring.SetVertexCount(2); part.OnJustAboutToBeDestroyed += OnPartDestroyed; - - EstimatedNextFramePosition = part.Rigidbody.position; } [KSPEvent(guiActive = true, active = true, externalToEVAOnly = false, guiActiveUnfocused = true, guiName = "Cut rope", unfocusedRange = 5)] @@ -139,8 +126,6 @@ namespace Aerostats if (Balloon != null) { Balloon.OnDetached(); - Balloon.part.decouple(); // after that, the balloon becomes an independent vessel - Balloon.part.vessel.vesselName = vessel.vesselName + " balloon"; Balloon = null; } Destroy(Spring); @@ -162,19 +147,6 @@ namespace Aerostats Cut(); } - private void CheckKrakensbane() - { - // detect Krakensbane teleportation, and fix up the balloon position (otherwise it results in instant ship disintegration due to extreme forces on the spring) - if ((part.Rigidbody.position - EstimatedNextFramePosition).magnitude > 1000.0f) - { - Util.PostDebugScreenMessage("Krakensbane teleportation detected! (dist=" + (part.Rigidbody.position - EstimatedNextFramePosition).magnitude + ")"); - var offset = part.rigidbody.position - EstimatedNextFramePosition; - Balloon.rigidbody.position += offset; - Balloon.transform.position = Balloon.rigidbody.position; - } - EstimatedNextFramePosition = part.rigidbody.position + part.rigidbody.velocity * Time.fixedDeltaTime; - } - private void FixedUpdate() { if (Destroyed) @@ -191,11 +163,6 @@ namespace Aerostats if (Deployed) { - // makes sure the balloon can move freely relatively to the vessel (apparently, KSP creates a joint when attaching a part) - RemoveAttachJointBetween(Balloon.part, part); - - CheckKrakensbane(); - float currentMaxQuantity = Balloon.GetCurrentMaxQuantity(); LiftingGasTargetQuantity = Math.Max(MinimumFillQuantity, LiftingGasTargetQuantity); @@ -260,23 +227,11 @@ namespace Aerostats if (Deployed) { - CheckKrakensbane(); var balloonAttachPoint = Balloon.rigidbody.position - Balloon.transform.up.normalized * Balloon.Radius; Spring.SetPosition(0, part.transform.position); Spring.SetPosition(1, balloonAttachPoint); } } - - private void Update() - { - if (Destroyed) - return; - - if (Deployed) - { - CheckKrakensbane(); - } - } } }