private void Init(IShipconstruct v, SimCurves _simCurves) { totalMass = 0; dryMass = 0; CoM = Vector3.zero; CoM_dry = Vector3.zero; List<Part> oParts = v.Parts; List<SimulatedPart> variableDragParts_ctrls = new List<SimulatedPart>(); count = oParts.Count; if (HighLogic.LoadedSceneIsEditor) { for (int i = 0; i < v.Parts.Count; i++) { Part p = v.Parts[i]; if (p.dragModel == Part.DragModel.CUBE && !p.DragCubes.None) { DragCubeList cubes = p.DragCubes; DragCubeList.CubeData p_drag_data = new DragCubeList.CubeData(); try { cubes.SetDragWeights(); cubes.SetPartOcclusion(); cubes.AddSurfaceDragDirection(-Vector3.forward, 0, ref p_drag_data); } catch (Exception) { cubes.SetDrag(Vector3.forward, 0); cubes.ForceUpdate(true, true); cubes.SetDragWeights(); cubes.SetPartOcclusion(); cubes.AddSurfaceDragDirection(-Vector3.forward, 0, ref p_drag_data); //Debug.Log(String.Format("Trajectories: Caught NRE on Drag Initialization. Should be fixed now. {0}", e)); } } } } simCurves = _simCurves; if (parts.Capacity < count) parts.Capacity = count; bool lgWarning = false; int stage = 0; for (int i = 0; i < count; i++) { if (!lgWarning) { ModuleWheels.ModuleWheelDeployment gear = oParts[i].FindModuleImplementing<ModuleWheels.ModuleWheelDeployment>(); bool forcedRetract = !oParts[i].ShieldedFromAirstream && gear != null && gear.Position > 0; if (forcedRetract) lgWarning = true; } SimulatedPart simulatedPart = SimulatedPart.Borrow(oParts[i], this); parts.Add(simulatedPart); totalMass += simulatedPart.totalMass; dryMass += simulatedPart.dryMass; CoM += simulatedPart.totalMass * simulatedPart.CoM; CoM_dry += simulatedPart.dryMass * simulatedPart.CoM; ModuleLiftingSurface liftingSurface = oParts[i].FindModuleImplementing<ModuleLiftingSurface>(); if (liftingSurface != null) { parts[i].hasLiftModule = true; if (liftingSurface is ModuleControlSurface ctrlSurface) { ctrls.Add(SimulatedControlSurface.Borrow(ctrlSurface, simulatedPart)); variableDragParts_ctrls.Add(simulatedPart); if (ctrlSurface.ctrlSurfaceArea < 1) surfaces.Add(SimulatedLiftingSurface.Borrow(ctrlSurface, simulatedPart)); } else surfaces.Add(SimulatedLiftingSurface.Borrow(liftingSurface, simulatedPart)); } List<ITorqueProvider> torqueProviders = oParts[i].FindModulesImplementing<ITorqueProvider>(); // TODO: Add them to a list. if(oParts[i].inverseStage > stage) { SimulatedEngine.Release(engines); engines.Clear(); stage = oParts[i].inverseStage; } if (oParts[i].inverseStage >= stage) { MultiModeEngine multiMode = oParts[i].FindModuleImplementing<MultiModeEngine>(); if (multiMode != null) { engines.Add(SimulatedEngine.Borrow(oParts[i].FindModulesImplementing<ModuleEngines>().Find(engine => engine.engineID == multiMode.mode), simulatedPart)); } else { ModuleEngines engine = oParts[i].FindModulesImplementing<ModuleEngines>().FirstOrDefault(); if (engine != null) engines.Add(SimulatedEngine.Borrow(engine, simulatedPart)); } } } CoM /= totalMass; CoM_dry /= dryMass; if (lgWarning) ScreenMessages.PostScreenMessage("Landing gear deployed, results may not be accurate.", 5, ScreenMessageStyle.UPPER_CENTER); /*for (int i = 0; i < count; i++) { parts[i].CoM -= this.CoM; parts[i].CoL -= this.CoM; parts[i].CoP -= this.CoM; }*/ parts.RemoveAll(part => variableDragParts_ctrls.Contains(part)); }
protected void AddPart(Part part) { if (parts.Count > 0 && part.HasModuleImplementing <Expansions.Serenity.ModuleRoboticServoRotor>()) { partCollections.Add(RotorPartCollection.Borrow(parentVessel, part)); return; } SimulatedPart simulatedPart = SimulatedPart.Borrow(part, parentVessel); parts.Add(simulatedPart); parentVessel.totalMass += simulatedPart.totalMass; parentVessel.dryMass += simulatedPart.dryMass; parentVessel.CoM += simulatedPart.totalMass * simulatedPart.CoM; parentVessel.CoM_dry += simulatedPart.dryMass * simulatedPart.CoM; bool variableDragCube_Ctrl = false; ModuleLiftingSurface liftingSurface = part.FindModuleImplementing <ModuleLiftingSurface>(); if (liftingSurface != null) { part.hasLiftModule = true; SimulatedLiftingSurface surface; if (liftingSurface is ModuleControlSurface ctrlSurface) { surface = SimulatedControlSurface.Borrow(ctrlSurface, simulatedPart); ctrls.Add((SimulatedControlSurface)surface); // Controls change their drag cubes with deployment and so we can't precalculate them. // The effect of their drag cubes is captured in the methods for SimulatedControlSurface variableDragCube_Ctrl = true; if (ctrlSurface.ctrlSurfaceArea < 1) { surface = SimulatedLiftingSurface.Borrow(ctrlSurface, simulatedPart); surfaces.Add(surface); } } else { surface = SimulatedLiftingSurface.Borrow(liftingSurface, simulatedPart); surfaces.Add(surface); } Math.Abs(0); parentVessel.relativeWingArea += surface.deflectionLiftCoeff * Math.Abs(surface.liftVector[1]); } List <ITorqueProvider> torqueProviders = part.FindModulesImplementing <ITorqueProvider>(); // TODO: Add them to a list. if (part.inverseStage > parentVessel.stage) { // Recursively clear all engines - there's an earlier stage active. parentVessel.partCollection.ClearEngines(); parentVessel.stage = part.inverseStage; } if (part.inverseStage >= parentVessel.stage) { MultiModeEngine multiMode = part.FindModuleImplementing <MultiModeEngine>(); if (multiMode != null) { engines.Add(SimulatedEngine.Borrow(part.FindModulesImplementing <ModuleEngines>().Find(engine => engine.engineID == multiMode.mode), simulatedPart)); } else { ModuleEngines engine = part.FindModulesImplementing <ModuleEngines>().FirstOrDefault(); if (engine != null) { engines.Add(SimulatedEngine.Borrow(engine, simulatedPart)); } } } if (variableDragCube_Ctrl) { simulatedPart.Release(); parts.Remove(simulatedPart); } for (int i = part.children.Count - 1; i >= 0; i--) { AddPart(part.children[i]); } }