public void UpdateProp() { ProceduralPart ppart = PPart; UpdateFairing(); if (ppart != null) { ProceduralShapeBezierCone shape = ppart.CurrentShape as ProceduralShapeBezierCone; if (null != shape) { float diameter = shape.topDiameter; float length = shape.length; if (HighLogic.LoadedSceneIsEditor) { float surfaceArea = Mathf.PI * (diameter / 2) * (diameter / 2); PartResource pr = part.Resources[ablativeResource]; if (null != pr) { double ratio = pr.maxAmount != 0 ? pr.amount / pr.maxAmount : 1.0; //Debug.LogWarning("ratio: " + ratio); //Debug.LogWarning("amount: " + pr.amount); //Debug.LogWarning("max amount: " + pr.maxAmount); pr.maxAmount = (double)(ablatorPerArea * surfaceArea); pr.amount = Math.Min(ratio * pr.maxAmount, pr.maxAmount); //ResourceListChanged(); MaxAmountChanged(part, pr, pr.maxAmount); InitialAmountChanged(part, pr, pr.maxAmount); } } //Debug.Log(massPerDiameter + " * " + diameter); mass = massPerDiameter * diameter + massFromDiameterCurve.Evaluate(diameter); //Debug.LogWarning("changed mass: " + mass); MassChanged(mass); //Debug.Log("CoL offset " + -length); part.CoLOffset.y = -length; part.CoPOffset.y = CoPoffset.Evaluate(diameter); //Debug.Log("CoP offset: "+ part.CoPOffset.y); if (HighLogic.LoadedSceneIsEditor) { GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship); } } } // We don't need to tell FAR, because the shape will do it for us anyway. }
// onSymmetryFieldChanged() callback has the incorrect value for parameter obj // So we manually invoke things for our symmetry counterparts. public void OnShapeSelectionChanged(BaseField f, object obj) { // Debug.Log($"{ModTag} OnShapeSelectionChanged for {this} from {obj} to {f.GetValue(this)}"); ChangeShape(fromShape: availableShapes[obj as string]); foreach (Part p in part.symmetryCounterparts) { ProceduralPart pPart = p.FindModuleImplementing <ProceduralPart>(); pPart.ChangeShape(fromShape: pPart.availableShapes[obj as string]); } }
// Thats for DRE, which is not updated yet //private void UpdateDissipationAndLoss(double ablativeResource) //{ // // The heat model is going to change considerably. // // Will just do an unconfigurable quick and dirty way for now. // FloatCurve loss = new FloatCurve(); // loss.Add(650, 0, 0, 0); // loss.Add(1000, (float)(0.2 * lossTweak * ablativeResource)); // loss.Add(3000, (float)(0.3 * lossTweak * ablativeResource), 0, 0); // FloatCurve dissipation = new FloatCurve(); // dissipation.Add(300, 0, 0, 0); // dissipation.Add(500, (float)(80000 * dissipationTweak / ablativeResource), 0, 0); // // Save it. // PartModule modHeatShield = part.Modules["ModuleHeatShield"]; // Type type = modHeatShield.GetType(); // type.GetField("loss").SetValue(modHeatShield, loss); // type.GetField("dissipation").SetValue(modHeatShield, dissipation); //} public float GetCurrentCostMult() { if (multiplyCostByDiameter != 0) { ProceduralPart ppart = PPart; if (ppart != null) { ProceduralShapeBezierCone shape = ppart.CurrentShape as ProceduralShapeBezierCone; if (null != shape) { float diameter = shape.topDiameter; return(diameter * multiplyCostByDiameter); } } } return(1); }
void UpdateFairing() { ProceduralPart ppart = PPart; if (useFairing && ppart != null) { ProceduralAbstractSoRShape shape = ppart.CurrentShape as ProceduralAbstractSoRShape; if (shape != null) { Vector3[] topEndcapVerticies = shape.GetEndcapVerticies(true); Vector3[] topInner = new Vector3[topEndcapVerticies.Length + 1]; topEndcapVerticies.CopyTo(topInner, 0); topInner[topEndcapVerticies.Length] = topEndcapVerticies[0]; int vertCount = topInner.Length; //foreach (Vector3 v in topInner) // Debug.Log(v); Vector3[] topOuter = (Vector3[])topInner.Clone(); for (int i = 0; i < vertCount; ++i) { float r = topInner[i].magnitude; float r_ = r + fairingThickness; float scaleFactor = r_ / r; topOuter[i].x *= scaleFactor; topOuter[i].z *= scaleFactor; } TextureScale.x = topOuter[0].magnitude * 2 * Mathf.PI; Vector3[] sideTop = (Vector3[])topOuter.Clone(); Vector3[] sideBottom = (Vector3[])sideTop.Clone(); Vector3[] bottomInner = (Vector3[])topInner.Clone(); Vector3[] bottomOuter = (Vector3[])topOuter.Clone(); for (int i = 0; i < vertCount; ++i) { if (bottomNode != null) { sideBottom[i].y = bottomNode.position.y; bottomInner[i].y = bottomNode.position.y; bottomOuter[i].y = bottomNode.position.y; } } TextureScale.y = Mathf.Abs(topOuter[0].y - bottomOuter[0].y); Vector3[] innerSideTop = (Vector3[])topInner.Clone(); Vector3[] innerSideBottom = (Vector3[])bottomInner.Clone(); int topInnerStart = 0; int topOuterStart = topInnerStart + vertCount; int sideTopStart = topOuterStart + vertCount; int sideBottomStart = sideTopStart + vertCount; int bottomInnerStart = sideBottomStart + vertCount; int bottomOuterStart = bottomInnerStart + vertCount; int innerSideTopStart = bottomOuterStart + vertCount; int innerSideBottomStart = innerSideTopStart + vertCount; UncheckedMesh m = new UncheckedMesh(vertCount * 8, vertCount * 8 * 6); //int tri = 0; for (int i = 0; i < vertCount; ++i) { m.verticies[topInnerStart + i] = topInner[i]; m.verticies[topOuterStart + i] = topOuter[i]; m.verticies[sideTopStart + i] = sideTop[i]; m.verticies[sideBottomStart + i] = sideBottom[i]; m.verticies[bottomInnerStart + i] = bottomInner[i]; m.verticies[bottomOuterStart + i] = bottomOuter[i]; m.verticies[innerSideTopStart + i] = innerSideTop[i]; m.verticies[innerSideBottomStart + i] = innerSideBottom[i]; m.normals[topInnerStart + i] = new Vector3(0.0f, 1.0f, 0.0f); m.normals[topOuterStart + i] = new Vector3(0.0f, 1.0f, 0.0f); m.normals[sideTopStart + i] = m.verticies[sideTopStart + i].xz().normalized; m.normals[sideBottomStart + i] = m.verticies[sideBottomStart + i].xz().normalized; m.normals[bottomInnerStart + i] = new Vector3(0.0f, -1.0f, 0.0f); m.normals[bottomOuterStart + i] = new Vector3(0.0f, -1.0f, 0.0f); m.normals[innerSideTopStart + i] = -m.verticies[innerSideTopStart + i].xz().normalized; m.normals[innerSideBottomStart + i] = -m.verticies[innerSideBottomStart + i].xz().normalized; m.uv[topInnerStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 0.0f); m.uv[topOuterStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 1.0f); m.uv[sideTopStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 1.0f); m.uv[sideBottomStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 0.0f); m.uv[bottomInnerStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 0.0f); m.uv[bottomOuterStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 1.0f); m.uv[innerSideTopStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 0.0f); m.uv[innerSideBottomStart + i] = new Vector2(Mathf.InverseLerp(0, vertCount - 1, i), 1.0f); m.tangents[topInnerStart + i] = Vector3.Cross(m.normals[topInnerStart + i], m.verticies[topInnerStart + i]).xz().normalized.toVec4(-1); m.tangents[topOuterStart + i] = Vector3.Cross(m.normals[topOuterStart + i], m.verticies[topOuterStart + i]).xz().normalized.toVec4(-1); m.tangents[sideTopStart + i] = Vector3.Cross(m.normals[sideTopStart + i], new Vector3(0, 1, 0)).normalized.toVec4(-1); m.tangents[sideBottomStart + i] = Vector3.Cross(m.normals[sideTopStart + i], new Vector3(0, 1, 0)).normalized.toVec4(-1); m.tangents[bottomInnerStart + i] = Vector3.Cross(m.normals[bottomInnerStart + i], m.verticies[topInnerStart + i]).xz().normalized.toVec4(-1); m.tangents[bottomOuterStart + i] = Vector3.Cross(m.normals[bottomOuterStart + i], m.verticies[topOuterStart + i]).xz().normalized.toVec4(-1); m.tangents[innerSideTopStart + i] = Vector3.Cross(m.normals[innerSideTopStart + i], new Vector3(0, 1, 0)).normalized.toVec4(-1); m.tangents[innerSideBottomStart + i] = Vector3.Cross(m.normals[innerSideTopStart + i], new Vector3(0, 1, 0)).normalized.toVec4(-1); //Debug.Log(i +" uv: " + Mathf.InverseLerp(0, vertCount - 1, i)); } int triangleOffset = 0; triangleOffset = ConnectRings(m, topInnerStart, topOuterStart, vertCount, 0); triangleOffset = ConnectRings(m, sideTopStart, sideBottomStart, vertCount, triangleOffset); triangleOffset = ConnectRings(m, bottomOuterStart, bottomInnerStart, vertCount, triangleOffset); triangleOffset = ConnectRings(m, innerSideBottomStart, innerSideTopStart, vertCount, triangleOffset); if (fairingMesh != null) { m.WriteTo(fairingMesh); fairingMesh.RecalculateNormals(); } else { Debug.Log("no fairing mesh"); } } oldTextureSet = null; UpdateTexture(); } }
private void InitializeBells() { print("*PP* InitializeBells"); // Initialize the configs. if (srbConfigs == null) { LoadSRBConfigs(); } BaseField field = Fields["selectedBellName"]; // ReSharper disable once PossibleNullReferenceException switch (srbConfigs.Count) { case 0: Debug.LogError("*PT* No SRB bells configured"); return; case 1: field.guiActiveEditor = false; break; default: field.guiActiveEditor = true; UI_ChooseOption range = (UI_ChooseOption)field.uiControlEditor; range.options = srbConfigs.Keys.ToArray(); break; } Transform srbBell = part.FindModelTransform(srbBellName); thrustTransform = srbBell.Find(thrustVectorTransformName); foreach (SRBBellConfig conf in srbConfigs.Values) { conf.model = part.FindModelTransform(conf.modelName); if (conf.model == null) { Debug.LogError("*PT* Unable to find model transform for SRB bell name: " + conf.modelName); srbConfigs.Remove(conf.modelName); continue; } conf.model.transform.parent = srbBell; conf.srbAttach = conf.model.Find(conf.srbAttachName); if (conf.srbAttach == null) { Debug.LogError("*PT* Unable to find srbAttach for SRB bell name: " + conf.modelName); srbConfigs.Remove(conf.modelName); continue; } // Only enable the colider for flight mode. This prevents any surface attachments. if (HighLogic.LoadedSceneIsEditor && conf.model.collider != null) { Destroy(conf.model.collider); } conf.model.gameObject.SetActive(false); } // Select the bell if (string.IsNullOrEmpty(selectedBellName) || !srbConfigs.ContainsKey(selectedBellName)) { selectedBellName = srbConfigsSerialized[0].GetValue("name"); } selectedBell = srbConfigs[selectedBellName]; // Config for Real Fuels. if (part.Modules.Contains("ModuleEngineConfigs")) { // ReSharper disable once InconsistentNaming var mEC = part.Modules["ModuleEngineConfigs"]; ModularEnginesChangeThrust = (Action <float>)Delegate.CreateDelegate(typeof(Action <float>), mEC, "ChangeThrust"); try { ModularEnginesChangeEngineType = (Action <string>)Delegate.CreateDelegate(typeof(Action <string>), mEC, "ChangeEngineType"); } catch { ModularEnginesChangeEngineType = null; } //Fields["burnTime"].guiActiveEditor = false; //Fields["srbISP"].guiActiveEditor = false; //Fields["heatProduction"].guiActiveEditor = false; } Fields["thrust"].guiActiveEditor = !UsingME; Fields["burnTime"].guiActiveEditor = !UsingME; Fields["burnTimeME"].guiActiveEditor = UsingME; Fields["thrustME"].guiActiveEditor = UsingME; // Initialize the modules. InitModulesFromBell(); // Break out at this stage during loading scene if (GameSceneFilter.AnyInitializing.IsLoaded()) { UpdateThrustDependentCalcs(); return; } // Update the thrust according to the equation when in editor mode, don't mess with ships in flight if (GameSceneFilter.AnyEditor.IsLoaded()) { UpdateThrustDependentCalcs(); } else { if (bellScale <= 0 || heatProduction <= 0) { // We've reloaded from a legacy save // Use the new heat production equation, but use the legacy bell scaling one. UpdateThrustDependentCalcs(); // Legacy bell scaling equation bellScale = Mathf.Sqrt(thrust / deprecatedThrustScaleFactor); } UpdateEngineAndBellScale(); } // It makes no sense to have a thrust limiter for SRBs // Even though this is present in stock, I'm disabling it. BaseField thrustLimiter = ((PartModule)Engine).Fields["thrustPercentage"]; thrustLimiter.guiActive = false; thrustLimiter.guiActiveEditor = false; ProceduralPart pPart = GetComponent <ProceduralPart>(); if (pPart != null) { // Attach the bell. In the config file this isn't in normalized position, move it into normalized position first. print("*PP* Setting bell position: " + pPart.transform.TransformPoint(0, -0.5f, 0)); srbBell.position = pPart.transform.TransformPoint(0, -0.5f, 0); pPart.AddAttachment(srbBell, true); // Move the bottom attach node into position. // This needs to be done in flight mode too for the joints to work correctly bottomAttachNode = part.findAttachNode(bottomAttachNodeName); Vector3 delta = selectedBell.srbAttach.position - selectedBell.model.position; bottomAttachNode.originalPosition = bottomAttachNode.position += part.transform.InverseTransformDirection(delta); pPart.AddNodeOffset(bottomAttachNodeName, GetOffset); } // Move thrust transform to the end of the bell thrustTransform.position = selectedBell.srbAttach.position; }
public TUTexturePickerGUI(ProceduralPart parent) { this.parent = parent; SetupTUReflection(); }