public static void StartPointer(Part rootPart, KIS_Item item, OnPointerClick pClick, OnPointerState pState, Transform from = null) { if (!running) { DebugEx.Fine("StartPointer()"); customRot = Vector3.zero; aboveDistance = 0; partToAttach = rootPart; sourceTransform = from; running = true; SendPointerClick = pClick; SendPointerState = pState; if (rootPart) { MakePointer(rootPart); } else { VariantsUtils.ExecuteAtPartVariant( item.availablePart, VariantsUtils.GetCurrentPartVariant(item.availablePart, item.partNode), MakePointer); pointer.transform.localScale *= KISAPI.PartNodeUtils.GetTweakScaleSizeModifier(item.partNode); } LockUI(); allowedAttachmentParts = allowedAttachmentParts; // Apply selection. SendPointerState(PointerTarget.Nothing, PointerState.OnPointerStarted, null, null); } }
public void EnableIcon(int resolution) { DisableIcon(); icon = new KIS_IconViewer( availablePart, resolution, VariantsUtils.GetCurrentPartVariant(availablePart, partNode)); }
/// <summary>Returns the part's model.</summary> /// <remarks>The returned model is a copy from the part prefab.</remarks> /// <param name="avPart">The part proto to get the model from.</param> /// <param name="variant"> /// The part's variant to apply. If <c>null</c>, then variant will be extracted from /// <paramref name="partNode"/>. /// </param> /// <param name="partNode"> /// The part's persistent state. It's used to extract the external scale modifiers and part's /// variant. It can be <c>null</c>. /// </param> /// <returns>The model of the part. Don't forget to destroy it when not needed.</returns> public GameObject GetPartModel( AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null) { if (variant == null && partNode != null) { variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode); } GameObject modelObj = null; VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => { var partPrefabModel = Hierarchy.GetPartModelTransform(p).gameObject; modelObj = UnityEngine.Object.Instantiate(partPrefabModel); modelObj.SetActive(true); }); // Handle TweakScale settings. if (partNode != null) { var scale = KISAPI.PartNodeUtils.GetTweakScaleSizeModifier(partNode); if (Math.Abs(1.0 - scale) > double.Epsilon) { DebugEx.Fine("Applying TweakScale size modifier: {0}", scale); var scaleRoot = new GameObject("TweakScale"); scaleRoot.transform.localScale = new Vector3((float)scale, (float)scale, (float)scale); modelObj.transform.SetParent(scaleRoot.transform, worldPositionStays: false); modelObj = scaleRoot; } } return(modelObj); }
/// <summary>Calculates part's dry cost given the config and the variant.</summary> /// <param name="avPart">The part's proto.</param> /// <param name="variant"> /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from /// <paramref name="partNode"/>. /// </param> /// <param name="partNode"> /// The part's persistent config. It will be looked up for the various cost modifiers. /// </param> /// <returns>The dry cost of the part.</returns> public double GetPartDryCost( AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null) { // TweakScale compatibility if (partNode != null) { var tweakScale = KISAPI.PartNodeUtils.GetTweakScaleModule(partNode); if (tweakScale != null) { var tweakedCost = ConfigAccessor.GetValueByPath <double>(tweakScale, "DryCost"); if (tweakedCost.HasValue) { // TODO(ihsoft): Get back to this code once TweakScale supports variants. return(tweakedCost.Value); } DebugEx.Error("No dry cost specified in a tweaked part {0}:\n{1}", avPart.name, tweakScale); } } var itemCost = avPart.cost; if (variant == null && partNode != null) { variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode); } VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => itemCost += p.GetModuleCosts(avPart.cost)); return(itemCost); }
public KIS_IconViewer(Part part, int resolution) { if (part.Modules.OfType <KerbalEVA>().Any()) { MakeKerbalAvatar(part, resolution); } else { MakePartIcon(part.partInfo, resolution, VariantsUtils.GetCurrentPartVariant(part)); } }
public KIS_IconViewer(Part part, int resolution) { if (part.vessel != null && part.vessel.isEVA) { MakeKerbalAvatar(part, resolution); } else { MakePartIcon(part.partInfo, resolution, VariantsUtils.GetCurrentPartVariant(part)); } }
/// <summary>Calculates part's dry mass given the config and the variant.</summary> /// <param name="avPart">The part's proto.</param> /// <param name="variant"> /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from /// <paramref name="partNode"/>. /// </param> /// <param name="partNode"> /// The part's persistent config. It will be looked up for the variant if it's not specified. /// </param> /// <returns>The dry cost of the part.</returns> public double GetPartDryMass( AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null) { var itemMass = avPart.partPrefab.mass; if (variant == null && partNode != null) { variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode); } VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => itemMass += p.GetModuleMass(p.mass)); return(itemMass); }
/// <summary>Returns part's boundary box basing on its geometrics.</summary> /// <remarks>The size is calculated from the part prefab model.</remarks> /// <param name="avPart">The part proto to get the models from.</param> /// <param name="variant"> /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from /// <paramref name="partNode"/>. /// </param> /// <param name="partNode"> /// The part's persistent config. It will be looked up for the variant if it's not specified. /// </param> /// <returns>The volume in liters.</returns> public Vector3 GetPartBounds( AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null) { var bounds = default(Bounds); if (variant == null && partNode != null) { variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode); } VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => { var partModel = GetSceneAssemblyModel(p).transform; bounds.Encapsulate(GetMeshBounds(partModel)); UnityEngine.Object.DestroyImmediate(partModel.gameObject); }); return(bounds.size); }
static void OnMouseEnterPart(Part hoverPart) { if (hoverPart == partToAttach) { return; } if (allowMount) { ModuleKISPartMount pMount = hoverPart.GetComponent <ModuleKISPartMount>(); if (pMount) { // Set current attach node AttachNode an = attachNodes.Find(f => f.id == pMount.mountedPartNode); if (an != null) { attachNodeIndex = attachNodes.IndexOf(an); SetPointerVisible(false); } else { SetPointerVisible(true); } // Init attach node foreach (KeyValuePair <AttachNode, List <string> > mount in pMount.GetMounts()) { if (!mount.Key.attachedPart) { KIS_Shared.AssignAttachIcon(hoverPart, mount.Key, colorMountOk, "KISMount"); } } } } if (allowStack && currentAttachNode.nodeType != AttachNode.NodeType.Surface) { var variant = VariantsUtils.GetCurrentPartVariant(hoverPart); if (variant != null) { VariantsUtils.ApplyVariantOnAttachNodes(hoverPart, variant); } foreach (var an in KIS_Shared.GetAvailableAttachNodes(hoverPart, needSrf: false)) { KIS_Shared.AssignAttachIcon(hoverPart, an, colorStack); } } SendPointerState(pointerTarget, PointerState.OnMouseEnterPart, hoverPart, null); }
/// <summary>Returns part's volume basing on its geometrics.</summary> /// <remarks> /// The volume is calculated basing on the smallest boundary box that encapsulates all the meshes /// in the part. The deployable parts can take much more space in teh deployed state. /// </remarks> /// <param name="avPart">The part proto to get the models from.</param> /// <param name="variant"> /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from /// <paramref name="partNode"/>. /// </param> /// <param name="partNode"> /// The part's persistent config. It will be looked up for the variant if it's not specified. /// </param> /// <returns>The volume in liters.</returns> public float GetPartVolume( AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null) { var itemModule = avPart.partPrefab.Modules.OfType <KIS.ModuleKISItem>().FirstOrDefault(); if (itemModule != null && itemModule.volumeOverride > 0) { return(itemModule.volumeOverride // Ignore geometry. * KISAPI.PartNodeUtils.GetTweakScaleSizeModifier(partNode)); // But respect TweakScale. } var bounds = default(Bounds); VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => { var partModel = GetSceneAssemblyModel(p).transform; bounds.Encapsulate(GetMeshBounds(partModel)); UnityEngine.Object.DestroyImmediate(partModel.gameObject); }); var boundsSize = bounds.size; return(boundsSize.x * boundsSize.y * boundsSize.z * 1000f); }
/// <summary>Returns the part's model, used to make the perview icon.</summary> /// <remarks> /// Note, that this is not the actual part appearance. It's an optimized version, specifically /// made for the icon preview. In particular, the model is scaled to fit the icon's constrains. /// </remarks> /// <param name="avPart">The part proto to get the model from.</param> /// <param name="variant"> /// The part's variant to apply. If <c>null</c>, then variant will be extracted from /// <paramref name="partNode"/>. /// </param> /// <param name="partNode"> /// The part's persistent state. It's used to extract the part's variant. It can be <c>null</c>. /// </param> /// <param name="skipVariantsShader"> /// Tells if the variant shaders must not be applied to the model. For the purpose of making a /// preview icon it's usually undesirable to have the shaders changed. /// </param> /// <returns>The model of the part. Don't forget to destroy it when not needed.</returns> public GameObject GetIconPrefab( AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null, bool skipVariantsShader = true) { var iconPrefab = UnityEngine.Object.Instantiate(avPart.iconPrefab); iconPrefab.SetActive(true); if (variant == null && partNode != null) { variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode); } if (variant != null) { DebugEx.Fine( "Applying variant to the iconPrefab: part={0}, variant={1}", avPart.name, variant.Name); ModulePartVariants.ApplyVariant( null, Hierarchy.FindTransformByPath(iconPrefab.transform, "**/model"), variant, KSP.UI.Screens.EditorPartIcon.CreateMaterialArray(iconPrefab), skipVariantsShader); } return(iconPrefab); }