public Vector3d RunDragCalculation(Vector3d velocity, double MachNumber, double rho, double failureForceScaling) { if (isShielded) { Cl = Cd = Cm = 0; return(Vector3d.zero); } double v_scalar = velocity.magnitude; if (v_scalar > 0.1) //Don't Bother if it's not moving or in space { CoDshift = Vector3d.zero; Cd = 0; Vector3d velocity_normalized = velocity / v_scalar; Vector3d upVector = part_transform.TransformDirection(localUpVector); perp = Vector3d.Cross(upVector, velocity).normalized; liftDir = Vector3d.Cross(velocity, perp).normalized; Vector3d local_velocity = part_transform.InverseTransformDirection(velocity_normalized); DragModel(local_velocity, MachNumber, rho); double qS = 0.5 * rho * v_scalar * v_scalar * S; //dynamic pressure, q Vector3d D = velocity_normalized * (-qS * Cd); //drag Vector3d L = liftDir * (qS * Cl); Vector3d force = (L + D) * 0.001; double force_scalar = force.magnitude; currentDrag = (float)force_scalar; Vector3d moment = perp * (qS * Cm * 0.001); Rigidbody rb = part.Rigidbody; if (HighLogic.LoadedSceneIsFlight && (object)rb != null) { if (rb.angularVelocity.sqrMagnitude != 0) { Vector3d rot = Vector3d.Exclude(velocity_normalized, rb.angularVelocity); //This prevents aerodynamic damping a spinning object if its spin axis is aligned with the velocity axis rot *= (-0.00001 * qS); moment += rot; } } //Must handle aero-structural failure before transforming CoD pos and adding pitching moment to forces or else parts with blunt body drag fall apart too easily if (Math.Abs(Vector3d.Dot(force, upVector)) > YmaxForce * failureForceScaling || Vector3d.Exclude(upVector, force).magnitude > XZmaxForce * failureForceScaling) { if (part.parent && !vessel.packed) { part.SendEvent("AerodynamicFailureStatus"); FlightLogger.eventLog.Add("[" + FARMathUtil.FormatTime(vessel.missionTime) + "] Joint between " + part.partInfo.title + " and " + part.parent.partInfo.title + " failed due to aerodynamic stresses."); part.decouple(25); if (FARDebugValues.aeroFailureExplosions) { FXMonger.Explode(part, GetCoDWithoutMomentShift(), 5); } } } globalCoDShift = Vector3d.Cross(force, moment) / (force_scalar * force_scalar); if (double.IsNaN(force_scalar) || double.IsNaN(moment.sqrMagnitude) || double.IsNaN(globalCoDShift.sqrMagnitude)) { Debug.LogWarning("FAR Error: Aerodynamic force = " + force.magnitude + " Aerodynamic moment = " + moment.magnitude + " CoD Local = " + CoDshift.magnitude + " CoD Global = " + globalCoDShift.magnitude + " " + part.partInfo.title); force = moment = CoDshift = globalCoDShift = Vector3.zero; return(force); } double numericalControlFactor = (rb.mass * v_scalar * 0.67) / (force_scalar * TimeWarp.fixedDeltaTime); force *= Math.Min(numericalControlFactor, 1); //part.Rigidbody.AddTorque(moment); return(force); } else { return(Vector3d.zero); } }
public Vector3d RunDragCalculation(Vector3d velocity, double MachNumber, double rho) { if (isShielded) { Cl = Cd = Cm = 0; return(Vector3d.zero); } double v_scalar = velocity.magnitude; if (v_scalar > 0.1) //Don't Bother if it's not moving or in space { CoDshift = Vector3d.zero; Cd = 0; Vector3d velocity_normalized = velocity / v_scalar; //float Parallel = Vector3.Dot(upVector, velocity_normalized); Vector3d upVector = part_transform.TransformDirection(localUpVector); perp = Vector3d.Cross(upVector, velocity).normalized; liftDir = Vector3d.Cross(velocity, perp).normalized; Vector3d local_velocity = part_transform.InverseTransformDirection(velocity_normalized); DragModel(local_velocity, MachNumber); //if(gear && start != StartState.Editor) // if(gear.gearState != ModuleLandingGear.GearStates.RETRACTED) // Cd += 0.1f; /* if(anim) * if (anim.Progress > 0.5f) * Cd *= 1.5f;*/ double qS = 0.5 * rho * v_scalar * v_scalar * S; //dynamic pressure, q Vector3d D = velocity_normalized * (-qS * Cd); //drag Vector3d L = liftDir * (qS * Cl); Vector3d force = (L + D) * 0.001; double force_scalar = force.magnitude; currentDrag = (float)force_scalar; Vector3d moment = perp * (qS * Cm * 0.001); Rigidbody rb = part.Rigidbody; if (start != StartState.Editor && rb) { if (rb.angularVelocity.sqrMagnitude != 0) { Vector3d rot = Vector3d.Exclude(velocity_normalized, rb.angularVelocity); //This prevents aerodynamic damping a spinning object if its spin axis is aligned with the velocity axis rot *= (-0.00001 * qS); // This seems redundant due to the moment addition below? /* * if(!float.IsNaN(rot.sqrMagnitude)) * part.Rigidbody.AddTorque(rot); */ moment += rot; } //moment = (moment + lastMoment) / 2; //lastMoment = moment; // CoDshift += CenterOfDrag; } //Must handle aero-structural failure before transforming CoD pos and adding pitching moment to forces or else parts with blunt body drag fall apart too easily if (Math.Abs(Vector3d.Dot(force, upVector)) > YmaxForce || Vector3d.Exclude(upVector, force).magnitude > XZmaxForce) { if (part.parent && !vessel.packed) { part.SendEvent("AerodynamicFailureStatus"); FlightLogger.eventLog.Add("[" + FARMathUtil.FormatTime(vessel.missionTime) + "] Joint between " + part.partInfo.title + " and " + part.parent.partInfo.title + " failed due to aerodynamic stresses."); part.decouple(25); } } globalCoDShift = Vector3d.Cross(force, moment) / (force_scalar * force_scalar); if (double.IsNaN(force_scalar) || double.IsNaN(moment.sqrMagnitude) || double.IsNaN(globalCoDShift.sqrMagnitude)) { Debug.LogWarning("FAR Error: Aerodynamic force = " + force.magnitude + " Aerodynamic moment = " + moment.magnitude + " CoD Local = " + CoDshift.magnitude + " CoD Global = " + globalCoDShift.magnitude + " " + part.partInfo.title); force = moment = CoDshift = globalCoDShift = Vector3.zero; return(force); } //part.Rigidbody.AddTorque(moment); return(force); } else { return(Vector3d.zero); } }