From 44ade85d48b6121b3585c2fa29b50647f35e79e9 Mon Sep 17 00:00:00 2001 From: meirumeiru <33137857+meirumeiru@users.noreply.github.com> Date: Mon, 10 Apr 2023 22:44:08 +0200 Subject: [PATCH] everything is new every aspect of KJR has been redesigned --- .../Gui/WindowManager.cs | 118 +-- .../KerbalJointReinforcement/KJRAnalyzer.cs | 22 +- .../KerbalJointReinforcement/KJRJointUtils.cs | 914 ++++++++++++------ .../KerbalJointReinforcement/KJRManager.cs | 521 +++++----- .../KJRMultiJointManager.cs | 8 +- .../KerbalJointReinforcement/KJRSettings.cs | 72 ++ .../KerbalJointReinforcement.csproj | 2 + .../Properties/AssemblyInfo.cs | 4 +- .../KerbalJointReinforcement.version | 2 +- .../KerbalJointReinforcementNext/config.xml | 21 +- 10 files changed, 968 insertions(+), 716 deletions(-) create mode 100644 KerbalJointReinforcement/KerbalJointReinforcement/KJRSettings.cs diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/Gui/WindowManager.cs b/KerbalJointReinforcement/KerbalJointReinforcement/Gui/WindowManager.cs index 03e32a0..b0a7d92 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/Gui/WindowManager.cs +++ b/KerbalJointReinforcement/KerbalJointReinforcement/Gui/WindowManager.cs @@ -62,18 +62,12 @@ internal void Invalidate() public bool ShowKSPJoints = false; public bool ReinforceExistingJoints = true; - public bool BuildAdditionalJointToParent = false; - public bool ShowAdditionalJointToParent = false; - - public bool BuildMultiPartJointTreeChildren = false; - public bool ShowMultiPartJointTreeChildren = false; - - public bool BuildMultiPartJointTreeChildrenRoot = false; - public bool ShowMultiPartJointTreeChildrenRoot = false; - public bool ReinforceInversions = true; public bool ShowReinforcedInversions = false; + public bool BuildExtraStabilityJoints = false; + public bool ShowExtraStabilityJoints = false; + public bool ShowInstability = false; internal bool GUIEnabled = false; @@ -89,7 +83,7 @@ private void Awake() { LoadConfigXml(); - KJRAnalyzer.OnLoad(ShowKSPJoints | ShowAdditionalJointToParent | ShowMultiPartJointTreeChildren | ShowMultiPartJointTreeChildrenRoot); + KJRAnalyzer.OnLoad(ShowKSPJoints | ShowReinforcedInversions | ShowExtraStabilityJoints); Logger.Log("[NewGUI] awake, Mode: " + AddonName); @@ -182,30 +176,18 @@ private void InitSettingsWindow(bool startSolid = true) var OptReinforceExistingJoints = AddNewOption(content, "Reinforce Existing Joints"); OptReinforceExistingJoints.isOn = ReinforceExistingJoints; - var OptBuildAdditionalJointToParent = AddNewOption(content, "Build Additional Joints To Parent"); - OptBuildAdditionalJointToParent.isOn = BuildAdditionalJointToParent; - - var OptShowAdditionalJointToParent = AddNewOption(content, "Show Additional Joints To Parent"); - OptShowAdditionalJointToParent.isOn = ShowAdditionalJointToParent; - - var OptBuildMultiPartJointTreeChildren = AddNewOption(content, "Build MultiPartJointTreeChildren"); - OptBuildMultiPartJointTreeChildren.isOn = BuildMultiPartJointTreeChildren; - - var OptShowMultiPartJointTreeChildren = AddNewOption(content, "Show MultiPartJointTreeChildren"); - OptShowMultiPartJointTreeChildren.isOn = ShowMultiPartJointTreeChildren; - - var OptBuildMultiPartJointTreeChildrenRoot = AddNewOption(content, "Build MultiPartJointTreeChildrenRoot"); - OptBuildMultiPartJointTreeChildrenRoot.isOn = BuildMultiPartJointTreeChildrenRoot; - - var OptShowMultiPartJointTreeChildrenRoot = AddNewOption(content, "Show MultiPartJointTreeChildrenRoot"); - OptShowMultiPartJointTreeChildrenRoot.isOn = ShowMultiPartJointTreeChildrenRoot; - var OptReinforceInversions = AddNewOption(content, "Reinforce Inversions"); OptReinforceInversions.isOn = ReinforceInversions; var OptShowReinforcedInversions = AddNewOption(content, "Show Reinforced Inversions"); OptShowReinforcedInversions.isOn = ShowReinforcedInversions; + var OptBuildExtraStabilityJoints = AddNewOption(content, "Build Extra Stability Joints"); + OptBuildExtraStabilityJoints.isOn = BuildExtraStabilityJoints; + + var OptShowExtraStabilityJoints = AddNewOption(content, "Show Extra Stability Joints"); + OptShowExtraStabilityJoints.isOn = ShowExtraStabilityJoints; + var OptAutoStrutDisplay = AddNewOption(content, "Show AutoStruts"); OptAutoStrutDisplay.isOn = PhysicsGlobals.AutoStrutDisplay; @@ -219,14 +201,10 @@ private void InitSettingsWindow(bool startSolid = true) { OptShowKSPJoints.isOn = ShowKSPJoints; OptReinforceExistingJoints.isOn = ReinforceExistingJoints; - OptBuildAdditionalJointToParent.isOn = BuildAdditionalJointToParent; - OptShowAdditionalJointToParent.isOn = ShowAdditionalJointToParent; - OptBuildMultiPartJointTreeChildren.isOn = BuildMultiPartJointTreeChildren; - OptShowMultiPartJointTreeChildren.isOn = ShowMultiPartJointTreeChildren; - OptBuildMultiPartJointTreeChildrenRoot.isOn = BuildMultiPartJointTreeChildrenRoot; - OptShowMultiPartJointTreeChildrenRoot.isOn = ShowMultiPartJointTreeChildrenRoot; OptReinforceInversions.isOn = ReinforceInversions; OptShowReinforcedInversions.isOn = ShowReinforcedInversions; + OptBuildExtraStabilityJoints.isOn = BuildExtraStabilityJoints; + OptShowExtraStabilityJoints.isOn = ShowExtraStabilityJoints; OptAutoStrutDisplay.isOn = PhysicsGlobals.AutoStrutDisplay; OptShowInstability.isOn = ShowInstability; }); @@ -242,37 +220,25 @@ private void InitSettingsWindow(bool startSolid = true) bCycle = true; OptReinforceExistingJoints.isOn = ReinforceExistingJoints = true; - if(BuildAdditionalJointToParent) - bCycle = true; - OptBuildAdditionalJointToParent.isOn = BuildAdditionalJointToParent = false; - - OptShowAdditionalJointToParent.isOn = ShowAdditionalJointToParent = false; - - if(BuildMultiPartJointTreeChildren) - bCycle = true; - OptBuildMultiPartJointTreeChildren.isOn = BuildMultiPartJointTreeChildren = false; - - OptShowMultiPartJointTreeChildren.isOn = ShowMultiPartJointTreeChildren = false; - - if(BuildMultiPartJointTreeChildrenRoot) - bCycle = true; - OptBuildMultiPartJointTreeChildrenRoot.isOn = BuildMultiPartJointTreeChildrenRoot = false; - - OptShowMultiPartJointTreeChildrenRoot.isOn = ShowMultiPartJointTreeChildrenRoot = false; - if(!ReinforceInversions) bCycle = true; OptReinforceInversions.isOn = ReinforceInversions = true; OptShowReinforcedInversions.isOn = ShowReinforcedInversions = false; + if(BuildExtraStabilityJoints) + bCycle = true; + OptBuildExtraStabilityJoints.isOn = BuildExtraStabilityJoints = false; + + OptShowExtraStabilityJoints.isOn = ShowExtraStabilityJoints = false; + OptAutoStrutDisplay.isOn = PhysicsGlobals.AutoStrutDisplay = false; if(ShowInstability) bCycle2 = true; OptShowInstability.isOn = ShowInstability = false; - KJRAnalyzer.Show = ShowKSPJoints | ShowAdditionalJointToParent | ShowMultiPartJointTreeChildren | ShowMultiPartJointTreeChildrenRoot; + KJRAnalyzer.Show = ShowKSPJoints | ShowReinforcedInversions | ShowExtraStabilityJoints; if(HighLogic.LoadedSceneIsFlight) { @@ -296,37 +262,21 @@ private void InitSettingsWindow(bool startSolid = true) ReinforceExistingJoints = OptReinforceExistingJoints.isOn; } - if(BuildAdditionalJointToParent != OptBuildAdditionalJointToParent.isOn) - { - bCycle = true; - BuildAdditionalJointToParent = OptBuildAdditionalJointToParent.isOn; - } - - ShowAdditionalJointToParent = OptShowAdditionalJointToParent.isOn; - - if(BuildMultiPartJointTreeChildren != OptBuildMultiPartJointTreeChildren.isOn) - { - bCycle = true; - BuildMultiPartJointTreeChildren = OptBuildMultiPartJointTreeChildren.isOn; - } - - ShowMultiPartJointTreeChildren = OptShowMultiPartJointTreeChildren.isOn; - - if(BuildMultiPartJointTreeChildrenRoot != OptBuildMultiPartJointTreeChildrenRoot.isOn) + if(ReinforceInversions != OptReinforceInversions.isOn) { bCycle = true; - BuildMultiPartJointTreeChildrenRoot = OptBuildMultiPartJointTreeChildrenRoot.isOn; + ReinforceInversions = OptReinforceInversions.isOn; } - ShowMultiPartJointTreeChildrenRoot = OptShowMultiPartJointTreeChildrenRoot.isOn; + ShowReinforcedInversions = OptShowReinforcedInversions.isOn; - if(ReinforceInversions != OptReinforceInversions.isOn) + if(BuildExtraStabilityJoints != OptBuildExtraStabilityJoints.isOn) { bCycle = true; - ReinforceInversions = OptReinforceInversions.isOn; + BuildExtraStabilityJoints = OptBuildExtraStabilityJoints.isOn; } - ShowReinforcedInversions = OptShowReinforcedInversions.isOn; + ShowExtraStabilityJoints = OptShowExtraStabilityJoints.isOn; PhysicsGlobals.AutoStrutDisplay = OptAutoStrutDisplay.isOn; @@ -336,7 +286,7 @@ private void InitSettingsWindow(bool startSolid = true) ShowInstability = OptShowInstability.isOn; } - KJRAnalyzer.Show = ShowKSPJoints | ShowAdditionalJointToParent | ShowMultiPartJointTreeChildren | ShowMultiPartJointTreeChildrenRoot; + KJRAnalyzer.Show = ShowKSPJoints | ShowReinforcedInversions | ShowExtraStabilityJoints; if(HighLogic.LoadedSceneIsFlight) { @@ -581,14 +531,10 @@ public void SaveConfigXml() config.SetValue("dbg_UIScaleValue", (double)_UIScaleValue); config.SetValue("dbg_ShowKSPJoints", ShowKSPJoints); config.SetValue("dbg_ReinforceExistingJoints", ReinforceExistingJoints); - config.SetValue("dbg_BuildAdditionalJointToParent", BuildAdditionalJointToParent); - config.SetValue("dbg_ShowAdditionalJointToParent", ShowAdditionalJointToParent); - config.SetValue("dbg_BuildMultiPartJointTreeChildren", BuildMultiPartJointTreeChildren); - config.SetValue("dbg_ShowMultiPartJointTreeChildren", ShowMultiPartJointTreeChildren); - config.SetValue("dbg_BuildMultiPartJointTreeChildrenRoot", BuildMultiPartJointTreeChildrenRoot); - config.SetValue("dbg_ShowMultiPartJointTreeChildrenRoot", ShowMultiPartJointTreeChildrenRoot); config.SetValue("dbg_ReinforceInversions", ReinforceInversions); config.SetValue("dbg_ShowReinforcedInversions", ShowReinforcedInversions); + config.SetValue("dbg_BuildExtraStabilityJoints", BuildExtraStabilityJoints); + config.SetValue("dbg_ShowExtraStabilityJoints", ShowExtraStabilityJoints); config.save(); } @@ -604,14 +550,10 @@ public void LoadConfigXml() _UIScaleValue = (float)config.GetValue("dbg_UIScaleValue", 1.0); ShowKSPJoints = config.GetValue("dbg_ShowKSPJoints", false); ReinforceExistingJoints = config.GetValue("dbg_ReinforceExistingJoints", true); - BuildAdditionalJointToParent = config.GetValue("dbg_BuildAdditionalJointToParent", false); - ShowAdditionalJointToParent = config.GetValue("dbg_ShowAdditionalJointToParent", false); - BuildMultiPartJointTreeChildren = config.GetValue("dbg_BuildMultiPartJointTreeChildren", false); - ShowMultiPartJointTreeChildren = config.GetValue("dbg_ShowMultiPartJointTreeChildren", false); - BuildMultiPartJointTreeChildrenRoot = config.GetValue("dbg_BuildMultiPartJointTreeChildrenRoot", false); - ShowMultiPartJointTreeChildrenRoot = config.GetValue("dbg_ShowMultiPartJointTreeChildrenRoot", false); ReinforceInversions = config.GetValue("dbg_ReinforceInversions", true); ShowReinforcedInversions = config.GetValue("dbg_ShowReinforcedInversions", false); + BuildExtraStabilityJoints = config.GetValue("dbg_BuildExtraStabilityJoints", false); + ShowExtraStabilityJoints = config.GetValue("dbg_ShowExtraStabilityJoints", false); } } diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/KJRAnalyzer.cs b/KerbalJointReinforcement/KerbalJointReinforcement/KJRAnalyzer.cs index 5e1fe38..acecdb1 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/KJRAnalyzer.cs +++ b/KerbalJointReinforcement/KerbalJointReinforcement/KJRAnalyzer.cs @@ -174,33 +174,19 @@ public static void WasModified(Vessel v) t.color = Color.green; break; - case KJRMultiJointManager.Reason.AdditionalJointToParent: - if(!WindowManager.Instance.ShowAdditionalJointToParent) + case KJRMultiJointManager.Reason.ReinforceInversions: + if(!WindowManager.Instance.ShowReinforcedInversions) continue; t.color = Color.magenta; break; - case KJRMultiJointManager.Reason.MultiPartJointTreeChildren: - if(!WindowManager.Instance.ShowMultiPartJointTreeChildren) + case KJRMultiJointManager.Reason.ExtraStabilityJoint: + if(!WindowManager.Instance.ShowExtraStabilityJoints) continue; t.color = Color.yellow; break; - - case KJRMultiJointManager.Reason.MultiPartJointTreeChildrenRoot: - if(!WindowManager.Instance.ShowMultiPartJointTreeChildrenRoot) - continue; - - t.color = Color.cyan; - break; - - case KJRMultiJointManager.Reason.ReinforceInversions: - if(!WindowManager.Instance.ShowReinforcedInversions) - continue; - - t.color = Color.blue; - break; } t.line = new LineDrawer(); diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/KJRJointUtils.cs b/KerbalJointReinforcement/KerbalJointReinforcement/KJRJointUtils.cs index 23bf1b3..4956f92 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/KJRJointUtils.cs +++ b/KerbalJointReinforcement/KerbalJointReinforcement/KJRJointUtils.cs @@ -10,18 +10,17 @@ namespace KerbalJointReinforcement { public static class KJRJointUtils { + public static bool loaded = false; + public static bool reinforceAttachNodes = true; - public static bool multiPartAttachNodeReinforcement = false; - public static bool reinforceDecouplersFurther = false; - public static bool reinforceLaunchClampsFurther = false; public static bool reinforceInversions = true; + public static bool addExtraStabilityJoints = false; + public static bool reinforceLaunchClamps = false; public static bool useVolumeNotArea = true; public static float massForAdjustment = 0.01f; - public static float stiffeningExtensionMassRatioThreshold = 5f; - - public static float decouplerAndClampJointStrength = float.PositiveInfinity; + // reinforcement settings public static float angularDriveSpring = 5e12f; public static float angularDriveDamper = 25f; @@ -30,26 +29,45 @@ public static class KJRJointUtils public static float breakStrengthPerArea = 1500f; public static float breakTorquePerMOI = 6000f; + // inversion settings + public static float inversionMassFactor = 2f; + public static float solutionMassFactor = 2f; + public static float jointMassFactor = 8f; + + // extra joint settings + public static int extraLevel = 0; + + public static float extraLinearForce = PhysicsGlobals.JointForce; + public static float extraLinearSpring = PhysicsGlobals.JointForce; + public static float extraLinearDamper = 0f; + + public static float extraAngularForce = PhysicsGlobals.JointForce; + public static float extraAngularSpring = 60000f; + public static float extraAngularDamper = 0f; + + public static float extraBreakingForce = float.MaxValue; + public static float extraBreakingTorque = float.MaxValue; + + public static bool debug = false; + + public static List tempPartList; + public static int jc; // FEHLER, temp + + public static void LoadConstants() { PluginConfiguration config = PluginConfiguration.CreateForType(); config.load(); reinforceAttachNodes = config.GetValue("reinforceAttachNodes", true); - multiPartAttachNodeReinforcement = config.GetValue("multiPartAttachNodeReinforcement", false); - reinforceDecouplersFurther = config.GetValue("reinforceDecouplersFurther", false); - reinforceLaunchClampsFurther = config.GetValue("reinforceLaunchClampsFurther", false); reinforceInversions = config.GetValue("reinforceInversions", true); + addExtraStabilityJoints = config.GetValue("addExtraStabilityJoints", false); + reinforceLaunchClamps = config.GetValue("reinforceLaunchClamps", false); useVolumeNotArea = config.GetValue("useVolumeNotArea", true); massForAdjustment = (float)config.GetValue("massForAdjustment", 0.01f); - stiffeningExtensionMassRatioThreshold = (float)config.GetValue("stiffeningExtensionMassRatioThreshold", 5f); - - decouplerAndClampJointStrength = (float)config.GetValue("decouplerAndClampJointStrength", float.PositiveInfinity); - if(decouplerAndClampJointStrength < 0) - decouplerAndClampJointStrength = float.PositiveInfinity; angularDriveSpring = (float)config.GetValue("angularDriveSpring", 5e12f); angularDriveDamper = (float)config.GetValue("angularDriveDamper", 25f); @@ -60,124 +78,61 @@ public static void LoadConstants() breakStrengthPerArea = (float)config.GetValue("breakStrengthPerArea", 1500f); breakTorquePerMOI = (float)config.GetValue("breakTorquePerMOI", 6000f); - debug = config.GetValue("debug", false); + inversionMassFactor = (float)config.GetValue("inversionMassFactor", 2f); + solutionMassFactor = (float)config.GetValue("solutionMassFactor", 2f); + jointMassFactor = (float)config.GetValue("jointMassFactor", 8f); - if(debug) - { - StringBuilder debugString = new StringBuilder(); - debugString.AppendLine("\n\rAngular Drive: \n\rSpring: " + angularDriveSpring + "\n\rDamp: " + angularDriveDamper); + extraLevel = config.GetValue("extraLevel", 0); + + extraLinearForce = (float)config.GetValue("extraLinearForce", PhysicsGlobals.JointForce); + extraLinearSpring = (float)config.GetValue("extraLinearSpring", PhysicsGlobals.JointForce); + extraLinearDamper = (float)config.GetValue("extraLinearDamper", 0f); - debugString.AppendLine("\n\rJoint Strength Multipliers: \n\rForce Multiplier: " + breakForceMultiplier + "\n\rTorque Multiplier: " + breakTorqueMultiplier); - debugString.AppendLine("Joint Force Strength Per Unit Area: " + breakStrengthPerArea); - debugString.AppendLine("Joint Torque Strength Per Unit MOI: " + breakTorquePerMOI); + extraAngularForce = (float)config.GetValue("extraAngularForce", PhysicsGlobals.JointForce); + extraAngularSpring = (float)config.GetValue("extraAngularSpring", 60000f); + extraAngularDamper = (float)config.GetValue("extraAngularDamper", 0f); - debugString.AppendLine("Strength For Additional Decoupler And Clamp Joints: " + decouplerAndClampJointStrength); + extraBreakingForce = (float)config.GetValue("extraBreakingForce", float.MaxValue); + extraBreakingTorque = (float)config.GetValue("extraBreakingTorque", float.MaxValue); - debugString.AppendLine("\n\rDebug Output: " + debug); - debugString.AppendLine("Reinforce Attach Nodes: " + reinforceAttachNodes); - debugString.AppendLine("Reinforce Decouplers Further: " + reinforceDecouplersFurther); - debugString.AppendLine("Reinforce Launch Clamps Further: " + reinforceLaunchClampsFurther); - debugString.AppendLine("Use Volume For Calculations, Not Area: " + useVolumeNotArea); + debug = config.GetValue("debug", false); - debugString.AppendLine("\n\rMass For Joint Adjustment: " + massForAdjustment); +#if IncludeAnalyzer - debugString.AppendLine("\n\rDecoupler Stiffening Extension Mass Ratio Threshold: " + stiffeningExtensionMassRatioThreshold); + reinforceAttachNodes = true; + reinforceInversions = true; + addExtraStabilityJoints = true; + reinforceLaunchClamps = true; - Debug.Log(debugString.ToString()); - } +#endif + + loaded = true; } //////////////////////////////////////// // find part information - public static float MaximumPossiblePartMass(Part p) + public static float MaximumPossiblePartMass(Part part) { - float maxMass = p.mass; - foreach(PartResource r in p.Resources) + float maxMass = part.mass; + foreach(PartResource r in part.Resources) maxMass += (float)(r.info.density * r.maxAmount); if(debug) - Debug.Log("Maximum mass for part " + p.partInfo.title + " is " + maxMass); + Debug.Log("KJR: maximum mass for part " + part.partInfo.title + " is " + maxMass); return maxMass; } - public static Vector3 GuessUpVector(Part part) - { - // for intakes, use the intake vector - if(part.Modules.Contains()) - { - ModuleResourceIntake i = part.Modules.GetModule(); - Transform intakeTrans = part.FindModelTransform(i.intakeTransformName); - return part.transform.InverseTransformDirection(intakeTrans.forward); - } - - // if surface attachable, and node normal is up, check stack nodes or use forward - else if(part.srfAttachNode != null && - part.attachRules.srfAttach && - Mathf.Abs(part.srfAttachNode.orientation.normalized.y) > 0.9f) - { - // when the node normal is exactly Vector3.up, the editor orients forward along the craft axis - Vector3 dir = Vector3.forward; - bool first = true; - - foreach(AttachNode node in part.attachNodes) - { - // doesn't seem to ever happen, but anyway - if(node.nodeType == AttachNode.NodeType.Surface) - continue; - - // if all node orientations agree, use that axis - if(first) - { - first = false; - dir = node.orientation.normalized; - } - // conflicting node directions - bail out - else if(Mathf.Abs(Vector3.Dot(dir, node.orientation.normalized)) < 0.9f) - return Vector3.up; - } - - if(debug) - MonoBehaviour.print(part.partInfo.title + ": Choosing axis " + dir + " for KJR surface attach" + (first ? "" : " from node") + "."); - - return dir; - } - else - return Vector3.up; - } - - public static Vector3 CalculateExtents(Part p, Vector3 up) - { - up = up.normalized; - - // align y axis of the result to the 'up' vector in local coordinate space - if(Mathf.Abs(up.y) < 0.9f) - return CalculateExtents(p, Quaternion.FromToRotation(Vector3.up, up)); - - return CalculateExtents(p, Quaternion.identity); - } - - public static Vector3 CalculateExtents(Part p, Vector3 up, Vector3 forward) - { - // adjust forward to be orthogonal to up; LookRotation might do the opposite - Vector3.OrthoNormalize(ref up, ref forward); - - // align y to up and z to forward in local coordinate space - return CalculateExtents(p, Quaternion.LookRotation(forward, up)); - } - - public static Vector3 CalculateExtents(Part p, Quaternion alignment) + public static Vector3 CalculateExtents(Part part, Quaternion alignment) { Vector3 maxBounds = new Vector3(-100, -100, -100); Vector3 minBounds = new Vector3(100, 100, 100); - // alignment transforms from our desired rotation to the local coordinates, so inverse needed - Matrix4x4 rotation = Matrix4x4.TRS(Vector3.zero, Quaternion.Inverse(alignment), Vector3.one); - Matrix4x4 base_matrix = rotation * p.transform.worldToLocalMatrix; + Matrix4x4 base_matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Inverse(alignment), Vector3.one) * part.transform.worldToLocalMatrix; // get the max boundaries of the part - foreach (Transform t in p.FindModelComponents()) + foreach (Transform t in part.FindModelComponents()) { MeshFilter mf = t.GetComponent(); if((mf == null) || (mf.sharedMesh == null)) @@ -200,33 +155,15 @@ public static Vector3 CalculateExtents(Part p, Quaternion alignment) if(maxBounds == new Vector3(-100, -100, -100) && minBounds == new Vector3(100, 100, 100)) { - Debug.LogWarning("KerbalJointReinforcement: extents could not be properly built for part " + p.partInfo.title); + Debug.LogWarning("KJR: extents could not be properly built for part " + part.partInfo.title); maxBounds = minBounds = Vector3.zero; } else if(debug) - Debug.Log("Extents: " + minBounds + " .. " + maxBounds + " = " + (maxBounds - minBounds)); + Debug.Log("KJR: extents > " + minBounds + " .. " + maxBounds + " = " + (maxBounds - minBounds)); - // attachNodeLoc = p.transform.worldToLocalMatrix.MultiplyVector(p.parent.transform.position - p.transform.position); return maxBounds - minBounds; } - public static float CalculateRadius(Part p, Vector3 attachNodeLoc) - { - // y along attachNodeLoc; x,z orthogonal - Vector3 maxExtents = CalculateExtents(p, attachNodeLoc); - - // equivalent radius of an ellipse painted into the rectangle - return Mathf.Sqrt(maxExtents.x * maxExtents.z) / 2; - } - - public static float CalculateSideArea(Part p, Vector3 attachNodeLoc) - { - Vector3 maxExtents = CalculateExtents(p, attachNodeLoc); - // maxExtents = Vector3.Exclude(maxExtents, Vector3.up); - - return maxExtents.x * maxExtents.z; - } - //////////////////////////////////////// // find joint reinforcement information @@ -257,7 +194,7 @@ public static bool IsJointAdjustmentAllowed(Part p) if((module is KerbalEVA) || (module is ModuleWheelBase) || (module is ModuleGrappleNode) - || (module is LaunchClamp)) // FEHLER, ist das wirklich "not allowed"? ... oder müsste man das Launch-Clamp-Reinforcement nochmal überarbeiten? + || (module is LaunchClamp)) return false; } @@ -267,120 +204,256 @@ public static bool IsJointAdjustmentAllowed(Part p) return true; } - //////////////////////////////////////// - // find parts - - public static List DecouplerPartStiffeningListParents(Part p) +// default + public static bool CalculateStrength0(Part part, Part connectedPart, out float momentOfInertia, out float linearForce, out float torqueForce) { - List tmpPartList = new List(); + AttachNode an = part.FindAttachNodeByPart(connectedPart); + + float stackNodeFactor = 2f; + float srfNodeFactor = 0.8f; + + float breakingForceModifier = 1f; + float breakingTorqueModifier = 1f; + + linearForce = Mathf.Min(part.breakingForce, connectedPart.breakingForce) * + breakingForceModifier * + (an.size + 1f) * (part.attachMode == AttachModes.SRF_ATTACH ? srfNodeFactor : stackNodeFactor) + / part.attachJoint.joints.Count; + + torqueForce = Mathf.Min(part.breakingTorque, connectedPart.breakingTorque) * + breakingTorqueModifier * + (an.size + 1f) * (part.attachMode == AttachModes.SRF_ATTACH ? srfNodeFactor : stackNodeFactor) + / part.attachJoint.joints.Count; - // non-physical parts are skipped over by attachJoints, so do the same - bool extend = (p.physicalSignificance == Part.PhysicalSignificance.NONE); + momentOfInertia = 0f; // gibt's nicht hier - List newAdditions = new List(); + return true; + } + +// Ferram, old KJR + public static bool CalculateStrength(Part part, Part connectedPart, out float momentOfInertia, out float linearForce, out float torqueForce) + { + float partMass = part.mass + part.GetResourceMass(); - if(extend) + float parentMass = connectedPart.mass + connectedPart.GetResourceMass(); + + if(partMass < KJRJointUtils.massForAdjustment || parentMass < KJRJointUtils.massForAdjustment) { - if(p.parent && IsJointAdjustmentAllowed(p)) - newAdditions.AddRange(DecouplerPartStiffeningListParents(p.parent)); - } + if(KJRJointUtils.debug) + Debug.Log("KJR: part mass too low, skipping: " + part.partInfo.name + " (" + part.flightID + ")"); + + momentOfInertia = 0f; + linearForce = 0f; + torqueForce = 0f; + + return false; + } + + // default für stack ist 4, für srf 1.6 -> ich nehm mal fix 4 +KJRJointUtils.breakForceMultiplier = 4f; +KJRJointUtils.breakTorqueMultiplier = 4f; + + float breakForce = Math.Min(part.breakingForce, connectedPart.breakingForce) * KJRJointUtils.breakForceMultiplier; + float breakTorque = Math.Min(part.breakingTorque, connectedPart.breakingTorque) * KJRJointUtils.breakTorqueMultiplier; + + Quaternion up; + Vector3 anchor = part.attachJoint.joints[0].anchor; + for(int i = 1; i < part.attachJoint.joints.Count; i++) anchor += part.attachJoint.joints[i].anchor; + + if(anchor.magnitude > 0.05f) + up = Quaternion.FromToRotation(Vector3.up, anchor.normalized); + else if((connectedPart.transform.position - part.transform.position).magnitude > 0.05f) + up = Quaternion.FromToRotation(Vector3.up, part.transform.InverseTransformDirection((connectedPart.transform.position - part.transform.position)).normalized); else - { - if(p.parent && IsJointAdjustmentAllowed(p)) - { - float massRatio = MaximumPossiblePartMass(p.parent) / MaximumPossiblePartMass(p); + up = Quaternion.identity; + + Vector3 partExtents = CalculateExtents(part, up); - if(massRatio > stiffeningExtensionMassRatioThreshold) - { - newAdditions.Add(p.parent); - if(debug) - Debug.Log("Part " + p.parent.partInfo.title + " added to list due to mass ratio difference"); - } - } - } - if(newAdditions.Count > 0) - tmpPartList.AddRange(newAdditions); + Quaternion connectedUp; + Vector3 connectedAnchor = part.attachJoint.joints[0].connectedAnchor; + for(int i = 1; i < part.attachJoint.joints.Count; i++) connectedAnchor += part.attachJoint.joints[i].connectedAnchor; + + if(connectedAnchor.magnitude > 0.05f) + connectedUp = Quaternion.FromToRotation(Vector3.up, connectedAnchor.normalized); + else if((part.transform.position - connectedPart.transform.position).magnitude > 0.05f) + connectedUp = Quaternion.FromToRotation(Vector3.up, connectedPart.transform.InverseTransformDirection((part.transform.position - connectedPart.transform.position)).normalized); else - extend = false; + connectedUp = Quaternion.identity; - if(!extend) - tmpPartList.Add(p); + Vector3 connectedPartExtents = CalculateExtents(connectedPart, connectedUp); - return tmpPartList; - } - public static List DecouplerPartStiffeningListChildren(Part p) - { - List tmpPartList = new List(); + float radius = Mathf.Sqrt(partExtents.x * partExtents.z) / 2; + + float connectedRadius = Mathf.Sqrt(connectedPartExtents.x * connectedPartExtents.z) / 2; + - // non-physical parts are skipped over by attachJoints, so do the same - bool extend = (p.physicalSignificance == Part.PhysicalSignificance.NONE); + float usedRadius = Mathf.Min(radius, connectedRadius); - List newAdditions = new List(); + if(usedRadius < 0.001f) + usedRadius = 0.001f; - if(extend) + float area = Mathf.PI * usedRadius * usedRadius; // area of cylinder + momentOfInertia = area * usedRadius * usedRadius / 4; // moment of inertia of cylinder + + // if using volume, raise al stiffness-affecting parameters to the 1.5 power + if(KJRJointUtils.useVolumeNotArea) { - if(p.children != null) - { - foreach(Part q in p.children) - { - if(q != null && q.parent == p && IsJointAdjustmentAllowed(q)) - newAdditions.AddRange(DecouplerPartStiffeningListChildren(q)); - } - } + area = Mathf.Pow(area, 1.5f); + momentOfInertia = Mathf.Pow(momentOfInertia, 1.5f); } - else - { - if(p.children != null) - { - float thisPartMaxMass = MaximumPossiblePartMass(p); - foreach(Part q in p.children) - { - if(q != null && q.parent == p && IsJointAdjustmentAllowed(q)) - { - float massRatio = MaximumPossiblePartMass(q) / thisPartMaxMass; - - if(massRatio > stiffeningExtensionMassRatioThreshold) - { - newAdditions.Add(q); - if(debug) - Debug.Log("Part " + q.partInfo.title + " added to list due to mass ratio difference"); - } - } - } - } + linearForce = Mathf.Max(KJRJointUtils.breakStrengthPerArea * area, breakForce); + torqueForce = Mathf.Max(KJRJointUtils.breakTorquePerMOI * momentOfInertia, breakTorque); + + return true; + } + +// contactArea + public static bool CalculateStrength2(Part part, Part connectedPart, out float momentOfInertia, out float linearForce, out float torqueForce) + { + AttachNode an2 = part.FindAttachNodeByPart(connectedPart); + + float area = an2.contactArea; + momentOfInertia = area * (area / Mathf.PI) / 4; // moment of inertia of cylinder + + // if using volume, raise al stiffness-affecting parameters to the 1.5 power + if(KJRJointUtils.useVolumeNotArea) + { + area = Mathf.Pow(area, 1.5f); + momentOfInertia = Mathf.Pow(momentOfInertia, 1.5f); } - if(newAdditions.Count > 0) - tmpPartList.AddRange(newAdditions); - else - extend = false; - if(!extend) - tmpPartList.Add(p); + // default für stack ist 4, für srf 1.6 -> ich nehm mal fix 4 +KJRJointUtils.breakForceMultiplier = 4f; +KJRJointUtils.breakTorqueMultiplier = 4f; - return tmpPartList; + float breakForce = Math.Min(part.breakingForce, connectedPart.breakingForce) * KJRJointUtils.breakForceMultiplier; + float breakTorque = Math.Min(part.breakingTorque, connectedPart.breakingTorque) * KJRJointUtils.breakTorqueMultiplier; + + + linearForce = Mathf.Max(KJRJointUtils.breakStrengthPerArea * area, breakForce); + torqueForce = Mathf.Max(KJRJointUtils.breakTorquePerMOI * momentOfInertia, breakTorque); + + +// shadow -> never go below stock + + float stackNodeFactor = 2f; + float srfNodeFactor = 0.8f; + + float breakingForceModifier = 1f; + float breakingTorqueModifier = 1f; + + float defaultLinearForce = Mathf.Min(part.breakingForce, connectedPart.breakingForce) * + breakingForceModifier * + (an2.size + 1f) * (part.attachMode == AttachModes.SRF_ATTACH ? srfNodeFactor : stackNodeFactor) + / part.attachJoint.joints.Count; + + float defaultTorqueForce = Mathf.Min(part.breakingTorque, connectedPart.breakingTorque) * + breakingTorqueModifier * + (an2.size + 1f) * (part.attachMode == AttachModes.SRF_ATTACH ? srfNodeFactor : stackNodeFactor) + / part.attachJoint.joints.Count; + + linearForce = Mathf.Max(linearForce, defaultLinearForce); + torqueForce = Mathf.Max(torqueForce, defaultTorqueForce); + + return true; } - public static void FindRootsAndEndPoints(Part part, ref Dictionary> childPartsToConnectByRoot) + public static void CalculateOverallStrength(Part part, Part linkPart, + ref float ang_maximumForce, ref float ang_positionSpring, ref float ang_positionDamper, ref float lin_maximumForce, ref float lin_positionSpring, ref float lin_positionDamper, ref float breakForce, ref float breakTorque) { - if(part.rb) + if(part == null) { - List _endpoints = new List(); - childPartsToConnectByRoot.Add(part, _endpoints); - - FindEndPoints(part, ref _endpoints, ref childPartsToConnectByRoot); + Debug.LogError("KJR: CalculateOverallStrength -> part chain not found"); + return; } - else + + ConfigurableJoint j = part.attachJoint.joints[0]; + + ang_maximumForce = Mathf.Min(ang_maximumForce, j.angularXDrive.maximumForce); + ang_positionSpring = Mathf.Min(ang_positionSpring, j.angularXDrive.positionSpring); + ang_positionDamper = Mathf.Min(ang_positionDamper, j.angularXDrive.positionDamper); + lin_maximumForce = Mathf.Min(lin_maximumForce, j.xDrive.maximumForce); + lin_positionSpring = Mathf.Min(lin_positionSpring, j.xDrive.positionSpring); + lin_positionDamper = Mathf.Min(lin_positionDamper, j.xDrive.positionDamper); + breakForce = Mathf.Min(breakForce, j.breakForce); + breakTorque = Mathf.Min(breakTorque, j.breakTorque); + + if(part.parent.RigidBodyPart != linkPart) + CalculateOverallStrength(part.parent.RigidBodyPart, linkPart, + ref ang_maximumForce, ref ang_positionSpring, ref ang_positionDamper, ref lin_maximumForce, ref lin_positionSpring, ref lin_positionDamper, ref breakForce, ref breakTorque); + } + + //////////////////////////////////////// + // find parts + + // creates a link set from the part to its root (or the first parent that cannot be used) + // the set contains also the part and the root and is intended to be used as input for BuildLinkSetDifference + + public static void BuildLinkSetConditional(Part part, ref List set) + { + while(part != null) { - foreach(Part child in part.children) - FindRootsAndEndPoints(child, ref childPartsToConnectByRoot); + set.Add(part); + part = KJRJointUtils.IsJointAdjustmentAllowed(part) ? part.parent : null; } } - public static bool FindEndPoints(Part part, ref List endpoints, ref Dictionary> childPartsToConnectByRoot) + // creates a link set from the part to the specified root + // the set contains also the part and the root and is intended to be used as input for BuildLinkSetDifference + + public static void BuildLinkSet(Part part, Part root, ref List set) + { +// do { set.Add(part); part = part.parent; } while(part != root); +// set.Add(part); + + set.Add(part); + BuildLinkSetDirect(part.parent, root, ref set); + set.Add(root); + } + + // creates a link set from the part to the specified root + // the result is a usable linkset + + public static void BuildLinkSetDirect(Part part, Part root, ref List set) + { + while(part != root) + { set.Add(part); part = part.parent; } + } + + // creates a link set from two input link sets by finding the common parts + // the result is a usable linkset + + public static bool BuildLinkSetDifference(ref List result, ref int root, ref List set1, ref List set2) + { + int i = set1.Count - 1; + int j = set2.Count - 1; + + if(set1[i] != set2[j]) + return false; // not same root, so they can never be in a valid set + + while((i >= 0) && (j >= 0) && (set1[i] == set2[j])) + { --i; --j; } + + if(i + j < 0) + return false; // set would be empty + + result = new List(i + 1 + j); + root = i; + + for(int _i = 1; _i <= i + 1; _i++) + result.Add(set1[_i]); + + for(int _j = j; _j >= 1; _j--) + result.Add(set1[_j]); + + return true; + } + + private static bool FindEndPoints(Part part, ref List endpoints, ref Dictionary> childPartsToConnectByRoot) { bool bResult = false; @@ -393,7 +466,7 @@ public static bool FindEndPoints(Part part, ref List endpoints, ref Dictio } if(!bResult - && part.rb + && (part.rb != null) && IsJointAdjustmentAllowed(part) && (MaximumPossiblePartMass(part) > massForAdjustment)) { @@ -405,24 +478,85 @@ public static bool FindEndPoints(Part part, ref List endpoints, ref Dictio return bResult; } + public static void FindRootsAndEndPoints(Part part, ref Dictionary> childPartsToConnectByRoot) + { + if(part.rb) + { + List _endpoints = new List(); + childPartsToConnectByRoot.Add(part, _endpoints); + + FindEndPoints(part, ref _endpoints, ref childPartsToConnectByRoot); + } + else + { + foreach(Part child in part.children) + FindRootsAndEndPoints(child, ref childPartsToConnectByRoot); + } + } + + public class Sol2 + { + public Sol2(Part _part, Part _linkPart) + { + part = _part; + linkPart = _linkPart; + + angularForce = float.PositiveInfinity; + angularSpring = float.PositiveInfinity; + angularDamper = float.PositiveInfinity; + linearForce = float.PositiveInfinity; + linearSpring = float.PositiveInfinity; + linearDamper = float.PositiveInfinity; + breakingForce = float.PositiveInfinity; + breakingTorque = float.PositiveInfinity; + } + + public Part part; + public Part linkPart; + + public List set; + public int ridx; + + public float angularForce; + public float angularSpring; + public float angularDamper; + public float linearForce; + public float linearSpring; + public float linearDamper; + public float breakingForce; + public float breakingTorque; + }; + + static int compareSol(Sol2 left, Sol2 right) + { + return left.set.Count - right.set.Count; + } + // search for a bad mass configuration // (a much lighter part on the way up to the root) + public static bool IsInversion(Part part, out Part parent) { parent = part; while(parent = IsJointAdjustmentAllowed(parent) ? parent.parent : null) { - if((parent.rb != null) // only when physical significant - && (part.mass > parent.mass * 2f)) - return true; + if(parent.rb != null) // only when physical significant + { + if(part.mass > parent.mass * inversionMassFactor) + return true; // inversion found + + if(parent.mass * solutionMassFactor >= part.mass) + return false; // heavy parent found -> that's enough as anchor for us + } } - return false; + return false; // no inversion found, but also no realy heavy parent -> that's ok for us } // search for a part that could be used as anchor to solve the bad mass configuration // (a part that is heavy enough on the way up to the root) + public static bool FindInversionResolution(Part part, Part parent, out Part inversionResolution) { inversionResolution = parent; @@ -439,12 +573,30 @@ public static bool FindInversionResolution(Part part, Part parent, out Part inve } } - // we don't try to find a heavy child to connect to, because it feels wrong + return inversionResolution.mass * solutionMassFactor >= part.mass; + } + + public static bool FindChildInversionResolutions(Part part, Part current, ref List set) + { + if(current == part) + return set.Count > 0; // ich selber und alles was an mir hängt ist keine Lösung um meine Verbindung zum Schiff stabiler zu machen + + if(!IsJointAdjustmentAllowed(current)) + return set.Count > 0; // weil, weiter geht's nicht + + if((current.rb != null) // only when physical significant + && (current.mass * solutionMassFactor >= part.mass)) + { + set.Add(current); + } + + for(int i = 0; i < current.children.Count; i++) + FindChildInversionResolutions(part, current.children[i], ref set); - return inversionResolution.mass * 2f >= part.mass; // the found part is acceptable, when it has at least half the mass of part + return set.Count > 0; } - public static void FindInversionAndResolutions(Part part, ref Dictionary inversionResolutions) + public static void FindInversionAndResolutions(Part part, ref List sols, ref List unresolved) { Part parent; @@ -452,34 +604,170 @@ public static void FindInversionAndResolutions(Part part, ref Dictionary= KJRJointUtils.massForAdjustment) && IsInversion(part, out parent)) { - Part inversionResolution; + Part linkPart; - if(FindInversionResolution(part, parent, out inversionResolution)) + if(FindInversionResolution(part, parent, out linkPart)) { - inversionResolutions.Add(part, inversionResolution); + Sol2 sol = new Sol2(part, linkPart); + + sol.set = new List(); + BuildLinkSetDirect(part.parent, linkPart, ref sol.set); + + // hab jetzt das, jetzt bau ich mir die Stärke davon + + CalculateOverallStrength(sol.part, sol.linkPart, + ref sol.angularForce, ref sol.angularSpring, ref sol.angularDamper, ref sol.linearForce, ref sol.linearSpring, ref sol.linearDamper, ref sol.breakingForce, ref sol.breakingTorque); + + sols.Add(sol); } + else + unresolved.Add(part); } foreach(Part child in part.children) - FindInversionAndResolutions(child, ref inversionResolutions); + FindInversionAndResolutions(child, ref sols, ref unresolved); + } + + public static void FindChildInversionResolution(Part part, ref List sols, ref List unresolved) + { + Part root = part; + while(root.parent && IsJointAdjustmentAllowed(root)) + root = root.parent; + + if(!FindChildInversionResolutions(part, root, ref tempPartList)) + return; // hat keinen Sinn + + List set1 = new List(); + BuildLinkSet(part, root, ref set1); + + List set2 = new List(); + + List allSols = new List(); + + bool onlyResolved = true; + retry: + + for(int i = 0; i < tempPartList.Count; i++) + { + if(onlyResolved && + unresolved.Contains(tempPartList[i])) + continue; + + set2.Clear(); + BuildLinkSet(tempPartList[i], root, ref set2); + + Sol2 sol = new Sol2(part, tempPartList[i]); + + sol.set = null; + sol.ridx = 0; + if(!BuildLinkSetDifference(ref sol.set, ref sol.ridx, ref set1, ref set2)) + continue; + + CalculateOverallStrength(sol.part, sol.set[sol.ridx], + ref sol.angularForce, ref sol.angularSpring, ref sol.angularDamper, ref sol.linearForce, ref sol.linearSpring, ref sol.linearDamper, ref sol.breakingForce, ref sol.breakingTorque); + + CalculateOverallStrength(sol.linkPart, sol.set[sol.ridx], + ref sol.angularForce, ref sol.angularSpring, ref sol.angularDamper, ref sol.linearForce, ref sol.linearSpring, ref sol.linearDamper, ref sol.breakingForce, ref sol.breakingTorque); + + allSols.Add(sol); + } + + if(onlyResolved && (allSols.Count == 0)) + { + onlyResolved = false; + goto retry; + } + + // habe alle sol's... jetzt rechnen, welche ich nehme + + allSols.Sort(compareSol); + + int idx = 0; + for(int i = 1; i < allSols.Count; i++) + { + if(allSols[idx].breakingForce < allSols[i].breakingForce) // FEHLER, oder nach Länge beurteilen? oder die anderen Lösungen nicht nach Gewicht, sondern auch nach force? oder hier noch nach Gewicht urteilen? + idx = i; + } + + sols.Add(allSols[idx]); } //////////////////////////////////////// // build joints - public static ConfigurableJoint BuildJoint(Part part, Part linkPart, JointDrive xDrive, JointDrive yDrive, JointDrive zDrive, JointDrive angularDrive, float linearStrength, float angularStrength) + public static ConfigurableJoint BuildJoint(Sol2 s) + { + ++jc; + + ConfigurableJoint newJoint; + + // remark: do not reverse the joint / it is essential for a correct handling of breaking joints + + newJoint = s.part.gameObject.AddComponent(); + newJoint.connectedBody = s.linkPart.Rigidbody; + + newJoint.anchor = Vector3.zero; + + newJoint.autoConfigureConnectedAnchor = false; + newJoint.connectedAnchor = Quaternion.Inverse(s.linkPart.orgRot) * (s.part.orgPos - s.linkPart.orgPos); + newJoint.SetTargetRotationLocal((Quaternion.Inverse(s.part.transform.rotation) * s.linkPart.transform.rotation * (Quaternion.Inverse(s.linkPart.orgRot) * s.part.orgRot)).normalized, Quaternion.identity); + + newJoint.xMotion = newJoint.yMotion = newJoint.zMotion = ConfigurableJointMotion.Limited; + newJoint.angularYMotion = newJoint.angularZMotion = newJoint.angularXMotion = ConfigurableJointMotion.Limited; + + JointDrive angularDrive = new JointDrive { maximumForce = s.angularForce, positionSpring = s.angularSpring, positionDamper = s.angularDamper }; + newJoint.angularXDrive = newJoint.angularYZDrive = newJoint.slerpDrive = angularDrive; + + JointDrive linearDrive = new JointDrive { maximumForce = s.linearForce, positionSpring = s.linearSpring, positionDamper = s.linearDamper }; + newJoint.xDrive = newJoint.yDrive = newJoint.zDrive = linearDrive; + + newJoint.linearLimit = newJoint.angularYLimit = newJoint.angularZLimit = newJoint.lowAngularXLimit = newJoint.highAngularXLimit + = new SoftJointLimit { limit = 0, bounciness = 0 }; + newJoint.linearLimitSpring = newJoint.angularYZLimitSpring = newJoint.angularXLimitSpring + = new SoftJointLimitSpring { spring = 0, damper = 0 }; + + SoftJointLimit angularLimit = default(SoftJointLimit); + angularLimit.limit = 180f; + angularLimit.bounciness = 0f; + + SoftJointLimitSpring angularLimitSpring = default(SoftJointLimitSpring); + angularLimitSpring.spring = 0f; + angularLimitSpring.damper = 0f; + + SoftJointLimit linearJointLimit = default(SoftJointLimit); + linearJointLimit.limit = 1f; + linearJointLimit.bounciness = 0f; + + SoftJointLimitSpring linearJointLimitSpring = default(SoftJointLimitSpring); + linearJointLimitSpring.damper = 0f; + linearJointLimitSpring.spring = 0f; + + newJoint.rotationDriveMode = RotationDriveMode.XYAndZ; + newJoint.highAngularXLimit = angularLimit; + newJoint.lowAngularXLimit = angularLimit; + newJoint.angularYLimit = angularLimit; + newJoint.angularZLimit = angularLimit; + newJoint.angularXLimitSpring = angularLimitSpring; + newJoint.angularYZLimitSpring = angularLimitSpring; + newJoint.linearLimit = linearJointLimit; + newJoint.linearLimitSpring = linearJointLimitSpring; + + newJoint.breakForce = s.breakingForce; + newJoint.breakTorque = s.breakingTorque; + + return newJoint; + } + + public static ConfigurableJoint BuildExtraJoint(Part part, Part linkPart) { + ++jc; + ConfigurableJoint newJoint; + // reverse the joint for even better stability if((part.mass < linkPart.mass) && (part.rb != null)) { Part t = part; part = linkPart; linkPart = t; } -// FEHLER, xtreme-Debugging, darf nicht mehr passieren jetzt -if(part.rb == null) - Debug.LogError("KJR: BuildJoint -> p.rb == null!!!!!"); -if(linkPart.rb == null) - Debug.LogError("KJR: BuildJoint -> linkPart.rb == null!!!!!"); - newJoint = part.gameObject.AddComponent(); newJoint.connectedBody = linkPart.Rigidbody; @@ -492,118 +780,128 @@ public static ConfigurableJoint BuildJoint(Part part, Part linkPart, JointDrive newJoint.xMotion = newJoint.yMotion = newJoint.zMotion = ConfigurableJointMotion.Free; newJoint.angularYMotion = newJoint.angularZMotion = newJoint.angularXMotion = ConfigurableJointMotion.Free; - newJoint.xDrive = xDrive; newJoint.yDrive = yDrive; newJoint.zDrive = zDrive; + JointDrive angularDrive = new JointDrive { maximumForce = (extraLevel == 0) ? 10f : extraAngularForce, positionSpring = extraAngularSpring, positionDamper = extraAngularDamper }; newJoint.angularXDrive = newJoint.angularYZDrive = angularDrive; - newJoint.breakForce = linearStrength; - newJoint.breakTorque = angularStrength; + JointDrive linearDrive = new JointDrive { maximumForce = (extraLevel == 0) ? 10f : extraLinearForce, positionSpring = extraLinearSpring, positionDamper = extraLinearDamper }; + newJoint.xDrive = newJoint.yDrive = newJoint.zDrive = linearDrive; + + newJoint.breakForce = extraBreakingForce; + newJoint.breakTorque = extraBreakingTorque; return newJoint; } - public static ConfigurableJoint BuildJoint(Part p, Part linkPart) + public static void ConnectLaunchClampToGround(Part clamp) { - JointDrive linearDrive = new JointDrive { maximumForce = PhysicsGlobals.JointForce, positionSpring = PhysicsGlobals.JointForce }; - - return BuildJoint(p, linkPart, - linearDrive, linearDrive, linearDrive, - new JointDrive { maximumForce = PhysicsGlobals.JointForce, positionSpring = 60000f }, - decouplerAndClampJointStrength, decouplerAndClampJointStrength); + FixedJoint newJoint = clamp.gameObject.AddComponent(); + newJoint.connectedBody = null; + newJoint.breakForce = float.MaxValue; + newJoint.breakTorque = float.MaxValue; } - public static void ConnectLaunchClampToGround(Part clamp) - { - float breakForce = Mathf.Infinity; - float breakTorque = Mathf.Infinity; - FixedJoint newJoint; - newJoint = clamp.gameObject.AddComponent(); - newJoint.connectedBody = null; - newJoint.anchor = Vector3.zero; - newJoint.axis = Vector3.up; - //newJoint.secondaryAxis = Vector3.forward; - newJoint.breakForce = breakForce; - newJoint.breakTorque = breakTorque; - //newJoint.xMotion = newJoint.yMotion = newJoint.zMotion = ConfigurableJointMotion.Locked; - //newJoint.angularXMotion = newJoint.angularYMotion = newJoint.angularZMotion = ConfigurableJointMotion.Locked; - } -// FEHLER, das hier baut sowas auf wie der attach-Joint und macht das auch nach den Regeln von oben -// ausser, dass die breakForce und so nicht zwischen den Teils ist, sondern das minimum aller Teils dazwischen - public static void MoveFromTo(Part part, Part linkPart, - ref float ang_positionSpring, ref float ang_positionDamper, ref float ang_maximumForce, ref float lin_positionSpring, ref float lin_positionDamper, ref float lin_maximumForce, ref float breakForce, ref float breakTorque) + + + + + + + + + + + + + + + public static Vector3 GuessUpVector(Part part) { - if(part == null) + // for intakes, use the intake vector + if(part.Modules.Contains()) { - Debug.LogError("KJR: MoveFromTo -> not found!!!!!"); - return; + ModuleResourceIntake i = part.Modules.GetModule(); + Transform intakeTrans = part.FindModelTransform(i.intakeTransformName); + return part.transform.InverseTransformDirection(intakeTrans.forward); } - ConfigurableJoint j = part.attachJoint.joints[0]; + // if surface attachable, and node normal is up, check stack nodes or use forward + else if(part.srfAttachNode != null && + part.attachRules.srfAttach && + Mathf.Abs(part.srfAttachNode.orientation.normalized.y) > 0.9f) + { + // when the node normal is exactly Vector3.up, the editor orients forward along the craft axis + Vector3 dir = Vector3.forward; + bool first = true; - ang_positionSpring = Mathf.Min(ang_positionSpring, j.angularXDrive.positionSpring); - ang_positionDamper = Mathf.Min(ang_positionDamper, j.angularXDrive.positionDamper); - ang_maximumForce = Mathf.Min(ang_maximumForce, j.angularXDrive.maximumForce); - lin_positionSpring = Mathf.Min(lin_positionSpring, j.xDrive.positionSpring); - lin_positionDamper = Mathf.Min(lin_positionDamper, j.xDrive.positionDamper); - lin_maximumForce = Mathf.Min(lin_maximumForce, j.xDrive.maximumForce); - breakForce = Mathf.Min(breakForce, j.breakForce); - breakTorque = Mathf.Min(breakTorque, j.breakTorque); + foreach(AttachNode node in part.attachNodes) + { + // doesn't seem to ever happen, but anyway + if(node.nodeType == AttachNode.NodeType.Surface) + continue; - if(part.parent.RigidBodyPart != linkPart) - MoveFromTo(part.parent.RigidBodyPart, linkPart, - ref ang_positionSpring, ref ang_positionDamper, ref ang_maximumForce, ref lin_positionSpring, ref lin_positionDamper, ref lin_maximumForce, ref breakForce, ref breakTorque); + // if all node orientations agree, use that axis + if(first) + { + first = false; + dir = node.orientation.normalized; + } + // conflicting node directions - bail out + else if(Mathf.Abs(Vector3.Dot(dir, node.orientation.normalized)) < 0.9f) + return Vector3.up; + } + + if(debug) + MonoBehaviour.print(part.partInfo.title + ": Choosing axis " + dir + " for KJR surface attach" + (first ? "" : " from node") + "."); + + return dir; + } + else + return Vector3.up; } - public static ConfigurableJoint BuildJoint2(Part part, Part linkPart) + public static Vector3 CalculateExtents(Part p, Vector3 up) { - float ang_positionSpring = float.PositiveInfinity; - float ang_positionDamper = float.PositiveInfinity; - float ang_maximumForce = float.PositiveInfinity; - float lin_positionSpring = float.PositiveInfinity; - float lin_positionDamper = float.PositiveInfinity; - float lin_maximumForce = float.PositiveInfinity; - float breakForce = float.PositiveInfinity; - float breakTorque = float.PositiveInfinity; - - MoveFromTo(part, linkPart, - ref ang_positionSpring, ref ang_positionDamper, ref ang_maximumForce, ref lin_positionSpring, ref lin_positionDamper, ref lin_maximumForce, ref breakForce, ref breakTorque); + up = up.normalized; - ConfigurableJoint newJoint; + // align y axis of the result to the 'up' vector in local coordinate space + if(Mathf.Abs(up.y) < 0.9f) + return CalculateExtents(p, Quaternion.FromToRotation(Vector3.up, up)); - if((part.mass < linkPart.mass) && (part.rb != null)) - { Part t = part; part = linkPart; linkPart = t; } + return CalculateExtents(p, Quaternion.identity); + } - newJoint = part.gameObject.AddComponent(); - newJoint.connectedBody = linkPart.Rigidbody; + public static Vector3 CalculateExtents(Part p, Vector3 up, Vector3 forward) + { + // adjust forward to be orthogonal to up; LookRotation might do the opposite + Vector3.OrthoNormalize(ref up, ref forward); - newJoint.anchor = Vector3.zero; + // align y to up and z to forward in local coordinate space + return CalculateExtents(p, Quaternion.LookRotation(forward, up)); + } - newJoint.autoConfigureConnectedAnchor = false; - newJoint.connectedAnchor = Quaternion.Inverse(linkPart.orgRot) * (part.orgPos - linkPart.orgPos); - newJoint.SetTargetRotationLocal((Quaternion.Inverse(part.transform.rotation) * linkPart.transform.rotation * (Quaternion.Inverse(linkPart.orgRot) * part.orgRot)).normalized, Quaternion.identity); + public static float CalculateRadius(Part p, Vector3 attachNodeLoc) + { + // y along attachNodeLoc; x,z orthogonal + Vector3 maxExtents = CalculateExtents(p, attachNodeLoc); - newJoint.xMotion = newJoint.yMotion = newJoint.zMotion = ConfigurableJointMotion.Free; - newJoint.angularYMotion = newJoint.angularZMotion = newJoint.angularXMotion = ConfigurableJointMotion.Free; + // equivalent radius of an ellipse painted into the rectangle + return Mathf.Sqrt(maxExtents.x * maxExtents.z) / 2; + } - JointDrive angDrive = new JointDrive { positionSpring = ang_positionSpring, positionDamper = ang_positionDamper, maximumForce = ang_maximumForce }; - newJoint.angularXDrive = newJoint.angularYZDrive = newJoint.slerpDrive = angDrive; + public static float CalculateSideArea(Part p, Vector3 attachNodeLoc) + { + Vector3 maxExtents = CalculateExtents(p, attachNodeLoc); + // maxExtents = Vector3.Exclude(maxExtents, Vector3.up); - JointDrive linDrive = new JointDrive { positionSpring = lin_positionSpring, positionDamper = lin_positionDamper, maximumForce = lin_maximumForce }; - newJoint.xDrive = newJoint.yDrive = newJoint.zDrive = linDrive; + return maxExtents.x * maxExtents.z; + } - newJoint.linearLimit = newJoint.angularYLimit = newJoint.angularZLimit = newJoint.lowAngularXLimit = newJoint.highAngularXLimit - = new SoftJointLimit { limit = 0, bounciness = 0 }; - newJoint.linearLimitSpring = newJoint.angularYZLimitSpring = newJoint.angularXLimitSpring - = new SoftJointLimitSpring { spring = 0, damper = 0 }; - newJoint.breakForce = breakForce; - newJoint.breakTorque = breakTorque; - return newJoint; - } } } diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/KJRManager.cs b/KerbalJointReinforcement/KerbalJointReinforcement/KJRManager.cs index 2e30959..b78e03d 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/KJRManager.cs +++ b/KerbalJointReinforcement/KerbalJointReinforcement/KJRManager.cs @@ -99,8 +99,15 @@ IEnumerator RunVesselJointUpdateFunctionDelayed(Vessel v) { updatingVessels.Remove(v); +KJRJointUtils.jc = 0; RunVesselJointUpdateFunction(v); +ScreenMessages.PostScreenMessage("KJR joints built: " + KJRJointUtils.jc, 30, ScreenMessageStyle.UPPER_CENTER); + + foreach(Part p in v.Parts) + p.ReleaseAutoStruts(); // FEHLER, weiss halt nicht + + #if IncludeAnalyzer KJRAnalyzerJoint.RunVesselJointUpdateFunction(v); @@ -307,19 +314,7 @@ private void RunVesselJointUpdateFunction(Vessel v) } } - if(KJRJointUtils.reinforceDecouplersFurther) - { - ModuleDecouplerBase d = p.GetComponent(); // FEHLER, wieso nicht auch ModuleDockingNode ?? - - if(p.parent && (p.children.Count > 0) && d && !d.isDecoupled) - { - bReinforced = true; - ReinforceDecouplers(p); - continue; - } - } - - if(KJRJointUtils.reinforceLaunchClampsFurther) + if(KJRJointUtils.reinforceLaunchClamps) { if(p.parent && p.GetComponent()) { @@ -332,22 +327,38 @@ private void RunVesselJointUpdateFunction(Vessel v) } #endif - if(bReinforced && !updatedVessels.Contains(v)) - updatedVessels.Add(v); - - if(bReinforced && KJRJointUtils.reinforceAttachNodes && KJRJointUtils.multiPartAttachNodeReinforcement) - MultiPartJointTreeChildren(v); - #if IncludeAnalyzer if(WindowManager.Instance.ReinforceInversions) { #endif - if(bReinforced && KJRJointUtils.reinforceInversions) + if(KJRJointUtils.reinforceInversions) + { ReinforceInversions(v); + bReinforced = true; + } + +#if IncludeAnalyzer + } +#endif + +#if IncludeAnalyzer + if(WindowManager.Instance.BuildExtraStabilityJoints) + { +#endif + if(KJRJointUtils.addExtraStabilityJoints) + { + if(KJRJointUtils.extraLevel >= 2) + AdditionalJointsToParent(v); + AdditionalJointsBetweenEndpoints(v); + bReinforced = true; + } #if IncludeAnalyzer } #endif + + if(bReinforced && !updatedVessels.Contains(v)) + updatedVessels.Add(v); } #if IncludeAnalyzer @@ -360,6 +371,12 @@ public void FixedUpdate() } #endif +static bool TakeNew = false; + static float _l = 0.9f; + static float _u = 1.1f; + +static int calctype = 2; + // attachJoint's are always joints from a part to its parent private void ReinforceAttachJoints(Part p) { @@ -374,8 +391,10 @@ private void ReinforceAttachJoints(Part p) List jointList; - if(p.Modules.Contains()) + if(p.Modules.Contains()) // FEHLER, wieso dann nicht? { +float decouplerAndClampJointStrength = float.MaxValue; // FEHLER, temp, neue Zwischenlösung + CModuleStrut s = p.Modules.GetModule(); if((s.jointTarget != null) && (s.jointRoot != null)) @@ -392,8 +411,8 @@ private void ReinforceAttachJoints(Part p) continue; JointDrive strutDrive = j.angularXDrive; - strutDrive.positionSpring = KJRJointUtils.decouplerAndClampJointStrength; - strutDrive.maximumForce = KJRJointUtils.decouplerAndClampJointStrength; + strutDrive.positionSpring = decouplerAndClampJointStrength; + strutDrive.maximumForce = decouplerAndClampJointStrength; j.xDrive = j.yDrive = j.zDrive = j.angularXDrive = j.angularYZDrive = strutDrive; j.xMotion = j.yMotion = j.zMotion = ConfigurableJointMotion.Locked; @@ -401,8 +420,8 @@ private void ReinforceAttachJoints(Part p) //float scalingFactor = (s.jointTarget.mass + s.jointTarget.GetResourceMass() + s.jointRoot.mass + s.jointRoot.GetResourceMass()) * 0.01f; - j.breakForce = KJRJointUtils.decouplerAndClampJointStrength; - j.breakTorque = KJRJointUtils.decouplerAndClampJointStrength; + j.breakForce = decouplerAndClampJointStrength; + j.breakTorque = decouplerAndClampJointStrength; } p.attachMethod = AttachNodeMethod.LOCKED_JOINT; @@ -417,9 +436,6 @@ private void ReinforceAttachJoints(Part p) StringBuilder debugString = KJRJointUtils.debug ? new StringBuilder() : null; - bool addAdditionalJointToParent = KJRJointUtils.multiPartAttachNodeReinforcement; - addAdditionalJointToParent &= !p.Modules.Contains(); - if(!KJRJointUtils.IsJointUnlockable(p)) // exclude those actions from joints that can be dynamically unlocked { float partMass = p.mass + p.GetResourceMass(); @@ -467,63 +483,6 @@ private void ReinforceAttachJoints(Part p) if(node == null && p.attachMode == AttachModes.SRF_ATTACH) node = attach = p.srfAttachNode; - if(KJRJointUtils.debug) - { - debugString.AppendLine("Original joint from " + p.partInfo.title + " to " + p.parent.partInfo.title); - debugString.AppendLine(" " + p.partInfo.name + " (" + p.flightID + ") -> " + p.parent.partInfo.name + " (" + p.parent.flightID + ")"); - debugString.AppendLine(""); - debugString.AppendLine(p.partInfo.title + " Inertia Tensor: " + p.rb.inertiaTensor + " " + p.parent.partInfo.name + " Inertia Tensor: " + connectedBody.inertiaTensor); - debugString.AppendLine(""); - - - debugString.AppendLine("Std. Joint Parameters"); - debugString.AppendLine("Connected Body: " + p.attachJoint.Joint.connectedBody); - debugString.AppendLine("Attach mode: " + p.attachMode + " (was " + j.GetType().Name + ")"); - if(attach != null) - debugString.AppendLine("Attach node: " + attach.id + " - " + attach.nodeType + " " + attach.size); - if(p_attach != null) - debugString.AppendLine("Parent node: " + p_attach.id + " - " + p_attach.nodeType + " " + p_attach.size); - debugString.AppendLine("Anchor: " + p.attachJoint.Joint.anchor); - debugString.AppendLine("Axis: " + p.attachJoint.Joint.axis); - debugString.AppendLine("Sec Axis: " + p.attachJoint.Joint.secondaryAxis); - debugString.AppendLine("Break Force: " + p.attachJoint.Joint.breakForce); - debugString.AppendLine("Break Torque: " + p.attachJoint.Joint.breakTorque); - debugString.AppendLine(""); - - debugString.AppendLine("Joint Motion Locked: " + Convert.ToString(p.attachJoint.Joint.xMotion == ConfigurableJointMotion.Locked)); - - debugString.AppendLine("X Drive"); - debugString.AppendLine("Position Spring: " + p.attachJoint.Joint.xDrive.positionSpring); - debugString.AppendLine("Position Damper: " + p.attachJoint.Joint.xDrive.positionDamper); - debugString.AppendLine("Max Force: " + p.attachJoint.Joint.xDrive.maximumForce); - debugString.AppendLine(""); - - debugString.AppendLine("Y Drive"); - debugString.AppendLine("Position Spring: " + p.attachJoint.Joint.yDrive.positionSpring); - debugString.AppendLine("Position Damper: " + p.attachJoint.Joint.yDrive.positionDamper); - debugString.AppendLine("Max Force: " + p.attachJoint.Joint.yDrive.maximumForce); - debugString.AppendLine(""); - - debugString.AppendLine("Z Drive"); - debugString.AppendLine("Position Spring: " + p.attachJoint.Joint.zDrive.positionSpring); - debugString.AppendLine("Position Damper: " + p.attachJoint.Joint.zDrive.positionDamper); - debugString.AppendLine("Max Force: " + p.attachJoint.Joint.zDrive.maximumForce); - debugString.AppendLine(""); - - debugString.AppendLine("Angular X Drive"); - debugString.AppendLine("Position Spring: " + p.attachJoint.Joint.angularXDrive.positionSpring); - debugString.AppendLine("Position Damper: " + p.attachJoint.Joint.angularXDrive.positionDamper); - debugString.AppendLine("Max Force: " + p.attachJoint.Joint.angularXDrive.maximumForce); - debugString.AppendLine(""); - - debugString.AppendLine("Angular YZ Drive"); - debugString.AppendLine("Position Spring: " + p.attachJoint.Joint.angularYZDrive.positionSpring); - debugString.AppendLine("Position Damper: " + p.attachJoint.Joint.angularYZDrive.positionDamper); - debugString.AppendLine("Max Force: " + p.attachJoint.Joint.angularYZDrive.maximumForce); - debugString.AppendLine(""); - } - - float breakForce = Math.Min(p.breakingForce, connectedPart.breakingForce) * KJRJointUtils.breakForceMultiplier; float breakTorque = Math.Min(p.breakingTorque, connectedPart.breakingTorque) * KJRJointUtils.breakTorqueMultiplier; Vector3 anchor = j.anchor; @@ -635,14 +594,57 @@ private void ReinforceAttachJoints(Part p) momentOfInertia = Mathf.Pow(momentOfInertia, 1.5f); } + // FEHLER, jetzt probier ich meine Berechnung + float momentOfInertia2, breakForce2, breakTorque2; +if(calctype == 1) + { + KJRJointUtils.CalculateStrength(p, connectedPart, + out momentOfInertia2, out breakForce2, out breakTorque2); + } +else if(calctype == 2) + { + KJRJointUtils.CalculateStrength2(p, connectedPart, + out momentOfInertia2, out breakForce2, out breakTorque2); + } +else + { + KJRJointUtils.CalculateStrength0(p, connectedPart, + out momentOfInertia2, out breakForce2, out breakTorque2); +momentOfInertia2 = momentOfInertia; + } + breakForce = Mathf.Max(KJRJointUtils.breakStrengthPerArea * area, breakForce); breakTorque = Mathf.Max(KJRJointUtils.breakTorquePerMOI * momentOfInertia, breakTorque); +if((momentOfInertia * _l > momentOfInertia2) +|| (momentOfInertia * _u < momentOfInertia2) +|| (breakForce * _l > breakForce2) +|| (breakForce * _u < breakForce2) +|| (breakTorque * _l > breakTorque2) +|| (breakTorque * _u < breakTorque2)) + { + // mehr als 10% rauf oder runter + + TakeNew = TakeNew; + } +else if(TakeNew) + { + momentOfInertia = momentOfInertia2; + breakForce = breakForce2; + breakTorque = breakTorque2; + } + JointDrive angDrive = j.angularXDrive; angDrive.positionSpring = Mathf.Max(momentOfInertia * KJRJointUtils.angularDriveSpring, angDrive.positionSpring); angDrive.positionDamper = Mathf.Max(momentOfInertia * KJRJointUtils.angularDriveDamper * 0.1f, angDrive.positionDamper); - angDrive.maximumForce = breakTorque; +// FEHLER, xtreme-Debugging +//if(KJRJointUtils.debug && (angDrive.maximumForce > breakTorque)) +// Debug.LogError("KJR: weakening joint!!!!!"); + // angDrive.maximumForce = breakTorque; -> FEHLER, das macht's wirklich schwächer, aber das andere ist mir fast zu stark +// FEHLER, neue Idee... weil, das scheint mir etwas komisch hier..., wir machen das Zeug nämlich schwächer? +angDrive.maximumForce = Mathf.Max(breakTorque, angDrive.maximumForce); + /*float moi_avg = p.rb.inertiaTensor.magnitude; moi_avg += (p.transform.localToWorldMatrix.MultiplyPoint(p.CoMOffset) - p.parent.transform.position).sqrMagnitude * p.rb.mass; @@ -656,7 +658,12 @@ private void ReinforceAttachJoints(Part p) j.angularXDrive = j.angularYZDrive = j.slerpDrive = angDrive; JointDrive linDrive = j.xDrive; - linDrive.maximumForce = breakForce; +//if(KJRJointUtils.debug && (linDrive.maximumForce > breakForce)) +// Debug.LogError("KJR: weakening joint!!!!!"); + // linDrive.maximumForce = breakForce; -> FEHLER, das macht's wirklich schwächer, aber das andere ist mir fast zu stark +// FEHLER, neue Idee... weil, das scheint mir etwas komisch hier..., wir machen das Zeug nämlich schwächer? +linDrive.maximumForce = Mathf.Max(breakForce, linDrive.maximumForce); + j.xDrive = j.yDrive = j.zDrive = linDrive; j.linearLimit = j.angularYLimit = j.angularZLimit = j.lowAngularXLimit = j.highAngularXLimit @@ -671,133 +678,87 @@ private void ReinforceAttachJoints(Part p) j.breakForce = breakForce; // FEHLER, das hier entfernt das "unbreakable"... wollen wir das? und das SetBreakingForces nachher überschreibt den Wert hier gleich wieder -> klären -> sonst noch korrekten Wert rechne? * PhysicsGlobals.JointBreakForceFactor irgendwas j.breakTorque = breakTorque; // FEHLER, gleiche Frage wie eine Zeile oberhalb + +//PhysicsGlobals.JointBreakForceFactor +//PhysicsGlobals.JointBreakTorqueFactor +//if(KJRJointUtils.debug && (linDrive.maximumForce > breakForce)) +// Debug.LogError("KJR: weakening joint!!!!!"); +// FEHLER, kann hier nix sagen... aber, egal jetzt mal + p.attachJoint.SetBreakingForces(j.breakForce, j.breakTorque); p.attachMethod = AttachNodeMethod.LOCKED_JOINT; - - if(KJRJointUtils.debug) - { - debugString.AppendLine("Updated joint from " + p.partInfo.title + " to " + p.parent.partInfo.title); - debugString.AppendLine(" " + p.partInfo.name + " (" + p.flightID + ") -> " + p.parent.partInfo.name + " (" + p.parent.flightID + ")"); - debugString.AppendLine(""); - debugString.AppendLine(p.partInfo.title + " Inertia Tensor: " + p.rb.inertiaTensor + " " + p.parent.partInfo.name + " Inertia Tensor: " + connectedBody.inertiaTensor); - debugString.AppendLine(""); - - debugString.AppendLine("Std. Joint Parameters"); - debugString.AppendLine("Connected Body: " + p.attachJoint.Joint.connectedBody); - debugString.AppendLine("Attach mode: " + p.attachMode + " (was " + j.GetType().Name + ")"); - if(attach != null) - debugString.AppendLine("Attach node: " + attach.id + " - " + attach.nodeType + " " + attach.size); - if(p_attach != null) - debugString.AppendLine("Parent node: " + p_attach.id + " - " + p_attach.nodeType + " " + p_attach.size); - debugString.AppendLine("Anchor: " + p.attachJoint.Joint.anchor); - debugString.AppendLine("Axis: " + p.attachJoint.Joint.axis); - debugString.AppendLine("Sec Axis: " + p.attachJoint.Joint.secondaryAxis); - debugString.AppendLine("Break Force: " + p.attachJoint.Joint.breakForce); - debugString.AppendLine("Break Torque: " + p.attachJoint.Joint.breakTorque); - debugString.AppendLine(""); - - debugString.AppendLine("Joint Motion Locked: " + Convert.ToString(p.attachJoint.Joint.xMotion == ConfigurableJointMotion.Locked)); - - debugString.AppendLine("Angular Drive"); - debugString.AppendLine("Position Spring: " + angDrive.positionSpring); - debugString.AppendLine("Position Damper: " + angDrive.positionDamper); - debugString.AppendLine("Max Force: " + angDrive.maximumForce); - debugString.AppendLine(""); - - debugString.AppendLine("Cross Section Properties"); - debugString.AppendLine("Radius: " + radius); - debugString.AppendLine("Area: " + area); - debugString.AppendLine("Moment of Inertia: " + momentOfInertia); - } } } -#if IncludeAnalyzer - addAdditionalJointToParent &= WindowManager.Instance.BuildAdditionalJointToParent; -#endif + if(KJRJointUtils.debug) + Debug.Log(debugString.ToString()); + } - if(addAdditionalJointToParent && p.parent.parent != null - && KJRJointUtils.IsJointAdjustmentAllowed(p.parent)) // verify that parent is not an excluded part -> we will skip this in our calculation, that's why we need to check it now + private void ReinforceInversionsBuildJoint(KJRJointUtils.Sol2 s) + { + if(multiJointManager.CheckDirectJointBetweenParts(s.part, s.linkPart)) { - ConfigurableJoint j = p.attachJoint.Joint; // second steps uses the first/main joint as reference - - Part newConnectedPart = p.parent.parent; + ++KJRJointUtils.jc; + return; + } - bool massRatioBelowThreshold = false; - int numPartsFurther = 0; + ConfigurableJoint joint = KJRJointUtils.BuildJoint(s); - float partMaxMass = KJRJointUtils.MaximumPossiblePartMass(p); - List partsCrossed = new List(); - List possiblePartsCrossed = new List(); + multiJointManager.RegisterMultiJoint(s.part, joint, true, KJRMultiJointManager.Reason.ReinforceInversions); + multiJointManager.RegisterMultiJoint(s.linkPart, joint, true, KJRMultiJointManager.Reason.ReinforceInversions); - partsCrossed.Add(p.parent); + foreach(Part p in s.set) + multiJointManager.RegisterMultiJoint(p, joint, false, KJRMultiJointManager.Reason.ReinforceInversions); + } - Part connectedRbPart = newConnectedPart; + public void ReinforceInversions(Vessel v) + { + if(v.Parts.Count <= 1) + return; - // search the first part with an acceptable mass/mass ration to this part (joints work better then) - do - { - float massRat1 = (partMaxMass < newConnectedPart.mass) ? (newConnectedPart.mass / partMaxMass) : (partMaxMass / newConnectedPart.mass); + List sols = new List(); - if(massRat1 <= KJRJointUtils.stiffeningExtensionMassRatioThreshold) - massRatioBelowThreshold = true; - else - { - float maxMass = KJRJointUtils.MaximumPossiblePartMass(newConnectedPart); - float massRat2 = (p.mass < maxMass) ? (maxMass / p.mass) : (p.mass / maxMass); - - if(massRat2 <= KJRJointUtils.stiffeningExtensionMassRatioThreshold) - massRatioBelowThreshold = true; - else - { - if((newConnectedPart.parent == null) - || !KJRJointUtils.IsJointAdjustmentAllowed(newConnectedPart)) - break; + // Dictionary inversionResolutions = new Dictionary(); + List unresolved = new List(); - newConnectedPart = newConnectedPart.parent; + KJRJointUtils.FindInversionAndResolutions(v.rootPart, ref sols, ref unresolved); - if(newConnectedPart.rb == null) - possiblePartsCrossed.Add(newConnectedPart); - else - { - connectedRbPart = newConnectedPart; - partsCrossed.AddRange(possiblePartsCrossed); - partsCrossed.Add(newConnectedPart); - possiblePartsCrossed.Clear(); - } +// FEHLER, mal sehen, was man damit jetzt tun könnte -> eigentlich müsste man das in die Liste der zu verstärkenden teils aufnehmen... irgendwie - numPartsFurther++; - } - } + KJRJointUtils.tempPartList = new List(); - } while(!massRatioBelowThreshold);// && numPartsFurther < 5); + foreach(Part entry in unresolved) + { + KJRJointUtils.tempPartList.Clear(); - if(newConnectedPart.rb != null && !multiJointManager.CheckDirectJointBetweenParts(p, newConnectedPart)) - { - ConfigurableJoint newJoint = KJRJointUtils.BuildJoint(p, newConnectedPart, - j.xDrive, j.yDrive, j.zDrive, j.angularXDrive, j.breakForce, j.breakTorque); + KJRJointUtils.FindChildInversionResolution(entry, ref sols, ref unresolved); + // FEHLER, da holen wir mal mögliche Lösungen raus und rechnen für die erste was... nur so zum Test + // was wir damit tun? keine Ahnung... und ist irgendwas davon sinnvoll? keine Ahnung... sehen wir dann mal + } - // register joint - multiJointManager.RegisterMultiJoint(p, newJoint, true, KJRMultiJointManager.Reason.AdditionalJointToParent); - multiJointManager.RegisterMultiJoint(newConnectedPart, newJoint, true, KJRMultiJointManager.Reason.AdditionalJointToParent); + KJRJointUtils.tempPartList = null; - foreach(Part part in partsCrossed) - multiJointManager.RegisterMultiJoint(part, newJoint, false, KJRMultiJointManager.Reason.AdditionalJointToParent); - } - } +// FEHLER, später die "solutions" zusammenhängen + // foreach(KeyValuePair entry in inversionResolutions) + // ReinforceInversionsBuildJoint(entry.Key, entry.Value); - if(KJRJointUtils.debug) - Debug.Log(debugString.ToString()); + foreach(KJRJointUtils.Sol2 s in sols) + ReinforceInversionsBuildJoint(s); } private void MultiPartJointBuildJoint(Part part, Part linkPart, KJRMultiJointManager.Reason jointReason) { - if(multiJointManager.CheckDirectJointBetweenParts(part, linkPart) - || !multiJointManager.TrySetValidLinkedSet(part, linkPart)) + if(multiJointManager.CheckDirectJointBetweenParts(part, linkPart)) + { + ++KJRJointUtils.jc; + return; + } + + if(!multiJointManager.TrySetValidLinkedSet(part, linkPart)) return; - ConfigurableJoint joint = KJRJointUtils.BuildJoint(part, linkPart); + ConfigurableJoint joint = KJRJointUtils.BuildExtraJoint(part, linkPart); multiJointManager.RegisterMultiJoint(part, joint, true, jointReason); multiJointManager.RegisterMultiJoint(linkPart, joint, true, jointReason); @@ -806,87 +767,89 @@ private void MultiPartJointBuildJoint(Part part, Part linkPart, KJRMultiJointMan multiJointManager.RegisterMultiJoint(p, joint, false, jointReason); } - // FEHLER, überarbeiten... ist das nicht etwas sehr viel was wir hier aufbauen??? - private void ReinforceDecouplers(Part part) + public void AdditionalJointsToParent(Vessel v) { - List childParts = new List(); - List parentParts = new List(); - - parentParts = KJRJointUtils.DecouplerPartStiffeningListParents(part.parent); - - foreach(Part p in part.children) + foreach(Part p in v.Parts) { - if(KJRJointUtils.IsJointAdjustmentAllowed(p)) + if((p.parent != null) && (p.parent.parent != null) && (p.physicalSignificance == Part.PhysicalSignificance.FULL)) { - childParts.AddRange(KJRJointUtils.DecouplerPartStiffeningListChildren(p)); - if(!childParts.Contains(p)) - childParts.Add(p); - } - } + ConfigurableJoint j = p.attachJoint.Joint; // second steps uses the first/main joint as reference - parentParts.Add(part); +float stiffeningExtensionMassRatioThreshold = 5f; // FEHLER, ich will die Funktion hier ausbauen, daher kommt das temp hier rein - StringBuilder debugString = null; + Part newConnectedPart = p.parent.parent; - if(KJRJointUtils.debug) - { - debugString = new StringBuilder(); - debugString.AppendLine(parentParts.Count + " parts above decoupler to be connected to " + childParts.Count + " below decoupler."); - debugString.AppendLine("The following joints added by " + part.partInfo.title + " to increase stiffness:"); - } + bool massRatioBelowThreshold = false; + int numPartsFurther = 0; - foreach(Part p in parentParts) - { - if(p == null || p.rb == null || p.Modules.Contains("ProceduralFairingDecoupler")) - continue; + float partMaxMass = KJRJointUtils.MaximumPossiblePartMass(p); + List partsCrossed = new List(); + List possiblePartsCrossed = new List(); - foreach(Part q in childParts) - { - if(q == null || q.rb == null || p == q || q.Modules.Contains("ProceduralFairingDecoupler")) - continue; + partsCrossed.Add(p.parent); - if(p.vessel != q.vessel) - continue; + Part connectedRbPart = newConnectedPart; - MultiPartJointBuildJoint(p, q, KJRMultiJointManager.Reason.ReinforceDecoupler); + // search the first part with an acceptable mass/mass ration to this part (joints work better then) + do + { + float massRat1 = (partMaxMass < newConnectedPart.mass) ? (newConnectedPart.mass / partMaxMass) : (partMaxMass / newConnectedPart.mass); - if(KJRJointUtils.debug) - debugString.AppendLine(p.partInfo.title + " connected to part " + q.partInfo.title); - } - } + if(massRat1 <= stiffeningExtensionMassRatioThreshold) + massRatioBelowThreshold = true; + else + { + float maxMass = KJRJointUtils.MaximumPossiblePartMass(newConnectedPart); + float massRat2 = (p.mass < maxMass) ? (maxMass / p.mass) : (p.mass / maxMass); + + if(massRat2 <= stiffeningExtensionMassRatioThreshold) + massRatioBelowThreshold = true; + else + { + if((newConnectedPart.parent == null) + || !KJRJointUtils.IsJointAdjustmentAllowed(newConnectedPart)) + break; - if(KJRJointUtils.debug) - Debug.Log(debugString.ToString()); - } + newConnectedPart = newConnectedPart.parent; - private void ReinforceLaunchClamps(Part part) - { - part.breakingForce = Mathf.Infinity; - part.breakingTorque = Mathf.Infinity; - part.mass = Mathf.Max(part.mass, (part.parent.mass + part.parent.GetResourceMass()) * 0.01f); // We do this to make sure that there is a mass ratio of 100:1 between the clamp and what it's connected to. This helps counteract some of the wobbliness simply, but also allows some give and springiness to absorb the initial physics kick. + if(newConnectedPart.rb == null) + possiblePartsCrossed.Add(newConnectedPart); + else + { + connectedRbPart = newConnectedPart; + partsCrossed.AddRange(possiblePartsCrossed); + partsCrossed.Add(newConnectedPart); + possiblePartsCrossed.Clear(); + } - if(KJRJointUtils.debug) - Debug.Log("KJR: Launch Clamp Break Force / Torque increased"); + numPartsFurther++; + } + } - StringBuilder debugString = null; + } while(!massRatioBelowThreshold);// && numPartsFurther < 5); - if(KJRJointUtils.debug) - { - debugString = new StringBuilder(); - debugString.AppendLine("The following joints added by " + part.partInfo.title + " to increase stiffness:"); - } +// FEHLER, könnte man's mit MultiPartJointBuildJoint machen? + if(newConnectedPart.rb != null) + { + if(!multiJointManager.CheckDirectJointBetweenParts(p, newConnectedPart)) + { + ConfigurableJoint newJoint = KJRJointUtils.BuildExtraJoint(p, newConnectedPart); - if(part.parent.Rigidbody != null) // FEHLER, wir tun alles, tragen es aber nur ein, wenn irgendwas einen Rigidbody hat? nicht mal zwingend das Teil selber? - MultiPartJointBuildJoint(part, part.parent, KJRMultiJointManager.Reason.ReinforceLaunchClamp); + // register joint + multiJointManager.RegisterMultiJoint(p, newJoint, true, KJRMultiJointManager.Reason.ExtraStabilityJoint); + multiJointManager.RegisterMultiJoint(newConnectedPart, newJoint, true, KJRMultiJointManager.Reason.ExtraStabilityJoint); - if(KJRJointUtils.debug) - { - debugString.AppendLine(part.parent.partInfo.title + " connected to part " + part.partInfo.title); - Debug.Log(debugString.ToString()); + foreach(Part part in partsCrossed) + multiJointManager.RegisterMultiJoint(part, newJoint, false, KJRMultiJointManager.Reason.ExtraStabilityJoint); + } + else + ++KJRJointUtils.jc; + } + } } } - public void MultiPartJointTreeChildren(Vessel v) + public void AdditionalJointsBetweenEndpoints(Vessel v) { if(v.Parts.Count <= 1) return; @@ -906,20 +869,9 @@ public void MultiPartJointTreeChildren(Vessel v) { Part p = childPartsToConnect[i]; -// FEHLER, xtreme-Debugging, darf nicht mehr passieren jetzt -if(p.rb == null) - Debug.LogError("KJR: MultiPartJointTreeChildren -> p.rb == null!!!!!"); - Part linkPart = childPartsToConnect[i + 1 >= childPartsToConnect.Count ? 0 : i + 1]; -// FEHLER, xtreme-Debugging, darf nicht mehr passieren jetzt -if(linkPart.rb == null) - Debug.LogError("KJR: MultiPartJointTreeChildren -> linkPart.rb == null!!!!!"); - -#if IncludeAnalyzer - if(WindowManager.Instance.BuildMultiPartJointTreeChildren) -#endif - MultiPartJointBuildJoint(p, linkPart, KJRMultiJointManager.Reason.MultiPartJointTreeChildren); + MultiPartJointBuildJoint(p, linkPart, KJRMultiJointManager.Reason.ExtraStabilityJoint); int part2Index = i + childPartsToConnect.Count / 2; @@ -928,50 +880,39 @@ public void MultiPartJointTreeChildren(Vessel v) Part linkPart2 = childPartsToConnect[part2Index]; -// FEHLER, xtreme-Debugging, darf nicht mehr passieren jetzt -if(linkPart2.rb == null) - Debug.LogError("KJR: MultiPartJointTreeChildren -> linkPart2.rb == null!!!!!"); - -#if IncludeAnalyzer - if(WindowManager.Instance.BuildMultiPartJointTreeChildren) -#endif - MultiPartJointBuildJoint(p, linkPart2, KJRMultiJointManager.Reason.MultiPartJointTreeChildren); + MultiPartJointBuildJoint(p, linkPart2, KJRMultiJointManager.Reason.ExtraStabilityJoint); -#if IncludeAnalyzer - if(WindowManager.Instance.BuildMultiPartJointTreeChildrenRoot) -#endif - MultiPartJointBuildJoint(p, root, KJRMultiJointManager.Reason.MultiPartJointTreeChildrenRoot); + MultiPartJointBuildJoint(p, root, KJRMultiJointManager.Reason.ExtraStabilityJoint); } } } - private void ReinforceInversionsBuildJoint(Part part, Part linkPart) + private void ReinforceLaunchClamps(Part part) { - if(multiJointManager.CheckDirectJointBetweenParts(part, linkPart) - || !multiJointManager.TrySetValidLinkedSet(part, linkPart)) - return; - - ConfigurableJoint joint = KJRJointUtils.BuildJoint2(part, linkPart); - - multiJointManager.RegisterMultiJoint(part, joint, true, KJRMultiJointManager.Reason.ReinforceInversions); - multiJointManager.RegisterMultiJoint(linkPart, joint, true, KJRMultiJointManager.Reason.ReinforceInversions); + part.breakingForce = Mathf.Infinity; + part.breakingTorque = Mathf.Infinity; + part.mass = Mathf.Max(part.mass, (part.parent.mass + part.parent.GetResourceMass()) * 0.01f); // We do this to make sure that there is a mass ratio of 100:1 between the clamp and what it's connected to. This helps counteract some of the wobbliness simply, but also allows some give and springiness to absorb the initial physics kick. - foreach(Part p in multiJointManager.linkedSet) - multiJointManager.RegisterMultiJoint(p, joint, false, KJRMultiJointManager.Reason.ReinforceInversions); - } + if(KJRJointUtils.debug) + Debug.Log("KJR: Launch Clamp Break Force / Torque increased"); - public void ReinforceInversions(Vessel v) - { - if(v.Parts.Count <= 1) - return; + StringBuilder debugString = null; - Dictionary inversionResolutions = new Dictionary(); + if(KJRJointUtils.debug) + { + debugString = new StringBuilder(); + debugString.AppendLine("The following joints added by " + part.partInfo.title + " to increase stiffness:"); + } - KJRJointUtils.FindInversionAndResolutions(v.rootPart, ref inversionResolutions); + if(part.parent.Rigidbody != null) // FEHLER, wir tun alles, tragen es aber nur ein, wenn irgendwas einen Rigidbody hat? nicht mal zwingend das Teil selber? + MultiPartJointBuildJoint(part, part.parent, KJRMultiJointManager.Reason.ReinforceLaunchClamp); - foreach(KeyValuePair entry in inversionResolutions) - ReinforceInversionsBuildJoint(entry.Key, entry.Value); + if(KJRJointUtils.debug) + { + debugString.AppendLine(part.parent.partInfo.title + " connected to part " + part.partInfo.title); + Debug.Log(debugString.ToString()); + } } } } diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/KJRMultiJointManager.cs b/KerbalJointReinforcement/KerbalJointReinforcement/KJRMultiJointManager.cs index 1084ead..b2589fc 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/KJRMultiJointManager.cs +++ b/KerbalJointReinforcement/KerbalJointReinforcement/KJRMultiJointManager.cs @@ -13,7 +13,7 @@ internal class KJRMultiJointManager { internal enum Reason { - None, ReinforceDecoupler, ReinforceLaunchClamp, AdditionalJointToParent, MultiPartJointTreeChildren, MultiPartJointTreeChildrenRoot, ReinforceInversions + None, ReinforceInversions, ExtraStabilityJoint, ReinforceLaunchClamp }; internal struct ConfigurableJointWithInfo @@ -51,12 +51,16 @@ public bool TrySetValidLinkedSet(Part part1, Part part2) part1 = KJRJointUtils.IsJointAdjustmentAllowed(part1) ? part1.parent : null; } + // KJRJointUtils.BuildLinkSet(part1, ref linkedSet); -> FEHLER, das hier nutzen + while(part2 != null) { tempPartList.Add(part2); part2 = KJRJointUtils.IsJointAdjustmentAllowed(part2) ? part2.parent : null; } + // KJRJointUtils.BuildLinkSet(part2, ref tempPartList); -> FEHLER, das hier nutzen + int i = linkedSet.Count - 1; int j = tempPartList.Count - 1; @@ -74,6 +78,8 @@ public bool TrySetValidLinkedSet(Part part1, Part part2) linkedSet.AddRange(tempPartList.GetRange(1, j)); return linkedSet.Count > 1; + + // FEHLER -> KRJJointUtils.BuildLinkSetDifference nutzen statt dem da oben } public void RegisterMultiJoint(Part part, ConfigurableJoint joint, bool direct, Reason jointReason) diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/KJRSettings.cs b/KerbalJointReinforcement/KerbalJointReinforcement/KJRSettings.cs new file mode 100644 index 0000000..f5e949c --- /dev/null +++ b/KerbalJointReinforcement/KerbalJointReinforcement/KJRSettings.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; + +using System.ComponentModel.DataAnnotations; + +using KSP.IO; +using UnityEngine; +/* +namespace KerbalJointReinforcement +{ + public class KJRSettings : GameParameters.CustomParameterNode + { + public override string Title + { get { return "General Options"; } } + + public override string DisplaySection + { get { return "Joint Reinforcement (KJR next)"; } } + + public override string Section + { get { return "Joint Reinforcement (KJR next)"; } } + + public override int SectionOrder + { get { return 1; } } + + public override GameParameters.GameMode GameMode + { get { return GameParameters.GameMode.ANY; } } + + public override bool HasPresets + { get { return false; } } + + + public enum StrengthLevel + { + Realistic, + Strong, + Strongest, + Indistructible + }; + + [GameParameters.CustomParameterUI("Strength and stiffness level", autoPersistance = false)] + public StrengthLevel level = StrengthLevel.Realistic; + + + public override void OnLoad(ConfigNode node) + { + base.OnLoad(node); + + if(!KJRJointUtils.loaded) + KJRJointUtils.LoadConstants(); + + level = KJRJointUtils.addExtraStabilityJoints ? StrengthLevel.Realistic : + (StrengthLevel)(KJRJointUtils.extraLevel + 1); + } + + public override void OnSave(ConfigNode node) + { + base.OnSave(node); + + KJRJointUtils.addExtraStabilityJoints = (level > StrengthLevel.Realistic); + KJRJointUtils.extraLevel = ((int)level) - 1; + + PluginConfiguration config = PluginConfiguration.CreateForType(); + config.load(); + + config.SetValue("addExtraStabilityJoints", KJRJointUtils.addExtraStabilityJoints); + config.SetValue("extraLevel", KJRJointUtils.extraLevel); + + config.save(); + } + } +} +*/ diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/KerbalJointReinforcement.csproj b/KerbalJointReinforcement/KerbalJointReinforcement/KerbalJointReinforcement.csproj index b0a82b2..a8eefc5 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/KerbalJointReinforcement.csproj +++ b/KerbalJointReinforcement/KerbalJointReinforcement/KerbalJointReinforcement.csproj @@ -44,6 +44,7 @@ C:\KerbalSpaceProgram_1.12.3\KSP_x64_Data\Managed\Assembly-CSharp.dll + C:\KerbalSpaceProgram_1.12.3\KSP_x64_Data\Managed\UnityEngine.dll @@ -95,6 +96,7 @@ + diff --git a/KerbalJointReinforcement/KerbalJointReinforcement/Properties/AssemblyInfo.cs b/KerbalJointReinforcement/KerbalJointReinforcement/Properties/AssemblyInfo.cs index 8615281..0539c5e 100644 --- a/KerbalJointReinforcement/KerbalJointReinforcement/Properties/AssemblyInfo.cs +++ b/KerbalJointReinforcement/KerbalJointReinforcement/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.2.20.0")] -[assembly: AssemblyFileVersion("4.2.20.0")] +[assembly: AssemblyVersion("4.2.21.0")] +[assembly: AssemblyFileVersion("4.2.21.0")] diff --git a/Resources/GameData/KerbalJointReinforcement/KerbalJointReinforcement.version b/Resources/GameData/KerbalJointReinforcement/KerbalJointReinforcement.version index 393f9e8..22099b7 100644 --- a/Resources/GameData/KerbalJointReinforcement/KerbalJointReinforcement.version +++ b/Resources/GameData/KerbalJointReinforcement/KerbalJointReinforcement.version @@ -9,7 +9,7 @@ "VERSION" : { "MAJOR" : 4, "MINOR" : 2, - "PATCH" : 20 + "PATCH" : 21 }, "KSP_VERSION" : { "MAJOR" : 1, diff --git a/Resources/GameData/KerbalJointReinforcement/Plugins/PluginData/KerbalJointReinforcementNext/config.xml b/Resources/GameData/KerbalJointReinforcement/Plugins/PluginData/KerbalJointReinforcementNext/config.xml index de6cb4e..2e53a20 100644 --- a/Resources/GameData/KerbalJointReinforcement/Plugins/PluginData/KerbalJointReinforcementNext/config.xml +++ b/Resources/GameData/KerbalJointReinforcement/Plugins/PluginData/KerbalJointReinforcementNext/config.xml @@ -1,16 +1,13 @@  1 - 0 - 0 - 0 1 - 1 - 0 - 0.01 - 5 - -1 + 0 + 0 + 1 + 0.01 + 5e12 25 @@ -18,4 +15,12 @@ 1 1500 6000 + + 2 + 2 + 8 + + 0 + + 0