private void CalculateTotalAeroForce()
        {
            aeroForces.ClearAll();

            if (_vessel.dynamicPressurekPa <= 0.00001)
            {
                return;
            }

            if (_currentAeroModules != null)
            {
                for (int i = 0; i < _currentAeroModules.Count; i++)
                {
                    FARAeroPartModule m = _currentAeroModules[i];
                    if ((object)m != null)
                    {
                        aeroForces.AddForce(m.transform.position, m.totalWorldSpaceAeroForce);
                        aeroForces.AddTorque(m.worldSpaceTorque);
                    }
                }
            }

            /*
             * for (int i = 0; i < _LEGACY_currentWingAeroModel.Count; i++)
             * {
             *  FARWingAerodynamicModel w = _LEGACY_currentWingAeroModel[i];
             *  if ((object)w == null)
             *      continue;
             *  totalAeroForceVector += w.worldSpaceForce;
             *  aeroForces.AddForce(w.AerodynamicCenter, w.worldSpaceForce);
             *
             *  totalAeroForceVector += w.worldSpaceForce;
             *  totalAeroTorqueVector += Vector3.Cross(w.AerodynamicCenter - _vessel.CoM, w.worldSpaceForce);
             * }
             *
             * for(int i = 0; i < _vessel.parts.Count; i++)
             * {
             *  Part p = _vessel.parts[i];
             *  totalAeroForceVector += -p.dragVectorDir * p.dragScalar; // dragVectorDir is actually the velocity vector direction
             * }
             */
        }
        private void CalculateTotalAeroForce()
        {
            aeroForces.ClearAll();


            if (_vessel.dynamicPressurekPa <= 0.00001)
            {
                return;
            }

            if (_currentAeroModules == null)
            {
                return;
            }
            foreach (FARAeroPartModule m in _currentAeroModules)
            {
                if (m is null)
                {
                    continue;
                }
                aeroForces.AddForce(m.transform.position, m.totalWorldSpaceAeroForce);
                aeroForces.AddTorque(m.worldSpaceTorque);
            }
        }
Пример #3
0
        void UpdateAerodynamicCenter()
        {
            FARCenterQuery aeroSection, dummy;

            aeroSection = new FARCenterQuery();
            dummy       = new FARCenterQuery();

            if ((object)EditorLogic.RootPart == null)
            {
                return;
            }

            Vector3 vel_base, vel_fuzz;

            Transform rootPartTrans = EditorLogic.RootPart.partTransform;

            if (EditorDriver.editorFacility == EditorFacility.SPH)
            {
                vel_base = Vector3.forward;
                vel_fuzz = 0.02f * Vector3.up;
            }
            else
            {
                vel_base = Vector3.up;
                vel_fuzz = -0.02f * Vector3.forward;
            }

            Vector3 vel = (vel_base - vel_fuzz).normalized;

            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                FARAeroSection section = _currentAeroSections[i];
                section.PredictionCalculateAeroForces(1, 3, 100000, 0.005f, vel, aeroSection);
            }

            FARBaseAerodynamics.PrecomputeGlobalCenterOfLift(aeroSection, dummy, vel, 1);

            Vector3 pos  = Vector3.zero;//rootPartTrans.position;
            float   mass = 0;

            for (int i = 0; i < EditorLogic.SortedShipList.Count; i++)
            {
                Part  p       = EditorLogic.SortedShipList[i];
                float tmpMass = p.mass + p.GetResourceMass();
                mass += tmpMass;
                pos  += p.partTransform.position * tmpMass;
            }
            pos /= mass;

            Vector3 avgForcePos = Vector3.zero;

            Vector3 force0, moment0;

            force0       = aeroSection.force;
            moment0      = aeroSection.TorqueAt(pos);
            avgForcePos += aeroSection.GetPos();

            //aeroSection.force = -aeroSection.force;
            //aeroSection.torque = -aeroSection.torque;

            aeroSection.ClearAll();

            vel = (vel_base + vel_fuzz).normalized;

            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                FARAeroSection section = _currentAeroSections[i];
                section.PredictionCalculateAeroForces(1, 3, 100000, 0.005f, vel, aeroSection);
            }

            FARBaseAerodynamics.PrecomputeGlobalCenterOfLift(aeroSection, dummy, vel, 1);

            Vector3 force1, moment1;

            force1       = aeroSection.force;
            moment1      = aeroSection.TorqueAt(pos);
            avgForcePos += aeroSection.GetPos();

            aeroSection.ClearAll();

            avgForcePos *= 0.5f;

            Vector3 deltaForce  = force1 - force0;
            Vector3 deltaMoment = moment1 - moment0;

            Vector3 deltaForcePerp    = Vector3.ProjectOnPlane(deltaForce, vel_base);
            float   deltaForcePerpMag = deltaForcePerp.magnitude;

            Vector3 deltaForcePerpNorm = deltaForcePerp / deltaForcePerpMag;

            Vector3 deltaMomentPerp = deltaMoment - Vector3.Dot(deltaMoment, deltaForcePerpNorm) * deltaForcePerpNorm - Vector3.Project(deltaMoment, vel_base);

            //float dist = deltaMomentPerp.magnitude / deltaForcePerpMag;
            //vesselRootLocalAeroCenter = vel_base * dist;

            vesselRootLocalAeroCenter = deltaMomentPerp.magnitude / deltaForcePerpMag * vel_base * Math.Sign(Vector3.Dot(Vector3.Cross(deltaForce, deltaMoment), vel_base));

            //Debug.Log(dist + " " + deltaMomentPerp.magnitude + " " + deltaForcePerpMag);
            //vesselRootLocalAeroCenter += avgForcePos;
            //avgForcePos = rootPartTrans.worldToLocalMatrix.MultiplyPoint3x4(avgForcePos);
            //vesselRootLocalAeroCenter += Vector3.ProjectOnPlane(avgForcePos, Vector3.up);
            //vesselRootLocalAeroCenter = aeroSection.GetPos();
            vesselRootLocalAeroCenter += pos;//Vector3.ProjectOnPlane(avgForcePos - pos, vesselRootLocalAeroCenter) + pos;
            vesselRootLocalAeroCenter  = rootPartTrans.worldToLocalMatrix.MultiplyPoint3x4(vesselRootLocalAeroCenter);
        }
        private void UpdateAerodynamicCenter()
        {
            var aeroSection = new FARCenterQuery();
            var dummy       = new FARCenterQuery();

            if (EditorLogic.RootPart is null)
            {
                return;
            }

            Vector3 vel_base, vel_fuzz;

            Transform rootPartTrans = EditorLogic.RootPart.partTransform;

            if (EditorDriver.editorFacility == EditorFacility.SPH)
            {
                vel_base = Vector3.forward;
                vel_fuzz = 0.02f * Vector3.up;
            }
            else
            {
                vel_base = Vector3.up;
                vel_fuzz = -0.02f * Vector3.forward;
            }

            Vector3 vel = (vel_base - vel_fuzz).normalized;

            foreach (FARAeroSection section in _currentAeroSections)
            {
                section.PredictionCalculateAeroForces(1, 0.5f, 100000, 0, 0.005f, vel, aeroSection);
            }

            FARBaseAerodynamics.PrecomputeGlobalCenterOfLift(aeroSection, dummy, vel, 1);

            Vector3 pos  = Vector3.zero;
            float   mass = 0;

            foreach (Part p in EditorLogic.SortedShipList)
            {
                if (FARAeroUtil.IsNonphysical(p))
                {
                    continue;
                }
                float tmpMass = p.mass + p.GetResourceMass();
                mass += tmpMass;
                pos  += p.partTransform.position * tmpMass;
            }

            pos /= mass;

            Vector3 force0  = aeroSection.force;
            Vector3 moment0 = aeroSection.TorqueAt(pos);

            aeroSection.ClearAll();

            vel = (vel_base + vel_fuzz).normalized;

            foreach (FARAeroSection section in _currentAeroSections)
            {
                section.PredictionCalculateAeroForces(1, 0.5f, 100000, 0, 0.005f, vel, aeroSection);
            }

            FARBaseAerodynamics.PrecomputeGlobalCenterOfLift(aeroSection, dummy, vel, 1);

            Vector3 force1  = aeroSection.force;
            Vector3 moment1 = aeroSection.TorqueAt(pos);

            aeroSection.ClearAll();

            Vector3 deltaForce  = force1 - force0;
            Vector3 deltaMoment = moment1 - moment0;

            Vector3 deltaForcePerp    = Vector3.ProjectOnPlane(deltaForce, vel_base);
            float   deltaForcePerpMag = deltaForcePerp.magnitude;

            Vector3 deltaForcePerpNorm = deltaForcePerp / deltaForcePerpMag;

            Vector3 deltaMomentPerp = deltaMoment -
                                      Vector3.Dot(deltaMoment, deltaForcePerpNorm) * deltaForcePerpNorm -
                                      Vector3.Project(deltaMoment, vel_base);

            vesselRootLocalAeroCenter = deltaMomentPerp.magnitude /
                                        deltaForcePerpMag *
                                        Math.Sign(Vector3.Dot(Vector3.Cross(deltaForce, deltaMoment), vel_base)) *
                                        vel_base;

            vesselRootLocalAeroCenter += pos;
            vesselRootLocalAeroCenter  = rootPartTrans.worldToLocalMatrix.MultiplyPoint3x4(vesselRootLocalAeroCenter);
        }