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