// Unfortunately the DragCubeList SetDrag method is not thread safe // so here is a thread safe version protected void SetDrag(Vector3d dragVector, float machNumber) { areaDrag = 0; liftForce = Vector3d.zero; if (cubes.None) { return; } for (int i = 0; i < 6; i++) { Vector3d faceDirection = DragCubeList.GetFaceDirection((DragCube.DragFace)i); float dragDot = (float)Vector3d.Dot(dragVector, faceDirection); float dragValue = DragCurveValue((dragDot + 1f) * 0.5f, machNumber); float faceAreaDrag = cubes.AreaOccluded[i] * dragValue; areaDrag = areaDrag + faceAreaDrag * cubes.WeightedDrag[i]; if (dragDot > 0f) { float lift = simCurves.LiftCurve.Evaluate(dragDot); if (!double.IsNaN(lift)) { liftForce = liftForce - faceDirection * (dragDot * cubes.AreaOccluded[i] * cubes.WeightedDrag[i] * lift); } } } }
private void BuildCubeData() { DragCubeList cubes = part.DragCubes; XP = $"{cubes.WeightedArea[0]:F2} ({cubes.GetCubeAreaDir(DragCubeList.GetFaceDirection(DragCube.DragFace.XP)):F2})"; XN = $"{cubes.WeightedArea[1]:F2} ({cubes.GetCubeAreaDir(DragCubeList.GetFaceDirection(DragCube.DragFace.XN)):F2})"; YP = $"{cubes.WeightedArea[2]:F2} ({cubes.GetCubeAreaDir(DragCubeList.GetFaceDirection(DragCube.DragFace.YP)):F2})"; YN = $"{cubes.WeightedArea[3]:F2} ({cubes.GetCubeAreaDir(DragCubeList.GetFaceDirection(DragCube.DragFace.YN)):F2})"; ZP = $"{cubes.WeightedArea[4]:F2} ({cubes.GetCubeAreaDir(DragCubeList.GetFaceDirection(DragCube.DragFace.ZP)):F2})"; ZN = $"{cubes.WeightedArea[5]:F2} ({cubes.GetCubeAreaDir(DragCubeList.GetFaceDirection(DragCube.DragFace.ZN)):F2})"; }
//Retreives an "apparent" diameter from a DragCube private float GetApparentDiameter(DragCube cube) { float area = 0; for (int i = 0; i < 6; i++) { area += cube.Area[i] * cube.Drag[i] * PhysicsGlobals.DragCurveValue((Vector3.Dot(Vector3.up, DragCubeList.GetFaceDirection((DragCube.DragFace)i)) + 1f) * 0.5f, 0); } return((float)(Math.Max(Math.Round(Math.Sqrt((area * PhysicsGlobals.DragCubeMultiplier * PhysicsGlobals.DragMultiplier) / Math.PI) * 2d, 1, MidpointRounding.AwayFromZero), 0.1))); }
static float GetFacingAreaSum(Vector3 direction, float[] faceAreaArray) { float num = 0; for (int i = 0; i < 6; i++) { float num2 = Mathf.Clamp01(Vector3.Dot(direction, DragCubeList.GetFaceDirection((DragCube.DragFace)i))); num += faceAreaArray [i] * num2; } return(num); }
public DragCubeList.CubeData AddSurfaceDragDirection(Vector3 direction, float machNumber) { part.DragCubes.SetDrag(direction, machNumber); //var liftCurves = GetPrivate<PhysicsGlobals.LiftingSurfaceCurve>("liftCurves", part.DragCubes); var liftCurves = part.DragCubes.BodyLiftCurve; float num = 0; DragCubeList.CubeData result = default(DragCubeList.CubeData); result.dragVector = direction; for (int i = 0; i < 6; i++) { Vector3 faceDirection = DragCubeList.GetFaceDirection((DragCube.DragFace)i); float num2 = Vector3.Dot(direction, faceDirection); float dotNormalized = (num2 + 1) * 0.5f; float num3 = PhysicsGlobals.DragCurveValue(PhysicsGlobals.SurfaceCurves, dotNormalized, machNumber); float num4 = this.areaOccluded [i] * num3; float num5 = this.weightedDrag [i]; float num6 = num5; if (num6 < 1) { num6 = PhysicsGlobals.DragCurveCd.Evaluate(num6); } result.area += num4; result.areaDrag += num4 * num6; result.crossSectionalArea += this.areaOccluded [i] * Mathf.Clamp01(num2); if (num5 < 0.01) { num5 = 1; } if (num5 < 1) { num5 = 1 / num5; } result.exposedArea += num4 / PhysicsGlobals.DragCurveMultiplier.Evaluate(machNumber) * num5; if (num2 > 0) { num += num2; double num7 = (double)liftCurves.liftCurve.Evaluate(num2); if (!double.IsNaN(num7)) { result.liftForce += -faceDirection * (num2 * this.areaOccluded [i] * this.weightedDrag [i] * (float)num7); } result.depth += num2 * this.weightedDepth [i]; result.dragCoeff += num2 * num6; } } float num8 = 1 / num; result.depth *= num8; result.dragCoeff *= num8; return(result); }
void AreaToCubeOperation(Vector3 direction, float area, Func <float, float, float> operation) { for (int i = 0; i < 6; i++) { float num = Mathf.Clamp01(Vector3.Dot(direction, DragCubeList.GetFaceDirection((DragCube.DragFace)i))); if (num > 0) { this.areaOccluded[i] = operation(area * num, this.areaOccluded[i]); float num2 = this.weightedArea [i] - this.areaOccluded[i]; if (this.areaOccluded[i] > 0) { this.weightedDrag[i] = Mathf.Max(0, (this.weightedDragOrig[i] * this.weightedArea[i] - num2) / this.areaOccluded[i]); } else { this.weightedDrag[i] = 1E-05f; } } } }
//Retrieves an "apparent" diameter from a DragCube private static float GetApparentDiameter(DragCube cube) { float area = 0; for (int i = 0; i < 6; i++) { // TODO 1.2: according to API docs this method should have only 2 arguments but it has 3 area += cube.Area[i] * cube.Drag[i] * PhysicsGlobals.DragCurveValue(PhysicsGlobals.SurfaceCurves, (Vector3.Dot(Vector3.up, DragCubeList .GetFaceDirection((DragCube.DragFace)i)) + 1) * 0.5f, 0); } return((float)Math.Max(Math.Round(Math.Sqrt(area * 0.1f * PhysicsGlobals.DragMultiplier / Math.PI) * 2, 1, MidpointRounding.AwayFromZero), 0.1)); }