Example #1
0
        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.
        }
Example #2
0
        // 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]);
            }
        }
Example #3
0
        // 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);
        }
Example #4
0
        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();
            }
        }
Example #5
0
        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();
 }