// Analysis disable once UnusedParameter public bool RenderGraphs(RenderTexture screen, float cameraAspect) { if (backgroundTexture != null) { Graphics.Blit(backgroundTexture, screen); } GL.Clear(true, (backgroundTexture == null), backgroundColorValue); if (!startupComplete) { JUtil.AnnoyUser(this); } GL.PushMatrix(); // This way 0,0 is in bottom left corner, which is what we want this time. GL.LoadPixelMatrix(0, screen.width, 0, screen.height); double time = Planetarium.GetUniversalTime(); foreach (GraphLine graph in graphs) { graph.Draw(graphSpace, time); } if (borders > 0) { GraphLine.DrawVector(borderVertices, borderColorValue); } GL.PopMatrix(); return(true); }
public void LateUpdate() { if (vessel != null && JUtil.VesselIsInIVA(vessel) && !startupComplete) { JUtil.AnnoyUser(this); enabled = false; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { rpmComp = RasterPropMonitorComputer.Instantiate(internalProp, true); if (string.IsNullOrEmpty(layout)) { throw new ArgumentNullException("layout"); } foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("RPM_GRAPHING_BACKGROUND")) { if (node.GetValue("layout") == layout) { if (!node.HasValue("backgroundColor")) { JUtil.LogErrorMessage(this, "?!? no backgroundColor"); } string s = node.GetValue("backgroundColor"); if (string.IsNullOrEmpty(s)) { JUtil.LogErrorMessage(this, "backgroundColor is missing?"); } backgroundColorValue = ConfigNode.ParseColor32(node.GetValue("backgroundColor")); ConfigNode[] dataNodes = node.GetNodes("DATA_SET"); for (int i = 0; i < dataNodes.Length; i++) { try { dataSets.Add(new DataSet(dataNodes[i], rpmComp)); } catch (ArgumentException e) { JUtil.LogErrorMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); throw; } } break; } } startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void LateUpdate() { if (JUtil.IsActiveVessel(vessel) && !startupComplete) { JUtil.AnnoyUser(this); // And disable ourselves. enabled = false; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { ConfigNode moduleConfig = null; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { if (string.IsNullOrEmpty(variableName)) { JUtil.LogErrorMessage(this, "Configuration failed in prop {0} ({1}), no variableName.", internalProp.propID, internalProp.propName); throw new ArgumentNullException(); } moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] variableNodes = moduleConfig.GetNodes("VARIABLESET"); for (int i = 0; i < variableNodes.Length; i++) { try { variableSets.Add(new CallbackAnimationSet(variableNodes[i], variableName, internalProp)); } catch (ArgumentException e) { JUtil.LogErrorMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } break; } } RPMVesselComputer comp = RPMVesselComputer.Instance(vessel); del = (Action <RPMVesselComputer, float>)Delegate.CreateDelegate(typeof(Action <RPMVesselComputer, float>), this, "OnCallback"); float value = comp.ProcessVariable(variableName).MassageToFloat(); for (int i = 0; i < variableSets.Count; ++i) { variableSets[i].Update(comp, value); } comp.RegisterCallback(variableName, del); JUtil.LogMessage(this, "Configuration complete in prop {1} ({2}), supporting {0} callback animators.", variableSets.Count, internalProp.propID, internalProp.propName); } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
/// <summary> /// Update the text mesh if it's changed. /// </summary> public void Update() { if (!string.IsNullOrEmpty(text_)) { if (invalidated) { if (font_ == null) { if (!fontNag) { JUtil.LogErrorMessage(this, "Font was not initialized"); JUtil.AnnoyUser(this); fontNag = true; } return; } if (text_.Contains("[")) { richText = true; GenerateRichText(); } else { richText = false; GenerateText(); } invalidated = false; invalidatedColor = false; } else if (invalidatedColor) { if (richText) { GenerateRichText(); } else { if (meshFilter_.mesh.colors32.Length > 0) { Color32[] newColor = new Color32[meshFilter_.mesh.colors32.Length]; for (int idx = 0; idx < newColor.Length; ++idx) { newColor[idx] = color_; } meshFilter_.mesh.colors32 = newColor; meshFilter_.mesh.UploadMeshData(false); } } invalidatedColor = false; } } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { ConfigNode moduleConfig = null; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] variableNodes = moduleConfig.GetNodes("VARIABLESET"); for (int i = 0; i < variableNodes.Length; i++) { try { variableSets.Add(new VariableAnimationSet(variableNodes[i], internalProp)); } catch (ArgumentException e) { JUtil.LogMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } break; } } // Fallback: If there are no VARIABLESET blocks, we treat the module configuration itself as a variableset block. if (variableSets.Count < 1 && moduleConfig != null) { try { variableSets.Add(new VariableAnimationSet(moduleConfig, internalProp)); } catch (ArgumentException e) { JUtil.LogMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } JUtil.LogMessage(this, "Configuration complete in prop {1}, supporting {0} variable indicators.", variableSets.Count, internalProp.propID); foreach (VariableAnimationSet thatSet in variableSets) { alwaysActive |= thatSet.alwaysActive; } startupComplete = true; } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); cameraBody = new GameObject(); cameraBody.name = "RPMPFD" + cameraBody.GetInstanceID(); cameraBody.layer = drawingLayer; hudCamera = cameraBody.AddComponent <Camera>(); hudCamera.enabled = false; hudCamera.orthographic = true; hudCamera.eventMask = 0; hudCamera.farClipPlane = 3f; hudCamera.orthographicSize = 1.0f; hudCamera.cullingMask = 1 << drawingLayer; // does this actually work? hudCamera.backgroundColor = backgroundColorValue; hudCamera.clearFlags = CameraClearFlags.Depth | CameraClearFlags.Color; hudCamera.transparencySortMode = TransparencySortMode.Orthographic; hudCamera.transform.position = Vector3.zero; hudCamera.transform.LookAt(new Vector3(0.0f, 0.0f, 1.5f), Vector3.up); if (!string.IsNullOrEmpty(progradeColor)) { progradeColorValue = ConfigNode.ParseColor32(progradeColor); } persistence = new PersistenceAccessor(internalProp); } catch (Exception e) { JUtil.LogErrorMessage(this, "Start() failed with an exception: {0}", e); JUtil.AnnoyUser(this); throw; } startupComplete = true; }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { rpmComp = RasterPropMonitorComputer.Instantiate(internalProp, true); if (lineMaterial == null) { lineMaterial = JUtil.DrawLineMaterial(); } if (!string.IsNullOrEmpty(borderColor)) { borderColorValue = ConfigNode.ParseColor32(borderColor); } if (!string.IsNullOrEmpty(backgroundColor)) { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); } //comp = RasterPropMonitorComputer.Instantiate(internalProp); graphSpace = new Rect(); graphSpace.xMin = graphRect.x; graphSpace.yMin = graphRect.y; graphSpace.xMax = graphRect.z; graphSpace.yMax = graphRect.w; xGraphSpan = xSpan; interval = secondsBetweenSamples; if (GameDatabase.Instance.ExistsTexture(backgroundTextureURL.EnforceSlashes())) { backgroundTexture = GameDatabase.Instance.GetTexture(backgroundTextureURL.EnforceSlashes(), false); } var bottomLeft = new Vector2(graphSpace.xMin, graphSpace.yMin); var bottomRight = new Vector2(graphSpace.xMax, graphSpace.yMin); var topLeft = new Vector2(graphSpace.xMin, graphSpace.yMax); var topRight = new Vector2(graphSpace.xMax, graphSpace.yMax); switch (borders) { case 2: borderVertices.Add(bottomRight); borderVertices.Add(bottomLeft); borderVertices.Add(topLeft); break; case 4: borderVertices.Add(bottomLeft); borderVertices.Add(topLeft); borderVertices.Add(topRight); borderVertices.Add(bottomRight); borderVertices.Add(bottomLeft); break; } foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("JSIGRAPHSET")) { if (node.HasValue("name") && node.GetValue("name") == graphSet) { foreach (ConfigNode graphNode in node.GetNodes("GRAPH")) { graphs.Add(new GraphLine(graphNode, rpmComp, xGraphSpan, ySpan, interval)); } } } JUtil.LogMessage(this, "Graphing {0} values.", graphs.Count); startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { // Skip the entire sequence when in editor -- this means we're part of a transparent pod and won't get used anyway. if (HighLogic.LoadedSceneIsEditor) { iconMaterial = new Material(Shader.Find("KSP/Alpha/Unlit Transparent")); iconMaterial.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); startupComplete = true; return; } try { if (!string.IsNullOrEmpty(backgroundColor)) { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); } if (!string.IsNullOrEmpty(iconColorSelf)) { iconColorSelfValue = ConfigNode.ParseColor32(iconColorSelf); } if (!string.IsNullOrEmpty(orbitColorSelf)) { orbitColorSelfValue = ConfigNode.ParseColor32(orbitColorSelf); } else { orbitColorSelfValue = MapView.PatchColors[0]; } if (!string.IsNullOrEmpty(iconColorTarget)) { iconColorTargetValue = ConfigNode.ParseColor32(iconColorTarget); } if (!string.IsNullOrEmpty(iconColorShadow)) { iconColorShadowValue = ConfigNode.ParseColor32(iconColorShadow); } if (!string.IsNullOrEmpty(iconColorAP)) { iconColorAPValue = ConfigNode.ParseColor32(iconColorAP); } else { iconColorAPValue = MapView.PatchColors[0]; } if (!string.IsNullOrEmpty(iconColorPE)) { iconColorPEValue = ConfigNode.ParseColor32(iconColorPE); } else { iconColorPEValue = MapView.PatchColors[0]; } if (!string.IsNullOrEmpty(orbitColorNextNode)) { orbitColorNextNodeValue = ConfigNode.ParseColor32(orbitColorNextNode); } else { orbitColorNextNodeValue = MapView.PatchColors[1]; } if (!string.IsNullOrEmpty(iconColorClosestApproach)) { iconColorClosestApproachValue = ConfigNode.ParseColor32(iconColorClosestApproach); } // This mess with shaders has to stop. Maybe we should have a single shader to draw EVERYTHING on the screen... iconMaterial = new Material(Shader.Find("KSP/Alpha/Unlit Transparent")); iconMaterial.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { try { comp = RasterPropMonitorComputer.Instantiate(internalProp); textObjTransform = internalProp.FindModelTransform(labelTransform); textObj = InternalComponents.Instance.CreateText(fontName, fontSize, textObjTransform, string.Empty); activeLabel = 0; SmarterButton.CreateButton(internalProp, switchTransform, Click); ConfigNode moduleConfig = null; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] variableNodes = moduleConfig.GetNodes("VARIABLESET"); for (int i = 0; i < variableNodes.Length; i++) { try { labelsEx.Add(new VariableLabelSet(variableNodes[i])); } catch (ArgumentException e) { JUtil.LogMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } break; } } // Fallback: If there are no VARIABLESET blocks, we treat the module configuration itself as a variableset block. if (labelsEx.Count < 1 && moduleConfig != null) { try { labelsEx.Add(new VariableLabelSet(moduleConfig)); } catch (ArgumentException e) { JUtil.LogMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } if (labelsEx.Count == 0) { JUtil.LogMessage(this, "No labels defined."); throw new ArgumentException("No labels defined"); } colorShiftRenderer = internalProp.FindModelComponent <Renderer>(coloredObject); if (labelsEx[activeLabel].hasColor) { colorShiftRenderer.material.SetColor(colorName, labelsEx[activeLabel].color); } if (labelsEx[activeLabel].hasText) { textObj.text.Text = StringProcessor.ProcessString(labelsEx[activeLabel].labelText, comp); } audioOutput = JUtil.SetupIVASound(internalProp, switchSound, switchSoundVolume, false); JUtil.LogMessage(this, "Configuration complete in prop {1}, supporting {0} variable indicators.", labelsEx.Count, internalProp.propID); } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public void Start() { // If we're not in the correct location, there's no point doing anything. if (!InstallationPathWarning.Warn()) { return; } if (HighLogic.LoadedSceneIsEditor) { return; } try { rpmComp = RasterPropMonitorComputer.Instantiate(internalProp, true); JUtil.LogMessage(this, "Attaching monitor {2}-{1} to {0}", rpmComp.RPMCid, internalProp.propID, internalProp.internalModel.internalName); // Install the calculator module. rpmComp.UpdateDataRefreshRate(refreshDataRate); // Loading the font... List <Texture2D> fontTexture = new List <Texture2D>(); fontTexture.Add(LoadFont(this, internalProp, fontTransform)); // Damn KSP's config parser!!! if (!string.IsNullOrEmpty(emptyColor)) { emptyColorValue = ConfigNode.ParseColor32(emptyColor); } if (!string.IsNullOrEmpty(defaultFontTint)) { defaultFontTintValue = ConfigNode.ParseColor32(defaultFontTint); } if (!string.IsNullOrEmpty(fontDefinition)) { JUtil.LogMessage(this, "Loading font definition from {0}", fontDefinition); fontDefinitionString = File.ReadAllLines(KSPUtil.ApplicationRootPath + "GameData/" + fontDefinition.EnforceSlashes(), Encoding.UTF8)[0]; } // Now that is done, proceed to setting up the screen. screenTexture = new RenderTexture(screenPixelWidth, screenPixelHeight, 24, RenderTextureFormat.ARGB32); screenMat = internalProp.FindModelTransform(screenTransform).GetComponent <Renderer>().material; bool manuallyInvertY = false; if (SystemInfo.graphicsDeviceVersion.StartsWith("Direct3D 9") || SystemInfo.graphicsDeviceVersion.StartsWith("Direct3D 11") || SystemInfo.graphicsDeviceVersion.StartsWith("Direct3D 12")) { manuallyInvertY = (UnityEngine.QualitySettings.antiAliasing > 0); } foreach (string layerID in textureLayerID.Split()) { screenMat.SetTexture(layerID.Trim(), screenTexture); // This code was written for a much older flavor of Unity, and the Unity 2017.1 update broke // some assumptions about who managed the y-inversion issue between OpenGL and DX9. if (manuallyInvertY) { screenMat.SetTextureScale(layerID.Trim(), new Vector2(1.0f, -1.0f)); screenMat.SetTextureOffset(layerID.Trim(), new Vector2(0.0f, 1.0f)); } } if (GameDatabase.Instance.ExistsTexture(noSignalTextureURL.EnforceSlashes())) { noSignalTexture = GameDatabase.Instance.GetTexture(noSignalTextureURL.EnforceSlashes(), false); } // The neat trick. IConfigNode doesn't work. No amount of kicking got it to work. // Well, we don't need it. GameDatabase, gimme config nodes for all props! foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { // Now, we know our own prop name. if (node.GetValue("name") == internalProp.propName) { // So this is the configuration of our prop in memory. Nice place. // We know it contains at least one MODULE node, us. // And we know our moduleID, which is the number in order of being listed in the prop. // Therefore the module by that number is our module's own config node. ConfigNode moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] pageNodes = moduleConfig.GetNodes("PAGE"); // Which we can now parse for page definitions. for (int i = 0; i < pageNodes.Length; i++) { // Mwahahaha. try { var newPage = new MonitorPage(i, pageNodes[i], this); activePage = activePage ?? newPage; if (newPage.isDefault) { activePage = newPage; } pages.Add(newPage); } catch (ArgumentException e) { JUtil.LogMessage(this, "Warning - {0}", e); } } // Now that all pages are loaded, we can use the moment in the loop to suck in all the extra fonts. foreach (string value in moduleConfig.GetValues("extraFont")) { fontTexture.Add(LoadFont(this, internalProp, value)); } break; } } JUtil.LogMessage(this, "Done setting up pages, {0} pages ready.", pages.Count); textRenderer = new TextRenderer(fontTexture, new Vector2((float)fontLetterWidth, (float)fontLetterHeight), fontDefinitionString, 17, screenPixelWidth, screenPixelHeight); // Load our state from storage... persistentVarName = "activePage" + internalProp.propID; int activePageID = rpmComp.GetPersistentVariable(persistentVarName, pages.Count, false).MassageToInt(); if (activePageID < pages.Count) { activePage = pages[activePageID]; } activePage.Active(true); // If we have global buttons, set them up. if (!string.IsNullOrEmpty(globalButtons)) { string[] tokens = globalButtons.Split(','); for (int i = 0; i < tokens.Length; i++) { string buttonName = tokens[i].Trim(); // Notice that holes in the global button list ARE legal. if (!string.IsNullOrEmpty(buttonName)) { SmarterButton.CreateButton(internalProp, buttonName, i, GlobalButtonClick, GlobalButtonRelease); } } } audioOutput = JUtil.SetupIVASound(internalProp, buttonClickSound, buttonClickVolume, false); if (needsElectricCharge) { delResourceCallback = (Action <bool>)Delegate.CreateDelegate(typeof(Action <bool>), this, "ResourceDepletedCallback"); rpmComp.RegisterResourceCallback(resourceName, delResourceCallback); } if (needsCommConnection) { delCommConnectionCallback = (Action <float>)Delegate.CreateDelegate(typeof(Action <float>), this, "CommConnectionCallback"); rpmComp.RegisterVariableCallback("COMMNETVESSELCONTROLSTATE", delCommConnectionCallback); } // And if the try block never completed, startupComplete will never be true. startupComplete = true; } catch { JUtil.AnnoyUser(this); // We can also disable ourselves, that should help. enabled = false; // And now that we notified the user that config is borked, we rethrow the exception so that // it gets logged and we can debug. throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { if (!string.IsNullOrEmpty(odometerMode) && modeList.ContainsKey(odometerMode)) { oMode = modeList[odometerMode]; } //else if (!string.IsNullOrEmpty(odometerMode)) { // JUtil.LogMessage(this, "found odometerMode {0}, but it's not in the dictionary", odometerMode); //} //else { // JUtil.LogMessage(this, "Did not find odometerMode"); //} if (string.IsNullOrEmpty(characterTexture) && oMode == OdometerMode.SI) { JUtil.LogErrorMessage(this, "Prop configured as SI scaled, but there is no characterTexture"); return; } if (string.IsNullOrEmpty(digitTexture)) { // We can't do anything without the digit texture JUtil.LogErrorMessage(this, "Prop can not function without a digitTexture"); return; } digitTex = GameDatabase.Instance.GetTexture(digitTexture.EnforceSlashes(), false); if (digitTex == null) { JUtil.LogErrorMessage(this, "Failed to load digitTexture {0}", digitTexture); return; } if (!string.IsNullOrEmpty(characterTexture)) { characterTex = GameDatabase.Instance.GetTexture(characterTexture.EnforceSlashes(), false); if (characterTex == null) { JUtil.LogErrorMessage(this, "Failed to load characterTexture {0}", characterTexture); return; } } if (!string.IsNullOrEmpty(overlayTexture)) { overlayTex = GameDatabase.Instance.GetTexture(overlayTexture.EnforceSlashes(), false); if (overlayTex == null) { JUtil.LogErrorMessage(this, "Failed to load overlayTexture {0}", overlayTexture); return; } } if (string.IsNullOrEmpty(altVariable) != string.IsNullOrEmpty(perPodPersistenceName)) { JUtil.LogErrorMessage(this, "Both altVariable and perPodPeristenceName must be defined, or neither"); return; } // MOARdV: Which one are we using? HUD uses the latter, OrbitDisplay, the former. Shader unlit = Shader.Find("KSP/Alpha/Unlit Transparent"); //Shader unlit = Shader.Find("Hidden/Internal-GUITexture"); digitMaterial = new Material(unlit); rpmComp = RasterPropMonitorComputer.Instantiate(internalProp); backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); lastUpdate = Planetarium.GetUniversalTime(); screenTexture = new RenderTexture(screenPixelWidth, screenPixelHeight, 24, RenderTextureFormat.ARGB32); screenMat = internalProp.FindModelTransform(screenTransform).renderer.material; foreach (string layerID in textureLayerID.Split()) { screenMat.SetTexture(layerID.Trim(), screenTexture); } startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
// Analysis disable once UnusedParameter public bool RenderOrbit(RenderTexture screen, float cameraAspect) { if (!startupComplete) { JUtil.AnnoyUser(this); } // Make sure the parameters fit on the screen. Vector4 displayPosition = orbitDisplayPosition; displayPosition.z = Mathf.Min(screen.width - displayPosition.x, displayPosition.z); displayPosition.w = Mathf.Min(screen.height - displayPosition.y, displayPosition.w); // Here is our pixel budget in each direction: double horizPixelSize = displayPosition.z - iconPixelSize; double vertPixelSize = displayPosition.w - iconPixelSize; // Find a basis for transforming values into the framework of // vessel.orbit. The rendering framework assumes the periapsis // is drawn directly to the right of the mainBody center of mass. // It assumes the orbit's prograde direction is "up" (screen // relative) at the periapsis, providing a counter-clockwise // motion for vessel. // Once we have the basic transform, we will add in scalars // that will ultimately transform an arbitrary point (relative to // the planet's center) into screen space. Matrix4x4 screenTransform = Matrix4x4.identity; double now = Planetarium.GetUniversalTime(); double timeAtPe = vessel.orbit.NextPeriapsisTime(now); // Get the 3 direction vectors, based on Pe being on the right of the screen // OrbitExtensions provides handy utilities to get these. Vector3d right = vessel.orbit.Up(timeAtPe); Vector3d forward = vessel.orbit.SwappedOrbitNormal(); // MOARdV: OrbitExtensions.Horizontal is unstable. I've seen it // become (0, 0, 0) intermittently in flight. Instead, use the // cross product of the other two. // We flip the sign of this vector because we are using an inverted // y coordinate system to keep the icons right-side up. Vector3d up = -Vector3d.Cross(forward, right); //Vector3d up = -vessel.orbit.Horizontal(timeAtPe); screenTransform.SetRow(0, new Vector4d(right.x, right.y, right.z, 0.0)); screenTransform.SetRow(1, new Vector4d(up.x, up.y, up.z, 0.0)); screenTransform.SetRow(2, new Vector4d(forward.x, forward.y, forward.z, 0.0)); // Figure out our bounds. First, make sure the entire planet // fits on the screen. We define the center of the vessel.mainBody // as the origin of our coodinate system. double maxX = vessel.mainBody.Radius; double minX = -maxX; double maxY = maxX; double minY = -maxX; if (vessel.mainBody.atmosphere) { maxX += vessel.mainBody.maxAtmosphereAltitude; minX = -maxX; maxY = maxX; minY = -maxX; } // Now make sure the entire orbit fits on the screen. Vector3 vesselPos; // The PeR, ApR, and semiMinorAxis are all one dimensional, so we // can just apply them directly to these values. maxX = Math.Max(maxX, vessel.orbit.PeR); if (vessel.orbit.eccentricity < 1.0) { minX = Math.Min(minX, -vessel.orbit.ApR); maxY = Math.Max(maxY, vessel.orbit.semiMinorAxis); minY = Math.Min(minY, -vessel.orbit.semiMinorAxis); } else if (vessel.orbit.EndUT > 0.0) { // If we're hyperbolic, let's get the SoI transition vesselPos = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(vessel.orbit.EndUT)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); } // Make sure the vessel shows up on-screen. Since a hyperbolic // orbit doesn't have a meaningful ApR, we use this as a proxy for // how far we need to extend the bounds to show the vessel. vesselPos = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(now)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); // Account for a target vessel var targetBody = FlightGlobals.fetch.VesselTarget as CelestialBody; var targetVessel = FlightGlobals.fetch.VesselTarget as Vessel; if (targetVessel != null) { if (targetVessel.mainBody == vessel.mainBody) { double tgtPe = targetVessel.orbit.NextPeriapsisTime(now); vesselPos = screenTransform.MultiplyPoint3x4(targetVessel.orbit.SwappedRelativePositionAtUT(tgtPe)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); if (targetVessel.orbit.eccentricity < 1.0) { vesselPos = screenTransform.MultiplyPoint3x4(targetVessel.orbit.SwappedRelativePositionAtUT(targetVessel.orbit.NextApoapsisTime(now))); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); } vesselPos = screenTransform.MultiplyPoint3x4(targetVessel.orbit.SwappedRelativePositionAtUT(now)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); } else { // We only care about tgtVessel if it is in the same SoI. targetVessel = null; } } if (targetBody != null) { // Validate some values up front, so we don't need to test them later. if (targetBody.GetOrbit() == null) { targetBody = null; } else if (targetBody.orbit.referenceBody == vessel.orbit.referenceBody) { // If the target body orbits our current world, let's at // least make sure the body's location is visible. vesselPos = screenTransform.MultiplyPoint3x4(targetBody.GetOrbit().SwappedRelativePositionAtUT(now)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); } } ManeuverNode node = (vessel.patchedConicSolver.maneuverNodes.Count > 0) ? vessel.patchedConicSolver.maneuverNodes[0] : null; if (node != null) { double nodePe = node.nextPatch.NextPeriapsisTime(now); vesselPos = screenTransform.MultiplyPoint3x4(node.nextPatch.SwappedRelativePositionAtUT(nodePe)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); if (node.nextPatch.eccentricity < 1.0) { double nodeAp = node.nextPatch.NextApoapsisTime(now); vesselPos = screenTransform.MultiplyPoint3x4(node.nextPatch.SwappedRelativePositionAtUT(nodeAp)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); } else if (node.nextPatch.EndUT > 0.0) { // If the next patch is hyperbolic, include the endpoint. vesselPos = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(node.nextPatch.EndUT)); maxX = Math.Max(maxX, vesselPos.x); minX = Math.Min(minX, vesselPos.x); maxY = Math.Max(maxY, vesselPos.y); minY = Math.Min(minY, vesselPos.y); } } // Add translation. This will ensure that all of the features // under consideration above will be displayed. screenTransform[0, 3] = -0.5f * (float)(maxX + minX); screenTransform[1, 3] = -0.5f * (float)(maxY + minY); double neededWidth = maxX - minX; double neededHeight = maxY - minY; // Pick a scalar that will fit the bounding box we just created. float pixelScalar = (float)Math.Min(horizPixelSize / neededWidth, vertPixelSize / neededHeight); screenTransform = Matrix4x4.Scale(new Vector3(pixelScalar, pixelScalar, pixelScalar)) * screenTransform; GL.Clear(true, true, backgroundColorValue); GL.PushMatrix(); GL.LoadPixelMatrix(-displayPosition.z * 0.5f, displayPosition.z * 0.5f, displayPosition.w * 0.5f, -displayPosition.w * 0.5f); GL.Viewport(new Rect(displayPosition.x, screen.height - displayPosition.y - displayPosition.w, displayPosition.z, displayPosition.w)); lineMaterial.SetPass(0); GL.Begin(GL.LINES); // Draw the planet: Vector3 focusCenter = screenTransform.MultiplyPoint3x4(new Vector3(0.0f, 0.0f, 0.0f)); // orbitDriver is null on the sun, so we'll just use white instead. GL.Color((vessel.mainBody.orbitDriver == null) ? new Color(1.0f, 1.0f, 1.0f) : vessel.mainBody.orbitDriver.orbitColor); DrawCircle(focusCenter.x, focusCenter.y, (float)(vessel.mainBody.Radius * pixelScalar), orbitPoints); if (vessel.mainBody.atmosphere) { // Use the atmospheric ambient to color the atmosphere circle. GL.Color(vessel.mainBody.atmosphericAmbientColor); DrawCircle(focusCenter.x, focusCenter.y, (float)((vessel.mainBody.Radius + vessel.mainBody.maxAtmosphereAltitude) * pixelScalar), orbitPoints); } if (targetVessel != null) { GL.Color(iconColorTargetValue); if (!targetVessel.orbit.activePatch && targetVessel.orbit.eccentricity < 1.0 && targetVessel.orbit.referenceBody == vessel.orbit.referenceBody) { // For some reason, activePatch is false for targetVessel. // If we have a stable orbit for the target, use a fallback // rendering method: ReallyDrawOrbit(targetVessel.orbit, vessel.orbit.referenceBody, screenTransform, orbitPoints); } else { DrawOrbit(targetVessel.orbit, vessel.orbit.referenceBody, screenTransform, orbitPoints); } } foreach (CelestialBody moon in vessel.orbit.referenceBody.orbitingBodies) { if (moon != targetBody) { GL.Color(moon.orbitDriver.orbitColor); ReallyDrawOrbit(moon.GetOrbit(), vessel.orbit.referenceBody, screenTransform, orbitPoints); } } if (targetBody != null) { GL.Color(iconColorTargetValue); ReallyDrawOrbit(targetBody.GetOrbit(), vessel.orbit.referenceBody, screenTransform, orbitPoints); } if (node != null) { GL.Color(orbitColorNextNodeValue); DrawOrbit(node.nextPatch, vessel.orbit.referenceBody, screenTransform, orbitPoints); } if (vessel.orbit.nextPatch != null && vessel.orbit.nextPatch.activePatch) { GL.Color(orbitColorNextNodeValue); DrawOrbit(vessel.orbit.nextPatch, vessel.orbit.referenceBody, screenTransform, orbitPoints); } // Draw the vessel orbit GL.Color(orbitColorSelfValue); DrawOrbit(vessel.orbit, vessel.orbit.referenceBody, screenTransform, orbitPoints); // Done drawing lines. GL.End(); // Draw target vessel icons. Vector3 transformedPosition; foreach (CelestialBody moon in vessel.orbit.referenceBody.orbitingBodies) { if (moon != targetBody) { transformedPosition = screenTransform.MultiplyPoint3x4(moon.getTruePositionAtUT(now) - vessel.orbit.referenceBody.getTruePositionAtUT(now)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, moon.orbitDriver.orbitColor, MapIcons.OtherIcon.PLANET); } } if (targetVessel != null || targetBody != null) { var orbit = (targetVessel != null) ? targetVessel.GetOrbit() : targetBody.GetOrbit(); DrawNextPe(orbit, vessel.orbit.referenceBody, now, iconColorTargetValue, screenTransform); DrawNextAp(orbit, vessel.orbit.referenceBody, now, iconColorTargetValue, screenTransform); if (targetBody != null) { transformedPosition = screenTransform.MultiplyPoint3x4(targetBody.getTruePositionAtUT(now) - vessel.orbit.referenceBody.getTruePositionAtUT(now)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, iconColorTargetValue, MapIcons.OtherIcon.PLANET); } else { transformedPosition = screenTransform.MultiplyPoint3x4(orbit.SwappedRelativePositionAtUT(now)); DrawIcon(transformedPosition.x, transformedPosition.y, targetVessel.vesselType, iconColorTargetValue); } if (vessel.orbit.AscendingNodeExists(orbit)) { double anTime = vessel.orbit.TimeOfAscendingNode(orbit, now); if (anTime < vessel.orbit.EndUT || (vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ESCAPE && vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ENCOUNTER)) { transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(anTime)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorSelfValue, MapIcons.OtherIcon.AN); } } if (vessel.orbit.DescendingNodeExists(orbit)) { double dnTime = vessel.orbit.TimeOfDescendingNode(orbit, now); if (dnTime < vessel.orbit.EndUT || (vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ESCAPE && vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ENCOUNTER)) { transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(dnTime)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorSelfValue, MapIcons.OtherIcon.DN); } } double tClosestApproach; double dClosestApproach = JUtil.GetClosestApproach(vessel.orbit, orbit, out tClosestApproach); Orbit o = GetPatchAtUT(vessel.orbit, tClosestApproach); if (o != null) { Vector3d encounterPosition = o.SwappedRelativePositionAtUT(tClosestApproach) + o.referenceBody.getTruePositionAtUT(tClosestApproach) - vessel.orbit.referenceBody.getTruePositionAtUT(tClosestApproach); transformedPosition = screenTransform.MultiplyPoint3x4(encounterPosition); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, iconColorClosestApproachValue, MapIcons.OtherIcon.SHIPATINTERCEPT); } // Unconditionally try to draw the closest approach point on // the target orbit. transformedPosition = screenTransform.MultiplyPoint3x4(orbit.SwappedRelativePositionAtUT(tClosestApproach)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, iconColorClosestApproachValue, MapIcons.OtherIcon.TGTATINTERCEPT); } else { if (vessel.orbit.AscendingNodeEquatorialExists()) { double anTime = vessel.orbit.TimeOfAscendingNodeEquatorial(now); if (anTime < vessel.orbit.EndUT || (vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ESCAPE && vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ENCOUNTER)) { transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(anTime)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorSelfValue, MapIcons.OtherIcon.AN); } } if (vessel.orbit.DescendingNodeEquatorialExists()) { double dnTime = vessel.orbit.TimeOfDescendingNodeEquatorial(now); if (dnTime < vessel.orbit.EndUT || (vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ESCAPE && vessel.orbit.patchEndTransition != Orbit.PatchTransitionType.ENCOUNTER)) { transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(dnTime)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorSelfValue, MapIcons.OtherIcon.DN); } } } // Draw orbital features DrawNextPe(vessel.orbit, vessel.orbit.referenceBody, now, iconColorPEValue, screenTransform); DrawNextAp(vessel.orbit, vessel.orbit.referenceBody, now, iconColorAPValue, screenTransform); if (vessel.orbit.nextPatch != null && vessel.orbit.nextPatch.activePatch) { transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(vessel.orbit.EndUT)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorSelfValue, MapIcons.OtherIcon.EXITSOI); Orbit nextPatch = vessel.orbit.nextPatch.nextPatch; if (nextPatch != null && nextPatch.activePatch) { transformedPosition = screenTransform.MultiplyPoint3x4(nextPatch.SwappedRelativePositionAtUT(nextPatch.EndUT) + nextPatch.referenceBody.getTruePositionAtUT(nextPatch.EndUT) - vessel.orbit.referenceBody.getTruePositionAtUT(nextPatch.EndUT)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorNextNodeValue, MapIcons.OtherIcon.EXITSOI); } } if (node != null && node.nextPatch.activePatch) { DrawNextPe(node.nextPatch, vessel.orbit.referenceBody, now, orbitColorNextNodeValue, screenTransform); DrawNextAp(node.nextPatch, vessel.orbit.referenceBody, now, orbitColorNextNodeValue, screenTransform); transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(node.UT)); DrawIcon(transformedPosition.x, transformedPosition.y, VesselType.Unknown, orbitColorNextNodeValue, MapIcons.OtherIcon.NODE); } // Draw ownship icon transformedPosition = screenTransform.MultiplyPoint3x4(vessel.orbit.SwappedRelativePositionAtUT(now)); DrawIcon(transformedPosition.x, transformedPosition.y, vessel.vesselType, iconColorSelfValue); GL.PopMatrix(); GL.Viewport(new Rect(0, 0, screen.width, screen.height)); return(true); }
// This is honestly very badly written code, probably the worst of what I have in this project. // Much of it dictated by the fact that I barely, if at all, understand what am I doing in vector mathematics, // the rest is because the problem is all built out of special cases. // Sorry. :) public bool RenderPFD(RenderTexture screen, float aspect) { if (screen == null) { return(false); } if (!startupComplete) { JUtil.AnnoyUser(this); } // Analysis disable once CompareOfFloatsByEqualityOperator if (aspect != cameraAspect) { cameraAspect = aspect; ballCamera.aspect = cameraAspect; } GL.Clear(true, true, backgroundColorValue); ballCamera.targetTexture = screen; Vector3d coM = vessel.findWorldCenterOfMass(); Vector3d up = (coM - vessel.mainBody.position).normalized; Vector3d velocityVesselOrbit = vessel.orbit.GetVel(); Vector3d velocityVesselOrbitUnit = velocityVesselOrbit.normalized; Vector3d velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(coM); Vector3d velocityVesselSurfaceUnit = velocityVesselSurface.normalized; Vector3d radialPlus = Vector3d.Exclude(velocityVesselOrbit, up).normalized; Vector3d normalPlus = -Vector3d.Cross(radialPlus, velocityVesselOrbitUnit); //Vector3d targetDirection = -FlightGlobals.fetch.vesselTargetDirection.normalized; Vector3d targetDirection = FlightGlobals.ship_tgtVelocity.normalized; navBall.transform.rotation = MirrorX(stockNavBall.navBall.rotation); if (heading != null) { Vector3d north = Vector3d.Exclude(up, (vessel.mainBody.position + (Vector3d)vessel.mainBody.transform.up * vessel.mainBody.Radius) - coM).normalized; Quaternion rotationSurface = Quaternion.LookRotation(north, up); Quaternion rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface); heading.renderer.material.SetTextureOffset("_MainTex", new Vector2(JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y) - headingSpan / 2f, 0)); } Quaternion gymbal = stockNavBall.attitudeGymbal; switch (FlightUIController.speedDisplayMode) { case FlightUIController.SpeedDisplayModes.Surface: MoveMarker(markerPrograde, velocityVesselSurfaceUnit, progradeColorValue, gymbal); MoveMarker(markerRetrograde, -velocityVesselSurfaceUnit, progradeColorValue, gymbal); break; case FlightUIController.SpeedDisplayModes.Target: MoveMarker(markerPrograde, targetDirection, progradeColorValue, gymbal); MoveMarker(markerRetrograde, -targetDirection, progradeColorValue, gymbal); break; case FlightUIController.SpeedDisplayModes.Orbit: MoveMarker(markerPrograde, velocityVesselOrbitUnit, progradeColorValue, gymbal); MoveMarker(markerRetrograde, -velocityVesselOrbitUnit, progradeColorValue, gymbal); break; } MoveMarker(markerNormal, normalPlus, normalColorValue, gymbal); MoveMarker(markerNormalMinus, -normalPlus, normalColorValue, gymbal); MoveMarker(markerRadial, radialPlus, radialColorValue, gymbal); MoveMarker(markerRadialMinus, -radialPlus, radialColorValue, gymbal); if (vessel.patchedConicSolver.maneuverNodes.Count > 0) { Vector3d burnVector = vessel.patchedConicSolver.maneuverNodes[0].GetBurnVector(vessel.orbit); MoveMarker(markerManeuver, burnVector.normalized, maneuverColorValue, gymbal); MoveMarker(markerManeuverMinus, -burnVector.normalized, maneuverColorValue, gymbal); ShowHide(true, markerManeuver, markerManeuverMinus); } ITargetable target = FlightGlobals.fetch.VesselTarget; if (target != null) { Vector3 targetSeparation = (vessel.GetTransform().position - target.GetTransform().position).normalized; MoveMarker(markerTarget, targetSeparation, targetColorValue, gymbal); MoveMarker(markerTargetMinus, -targetSeparation, targetColorValue, gymbal); var targetPort = target as ModuleDockingNode; if (targetPort != null) { // Thanks to Michael Enßlin Transform targetTransform = targetPort.transform; Transform selfTransform = vessel.ReferenceTransform; Vector3 targetOrientationVector = -targetTransform.up.normalized; Vector3 v1 = Vector3.Cross(selfTransform.up, targetTransform.forward); Vector3 v2 = Vector3.Cross(selfTransform.up, selfTransform.forward); float angle = Vector3.Angle(v1, v2); if (Vector3.Dot(selfTransform.up, Vector3.Cross(v1, v2)) < 0) { angle = -angle; } MoveMarker(markerDockingAlignment, targetOrientationVector, dockingColorValue, gymbal); markerDockingAlignment.transform.Rotate(Vector3.up, -angle); ShowHide(true, markerDockingAlignment); } ShowHide(true, markerTarget, markerTargetMinus); } // This dirty hack reduces the chance that the ball might get affected by internal cabin lighting. int backupQuality = QualitySettings.pixelLightCount; QualitySettings.pixelLightCount = 0; ShowHide(true, cameraBody, navBall, overlay, heading, markerPrograde, markerRetrograde, markerNormal, markerNormalMinus, markerRadial, markerRadialMinus); ballCamera.Render(); QualitySettings.pixelLightCount = backupQuality; ShowHide(false, cameraBody, navBall, overlay, heading, markerPrograde, markerRetrograde, markerManeuver, markerManeuverMinus, markerTarget, markerTargetMinus, markerNormal, markerNormalMinus, markerRadial, markerRadialMinus, markerDockingAlignment); return(true); }
/// <summary> /// Start and initialize all the things! /// </summary> public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { rpmComp = RasterPropMonitorComputer.Instantiate(internalProp, true); ConfigNode moduleConfig = null; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { if (string.IsNullOrEmpty(variableName)) { JUtil.LogErrorMessage(this, "Configuration failed in prop {0} ({1}), no variableName.", internalProp.propID, internalProp.propName); throw new ArgumentNullException(); } moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] variableNodes = moduleConfig.GetNodes("VARIABLESET"); for (int i = 0; i < variableNodes.Length; i++) { try { variableSets.Add(new CallbackAnimationSet(variableNodes[i], variableName, internalProp)); } catch (ArgumentException e) { JUtil.LogErrorMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } break; } } if (flashRate > 0.0f) { fm = JUtil.InstallFlashModule(part, flashRate); if (fm != null) { fm.flashSubscribers += FlashToggle; } } del = (Action <float>)Delegate.CreateDelegate(typeof(Action <float>), this, "OnCallback"); rpmComp.RegisterVariableCallback(variableName, del); JUtil.LogMessage(this, "Configuration complete in prop {1} ({2}), supporting {0} callback animators.", variableSets.Count, internalProp.propID, internalProp.propName); } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { RPMVesselComputer comp = RPMVesselComputer.Instance(vessel); if (!groupList.ContainsKey(actionName) && !customGroupList.ContainsKey(actionName)) { JUtil.LogErrorMessage(this, "Action \"{0}\" is not supported.", actionName); return; } // Parse the needs-electric-charge here. if (!string.IsNullOrEmpty(needsElectricCharge)) { switch (needsElectricCharge.ToLowerInvariant().Trim()) { case "true": case "yes": case "1": needsElectricChargeValue = true; break; case "false": case "no": case "0": needsElectricChargeValue = false; break; } } // Now parse consumeOnToggle and consumeWhileActive... if (!string.IsNullOrEmpty(consumeOnToggle)) { string[] tokens = consumeOnToggle.Split(','); if (tokens.Length == 3) { consumeOnToggleName = tokens[0].Trim(); if (!(PartResourceLibrary.Instance.GetDefinition(consumeOnToggleName) != null && float.TryParse(tokens[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out consumeOnToggleAmount))) { JUtil.LogErrorMessage(this, "Could not parse \"{0}\"", consumeOnToggle); } switch (tokens[2].Trim().ToLower()) { case "on": consumingOnToggleUp = true; break; case "off": consumingOnToggleDown = true; break; case "both": consumingOnToggleUp = true; consumingOnToggleDown = true; break; default: JUtil.LogErrorMessage(this, "So should I consume resources when turning on, turning off, or both in \"{0}\"?", consumeOnToggle); break; } } } if (!string.IsNullOrEmpty(consumeWhileActive)) { string[] tokens = consumeWhileActive.Split(','); if (tokens.Length == 2) { consumeWhileActiveName = tokens[0].Trim(); if (!(PartResourceLibrary.Instance.GetDefinition(consumeWhileActiveName) != null && float.TryParse(tokens[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out consumeWhileActiveAmount))) { JUtil.LogErrorMessage(this, "Could not parse \"{0}\"", consumeWhileActive); } else { consumingWhileActive = true; JUtil.LogMessage(this, "Switch in prop {0} prop id {1} will consume {2} while active at a rate of {3}", internalProp.propName, internalProp.propID, consumeWhileActiveName, consumeWhileActiveAmount); } } } if (groupList.ContainsKey(actionName)) { kspAction = groupList[actionName]; currentState = vessel.ActionGroups[kspAction]; // action group switches may not belong to a radio group switchGroupIdentifier = -1; } else { isCustomAction = true; switch (actionName) { case "intlight": persistentVarName = internalLightName; if (!string.IsNullOrEmpty(internalLightName)) { Light[] availableLights = internalModel.FindModelComponents <Light>(); if (availableLights != null && availableLights.Length > 0) { List <Light> lights = new List <Light>(availableLights); for (int i = lights.Count - 1; i >= 0; --i) { if (lights[i].name != internalLightName) { lights.RemoveAt(i); } } if (lights.Count > 0) { lightObjects = lights.ToArray(); needsElectricChargeValue |= string.IsNullOrEmpty(needsElectricCharge) || needsElectricChargeValue; } else { actionName = "dummy"; } } } else { actionName = "dummy"; } break; case "plugin": persistentVarName = string.Empty; comp.UpdateDataRefreshRate(refreshRate); foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { foreach (ConfigNode pluginConfig in node.GetNodes("MODULE")[moduleID].GetNodes("PLUGINACTION")) { if (pluginConfig.HasValue("name") && pluginConfig.HasValue("actionMethod")) { string action = pluginConfig.GetValue("name").Trim() + ":" + pluginConfig.GetValue("actionMethod").Trim(); actionHandler = (Action <bool>)comp.GetMethod(action, internalProp, typeof(Action <bool>)); if (actionHandler == null) { JUtil.LogErrorMessage(this, "Failed to instantiate action handler {0}", action); } else { if (pluginConfig.HasValue("stateMethod")) { string state = pluginConfig.GetValue("name").Trim() + ":" + pluginConfig.GetValue("stateMethod").Trim(); stateVariable = "PLUGIN_" + state; } else if (pluginConfig.HasValue("stateVariable")) { stateVariable = pluginConfig.GetValue("stateVariable").Trim(); } isPluginAction = true; break; } } } } } if (actionHandler == null) { actionName = "dummy"; JUtil.LogMessage(this, "Plugin handlers did not start, reverting to dummy mode."); } break; case "transfer": persistentVarName = string.Empty; comp.UpdateDataRefreshRate(refreshRate); foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { foreach (ConfigNode pluginConfig in node.GetNodes("MODULE")[moduleID].GetNodes("TRANSFERACTION")) { if ((pluginConfig.HasValue("name") || pluginConfig.HasValue("getVariable")) && pluginConfig.HasValue("perPodPersistenceName")) { transferPersistentName = pluginConfig.GetValue("perPodPersistenceName").Trim(); if (pluginConfig.HasValue("stateMethod")) { string state = pluginConfig.GetValue("name").Trim() + ":" + pluginConfig.GetValue("stateMethod").Trim(); stateVariable = "PLUGIN_" + state; } else if (pluginConfig.HasValue("stateVariable")) { stateVariable = pluginConfig.GetValue("stateVariable").Trim(); } if (pluginConfig.HasValue("setMethod")) { string action = pluginConfig.GetValue("name").Trim() + ":" + pluginConfig.GetValue("setMethod").Trim(); transferSetter = (Action <double>)comp.GetMethod(action, internalProp, typeof(Action <double>)); if (transferSetter == null) { JUtil.LogErrorMessage(this, "Failed to instantiate transfer handler {0}", pluginConfig.GetValue("name")); } else { //JUtil.LogMessage(this, "Got setter {0}", action); break; } } else if (pluginConfig.HasValue("getMethod")) { string action = pluginConfig.GetValue("name").Trim() + ":" + pluginConfig.GetValue("getMethod").Trim(); var getter = (Func <double>)comp.GetMethod(action, internalProp, typeof(Func <double>)); if (getter == null) { JUtil.LogErrorMessage(this, "Failed to instantiate transfer handler {0}", pluginConfig.GetValue("name")); } else { transferGetter = "PLUGIN_" + action; //JUtil.LogMessage(this, "Got getter {0}", action); break; } } else if (pluginConfig.HasValue("getVariable")) { transferGetter = pluginConfig.GetValue("getVariable").Trim(); } } } } } if (string.IsNullOrEmpty(transferGetter) && transferSetter == null) { actionName = "dummy"; stateVariable = string.Empty; JUtil.LogMessage(this, "Transfer handlers did not start, reverting to dummy mode."); } break; default: persistentVarName = "switch" + internalProp.propID + "_" + moduleID; break; } if (!string.IsNullOrEmpty(perPodPersistenceName)) { persistentVarName = perPodPersistenceName; } else { // If there's no persistence name, there's no valid group id for this switch switchGroupIdentifier = -1; } } if (customGroupList.ContainsKey(actionName)) { customAction = customGroupList[actionName]; } if (needsElectricChargeValue || !string.IsNullOrEmpty(persistentVarName) || !string.IsNullOrEmpty(perPodMasterSwitchName) || !string.IsNullOrEmpty(masterVariableName) || !string.IsNullOrEmpty(transferGetter) || transferSetter != null) { rpmComp = RasterPropMonitorComputer.Instantiate(internalProp); comp.UpdateDataRefreshRate(refreshRate); if (!string.IsNullOrEmpty(masterVariableName)) { string[] range = masterVariableRange.Split(','); if (range.Length == 2) { masterVariable = new VariableOrNumberRange(masterVariableName, range[0], range[1]); } else { masterVariable = null; } } } // set up the toggle switch if (!string.IsNullOrEmpty(switchTransform)) { if (momentarySwitch) { SmarterButton.CreateButton(internalProp, switchTransform, Click, Click); } else { SmarterButton.CreateButton(internalProp, switchTransform, Click); } } if (isCustomAction) { if (isPluginAction && !string.IsNullOrEmpty(stateVariable)) { try { currentState = (comp.ProcessVariable(stateVariable, -1).MassageToInt()) > 0; } catch { // no-op } } else { if (rpmComp != null && !string.IsNullOrEmpty(persistentVarName)) { if (switchGroupIdentifier >= 0) { int activeSwitch = rpmComp.GetVar(persistentVarName, 0); currentState = customGroupState = (switchGroupIdentifier == activeSwitch); } else { currentState = customGroupState = rpmComp.GetBool(persistentVarName, initialState); } if (customAction == CustomActions.IntLight) { // We have to restore lighting after reading the // persistent variable. SetInternalLights(customGroupState); } } } } if (rpmComp != null && !rpmComp.HasVar(persistentVarName)) { if (switchGroupIdentifier >= 0) { if (currentState) { rpmComp.SetVar(persistentVarName, switchGroupIdentifier); } } else { rpmComp.SetVar(persistentVarName, currentState); } } if (!string.IsNullOrEmpty(animationName)) { // Set up the animation Animation[] animators = animateExterior ? part.FindModelAnimators(animationName) : internalProp.FindModelAnimators(animationName); if (animators.Length > 0) { anim = animators[0]; } else { JUtil.LogErrorMessage(this, "Could not find animation \"{0}\" on {2} \"{1}\"", animationName, animateExterior ? part.name : internalProp.name, animateExterior ? "part" : "prop"); return; } anim[animationName].wrapMode = WrapMode.Once; if (currentState ^ reverse) { anim[animationName].speed = float.MaxValue; anim[animationName].normalizedTime = 0; } else { anim[animationName].speed = float.MinValue; anim[animationName].normalizedTime = 1; } anim.Play(animationName); } else if (!string.IsNullOrEmpty(coloredObject)) { // Set up the color shift. Renderer colorShiftRenderer = internalProp.FindModelComponent <Renderer>(coloredObject); disabledColorValue = ConfigNode.ParseColor32(disabledColor); enabledColorValue = ConfigNode.ParseColor32(enabledColor); colorShiftMaterial = colorShiftRenderer.material; colorShiftMaterial.SetColor(colorName, (currentState ^ reverse ? enabledColorValue : disabledColorValue)); } else { JUtil.LogMessage(this, "Warning, neither color nor animation are defined in prop {0} #{1} (this may be okay).", internalProp.propName, internalProp.propID); } audioOutput = JUtil.SetupIVASound(internalProp, switchSound, switchSoundVolume, false); if (!string.IsNullOrEmpty(loopingSound) && loopingSoundVolume > 0.0f) { loopingOutput = JUtil.SetupIVASound(internalProp, loopingSound, loopingSoundVolume, true); } startupComplete = true; } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public bool RenderHUD(RenderTexture screen, float cameraAspect) { if (screen == null) { return(false); } if (!startupComplete) { JUtil.AnnoyUser(this); } // Clear the background, if configured. GL.Clear(true, true, backgroundColorValue); // Configure the camera, if configured. // MOARdV: Might be worthwhile to refactor the flying camera so // it is created in Start (like new FlyingCamera(part, cameraTransform)), // and pass the screen, FoV, and aspect ratio (or just screen and // FoV) as Render parameters, so there's no need to test if the // camera's been created every render call. if (cameraObject == null && !string.IsNullOrEmpty(cameraTransform)) { cameraObject = new FlyingCamera(part, screen, cameraAspect); cameraObject.PointCamera(cameraTransform, hudFov); } // Draw the camera's view, if configured. if (cameraObject != null) { cameraObject.Render(); } // Configure the matrix so that the origin is the center of the screen. GL.PushMatrix(); // Draw the HUD ladder GL.LoadPixelMatrix(-horizonSize.x * 0.5f, horizonSize.x * 0.5f, -horizonSize.y * 0.5f, horizonSize.y * 0.5f); GL.Viewport(new Rect((screen.width - horizonSize.x) * 0.5f, (screen.height - horizonSize.y) * 0.5f, horizonSize.x, horizonSize.y)); Vector3 coM = vessel.findWorldCenterOfMass(); Vector3 up = (coM - vessel.mainBody.position).normalized; Vector3 forward = vessel.GetTransform().up; Vector3 right = vessel.GetTransform().right; Vector3 top = Vector3.Cross(right, forward); Vector3 north = Vector3.Exclude(up, (vessel.mainBody.position + (Vector3d)vessel.mainBody.transform.up * vessel.mainBody.Radius) - coM).normalized; Vector3d velocityVesselSurface = vessel.orbit.GetVel() - vessel.mainBody.getRFrmVel(coM); Vector3 velocityVesselSurfaceUnit = velocityVesselSurface.normalized; if (ladderMaterial) { // Figure out the texture coordinate scaling for the ladder. float ladderTextureOffset = horizonTextureSize.y / ladderMaterial.mainTexture.height; float cosUp = Vector3.Dot(forward, up); float cosRoll = Vector3.Dot(top, up); float sinRoll = Vector3.Dot(right, up); var normalizedRoll = new Vector2(cosRoll, sinRoll); normalizedRoll.Normalize(); if (normalizedRoll.magnitude < 0.99f) { // If we're hitting +/- 90 nearly perfectly, the sin and cos will // be too far out of whack to normalize. Arbitrarily pick // a roll of 0.0. normalizedRoll.x = 1.0f; normalizedRoll.y = 0.0f; } cosRoll = normalizedRoll.x; sinRoll = normalizedRoll.y; // Mihara: I'm pretty sure this was negative of what it should actually be, at least according to my mockup. float pitch = -(Mathf.Asin(cosUp) * Mathf.Rad2Deg); float ladderMidpointCoord; if (use360horizon) { // Straight up is texture coord 0.75; // Straight down is TC 0.25; ladderMidpointCoord = JUtil.DualLerp(0.25f, 0.75f, -90f, 90f, pitch); } else { // Straight up is texture coord 1.0; // Straight down is TC 0.0; ladderMidpointCoord = JUtil.DualLerp(0.0f, 1.0f, -90f, 90f, pitch); } ladderMaterial.SetPass(0); GL.Begin(GL.QUADS); // transform -x -y GL.TexCoord2(0.5f + horizonTextureSize.x, ladderMidpointCoord - ladderTextureOffset); GL.Vertex3(cosRoll * horizonSize.x + sinRoll * horizonSize.y, sinRoll * horizonSize.x - cosRoll * horizonSize.y, 0.0f); // transform +x -y GL.TexCoord2(0.5f - horizonTextureSize.x, ladderMidpointCoord - ladderTextureOffset); GL.Vertex3(-cosRoll * horizonSize.x + sinRoll * horizonSize.y, -sinRoll * horizonSize.x - cosRoll * horizonSize.y, 0.0f); // transform +x +y GL.TexCoord2(0.5f - horizonTextureSize.x, ladderMidpointCoord + ladderTextureOffset); GL.Vertex3(-cosRoll * horizonSize.x - sinRoll * horizonSize.y, -sinRoll * horizonSize.x + cosRoll * horizonSize.y, 0.0f); // transform -x +y GL.TexCoord2(0.5f + horizonTextureSize.x, ladderMidpointCoord + ladderTextureOffset); GL.Vertex3(cosRoll * horizonSize.x - sinRoll * horizonSize.y, sinRoll * horizonSize.x + cosRoll * horizonSize.y, 0.0f); GL.End(); float AoA = velocityVesselSurfaceUnit.AngleInPlane(right, forward); float AoATC; if (use360horizon) { // Straight up is texture coord 0.75; // Straight down is TC 0.25; AoATC = JUtil.DualLerp(0.25f, 0.75f, -90f, 90f, pitch + AoA); } else { // Straight up is texture coord 1.0; // Straight down is TC 0.0; AoATC = JUtil.DualLerp(0.0f, 1.0f, -90f, 90f, pitch + AoA); } float Ypos = JUtil.DualLerp( -horizonSize.y, horizonSize.y, ladderMidpointCoord - ladderTextureOffset, ladderMidpointCoord + ladderTextureOffset, AoATC); // Placing the icon on the (0, Ypos) location, so simplify the transform. DrawIcon(-sinRoll * Ypos, cosRoll * Ypos, GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE), progradeColorValue); } // Draw the rest of the HUD stuff (0,0) is the top left corner of the screen. GL.LoadPixelMatrix(0, screen.width, screen.height, 0); GL.Viewport(new Rect(0, 0, screen.width, screen.height)); if (headingMaterial != null) { Quaternion rotationSurface = Quaternion.LookRotation(north, up); Quaternion rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface); float headingTexture = JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y); float headingTextureOffset = (headingBarWidth / headingMaterial.mainTexture.width) / 2; headingMaterial.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(headingTexture - headingTextureOffset, 1.0f); GL.Vertex3(headingBarPosition.x, headingBarPosition.y, 0.0f); GL.TexCoord2(headingTexture + headingTextureOffset, 1.0f); GL.Vertex3(headingBarPosition.x + headingBarPosition.z, headingBarPosition.y, 0.0f); GL.TexCoord2(headingTexture + headingTextureOffset, 0.0f); GL.Vertex3(headingBarPosition.x + headingBarPosition.z, headingBarPosition.y + headingBarPosition.w, 0.0f); GL.TexCoord2(headingTexture - headingTextureOffset, 0.0f); GL.Vertex3(headingBarPosition.x, headingBarPosition.y + headingBarPosition.w, 0.0f); GL.End(); float slipAngle = velocityVesselSurfaceUnit.AngleInPlane(up, forward); float slipTC = JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y + slipAngle); float slipIconX = JUtil.DualLerp(headingBarPosition.x, headingBarPosition.x + headingBarPosition.z, headingTexture - headingTextureOffset, headingTexture + headingTextureOffset, slipTC); DrawIcon(slipIconX, headingBarPosition.y + headingBarPosition.w * 0.5f, GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE), progradeColorValue); } if (vertBar1Material != null) { float value = comp.ProcessVariable(vertBar1Variable).MassageToFloat(); if (float.IsNaN(value)) { value = 0.0f; } if (vertBar1UseLog10) { value = JUtil.PseudoLog10(value); } float vertBar1TexCoord = JUtil.DualLerp(vertBar1TextureLimit.x, vertBar1TextureLimit.y, vertBar1Limit.x, vertBar1Limit.y, value); vertBar1Material.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, vertBar1TexCoord + vertBar1TextureSize); GL.Vertex3(vertBar1Position.x, vertBar1Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar1TexCoord + vertBar1TextureSize); GL.Vertex3(vertBar1Position.x + vertBar1Position.z, vertBar1Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar1TexCoord - vertBar1TextureSize); GL.Vertex3(vertBar1Position.x + vertBar1Position.z, vertBar1Position.y + vertBar1Position.w, 0.0f); GL.TexCoord2(0.0f, vertBar1TexCoord - vertBar1TextureSize); GL.Vertex3(vertBar1Position.x, vertBar1Position.y + vertBar1Position.w, 0.0f); GL.End(); } if (vertBar2Material != null) { float value = comp.ProcessVariable(vertBar2Variable).MassageToFloat(); if (float.IsNaN(value)) { value = 0.0f; } if (vertBar2UseLog10) { value = JUtil.PseudoLog10(value); } float vertBar2TexCoord = JUtil.DualLerp(vertBar2TextureLimit.x, vertBar2TextureLimit.y, vertBar2Limit.x, vertBar2Limit.y, value); vertBar2Material.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, vertBar2TexCoord + vertBar2TextureSize); GL.Vertex3(vertBar2Position.x, vertBar2Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar2TexCoord + vertBar2TextureSize); GL.Vertex3(vertBar2Position.x + vertBar2Position.z, vertBar2Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar2TexCoord - vertBar2TextureSize); GL.Vertex3(vertBar2Position.x + vertBar2Position.z, vertBar2Position.y + vertBar2Position.w, 0.0f); GL.TexCoord2(0.0f, vertBar2TexCoord - vertBar2TextureSize); GL.Vertex3(vertBar2Position.x, vertBar2Position.y + vertBar2Position.w, 0.0f); GL.End(); } if (overlayMaterial != null) { overlayMaterial.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 0.0f, 0.0f); GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(screen.width, 0.0f, 0.0f); GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(screen.width, screen.height, 0.0f); GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, screen.height, 0.0f); GL.End(); } GL.PopMatrix(); return(true); }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { if (string.IsNullOrEmpty(perPodPersistenceName)) { JUtil.LogErrorMessage(this, "perPodPersistenceName must be defined"); return; } if (string.IsNullOrEmpty(defaultValue)) { JUtil.LogErrorMessage(this, "defaultValue must be defined"); return; } if (stepSize < 0.0f) { stepSize = 0.0f; } //JUtil.LogMessage(this, "Start(): {0}, {1}, {2}, {3}, {4}", perPodPersistenceName, defaultValue, minValue, maxValue, stepSize); if (!string.IsNullOrEmpty(minValue)) { minRange = VariableOrNumber.Instantiate(minValue); //JUtil.LogMessage(this, "Created lower bound variable"); } if (!string.IsNullOrEmpty(maxValue)) { maxRange = VariableOrNumber.Instantiate(maxValue); //JUtil.LogMessage(this, "Created upper bound variable"); } if ((minRange == null || maxRange == null) && loopInput == true) { JUtil.LogErrorMessage(this, "Overriding loopInput - minValue or maxValue is missing"); loopInput = false; } RPMVesselComputer comp = RPMVesselComputer.Instance(vessel); if (!comp.HasPersistentVariable(perPodPersistenceName)) { //JUtil.LogMessage(this, "Initializing per pod persistence value {0}", perPodPersistenceName); VariableOrNumber von = VariableOrNumber.Instantiate(defaultValue); float value; if (von.Get(out value, comp)) { if (stepSize > 0.0f) { float remainder = value % stepSize; value -= remainder; } comp.SetPersistentVariable(perPodPersistenceName, value); } else { JUtil.LogErrorMessage(this, "Failed to evaluate default value of {0} for {1}", defaultValue, perPodPersistenceName); return; } } ConfigNode moduleConfig = null; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] inputNodes = moduleConfig.GetNodes("USERINPUTSET"); for (int i = 0; i < inputNodes.Length; i++) { try { numericInputs.Add(new NumericInput(inputNodes[i], internalProp)); //JUtil.LogMessage(this, "Added USERINPUTSET {0}", inputNodes[i].GetValue("switchTransform")); } catch (ArgumentException e) { JUtil.LogErrorMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } break; } } enabled = true; } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { // Parse bloody KSPField colors. if (!string.IsNullOrEmpty(backgroundColor)) { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); } if (!string.IsNullOrEmpty(progradeColor)) { progradeColorValue = ConfigNode.ParseColor32(progradeColor); } if (!string.IsNullOrEmpty(maneuverColor)) { maneuverColorValue = ConfigNode.ParseColor32(maneuverColor); } if (!string.IsNullOrEmpty(targetColor)) { targetColorValue = ConfigNode.ParseColor32(targetColor); } if (!string.IsNullOrEmpty(normalColor)) { normalColorValue = ConfigNode.ParseColor32(normalColor); } if (!string.IsNullOrEmpty(radialColor)) { radialColorValue = ConfigNode.ParseColor32(radialColor); } if (!string.IsNullOrEmpty(dockingColor)) { dockingColorValue = ConfigNode.ParseColor32(dockingColor); } if (!string.IsNullOrEmpty(waypointColor)) { waypointColorValue = ConfigNode.ParseColor32(waypointColor); } Shader displayShader = JUtil.LoadInternalShader("RPM-DisplayShader"); stockNavBall = FlightUIController.fetch.GetComponentInChildren <NavBall>(); // Non-moving parts... cameraBody = new GameObject(); cameraBody.name = "RPMPFD" + cameraBody.GetInstanceID(); cameraBody.layer = drawingLayer; Vector3 navBallPosition = new Vector3(0.0f, 0.0f, 1.5f); ballCamera = cameraBody.AddComponent <Camera>(); ballCamera.enabled = false; ballCamera.orthographic = true; ballCamera.eventMask = 0; ballCamera.farClipPlane = 3f; ballCamera.orthographicSize = 1.0f; ballCamera.cullingMask = 1 << drawingLayer; ballCamera.clearFlags = CameraClearFlags.Depth; ballCamera.transparencySortMode = TransparencySortMode.Orthographic; ballCamera.transform.position = Vector3.zero; ballCamera.transform.LookAt(navBallPosition, Vector3.up); navBall = GameDatabase.Instance.GetModel(navBallModel.EnforceSlashes()); if (navBall == null) { JUtil.LogErrorMessage(this, "Failed to load navball model {0}", navBallModel); // Early return here - if we don't even have a navball, this module is pointless. return; } Destroy(navBall.collider); navBall.name = "RPMNB" + navBall.GetInstanceID(); navBall.layer = drawingLayer; navBall.transform.parent = cameraBody.transform; navBall.transform.position = navBallPosition; navBall.renderer.material.shader = displayShader; Texture2D horizonTex = GameDatabase.Instance.GetTexture(horizonTexture.EnforceSlashes(), false); if (horizonTex != null) { navBall.renderer.material.mainTexture = horizonTex; } else { JUtil.LogErrorMessage(this, "Failed to load horizon texture {0}", horizonTexture); } navBall.renderer.material.SetFloat("_Opacity", ballOpacity); startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { // Parse bloody KSPField colors. if (!string.IsNullOrEmpty(backgroundColor)) { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); } if (!string.IsNullOrEmpty(ballColor)) { ballColorValue = ConfigNode.ParseColor32(ballColor); } if (!string.IsNullOrEmpty(progradeColor)) { progradeColorValue = ConfigNode.ParseColor32(progradeColor); } if (!string.IsNullOrEmpty(maneuverColor)) { maneuverColorValue = ConfigNode.ParseColor32(maneuverColor); } if (!string.IsNullOrEmpty(targetColor)) { targetColorValue = ConfigNode.ParseColor32(targetColor); } if (!string.IsNullOrEmpty(normalColor)) { normalColorValue = ConfigNode.ParseColor32(normalColor); } if (!string.IsNullOrEmpty(radialColor)) { radialColorValue = ConfigNode.ParseColor32(radialColor); } if (!string.IsNullOrEmpty(dockingColor)) { dockingColorValue = ConfigNode.ParseColor32(dockingColor); } Shader unlit = Shader.Find("KSP/Alpha/Unlit Transparent"); overlayMaterial = new Material(unlit); overlayMaterial.mainTexture = GameDatabase.Instance.GetTexture(staticOverlay.EnforceSlashes(), false); if (!string.IsNullOrEmpty(headingBar)) { headingMaterial = new Material(unlit); headingMaterial.mainTexture = GameDatabase.Instance.GetTexture(headingBar.EnforceSlashes(), false); } horizonTex = GameDatabase.Instance.GetTexture(horizonTexture.EnforceSlashes(), false); gizmoTexture = JUtil.GetGizmoTexture(); // Ahaha, that's clever, does it work? stockNavBall = GameObject.Find("NavBall").GetComponent <NavBall>(); // ...well, it does, but the result is bizarre, // apparently, because the stock BALL ITSELF IS MIRRORED. navBall = GameDatabase.Instance.GetModel(navBallModel.EnforceSlashes()); Destroy(navBall.collider); navBall.name = "RPMNB" + navBall.GetInstanceID(); navBall.layer = drawingLayer; navBall.transform.position = Vector3.zero; navBall.transform.rotation = Quaternion.identity; navBall.transform.localRotation = Quaternion.identity; if (ballIsEmissive) { navBall.renderer.material.shader = Shader.Find("KSP/Emissive/Diffuse"); navBall.renderer.material.SetTexture("_MainTex", horizonTex); navBall.renderer.material.SetTextureOffset("_Emissive", navBall.renderer.material.GetTextureOffset("_MainTex")); navBall.renderer.material.SetTexture("_Emissive", horizonTex); navBall.renderer.material.SetColor("_EmissiveColor", ballColorValue); } else { navBall.renderer.material.shader = Shader.Find("KSP/Unlit"); navBall.renderer.material.mainTexture = horizonTex; navBall.renderer.material.color = ballColorValue; } navBall.renderer.material.SetFloat("_Opacity", ballOpacity); markerPrograde = BuildMarker(0, 2, progradeColorValue); markerRetrograde = BuildMarker(1, 2, progradeColorValue); markerManeuver = BuildMarker(2, 0, maneuverColorValue); markerManeuverMinus = BuildMarker(1, 2, maneuverColorValue); markerTarget = BuildMarker(2, 1, targetColorValue); markerTargetMinus = BuildMarker(2, 2, targetColorValue); markerNormal = BuildMarker(0, 0, normalColorValue); markerNormalMinus = BuildMarker(1, 0, normalColorValue); markerRadial = BuildMarker(1, 1, radialColorValue); markerRadialMinus = BuildMarker(0, 1, radialColorValue); markerDockingAlignment = BuildMarker(0, 2, dockingColorValue); // Non-moving parts... cameraBody = new GameObject(); cameraBody.name = "RPMPFD" + cameraBody.GetInstanceID(); cameraBody.layer = drawingLayer; ballCamera = cameraBody.AddComponent <Camera>(); ballCamera.enabled = false; ballCamera.orthographic = true; ballCamera.clearFlags = CameraClearFlags.Nothing; ballCamera.eventMask = 0; ballCamera.farClipPlane = 3f; ballCamera.orthographicSize = cameraSpan; ballCamera.cullingMask = 1 << drawingLayer; ballCamera.clearFlags = CameraClearFlags.Depth; // -2,0,0 seems to get the orientation exactly as the ship. // But logically, forward is Z+, right? // Which means that ballCamera.transform.position = new Vector3(0, 0, 2); ballCamera.transform.LookAt(Vector3.zero, Vector3.up); ballCamera.transform.position = new Vector3(cameraShift.x, cameraShift.y, 2); overlay = CreateSimplePlane("RPMPFDOverlay" + internalProp.propID, 1f, drawingLayer); overlay.layer = drawingLayer; overlay.transform.position = new Vector3(0, 0, 1.5f); overlay.renderer.material = overlayMaterial; overlay.transform.parent = cameraBody.transform; FaceCamera(overlay); if (headingMaterial != null) { heading = CreateSimplePlane("RPMPFDHeading" + internalProp.propID, 1f, drawingLayer); heading.layer = drawingLayer; heading.transform.position = new Vector3(headingBarPosition.x, headingBarPosition.y, headingAboveOverlay ? 1.55f : 1.45f); heading.transform.parent = cameraBody.transform; heading.transform.localScale = new Vector3(headingBarPosition.z, 0, headingBarPosition.w); heading.renderer.material = headingMaterial; heading.renderer.material.SetTextureScale("_MainTex", new Vector2(headingSpan, 1f)); FaceCamera(heading); } ShowHide(false, navBall, cameraBody, overlay, heading); startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { try { if (!groupList.ContainsKey(actionName) && !customGroupList.ContainsKey(actionName)) { JUtil.LogErrorMessage(this, "Action \"{0}\" is not supported.", actionName); return; } // Parse the needs-electric-charge here. if (!string.IsNullOrEmpty(needsElectricCharge)) { switch (needsElectricCharge.ToLowerInvariant().Trim()) { case "true": case "yes": case "1": needsElectricChargeValue = true; break; case "false": case "no": case "0": needsElectricChargeValue = false; break; } } // Now parse consumeOnToggle and consumeWhileActive... if (!string.IsNullOrEmpty(consumeOnToggle)) { string[] tokens = consumeOnToggle.Split(','); if (tokens.Length == 3) { consumeOnToggleName = tokens[0].Trim(); if (!(PartResourceLibrary.Instance.GetDefinition(consumeOnToggleName) != null && float.TryParse(tokens[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out consumeOnToggleAmount))) { JUtil.LogErrorMessage(this, "Could not parse \"{0}\"", consumeOnToggle); } switch (tokens[2].Trim().ToLower()) { case "on": consumingOnToggleUp = true; break; case "off": consumingOnToggleDown = true; break; case "both": consumingOnToggleUp = true; consumingOnToggleDown = true; break; default: JUtil.LogErrorMessage(this, "So should I consume resources when turning on, turning off, or both in \"{0}\"?", consumeOnToggle); break; } } } if (!string.IsNullOrEmpty(consumeWhileActive)) { string[] tokens = consumeWhileActive.Split(','); if (tokens.Length == 2) { consumeWhileActiveName = tokens[0].Trim(); if (!(PartResourceLibrary.Instance.GetDefinition(consumeWhileActiveName) != null && float.TryParse(tokens[1].Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out consumeWhileActiveAmount))) { JUtil.LogErrorMessage(this, "Could not parse \"{0}\"", consumeWhileActive); } else { consumingWhileActive = true; JUtil.LogMessage(this, "Switch in prop {0} prop id {1} will consume {2} while active at a rate of {3}", internalProp.propName, internalProp.propID, consumeWhileActiveName, consumeWhileActiveAmount); } } } if (groupList.ContainsKey(actionName)) { currentState = vessel.ActionGroups[groupList[actionName]]; } else { isCustomAction = true; switch (actionName) { case "intlight": persistentVarName = internalLightName; lightObjects = internalModel.FindModelComponents <Light>(); needsElectricChargeValue |= string.IsNullOrEmpty(needsElectricCharge) || needsElectricChargeValue; break; case "plugin": persistentVarName = string.Empty; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { foreach (ConfigNode pluginConfig in node.GetNodes("MODULE")[moduleID].GetNodes("PLUGINACTION")) { if (pluginConfig.HasValue("name") && pluginConfig.HasValue("actionMethod")) { if (!InstantiateHandler(pluginConfig, this, out actionHandler, out stateHandler)) { JUtil.LogErrorMessage(this, "Failed to instantiate action handler {0}", pluginConfig.GetValue("name")); } else { isPluginAction = true; break; } } } } } if (actionHandler == null) { actionName = "dummy"; JUtil.LogMessage(this, "Plugin handlers did not start, reverting to dummy mode."); } break; default: persistentVarName = "switch" + internalProp.propID + "_" + moduleID; break; } if (!string.IsNullOrEmpty(perPodPersistenceName)) { persistentVarName = perPodPersistenceName; } persistence = new PersistenceAccessor(part); } if (needsElectricChargeValue) { comp = RasterPropMonitorComputer.Instantiate(internalProp); comp.UpdateRefreshRates(lightCheckRate, lightCheckRate); } // set up the toggle switch if (!string.IsNullOrEmpty(switchTransform)) { SmarterButton.CreateButton(internalProp, switchTransform, Click); } if (isCustomAction) { if (isPluginAction && stateHandler != null) { currentState = stateHandler(); } else { if (!string.IsNullOrEmpty(persistentVarName)) { currentState = customGroupList[actionName] = (persistence.GetBool(persistentVarName) ?? currentState); if (actionName == "intlight") { // We have to restore lighting after reading the // persistent variable. SetInternalLights(customGroupList[actionName]); } } } } if (!string.IsNullOrEmpty(animationName)) { // Set up the animation Animation[] animators = animateExterior ? part.FindModelAnimators(animationName) : internalProp.FindModelAnimators(animationName); if (animators.Length > 0) { anim = animators[0]; } else { JUtil.LogErrorMessage(this, "Could not find animation \"{0}\" on {2} \"{1}\"", animationName, animateExterior ? part.name : internalProp.name, animateExterior ? "part" : "prop"); return; } anim[animationName].wrapMode = WrapMode.Once; if (currentState ^ reverse) { anim[animationName].speed = float.MaxValue; anim[animationName].normalizedTime = 0; } else { anim[animationName].speed = float.MinValue; anim[animationName].normalizedTime = 1; } anim.Play(animationName); } else if (!string.IsNullOrEmpty(coloredObject)) { // Set up the color shift. colorShiftRenderer = internalProp.FindModelComponent <Renderer>(coloredObject); disabledColorValue = ConfigNode.ParseColor32(disabledColor); enabledColorValue = ConfigNode.ParseColor32(enabledColor); colorShiftRenderer.material.SetColor(colorName, (currentState ^ reverse ? enabledColorValue : disabledColorValue)); } else { JUtil.LogMessage(this, "Warning, neither color nor animation are defined."); } audioOutput = JUtil.SetupIVASound(internalProp, switchSound, switchSoundVolume, false); startupComplete = true; } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); Shader unlit = Shader.Find("Hidden/Internal-GUITexture"); ladderMaterial = new Material(unlit); ladderMaterial.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); if (!String.IsNullOrEmpty(horizonTexture)) { ladderMaterial.mainTexture = GameDatabase.Instance.GetTexture(horizonTexture.EnforceSlashes(), false); if (ladderMaterial.mainTexture != null) { horizonTextureSize.x = horizonTextureSize.x / ladderMaterial.mainTexture.width; ladderMaterial.mainTexture.wrapMode = TextureWrapMode.Clamp; } } if (!String.IsNullOrEmpty(headingBar)) { headingMaterial = new Material(unlit); headingMaterial.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); headingMaterial.mainTexture = GameDatabase.Instance.GetTexture(headingBar.EnforceSlashes(), false); } if (!String.IsNullOrEmpty(staticOverlay)) { overlayMaterial = new Material(unlit); overlayMaterial.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); overlayMaterial.mainTexture = GameDatabase.Instance.GetTexture(staticOverlay.EnforceSlashes(), false); } if (!String.IsNullOrEmpty(vertBar1Texture) && !String.IsNullOrEmpty(vertBar1Variable)) { vertBar1Material = new Material(unlit); vertBar1Material.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); vertBar1Material.mainTexture = GameDatabase.Instance.GetTexture(vertBar1Texture.EnforceSlashes(), false); if (vertBar1Material.mainTexture != null) { float height = (float)vertBar1Material.mainTexture.height; vertBar1TextureLimit.x = 1.0f - (vertBar1TextureLimit.x / height); vertBar1TextureLimit.y = 1.0f - (vertBar1TextureLimit.y / height); vertBar1TextureSize = 0.5f * (vertBar1TextureSize / height); vertBar1Material.mainTexture.wrapMode = TextureWrapMode.Clamp; } } if (!String.IsNullOrEmpty(vertBar2Texture) && !String.IsNullOrEmpty(vertBar2Variable)) { vertBar2Material = new Material(unlit); vertBar2Material.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); vertBar2Material.mainTexture = GameDatabase.Instance.GetTexture(vertBar2Texture.EnforceSlashes(), false); if (vertBar2Material.mainTexture != null) { float height = (float)vertBar2Material.mainTexture.height; vertBar2TextureLimit.x = 1.0f - (vertBar2TextureLimit.x / height); vertBar2TextureLimit.y = 1.0f - (vertBar2TextureLimit.y / height); vertBar2TextureSize = 0.5f * (vertBar2TextureSize / height); vertBar2Material.mainTexture.wrapMode = TextureWrapMode.Clamp; } } if (vertBar1UseLog10) { vertBar1Limit.x = JUtil.PseudoLog10(vertBar1Limit.x); vertBar1Limit.y = JUtil.PseudoLog10(vertBar1Limit.y); } if (vertBar2UseLog10) { vertBar2Limit.x = JUtil.PseudoLog10(vertBar2Limit.x); vertBar2Limit.y = JUtil.PseudoLog10(vertBar2Limit.y); } if (!string.IsNullOrEmpty(progradeColor)) { progradeColorValue = ConfigNode.ParseColor32(progradeColor); } comp = RasterPropMonitorComputer.Instantiate(internalProp); iconMaterial = new Material(unlit); iconMaterial.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); gizmoTexture = JUtil.GetGizmoTexture(); startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); foreach (ConfigNode propNode in GameDatabase.Instance.GetConfigNodes("PROP")) { ConfigNode[] moduleNodes = propNode.GetNodes("MODULE"); foreach (ConfigNode moduleNode in moduleNodes) { ConfigNode[] pageNodes = moduleNode.GetNodes("PAGE"); foreach (ConfigNode pagenode in pageNodes) { ConfigNode[] bghandlerNodes = pagenode.GetNodes("BACKGROUNDHANDLER"); foreach (ConfigNode bghandlerNode in bghandlerNodes) { ConfigNode[] gaugeNodes = bghandlerNode.GetNodes("GAUGE"); foreach (ConfigNode node in gaugeNodes) { InfoGauge gauge = new InfoGauge(); JUtil.LogErrorMessage(this, "one item created"); gauge.Texture = node.GetValue("Texture"); JUtil.LogErrorMessage(this, "texture obtained"); gauge.Position = ConfigNode.ParseVector4(node.GetValue("Position")); JUtil.LogErrorMessage(this, "position obtained"); gauge.Limit = ConfigNode.ParseVector2(node.GetValue("Limit")); JUtil.LogErrorMessage(this, "limit obtained"); gauge.TextureLimit = ConfigNode.ParseVector4(node.GetValue("TextureLimit")); JUtil.LogErrorMessage(this, "texlim obtained"); gauge.TextureSize = float.Parse(node.GetValue("TextureSize")); JUtil.LogErrorMessage(this, "texsiz obtained"); gauge.VerticalMovement = bool.Parse(node.GetValue("VerticalMovement")); JUtil.LogErrorMessage(this, "vertmov obtained"); gauge.UseLog10 = bool.Parse(node.GetValue("UseLog10")); JUtil.LogErrorMessage(this, "uselog obtained"); gauge.Use360Horizon = bool.Parse(node.GetValue("Use360Horizon")); JUtil.LogErrorMessage(this, "360 obtained"); gauge.RotateWithVessel = bool.Parse(node.GetValue("RotateWithVessel")); JUtil.LogErrorMessage(this, "rotate obtained"); gauge.Variable = node.GetValue("Variable"); JUtil.LogErrorMessage(this, "variable obtained"); gaugeList.Add(gauge); JUtil.LogErrorMessage(this, "one item added"); } } } } } Shader unlit = Shader.Find("Hidden/Internal-GUITexture"); foreach (InfoGauge gauge in gaugeList) { if (!String.IsNullOrEmpty(gauge.Texture)) { gauge.Material = new Material(unlit); gauge.Material.color = new Color(0.0f, 0.0f, 0.0f, 0.0f); gauge.Material.mainTexture = GameDatabase.Instance.GetTexture(gauge.Texture.EnforceSlashes(), false); } if (gauge.Material.mainTexture != null) { float height = (float)gauge.Material.mainTexture.height; float width = (float)gauge.Material.mainTexture.width; gauge.TextureLimit.x = 1.0f - (gauge.TextureLimit.x / width); gauge.TextureLimit.y = 1.0f - (gauge.TextureLimit.y / width); gauge.TextureLimit.z = 1.0f - (gauge.TextureLimit.z / height); gauge.TextureLimit.w = 1.0f - (gauge.TextureLimit.w / height); gauge.TextureSize = 0.5f * (gauge.TextureSize / height);//实际调用的时候用的是宽和高的一半。 if (gauge.Use360Horizon) { gauge.Material.mainTexture.wrapMode = TextureWrapMode.Repeat; } else { gauge.Material.mainTexture.wrapMode = TextureWrapMode.Clamp; } } if (gauge.UseLog10) { gauge.Limit.x = JUtil.PseudoLog10(gauge.Limit.x); gauge.Limit.y = JUtil.PseudoLog10(gauge.Limit.y); } } JUtil.LogMessage(this, "material read"); comp = RasterPropMonitorComputer.Instantiate(internalProp); startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { // Skip the entire sequence when in editor -- this means we're part of a transparent pod and won't get used anyway. if (HighLogic.LoadedSceneIsEditor) { startupComplete = true; return; } try { if (!string.IsNullOrEmpty(backgroundColor)) { backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); } if (!string.IsNullOrEmpty(iconColorSelf)) { iconColorSelfValue = ConfigNode.ParseColor32(iconColorSelf); } if (!string.IsNullOrEmpty(orbitColorSelf)) { orbitColorSelfValue = ConfigNode.ParseColor32(orbitColorSelf); } else { orbitColorSelfValue = MapView.PatchColors[0]; } if (!string.IsNullOrEmpty(iconColorTarget)) { iconColorTargetValue = ConfigNode.ParseColor32(iconColorTarget); } if (!string.IsNullOrEmpty(iconColorShadow)) { iconColorShadowValue = ConfigNode.ParseColor32(iconColorShadow); } if (!string.IsNullOrEmpty(iconColorAP)) { iconColorAPValue = ConfigNode.ParseColor32(iconColorAP); } else { iconColorAPValue = MapView.PatchColors[0]; } if (!string.IsNullOrEmpty(iconColorPE)) { iconColorPEValue = ConfigNode.ParseColor32(iconColorPE); } else { iconColorPEValue = MapView.PatchColors[0]; } if (!string.IsNullOrEmpty(orbitColorNextNode)) { orbitColorNextNodeValue = ConfigNode.ParseColor32(orbitColorNextNode); } else { orbitColorNextNodeValue = MapView.PatchColors[1]; } if (!string.IsNullOrEmpty(iconColorClosestApproach)) { iconColorClosestApproachValue = ConfigNode.ParseColor32(iconColorClosestApproach); } startupComplete = true; } catch { JUtil.AnnoyUser(this); throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { textObjTransform = internalProp.FindModelTransform(labelTransform); textObj = InternalComponents.Instance.CreateText(fontName, fontSize, textObjTransform, string.Empty); activeLabel = 0; SmarterButton.CreateButton(internalProp, switchTransform, Click); ConfigNode moduleConfig = null; foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { if (node.GetValue("name") == internalProp.propName) { moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] variableNodes = moduleConfig.GetNodes("VARIABLESET"); for (int i = 0; i < variableNodes.Length; i++) { try { labelsEx.Add(new VariableLabelSet(variableNodes[i])); } catch (ArgumentException e) { JUtil.LogErrorMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } break; } } // Fallback: If there are no VARIABLESET blocks, we treat the module configuration itself as a variableset block. if (labelsEx.Count < 1 && moduleConfig != null) { try { labelsEx.Add(new VariableLabelSet(moduleConfig)); } catch (ArgumentException e) { JUtil.LogErrorMessage(this, "Error in building prop number {1} - {0}", e.Message, internalProp.propID); } } if (labelsEx.Count == 0) { JUtil.LogErrorMessage(this, "No labels defined."); throw new ArgumentException("No labels defined"); } colorShiftRenderer = internalProp.FindModelComponent <Renderer>(coloredObject); if (labelsEx[activeLabel].hasColor) { colorShiftRenderer.material.SetColor(colorName, labelsEx[activeLabel].color); } if (labelsEx[activeLabel].hasText) { if (labelsEx[activeLabel].oneShot) { // Fetching formatString directly is notionally bad // because there may be formatting stuff, but if // oneShot is true, we already know that this is a // constant string with no formatting. textObj.text.Text = labelsEx[activeLabel].label.formatString; } else { textObj.text.Text = ""; } } audioOutput = JUtil.SetupIVASound(internalProp, switchSound, switchSoundVolume, false); JUtil.LogMessage(this, "Configuration complete in prop {1}, supporting {0} variable indicators.", labelsEx.Count, internalProp.propID); } catch { JUtil.AnnoyUser(this); enabled = false; throw; } }
public void Start() { // If we're not in the correct location, there's no point doing anything. if (!InstallationPathWarning.Warn()) { return; } if (HighLogic.LoadedSceneIsEditor) { return; } try { // Install the calculator module. RPMVesselComputer comp = RPMVesselComputer.Instance(vessel); comp.UpdateDataRefreshRate(refreshDataRate); persistence = new PersistenceAccessor(internalProp); // Loading the font... List <Texture2D> fontTexture = new List <Texture2D>(); fontTexture.Add(LoadFont(this, internalProp, fontTransform)); // Damn KSP's config parser!!! if (!string.IsNullOrEmpty(emptyColor)) { emptyColorValue = ConfigNode.ParseColor32(emptyColor); } if (!string.IsNullOrEmpty(defaultFontTint)) { defaultFontTintValue = ConfigNode.ParseColor32(defaultFontTint); } if (!string.IsNullOrEmpty(fontDefinition)) { JUtil.LogMessage(this, "Loading font definition from {0}", fontDefinition); fontDefinitionString = File.ReadAllLines(KSPUtil.ApplicationRootPath + "GameData/" + fontDefinition.EnforceSlashes(), Encoding.UTF8)[0]; } // Now that is done, proceed to setting up the screen. screenTexture = new RenderTexture(screenPixelWidth, screenPixelHeight, 24, RenderTextureFormat.ARGB32); screenMat = internalProp.FindModelTransform(screenTransform).renderer.material; foreach (string layerID in textureLayerID.Split()) { screenMat.SetTexture(layerID.Trim(), screenTexture); } if (GameDatabase.Instance.ExistsTexture(noSignalTextureURL.EnforceSlashes())) { noSignalTexture = GameDatabase.Instance.GetTexture(noSignalTextureURL.EnforceSlashes(), false); } // Create camera instance... cameraStructure = new FlyingCamera(part, screenTexture, cameraAspect); // The neat trick. IConfigNode doesn't work. No amount of kicking got it to work. // Well, we don't need it. GameDatabase, gimme config nodes for all props! foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROP")) { // Now, we know our own prop name. if (node.GetValue("name") == internalProp.propName) { // So this is the configuration of our prop in memory. Nice place. // We know it contains at least one MODULE node, us. // And we know our moduleID, which is the number in order of being listed in the prop. // Therefore the module by that number is our module's own config node. ConfigNode moduleConfig = node.GetNodes("MODULE")[moduleID]; ConfigNode[] pageNodes = moduleConfig.GetNodes("PAGE"); // Which we can now parse for page definitions. for (int i = 0; i < pageNodes.Length; i++) { // Mwahahaha. try { var newPage = new MonitorPage(i, pageNodes[i], this); activePage = activePage ?? newPage; if (newPage.isDefault) { activePage = newPage; } pages.Add(newPage); } catch (ArgumentException e) { JUtil.LogMessage(this, "Warning - {0}", e); } } // Now that all pages are loaded, we can use the moment in the loop to suck in all the extra fonts. foreach (string value in moduleConfig.GetValues("extraFont")) { fontTexture.Add(LoadFont(this, internalProp, value)); } break; } } JUtil.LogMessage(this, "Done setting up pages, {0} pages ready.", pages.Count); textRenderer = new TextRenderer(fontTexture, new Vector2((float)fontLetterWidth, (float)fontLetterHeight), fontDefinitionString, 17, screenPixelWidth, screenPixelHeight); // Load our state from storage... persistentVarName = "activePage" + internalProp.propID; int activePageID = persistence.GetVar(persistentVarName, pages.Count); if (activePageID < pages.Count) { activePage = pages[activePageID]; } activePage.Active(true); // If we have global buttons, set them up. if (!string.IsNullOrEmpty(globalButtons)) { string[] tokens = globalButtons.Split(','); for (int i = 0; i < tokens.Length; i++) { string buttonName = tokens[i].Trim(); // Notice that holes in the global button list ARE legal. if (!string.IsNullOrEmpty(buttonName)) { SmarterButton.CreateButton(internalProp, buttonName, i, GlobalButtonClick, GlobalButtonRelease); } } } audioOutput = JUtil.SetupIVASound(internalProp, buttonClickSound, buttonClickVolume, false); // One last thing to make sure of: If our pod is transparent, we're always active. ourPodIsTransparent = JUtil.IsPodTransparent(part); // And if the try block never completed, startupComplete will never be true. startupComplete = true; } catch { JUtil.AnnoyUser(this); startupFailed = true; // We can also disable ourselves, that should help. enabled = false; // And now that we notified the user that config is borked, we rethrow the exception so that // it gets logged and we can debug. throw; } }
public void Start() { if (HighLogic.LoadedSceneIsEditor) { return; } try { rpmComp = RasterPropMonitorComputer.Instantiate(internalProp, true); backgroundColorValue = ConfigNode.ParseColor32(backgroundColor); cameraBody = new GameObject(); cameraBody.name = "RPMPFD" + cameraBody.GetInstanceID(); cameraBody.layer = drawingLayer; hudCamera = cameraBody.AddComponent <Camera>(); hudCamera.enabled = false; hudCamera.orthographic = true; hudCamera.eventMask = 0; hudCamera.farClipPlane = 3f; hudCamera.orthographicSize = 1.0f; hudCamera.cullingMask = 1 << drawingLayer; // does this actually work? hudCamera.backgroundColor = backgroundColorValue; hudCamera.clearFlags = CameraClearFlags.Depth | CameraClearFlags.Color; hudCamera.transparencySortMode = TransparencySortMode.Orthographic; hudCamera.transform.position = Vector3.zero; hudCamera.transform.LookAt(new Vector3(0.0f, 0.0f, 1.5f), Vector3.up); if (!string.IsNullOrEmpty(progradeColor)) { progradeColorValue = ConfigNode.ParseColor32(progradeColor); } if (!string.IsNullOrEmpty(cameraEffectShader)) { cameraEffectMaterial = new Material(JUtil.LoadInternalShader(cameraEffectShader)); if (!string.IsNullOrEmpty(cameraEffectVariables)) { try { string[] vars = cameraEffectVariables.Split('|'); for (int i = 0; i < vars.Length; ++i) { string[] components = vars[i].Split(','); if (components.Length == 2) { ShaderEffectVariable sev = new ShaderEffectVariable(); sev.variable = Shader.PropertyToID(components[0].Trim()); sev.value = rpmComp.InstantiateVariableOrNumber(components[1]); ceVariables.Add(sev); } } } catch { } } if (!string.IsNullOrEmpty(cameraEffectTextures)) { try { string[] vars = cameraEffectTextures.Split('|'); for (int i = 0; i < vars.Length; ++i) { string[] components = vars[i].Split(','); if (components.Length == 2) { Texture tex = GameDatabase.Instance.GetTexture(components[1], false); cameraEffectMaterial.SetTexture(components[0], tex); } } } catch { } } } } catch (Exception e) { JUtil.LogErrorMessage(this, "Start() failed with an exception: {0}", e); JUtil.AnnoyUser(this); throw; } startupComplete = true; }