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); } }
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); }