public void OnCenterOfLiftQuery(CenterOfLiftQuery CoLMarker) { // Compute the actual center ourselves once per frame // Feed the precomputed values to the vanilla indicator CoLMarker.pos = EditorAeroCenter.VesselRootLocalAeroCenter; //hacking the old stuff to work with the new CoLMarker.pos = EditorLogic.RootPart.partTransform.localToWorldMatrix.MultiplyPoint3x4(CoLMarker.pos); CoLMarker.dir = Vector3.zero; CoLMarker.lift = 1; }
public void OnCenterOfLiftQuery(CenterOfLiftQuery CoLMarker) { // Compute the actual center ourselves once per frame if (!GlobalCoLReady && HighLogic.LoadedSceneIsEditor) { PrecomputeGlobalCenterOfLift(); } // Feed the precomputed values to the vanilla indicator CoLMarker.pos = GlobalCoL; CoLMarker.dir = CoLForce.normalized; CoLMarker.lift = CoLForce.magnitude * 50f; }
public static void CenterOfLiftQueryRecurse(Part p, CenterOfLiftQuery qry, CenterOfLiftQuery local_qry, float mach) { if (p == null) { return; } CenterOfLiftQuery(p, qry, local_qry, mach); for (int i = 0; i < p.children.Count; i++) { CenterOfLiftQueryRecurse(p.children[i], qry, local_qry, mach); } }
public void OnCenterOfLiftQuery(CenterOfLiftQuery qry) { if (moduleID == 0) { CoLqueryData queryData = new CoLqueryData(); queryData.refVector = qry.refVector; for (int i = 0; i < liftSurfaces.Count; i++) { CoLqueryData newQuery = liftSurfaces[i].liftQuery(queryData.refVector); float influence = new Vector2(queryData.dir.magnitude, newQuery.dir.magnitude).normalized.y; queryData.pos = Vector3.Lerp(queryData.pos, newQuery.pos, influence); queryData.lift += newQuery.lift; queryData.dir = Vector3.Lerp(queryData.dir, newQuery.dir, influence); } queryData.dir.Normalize(); qry.dir = queryData.dir; qry.lift = queryData.lift; qry.pos = queryData.pos; } }
public void setup(CenterOfLiftQuery qry) { CelestialBody home = Planetarium.fetch.Home; pressure = home.GetPressure(altitude); density = home.GetDensity(pressure, home.GetTemperature(altitude)); sound_speed = home.GetSpeedOfSound(pressure, density); mach = (float)(speed / sound_speed); qry.refAirDensity = density; qry.refStaticPressure = pressure; qry.refAltitude = altitude; qry.refVector = Quaternion.AngleAxis(AoA, EditorLogic.RootPart.partTransform.right) * EditorLogic.VesselRotation * Vector3.up; qry.refVector *= speed; qry.lift = 0.0f; qry.dir = Vector3.zero; qry.pos = Vector3.zero; local_qry.refAirDensity = qry.refAirDensity; local_qry.refAltitude = qry.refAltitude; local_qry.refStaticPressure = qry.refStaticPressure; local_qry.refVector = qry.refVector; }
public void OnCenterOfLiftQuery(CenterOfLiftQuery CoLMarker) { // Compute the actual center ourselves once per frame // Feed the precomputed values to the vanilla indicator CoLMarker.pos = FerramAerospaceResearch.FARGUI.FAREditorGUI.EditorAeroCenter.VesselRootLocalAeroCenter; //hacking the old stuff to work with the new CoLMarker.pos = EditorLogic.RootPart.partTransform.localToWorldMatrix.MultiplyPoint3x4(CoLMarker.pos); CoLMarker.dir = Vector3.zero; CoLMarker.lift = 1; }
public void OnCenterOfLiftQuery(CenterOfLiftQuery CoLMarker) { // Compute the actual center ourselves once per frame if (!GlobalCoLReady && HighLogic.LoadedSceneIsEditor) PrecomputeGlobalCenterOfLift(); // Feed the precomputed values to the vanilla indicator CoLMarker.pos = GlobalCoL; CoLMarker.dir = CoLForce.normalized; CoLMarker.lift = CoLForce.magnitude * 50f; }
public static Vector3 get_part_torque(CenterOfLiftQuery qry, Part p, Vector3 CoM, ref float lift, ref float drag) { if (p == null || (p.Rigidbody != p.rb) && !PhysicsGlobals.ApplyDragToNonPhysicsParts) return Vector3.zero; Vector3 lift_pos = Vector3.zero; Vector3 drag_pos = Vector3.zero; if (!p.ShieldedFromAirstream) { var providers = p.FindModulesImplementing<ModuleLiftingSurface>(); if ((providers != null) && providers.Count > 0) p.hasLiftModule = true; Vector3 res = Vector3.zero; if (p.hasLiftModule && providers[0] is ModuleControlSurface) { p.DragCubes.SetCubeWeight("neutral", 1.5f); p.DragCubes.SetCubeWeight("fullDeflectionPos", 0.0f); p.DragCubes.SetCubeWeight("fullDeflectionNeg", 0.0f); } // drag from drag-cubes if (!p.DragCubes.None) { Vector3 drag_force = Vector3.zero; p.dragVector = qry.refVector; p.dragVectorSqrMag = p.dragVector.sqrMagnitude; p.dragVectorMag = Mathf.Sqrt(p.dragVectorSqrMag); p.dragVectorDir = p.dragVector / p.dragVectorMag; p.dragVectorDirLocal = -p.partTransform.InverseTransformDirection(p.dragVectorDir); p.dynamicPressurekPa = qry.refAirDensity * 0.0005 * p.dragVectorSqrMag; if (p.rb != p.Rigidbody && PhysicsGlobals.ApplyDragToNonPhysicsPartsAtParentCoM) { drag_pos = p.Rigidbody.worldCenterOfMass; lift_pos = drag_pos; } else { lift_pos = p.partTransform.TransformPoint(p.CoLOffset); drag_pos = p.partTransform.TransformPoint(p.CoPOffset); } p.DragCubes.SetDrag(p.dragVectorDirLocal, mach); float pseudoreynolds = (float)(density * Mathf.Abs(speed)); float pseudoredragmult = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(pseudoreynolds); float drag_k = p.DragCubes.AreaDrag * PhysicsGlobals.DragCubeMultiplier * pseudoredragmult; p.dragScalar = (float)(p.dynamicPressurekPa * drag_k * PhysicsGlobals.DragMultiplier); drag_force = p.dragScalar * -p.dragVectorDir; res += Vector3.Cross(drag_force, drag_pos - CoM); Vector3 sum_force = drag_force; drag += Vector3.Dot(sum_force, -p.dragVectorDir); } if (!p.hasLiftModule) { // stock aero lift if (!p.DragCubes.None) { p.bodyLiftScalar = (float)(p.dynamicPressurekPa * p.bodyLiftMultiplier * PhysicsGlobals.BodyLiftMultiplier * CorrectCoL.CoLMarkerFull.lift_curves.liftMachCurve.Evaluate(mach)); Vector3 lift_force = p.partTransform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce); lift_force = Vector3.ProjectOnPlane(lift_force, -p.dragVectorDir); res += Vector3.Cross(lift_force, lift_pos - CoM); Vector3 sum_force = lift_force; lift += Vector3.Dot(sum_force, Vector3.Cross(p.dragVectorDir, EditorLogic.RootPart.transform.right).normalized); } return res; } else { double q = 0.5 * qry.refAirDensity * qry.refVector.sqrMagnitude; for (int i = 0; i < providers.Count; i++) { Vector3 dragvect; Vector3 liftvect; Vector3 lift_force = Vector3.zero; Vector3 drag_force = Vector3.zero; float abs; ModuleLiftingSurface lsurf = providers[i]; ModuleControlSurface csurf = lsurf as ModuleControlSurface; lsurf.SetupCoefficients(qry.refVector, out dragvect, out liftvect, out lsurf.liftDot, out abs); lift_pos = p.partTransform.TransformPoint(p.CoLOffset); drag_pos = p.partTransform.TransformPoint(p.CoPOffset); lift_force = lsurf.GetLiftVector(liftvect, lsurf.liftDot, abs, q, mach); if (lsurf.useInternalDragModel) drag_force = lsurf.GetDragVector(dragvect, abs, q); if (csurf != null) { float deflection = (float)deflection_field.GetValue(csurf); Quaternion incidence = Quaternion.AngleAxis(csurf.ctrlSurfaceRange * deflection, p.partTransform.rotation * Vector3.right); liftvect = incidence * liftvect; lsurf.liftDot = Vector3.Dot(dragvect, liftvect); abs = Mathf.Abs(lsurf.liftDot); lift_force = lift_force * (1.0f - csurf.ctrlSurfaceArea); lift_force += lsurf.GetLiftVector(liftvect, lsurf.liftDot, abs, q, mach) * csurf.ctrlSurfaceArea; if (csurf.useInternalDragModel) { drag_force = drag_force * (1.0f - csurf.ctrlSurfaceArea); drag_force += csurf.GetDragVector(dragvect, abs, q) * csurf.ctrlSurfaceArea; } } res += Vector3.Cross(lift_force, lift_pos - CoM); res += Vector3.Cross(drag_force, drag_pos - CoM); Vector3 result_force = lift_force + drag_force; lift += Vector3.Dot(result_force, Vector3.Cross(qry.refVector, EditorLogic.RootPart.transform.right).normalized); drag += Vector3.Dot(result_force, -qry.refVector.normalized); } return res; } } return Vector3.zero; }
public static Vector3 get_part_torque(CenterOfLiftQuery qry, Part p, Vector3 CoM, ref float lift, ref float drag) { if (p == null || (p.Rigidbody != p.rb) && !PhysicsGlobals.ApplyDragToNonPhysicsParts) { return(Vector3.zero); } Vector3 lift_pos = Vector3.zero; Vector3 drag_pos = Vector3.zero; if (!p.ShieldedFromAirstream) { var providers = p.FindModulesImplementing <ModuleLiftingSurface>(); if ((providers != null) && providers.Count > 0) { p.hasLiftModule = true; } Vector3 res = Vector3.zero; if (p.hasLiftModule && providers[0] is ModuleControlSurface) { p.DragCubes.SetCubeWeight("neutral", 1.5f); p.DragCubes.SetCubeWeight("fullDeflectionPos", 0.0f); p.DragCubes.SetCubeWeight("fullDeflectionNeg", 0.0f); } // drag from drag-cubes if (!p.DragCubes.None) { Vector3 drag_force = Vector3.zero; p.dragVector = qry.refVector; p.dragVectorSqrMag = p.dragVector.sqrMagnitude; p.dragVectorMag = Mathf.Sqrt(p.dragVectorSqrMag); p.dragVectorDir = p.dragVector / p.dragVectorMag; p.dragVectorDirLocal = -p.partTransform.InverseTransformDirection(p.dragVectorDir); p.dynamicPressurekPa = qry.refAirDensity * 0.0005 * p.dragVectorSqrMag; if (p.rb != p.Rigidbody && PhysicsGlobals.ApplyDragToNonPhysicsPartsAtParentCoM) { drag_pos = p.Rigidbody.worldCenterOfMass; lift_pos = drag_pos; } else { lift_pos = p.partTransform.TransformPoint(p.CoLOffset); drag_pos = p.partTransform.TransformPoint(p.CoPOffset); } p.DragCubes.SetDrag(p.dragVectorDirLocal, mach); float pseudoreynolds = (float)(density * Mathf.Abs(speed)); float pseudoredragmult = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(pseudoreynolds); float drag_k = p.DragCubes.AreaDrag * PhysicsGlobals.DragCubeMultiplier * pseudoredragmult; p.dragScalar = (float)(p.dynamicPressurekPa * drag_k * PhysicsGlobals.DragMultiplier); drag_force = p.dragScalar * -p.dragVectorDir; res += Vector3.Cross(drag_force, drag_pos - CoM); Vector3 sum_force = drag_force; drag += Vector3.Dot(sum_force, -p.dragVectorDir); } if (!p.hasLiftModule) { // stock aero lift if (!p.DragCubes.None) { p.bodyLiftScalar = (float)(p.dynamicPressurekPa * p.bodyLiftMultiplier * PhysicsGlobals.BodyLiftMultiplier * CorrectCoL.CoLMarkerFull.lift_curves.liftMachCurve.Evaluate(mach)); Vector3 lift_force = p.partTransform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce); lift_force = Vector3.ProjectOnPlane(lift_force, -p.dragVectorDir); res += Vector3.Cross(lift_force, lift_pos - CoM); Vector3 sum_force = lift_force; lift += Vector3.Dot(sum_force, Vector3.Cross(p.dragVectorDir, EditorLogic.RootPart.transform.right).normalized); } return(res); } else { double q = 0.5 * qry.refAirDensity * qry.refVector.sqrMagnitude; for (int i = 0; i < providers.Count; i++) { Vector3 dragvect; Vector3 liftvect; Vector3 lift_force = Vector3.zero; Vector3 drag_force = Vector3.zero; float abs; ModuleLiftingSurface lsurf = providers[i]; ModuleControlSurface csurf = lsurf as ModuleControlSurface; lsurf.SetupCoefficients(qry.refVector, out dragvect, out liftvect, out lsurf.liftDot, out abs); lift_pos = p.partTransform.TransformPoint(p.CoLOffset); drag_pos = p.partTransform.TransformPoint(p.CoPOffset); lift_force = lsurf.GetLiftVector(liftvect, lsurf.liftDot, abs, q, mach); if (lsurf.useInternalDragModel) { drag_force = lsurf.GetDragVector(dragvect, abs, q); } if (csurf != null) { float deflection = (float)deflection_field.GetValue(csurf); Quaternion incidence = Quaternion.AngleAxis(csurf.ctrlSurfaceRange * deflection, p.partTransform.rotation * Vector3.right); liftvect = incidence * liftvect; lsurf.liftDot = Vector3.Dot(dragvect, liftvect); abs = Mathf.Abs(lsurf.liftDot); lift_force = lift_force * (1.0f - csurf.ctrlSurfaceArea); lift_force += lsurf.GetLiftVector(liftvect, lsurf.liftDot, abs, q, mach) * csurf.ctrlSurfaceArea; if (csurf.useInternalDragModel) { drag_force = drag_force * (1.0f - csurf.ctrlSurfaceArea); drag_force += csurf.GetDragVector(dragvect, abs, q) * csurf.ctrlSurfaceArea; } } res += Vector3.Cross(lift_force, lift_pos - CoM); res += Vector3.Cross(drag_force, drag_pos - CoM); Vector3 result_force = lift_force + drag_force; lift += Vector3.Dot(result_force, Vector3.Cross(qry.refVector, EditorLogic.RootPart.transform.right).normalized); drag += Vector3.Dot(result_force, -qry.refVector.normalized); } return(res); } } return(Vector3.zero); }
public static void CenterOfLiftQuery(Part p, CenterOfLiftQuery qry, CenterOfLiftQuery local_qry, float mach) { if (p == null) { return; } Vector3 pos = Vector3.zero; Vector3 dir = Vector3.zero; float abs_lift = 0.0f; if (!p.ShieldedFromAirstream) { var providers = p.FindModulesImplementing <ILiftProvider>(); if ((providers != null) && providers.Count > 0) { p.hasLiftModule = true; } if (!p.hasLiftModule) { // stock aero shenanigans if (!p.DragCubes.None) { p.dragVector = qry.refVector; p.dragVectorSqrMag = p.dragVector.sqrMagnitude; p.dragVectorMag = Mathf.Sqrt(p.dragVectorSqrMag); p.dragVectorDir = p.dragVector / p.dragVectorMag; p.dragVectorDirLocal = -p.partTransform.InverseTransformDirection(p.dragVectorDir); p.dynamicPressurekPa = qry.refAirDensity * 0.0005 * p.dragVectorSqrMag; p.bodyLiftScalar = (float)(p.dynamicPressurekPa * p.bodyLiftMultiplier * PhysicsGlobals.BodyLiftMultiplier * lift_curves.liftMachCurve.Evaluate(mach)); pos = p.partTransform.TransformPoint(p.CoLOffset); p.DragCubes.SetDrag(p.dragVectorDirLocal, mach); dir = p.partTransform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce); dir = Vector3.ProjectOnPlane(dir, -p.dragVectorDir); abs_lift = dir.magnitude; qry.pos += pos * abs_lift; qry.dir += dir; qry.lift += abs_lift; } } else { for (int i = 0; i < providers.Count; i++) { local_qry.lift = 0.0f; local_qry.pos = Vector3.zero; local_qry.dir = Vector3.zero; providers[i].OnCenterOfLiftQuery(local_qry); Vector3 corrected_lift = Vector3.ProjectOnPlane(local_qry.dir, qry.refVector); local_qry.lift = Mathf.Abs(Vector3.Dot(corrected_lift, local_qry.dir)) * local_qry.lift; pos += local_qry.pos * local_qry.lift; dir += corrected_lift.normalized * local_qry.lift; abs_lift += local_qry.lift; } qry.pos += pos; qry.dir += dir; qry.lift += abs_lift; } } }
public static void CenterOfLiftQueryRecurse(Part p, CenterOfLiftQuery qry, CenterOfLiftQuery local_qry, float mach) { if (p == null) return; CenterOfLiftQuery(p, qry, local_qry, mach); for (int i = 0; i < p.children.Count; i++) CenterOfLiftQueryRecurse(p.children[i], qry, local_qry, mach); }
public static void CenterOfLiftQuery(Part p, CenterOfLiftQuery qry, CenterOfLiftQuery local_qry, float mach) { if (p == null) return; Vector3 pos = Vector3.zero; Vector3 dir = Vector3.zero; float abs_lift = 0.0f; if (!p.ShieldedFromAirstream) { var providers = p.FindModulesImplementing<ILiftProvider>(); if ((providers != null) && providers.Count > 0) p.hasLiftModule = true; if (!p.hasLiftModule) { // stock aero shenanigans if (!p.DragCubes.None) { p.dragVector = qry.refVector; p.dragVectorSqrMag = p.dragVector.sqrMagnitude; p.dragVectorMag = Mathf.Sqrt(p.dragVectorSqrMag); p.dragVectorDir = p.dragVector / p.dragVectorMag; p.dragVectorDirLocal = -p.partTransform.InverseTransformDirection(p.dragVectorDir); p.dynamicPressurekPa = qry.refAirDensity * 0.0005 * p.dragVectorSqrMag; p.bodyLiftScalar = (float)(p.dynamicPressurekPa * p.bodyLiftMultiplier * PhysicsGlobals.BodyLiftMultiplier * lift_curves.liftMachCurve.Evaluate(mach)); pos = p.partTransform.TransformPoint(p.CoLOffset); p.DragCubes.SetDrag(p.dragVectorDirLocal, mach); dir = p.partTransform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce); dir = Vector3.ProjectOnPlane(dir, -p.dragVectorDir); abs_lift = dir.magnitude; qry.pos += pos * abs_lift; qry.dir += dir; qry.lift += abs_lift; } } else { for (int i = 0; i < providers.Count; i++) { local_qry.lift = 0.0f; local_qry.pos = Vector3.zero; local_qry.dir = Vector3.zero; providers[i].OnCenterOfLiftQuery(local_qry); Vector3 corrected_lift = Vector3.ProjectOnPlane(local_qry.dir, qry.refVector); local_qry.lift = Mathf.Abs(Vector3.Dot(corrected_lift, local_qry.dir)) * local_qry.lift; pos += local_qry.pos * local_qry.lift; dir += corrected_lift.normalized * local_qry.lift; abs_lift += local_qry.lift; } qry.pos += pos; qry.dir += dir; qry.lift += abs_lift; } } }