diff --git a/FreeIva.sln b/FreeIva.sln index 319c589c..a8ee8f33 100644 --- a/FreeIva.sln +++ b/FreeIva.sln @@ -3,12 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeIva", "FreeIva\FreeIva.csproj", "{AEB6EEAB-46BC-49EE-8941-3833E1B1171B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeIva", "FreeIva\FreeIva.csproj", "{AEB6EEAB-46BC-49EE-8941-3833E1B1171B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4D82D2DE-C252-46FC-852E-3CFB355CA3A6}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig CHANGELOG.md = CHANGELOG.md + FreeIva\FreeIva.csproj.user = FreeIva\FreeIva.csproj.user GameData\FreeIva\FreeIva.version = GameData\FreeIva\FreeIva.version README.md = README.md EndProjectSection diff --git a/FreeIva/InternalModules/GravityGimbal.cs b/FreeIva/InternalModules/GravityGimbal.cs new file mode 100644 index 00000000..0a0d9338 --- /dev/null +++ b/FreeIva/InternalModules/GravityGimbal.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace FreeIva.InternalModules +{ + // TODO: provide angle limits for rotation + + internal class GravityGimbal : InternalModule + { + [KSPField] + public Vector3 rotationAxis = new Vector3(1, 0, 0); // in prop space + + [KSPField] + public string transformName = string.Empty; + + [KSPField] + public float minAccel = 0.05f; + + [KSPField] + public float smoothingFactor = 0.2f; + + [SerializeField] Transform m_controlledTransform; + + InternalModuleFreeIva m_freeIvaModule; + Vector3 m_rotationAxisInternalSpace; + Quaternion m_defaultRotation; + + public override void OnLoad(ConfigNode node) + { + base.OnLoad(node); + + if (HighLogic.LoadedScene == GameScenes.LOADING) + { + if (transformName != string.Empty) + { + m_controlledTransform = TransformUtil.FindPropTransform(internalProp, transformName); + } + else + { + m_controlledTransform = internalProp.hasModel ? transform : internalModel.transform; + } + } + } + + protected void Start() + { + m_freeIvaModule = InternalModuleFreeIva.GetForModel(internalModel); + m_rotationAxisInternalSpace = transform.TransformDirection(rotationAxis); + m_defaultRotation = transform.rotation; + } + + void FixedUpdate() + { + if (m_controlledTransform != null) + { + Vector3 subjectiveGravity = FreeIva.GetInternalSubjectiveAcceleration(m_freeIvaModule, m_controlledTransform.position); + Quaternion targetRotation; + + if (KerbalIvaController.UseHorizon(subjectiveGravity, m_freeIvaModule.Centrifuge != null)) + { + Vector3 forward = Vector3.Cross(subjectiveGravity, m_rotationAxisInternalSpace); + Vector3 up = Vector3.Cross(forward, m_rotationAxisInternalSpace); + + targetRotation = Quaternion.LookRotation(forward, up); + } + else + { + targetRotation = m_defaultRotation; + } + + m_controlledTransform.rotation = Quaternion.Lerp(m_controlledTransform.rotation, targetRotation, smoothingFactor); + } + } + } +} diff --git a/FreeIva/InternalModules/InstanceInternal.cs b/FreeIva/InternalModules/InstanceInternal.cs new file mode 100644 index 00000000..e8cdbb8b --- /dev/null +++ b/FreeIva/InternalModules/InstanceInternal.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace FreeIva.InternalModules +{ + class ConfigNodeHolder : ScriptableObject + { + public ConfigNode Node; + } + + internal class InstanceInternal : InternalModule + { + [SerializeReference] + ConfigNodeHolder m_prefabInternalNode; + ConfigNode m_internalNode; + + [KSPField] + public string parentTransformName = string.Empty; + [SerializeField] Transform m_parentTransform; + + public override void OnLoad(ConfigNode moduleNode) + { + base.OnLoad(moduleNode); + + var internalNode = moduleNode.GetNode("INTERNAL"); + + if (HighLogic.LoadedScene == GameScenes.LOADING) + { + m_prefabInternalNode = ScriptableObject.CreateInstance(); + m_prefabInternalNode.Node = internalNode; + + if (parentTransformName != string.Empty) + { + m_parentTransform = TransformUtil.FindPropTransform(internalProp, parentTransformName); + } + else + { + m_parentTransform = internalProp.hasModel ? transform : internalModel.transform; + } + } + + if (internalNode != null) + { + m_internalNode = internalNode; + } + } + + void Start() + { + m_internalNode = m_internalNode ?? m_prefabInternalNode?.Node; + string internalName = m_internalNode?.GetValue("name"); + + if (internalName == null || m_parentTransform == null) + { + return; + } + + var internalPrefab = PartLoader.GetInternalPart(internalName); + if (internalPrefab != null) + { + var internalModel = GameObject.Instantiate(internalPrefab); + internalModel.transform.SetParent(m_parentTransform, false); + internalModel.part = part; + internalModel.gameObject.SetActive(true); + internalModel.Load(m_internalNode); + } + } + } +} diff --git a/FreeIva/KerbalIvaController.cs b/FreeIva/KerbalIvaController.cs index 640807a4..15321983 100644 --- a/FreeIva/KerbalIvaController.cs +++ b/FreeIva/KerbalIvaController.cs @@ -426,15 +426,20 @@ public void UpdatePosition(Vector3 flightAccel, Vector3 movementThrottle, bool j #endif } - Vector3 UpdateGravity() + internal static bool UseHorizon(Vector3 flightAccel, bool inCentrifuge) { - Vector3 flightAccel = FreeIva.GetInternalSubjectiveAcceleration(FreeIva.CurrentInternalModuleFreeIva, transform.position); - - float minAccelForHorizon = (FlightGlobals.ActiveVessel.LandedOrSplashed || currentCentrifuge != null) + float minAccelForHorizon = (FlightGlobals.ActiveVessel.LandedOrSplashed || inCentrifuge) ? MIN_ACCEL_FOR_HORIZON_LANDED : MIN_ACCEL_FOR_HORIZON_AIRBORNE; - usingRelativeMovement = flightAccel.magnitude >= minAccelForHorizon; + return flightAccel.magnitude >= minAccelForHorizon; + } + + Vector3 UpdateGravity() + { + Vector3 flightAccel = FreeIva.GetInternalSubjectiveAcceleration(FreeIva.CurrentInternalModuleFreeIva, transform.position); + + usingRelativeMovement = UseHorizon(flightAccel, currentCentrifuge != null); horizonDownVector = usingRelativeMovement ? flightAccel : Vector3.zero; // update attaching/detaching to things (note that detaching from a centrifuge is handled in ExitCentrifuge) diff --git a/GameData/FreeIva/HabTechProps/htProps_HatchCBM.cfg b/GameData/FreeIva/HabTechProps/htProps_HatchCBM.cfg index 70f65d7c..096823d3 100644 --- a/GameData/FreeIva/HabTechProps/htProps_HatchCBM.cfg +++ b/GameData/FreeIva/HabTechProps/htProps_HatchCBM.cfg @@ -11,7 +11,6 @@ PROP { model = FreeIva/Props/HatchBoxCollider position = 0, 0.00826506782, 0 - rotation = 0, 0, 0, -1 //quaternion scale = 0.604978085, 0.0175083745, 0.605912209 } @@ -19,7 +18,6 @@ PROP { model = HabTechProps/Props/doorHatchWindowPlug position = 0, 0.0130386753, -0.221190825 - rotation = 0, 0, 0, -1 //quaternion } } diff --git a/GameData/FreeIva/HabTechProps/htProps_HatchDoor.cfg b/GameData/FreeIva/HabTechProps/htProps_HatchDoor.cfg index f5da171c..03c081cb 100644 --- a/GameData/FreeIva/HabTechProps/htProps_HatchDoor.cfg +++ b/GameData/FreeIva/HabTechProps/htProps_HatchDoor.cfg @@ -10,7 +10,6 @@ PROP MODEL { model = FreeIva/Props/HatchBoxCollider - rotation = 0, 0, 0, -1 scale = 0.774956346, 0.0422763638, 1 }