Exemple #1
0
 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;
        }
Exemple #3
0
            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);
                }
            }
Exemple #4
0
    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;
        }
    }
Exemple #5
0
            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;
            }
Exemple #6
0
    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 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;
        }
Exemple #10
0
        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);
        }
Exemple #11
0
            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;
                    }
                }
            }
            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;
            }