-
-
Save HappyFaceIndustries/d997e268d38bd638881e4033606216f9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Reflection; | |
using System.Collections.Generic; | |
using UnityEngine; | |
namespace Telescope | |
{ | |
public class ModuleTelescope2 : PartModule | |
{ | |
//KSPFields | |
[KSPField(guiName = "FOV")] | |
public float FOV = 60f; | |
[KSPField] | |
public string CameraTransformName = "camera"; | |
[KSPField] | |
public string WindowName = "Telescope View"; | |
[KSPField] | |
public float SkyboxExposure = 0f; | |
//camera values | |
private Transform cameraTransform; | |
private Camera[] cameras; | |
private RenderTexture targetTexture; | |
private GameObject localCameraObj; | |
private GameObject scaledCameraObj; | |
private GameObject galaxyCameraObj; | |
private float CurrentFOV; | |
//GUI values | |
private bool UIOpen = false; | |
private bool showUI = true; | |
private float fov_ui = 0f; | |
private GUISkin skin = HighLogic.Skin; | |
private Rect WindowRect = new Rect(20, 80, 512, 512); | |
private string[] visibleObjects; | |
//constants | |
const double RadToDeg = 57.2957801818848; | |
const double KPtoAtms = 0.009869232; | |
//renderers | |
private Renderer[] skyboxRenderers; | |
private List<Renderer> scaledPlanetRenderers; | |
private AtmosphereFromGround[] atmospheres; | |
private MethodInfo atmosphereSetMaterialMethod; | |
//camera rendering info cache | |
Dictionary<AtmosphereFromGround, Vector4> atmoInfo = new Dictionary<AtmosphereFromGround, Vector4> (); | |
//lifetime methods | |
public override void OnStart (StartState state) | |
{ | |
//set the reference transform | |
part.SetReferenceTransform (cameraTransform); | |
//do nothing else unless we are in flight | |
if (!HighLogic.LoadedSceneIsFlight) | |
return; | |
//camera transform | |
cameraTransform = part.FindModelTransform (CameraTransformName); | |
if (cameraTransform == null) | |
{ | |
Debug.LogError ("cameraTransform not found, deleting ModuleTelescope"); | |
DestroyImmediate (this); | |
return; | |
} | |
//target texture | |
targetTexture = new RenderTexture (512, 512, 24); | |
targetTexture.antiAliasing = GameSettings.ANTI_ALIASING; | |
targetTexture.Create (); | |
//set up the cameras | |
SetupCamera (); | |
//fetch the renderers | |
skyboxRenderers = (from Renderer r in (FindObjectsOfType (typeof(Renderer)) as IEnumerable<Renderer>) | |
where (r.name == "XP" || r.name == "XN" || r.name == "YP" || r.name == "YN" || r.name == "ZP" || r.name == "ZN") | |
select r).ToArray<Renderer> (); | |
scaledPlanetRenderers = ScaledSpace.Instance.scaledSpaceTransforms.Where(t => t.renderer != null).Select (t => t.renderer).ToList(); | |
scaledPlanetRenderers.Add (ScaledSun.Instance.renderer); | |
atmospheres = UnityEngine.Object.FindObjectsOfType<AtmosphereFromGround> (); | |
atmosphereSetMaterialMethod = typeof(AtmosphereFromGround).GetMethod ("SetMaterial", BindingFlags.NonPublic | BindingFlags.Instance); | |
//register for GameEvents | |
GameEvents.onShowUI.Add (OnShowUI); | |
GameEvents.onHideUI.Add (OnHideUI); | |
} | |
public override void OnUpdate () | |
{ | |
//do nothing unless we are in flight | |
if (!HighLogic.LoadedSceneIsFlight) | |
return; | |
Events ["ShowUI"].guiActive = !UIOpen; | |
Events ["HideUI"].guiActive = UIOpen; | |
} | |
public void LateUpdate() | |
{ | |
//do nothing unless we are in flight | |
if (!HighLogic.LoadedSceneIsFlight) | |
return; | |
RenderCameras (); | |
} | |
public void OnDestroy() | |
{ | |
//do nothing unless we are in flight | |
if (!HighLogic.LoadedSceneIsFlight) | |
return; | |
GameEvents.onShowUI.Remove (OnShowUI); | |
GameEvents.onHideUI.Remove (OnHideUI); | |
if(scaledCameraObj != null) | |
Destroy (scaledCameraObj); | |
if(galaxyCameraObj != null) | |
Destroy (galaxyCameraObj); | |
} | |
//editor information | |
public override string GetInfo () | |
{ | |
return "It's a telescope!"; | |
} | |
//GUI | |
private void OnGUI() | |
{ | |
//do nothing unless we are in flight | |
if (!HighLogic.LoadedSceneIsFlight) | |
return; | |
if (!showUI) | |
return; | |
if (MapView.MapIsEnabled) | |
return; | |
if (UIOpen) | |
{ | |
GUI.skin = skin; | |
WindowRect = GUILayout.Window ("ModuleTelescope_UI".GetHashCode (), WindowRect, Window, WindowName, GUILayout.ExpandHeight (true), GUILayout.ExpandWidth (true)); | |
} | |
} | |
private void Window(int id) | |
{ | |
GUILayout.Box (targetTexture); | |
fov_ui = GUILayout.HorizontalSlider (fov_ui, 0f, 1f, GUILayout.ExpandWidth (true)); | |
CurrentFOV = Mathf.Pow (fov_ui, 8f) * FOV; | |
GUILayout.BeginHorizontal (); | |
foreach (var planet in visibleObjects) | |
{ | |
GUILayout.Label (planet); | |
GUILayout.Space (15f); | |
} | |
GUILayout.EndHorizontal (); | |
GUI.DragWindow (); | |
} | |
//KSPEvents | |
[KSPEvent(guiName = "Show GUI", guiActive = true, guiActiveUnfocused = false)] | |
public void ShowUI () | |
{ | |
UIOpen = true; | |
} | |
[KSPEvent(guiName = "Hide GUI", guiActive = true, guiActiveUnfocused = false)] | |
public void HideUI () | |
{ | |
UIOpen = false; | |
} | |
[KSPEvent(guiName = "Control From Here", guiActive = true, guiActiveUnfocused = false)] | |
public void SetReference() | |
{ | |
vessel.SetReferenceTransform (part); | |
} | |
//GameEvents | |
private void OnShowUI() | |
{ | |
showUI = true; | |
} | |
private void OnHideUI() | |
{ | |
showUI = false; | |
} | |
//camera methods | |
public void RenderCameras() | |
{ | |
//get cameraWorldPos | |
Vector3d cameraWorldPos = ScaledSpace.ScaledToLocalSpace (cameraTransform.position); | |
//set cameras' FOV | |
SetFOV (CurrentFOV); | |
//position scaled camera | |
scaledCameraObj.transform.position = ScaledSpace.LocalToScaledSpace (vessel.GetWorldPos3D ()); | |
scaledCameraObj.transform.rotation = cameraTransform.rotation; | |
//position galaxy camera | |
galaxyCameraObj.transform.rotation = cameraTransform.rotation; | |
//galaxy skybox rendering | |
//recalculate exposure setting for skybox | |
var exposure = CalculateExposure (cameraWorldPos); | |
var origColor = skyboxRenderers [0].sharedMaterial.GetColor (HighLogic.ShaderPropertyID_Color); | |
for (int i = 0; i < skyboxRenderers.Length; i++) | |
{ | |
var sr = skyboxRenderers [i]; | |
Color color = Color.Lerp (GalaxyCubeControl.Instance.minGalaxyColor, GalaxyCubeControl.Instance.maxGalaxyColor, exposure); | |
sr.material.SetColor (HighLogic.ShaderPropertyID_Color, color); | |
} | |
//render galaxyCamera | |
cameras [3].Render (); | |
//set exposure back to what it was | |
for (int i = 0; i < skyboxRenderers.Length; i++) | |
{ | |
var sr = skyboxRenderers [i]; | |
sr.material.SetColor (HighLogic.ShaderPropertyID_Color, origColor); | |
} | |
//scaled space rendering | |
//render atmospheres | |
foreach (var afg in atmospheres) | |
{ | |
//cache the atmosphere info | |
if (!atmoInfo.ContainsKey (afg)) | |
atmoInfo.Add (afg, new Vector4 (afg.cameraPos.x, afg.cameraPos.y, afg.cameraPos.z, afg.cameraHeight)); | |
else | |
atmoInfo [afg] = new Vector4 (afg.cameraPos.x, afg.cameraPos.y, afg.cameraPos.z, afg.cameraHeight); | |
//set the atmosphere's camera to the scaled camera | |
afg.cameraPos = cameraTransform.position; | |
afg.cameraHeight = cameraTransform.position.magnitude; | |
afg.cameraHeight2 = afg.cameraHeight * afg.cameraHeight; | |
atmosphereSetMaterialMethod.Invoke (afg, new object[]{ false }); | |
} | |
//render planets | |
foreach (var scaledPlanetRenderer in scaledPlanetRenderers) | |
{ | |
scaledPlanetRenderer.enabled = true; | |
} | |
cameras [2].Render (); | |
//reset atmoInfo | |
foreach (var afg in atmospheres) | |
{ | |
//reset the atmosphere info from the cache | |
if (atmoInfo.ContainsKey (afg)) | |
{ | |
var info = atmoInfo [afg]; | |
afg.cameraPos = new Vector3 (info.x, info.y, info.z); | |
afg.cameraHeight = info.z; | |
afg.cameraHeight2 = info.z * info.z; | |
atmosphereSetMaterialMethod.Invoke (afg, new object[]{ false }); | |
} | |
} | |
//localspace rendering | |
cameras [1].Render (); | |
cameras [0].Render (); | |
//update visibleObjects array | |
UpdateVisibleObjects (); | |
} | |
public void SetupCamera() | |
{ | |
//initialize camera array | |
cameras = new Camera[4]; | |
//fetch template cameras | |
Camera flightCameraNear = FlightCamera.fetch.cameras [0]; | |
Camera flightCameraFar = FlightCamera.fetch.cameras [1]; | |
Camera scaledSpaceCamera = FindCamera ("Camera ScaledSpace"); | |
Camera galaxyCamera = FindCamera ("GalaxyCamera"); | |
//create localCameraObj | |
localCameraObj = new GameObject ("ModuleTelescope_localCamera"); | |
localCameraObj.transform.parent = cameraTransform; | |
ResetTransform (localCameraObj); | |
//create scaledCameraObj | |
scaledCameraObj = new GameObject ("ModuleTelescope_scaledCamera"); | |
scaledCameraObj.transform.parent = ScaledSpace.SceneTransform; | |
ResetTransform (scaledCameraObj); | |
//create galaxyCameraObj | |
galaxyCameraObj = new GameObject ("ModuleTelescope_galaxyCamera"); | |
ResetTransform (galaxyCameraObj); | |
//create near local camera | |
GameObject cam0Obj = new GameObject ("flightCameraNear"); | |
cam0Obj.transform.parent = cameraTransform; | |
var cam0 = cam0Obj.AddComponent<Camera> (); | |
cam0.CopyFrom (flightCameraNear); | |
cam0.targetTexture = targetTexture; | |
cameras [0] = cam0; | |
ResetTransform (cam0Obj); | |
//create far local camera | |
GameObject cam1Obj = new GameObject ("flightCameraFar"); | |
cam1Obj.transform.parent = cameraTransform; | |
var cam1 = cam1Obj.AddComponent<Camera> (); | |
cam1.CopyFrom (flightCameraFar); | |
cam1.targetTexture = targetTexture; | |
cameras [1] = cam1; | |
ResetTransform (cam1Obj); | |
//create scaledspace camera | |
GameObject cam2Obj = new GameObject ("scaledSpaceCamera"); | |
cam2Obj.transform.parent = scaledCameraObj.transform; | |
var cam2 = cam2Obj.AddComponent<Camera> (); | |
cam2Obj.AddComponent ("FlareLayer"); | |
cam2.CopyFrom (scaledSpaceCamera); | |
cam2.targetTexture = targetTexture; | |
cameras [2] = cam2; | |
ResetTransform (cam2Obj); | |
//create galaxy camera | |
GameObject cam3Obj = new GameObject ("galaxyCamera"); | |
cam3Obj.transform.parent = galaxyCameraObj.transform; | |
var cam3 = cam3Obj.AddComponent<Camera> (); | |
cam3.CopyFrom (galaxyCamera); | |
cam3.targetTexture = targetTexture; | |
cameras [3] = cam3; | |
ResetTransform (cam3Obj); | |
} | |
public void SetFOV(float fov) | |
{ | |
//set the FOV | |
foreach (var c in cameras) | |
{ | |
c.fieldOfView = fov; | |
} | |
} | |
private Camera FindCamera(string cameraName) | |
{ | |
foreach (var cam in Camera.allCameras) | |
{ | |
if (cam.name == cameraName) | |
return cam; | |
} | |
Debug.LogError ("Could not find camera " + cameraName); | |
return null; | |
} | |
private float CalculateExposure(Vector3d cameraWorldPos) | |
{ | |
float pressure = (float)(FlightGlobals.getStaticPressure (cameraWorldPos) * KPtoAtms); | |
return Mathf.Lerp (SkyboxExposure, 0f, pressure); | |
} | |
private void ResetTransform(GameObject obj) | |
{ | |
ResetTransform (obj.transform); | |
} | |
private void ResetTransform(Transform trns) | |
{ | |
trns.localRotation = Quaternion.identity; | |
trns.localPosition = Vector3.zero; | |
trns.localScale = Vector3.one; | |
} | |
private void UpdateVisibleObjects() | |
{ | |
List<string> tempList = new List<string> (); | |
foreach (var scaledPlanetRenderer in scaledPlanetRenderers) | |
{ | |
if (scaledPlanetRenderer.IsVisibleFrom (cameras [2])) | |
tempList.Add (scaledPlanetRenderer.name); | |
} | |
visibleObjects = tempList.ToArray (); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment