/// <summary> /// Parse the Value from a string /// </summary> public void SetFromString(String s) { // Should we use OnDemand? Boolean useOnDemand = OnDemandStorage.useOnDemand; if (s.StartsWith("BUILTIN/")) { s = s.Substring(8); Value = Utility.FindMapSO <T>(s); } else { // check if OnDemand. if (useOnDemand) { if (Utility.TextureExists(s)) { String mapName = s; mapName = mapName.Substring(s.LastIndexOf('/') + 1); Int32 lastDot = mapName.LastIndexOf('.'); if (lastDot > 0) { mapName = mapName.Substring(0, lastDot); } if (typeof(T) == typeof(CBAttributeMapSO)) { CBAttributeMapSODemand valCB = ScriptableObject.CreateInstance <CBAttributeMapSODemand>(); valCB.Path = s; valCB.Depth = MapSO.MapDepth.RGB; valCB.name = mapName + " (CBRGB) for " + generatedBody.name; valCB.AutoLoad = OnDemandStorage.onDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, valCB); Value = valCB as T; } else { OnDemand.MapSODemand valMap = ScriptableObject.CreateInstance <MapSODemand>(); valMap.Path = s; valMap.Depth = MapSO.MapDepth.RGB; valMap.name = mapName + " (RGB) for " + generatedBody.name; valMap.AutoLoad = OnDemandStorage.onDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, valMap); Value = valMap as T; } } } else { // Load the texture Texture2D map = Utility.LoadTexture(s, false, false, false); if (map != null) { // Create a new map script object Value = ScriptableObject.CreateInstance <T>(); Value.CreateMap(MapSO.MapDepth.RGB, map); UnityEngine.Object.DestroyImmediate(map); } } } }
// Load the MapSO public void SetFromString(string s) { // Should we use OnDemand? bool useOnDemand = OnDemandStorage.useOnDemand; if (s.StartsWith("BUILTIN/")) { value = Utility.FindMapSO <T>(s); } else { // are we on-demand? Don't load now. if (useOnDemand) { if (Utility.TextureExists(s)) { string mapName = s; mapName = mapName.Substring(s.LastIndexOf('/') + 1); int lastDot = mapName.LastIndexOf('.'); if (lastDot > 0) { mapName = mapName.Substring(0, lastDot); } if (typeof(T) == typeof(CBAttributeMapSO)) { CBAttributeMapSODemand valCB = ScriptableObject.CreateInstance <CBAttributeMapSODemand>(); valCB.Path = s; valCB.Depth = MapSO.MapDepth.Greyscale; valCB.name = mapName + " (CBG) for " + generatedBody.name; valCB.AutoLoad = OnDemandStorage.onDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, valCB); value = valCB as T; } else { MapSODemand valMap = ScriptableObject.CreateInstance <MapSODemand>(); valMap.Path = s; valMap.Depth = MapSO.MapDepth.Greyscale; valMap.name = mapName + " (G) for " + generatedBody.name; valMap.AutoLoad = OnDemandStorage.onDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, valMap); value = valMap as T; } } } else // Load the texture { Texture2D map = Utility.LoadTexture(s, false, false, false); if (map != null) { // Create a new map script object value = ScriptableObject.CreateInstance <T>(); value.CreateMap(MapSO.MapDepth.Greyscale, map); UnityEngine.Object.DestroyImmediate(map); } } } value.name = s; }
/// <summary> /// Parse the Value from a string /// </summary> public void SetFromString(String s) { // Check if we are attempting to load a builtin texture if (s.StartsWith("BUILTIN/")) { String textureName = Regex.Replace(s, "BUILTIN/", ""); Value = Resources.FindObjectsOfTypeAll <Texture>().FirstOrDefault(tex => tex.name == textureName) as Texture2D; if (Value != null) { return; } Debug.LogError("[Kopernicus] Could not find built-in texture " + textureName); Logger.Active.Log("Could not find built-in texture " + textureName); return; } // Otherwise search the game database for one loaded from GameData/ if (GameDatabase.Instance.ExistsTexture(s)) { // Get the texture URL Value = GameDatabase.Instance.GetTexture(s, false); return; } // Or load the texture directly if (OnDemandStorage.TextureExists(s)) { Value = OnDemandStorage.LoadTexture(s, false, true, false); // Upload it to the GPU if the parser could load something if (Value == null) { return; } try { Value.Apply(false, true); } catch { Debug.LogError("[Kopernicus] Failed to upload texture " + Value.name + " to the GPU"); Logger.Active.Log("Failed to upload texture " + Value.name + " to the GPU"); } return; } // Texture was not found Value = null; }
/// <summary> /// Convert the value to a parsable String /// </summary> public String ValueToString() { if (Value == null) { return(null); } if (GameDatabase.Instance.ExistsTexture(Value.name) || OnDemandStorage.TextureExists(Value.name)) { return(Value.name); } return("BUILTIN/" + Value.name); }
/// <summary> /// Parse the Value from a string /// </summary> public void SetFromString(String s) { // Should we use OnDemand? Boolean useOnDemand = OnDemandStorage.UseOnDemand; if (s.StartsWith("BUILTIN/")) { s = s.Substring(8); Value = Utility.FindMapSO <T>(s); } else { // are we on-demand? Don't load now. if (useOnDemand && typeof(T) == typeof(MapSO)) { if (!Utility.TextureExists(s)) { return; } MapSODemandLarge map = ScriptableObject.CreateInstance <MapSODemandLarge>(); map.Path = s; map.AutoLoad = OnDemandStorage.OnDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, map); Value = map as T; } else // Load the texture { MapSODemandLarge map = ScriptableObject.CreateInstance <MapSODemandLarge>(); map.Path = s; map.AutoLoad = false; OnDemandStorage.AddMap(generatedBody.name, map); Value = map as T; } } if (Value != null) { Value.name = s; } }
/// <summary> /// Parse the Value from a string /// </summary> public void SetFromString(String s) { // Should we use OnDemand? Boolean useOnDemand = OnDemandStorage.UseOnDemand; Boolean useOnDemandBiomes = OnDemandStorage.UseOnDemandBiomes; if (s.StartsWith("BUILTIN/")) { s = s.Substring(8); Value = Utility.FindMapSO <T>(s); } else { // check if OnDemand. if (useOnDemand && typeof(T) == typeof(MapSO) || useOnDemandBiomes && typeof(T) == typeof(CBAttributeMapSO)) { if (!Utility.TextureExists(s)) { return; } if (typeof(T) == typeof(CBAttributeMapSO)) { CBAttributeMapSODemand cbMap = ScriptableObject.CreateInstance <CBAttributeMapSODemand>(); cbMap.Path = s; cbMap.Depth = MapSO.MapDepth.RGB; cbMap.AutoLoad = OnDemandStorage.OnDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, cbMap); Value = cbMap as T; } else { MapSODemand map = ScriptableObject.CreateInstance <MapSODemand>(); map.Path = s; map.Depth = MapSO.MapDepth.RGB; map.AutoLoad = OnDemandStorage.OnDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, map); Value = map as T; } } else { // Load the texture Texture2D map = Utility.LoadTexture(s, false, false, false); if (map == null) { return; } // Create a new map script object Value = ScriptableObject.CreateInstance <T>(); Value.CreateMap(MapSO.MapDepth.RGB, map); Object.DestroyImmediate(map); } } if (Value != null) { Value.name = s; } }
public PQSLoader(CelestialBody body) { // Is this a spawned body? if (body.scaledBody == null || Injector.IsInPrefab) { throw new InvalidOperationException("The body must be already spawned by the PSystemManager."); } if (body.pqsController != null) { // Save the PQSVersion Value = body.pqsController; // Get the required PQS information _transform = Value.GetComponentsInChildren <PQSMod_CelestialBodyTransform>(true) .FirstOrDefault(mod => mod.transform.parent == Value.transform); _collider = Value.GetComponentsInChildren <PQSMod_QuadMeshColliders>(true) .FirstOrDefault(mod => mod.transform.parent == Value.transform); // Clone the surface material of the PQS if (MaterialType == SurfaceMaterialType.AtmosphericOptimized) { SurfaceMaterial = new PQSMainOptimisedLoader(SurfaceMaterial); } else if (MaterialType == SurfaceMaterialType.AtmosphericMain) { SurfaceMaterial = new PQSMainShaderLoader(SurfaceMaterial); } else if (MaterialType == SurfaceMaterialType.AtmosphericBasic) { SurfaceMaterial = new PQSProjectionAerialQuadRelativeLoader(SurfaceMaterial); } else if (MaterialType == SurfaceMaterialType.Vacuum) { SurfaceMaterial = new PQSProjectionSurfaceQuadLoader(SurfaceMaterial); } else if (MaterialType == SurfaceMaterialType.AtmosphericExtra) { SurfaceMaterial = new PQSMainExtrasLoader(SurfaceMaterial); } SurfaceMaterial.name = Guid.NewGuid().ToString(); // Clone the fallback material of the PQS FallbackMaterial = new PQSProjectionFallbackLoader(FallbackMaterial) { name = Guid.NewGuid().ToString() }; } else { // Create a new PQS GameObject controllerRoot = new GameObject(); controllerRoot.transform.parent = body.transform; Value = controllerRoot.AddComponent <PQS>(); // I (Teknoman) am at this time unable to determine some of the magic parameters which cause the PQS to work... // And I (Thomas) am at this time just too lazy to do it differently... PSystemBody laythe = Utility.FindBody(Injector.StockSystemPrefab.rootBody, "Laythe"); Utility.CopyObjectFields(laythe.pqsVersion, Value); Value.surfaceMaterial = laythe.pqsVersion.surfaceMaterial; // Create the fallback material (always the same shader) FallbackMaterial = new PQSProjectionFallbackLoader(); Value.fallbackMaterial = FallbackMaterial; FallbackMaterial.name = Guid.NewGuid().ToString(); // Create the celestial body transform GameObject mod = new GameObject("_CelestialBody"); mod.transform.parent = controllerRoot.transform; _transform = mod.AddComponent <PQSMod_CelestialBodyTransform>(); _transform.sphere = Value; _transform.forceActivate = false; _transform.deactivateAltitude = 115000; _transform.forceRebuildOnTargetChange = false; _transform.planetFade = new PQSMod_CelestialBodyTransform.AltitudeFade { fadeFloatName = "_PlanetOpacity", fadeStart = 100000.0f, fadeEnd = 110000.0f, valueStart = 0.0f, valueEnd = 1.0f, secondaryRenderers = new List <GameObject>() }; _transform.secondaryFades = new PQSMod_CelestialBodyTransform.AltitudeFade[0]; _transform.requirements = PQS.ModiferRequirements.Default; _transform.modEnabled = true; _transform.order = 10; // Create the material direction // ReSharper disable Unity.InefficientPropertyAccess mod = new GameObject("_Material_SunLight"); mod.transform.parent = controllerRoot.gameObject.transform; PQSMod_MaterialSetDirection lightDirection = mod.AddComponent <PQSMod_MaterialSetDirection>(); lightDirection.sphere = Value; lightDirection.valueName = "_sunLightDirection"; lightDirection.requirements = PQS.ModiferRequirements.Default; lightDirection.modEnabled = true; lightDirection.order = 100; // Create the UV planet relative position mod = new GameObject("_Material_SurfaceQuads"); mod.transform.parent = controllerRoot.transform; PQSMod_UVPlanetRelativePosition uvs = mod.AddComponent <PQSMod_UVPlanetRelativePosition>(); uvs.sphere = Value; uvs.requirements = PQS.ModiferRequirements.Default; uvs.modEnabled = true; uvs.order = 999999; // Crete the quad mesh colliders mod = new GameObject("QuadMeshColliders"); mod.transform.parent = controllerRoot.gameObject.transform; _collider = mod.AddComponent <PQSMod_QuadMeshColliders>(); _collider.sphere = Value; _collider.maxLevelOffset = 0; _collider.requirements = PQS.ModiferRequirements.Default; _collider.modEnabled = true; _collider.order = 100; // ReSharper restore Unity.InefficientPropertyAccess } // Assigning the new PQS body.pqsController = Value; Transform transform = body.transform; body.pqsController.name = transform.name; body.pqsController.transform.name = transform.name; body.pqsController.gameObject.name = transform.name; body.pqsController.radius = body.Radius; // Add an OnDemand Handler if (Value.GetComponentsInChildren <PQSMod_OnDemandHandler>(true).Length == 0) { OnDemandStorage.AddHandler(Value); } // Load existing mods foreach (PQSMod mod in Value.GetComponentsInChildren <PQSMod>(true).Where(m => m.sphere == Value)) { Type modType = mod.GetType(); Type modLoaderType = typeof(ModLoader <>).MakeGenericType(modType); foreach (Type loaderType in Parser.ModTypes) { if (!modLoaderType.IsAssignableFrom(loaderType)) { continue; } // We found our loader type IModLoader loader = (IModLoader)Activator.CreateInstance(loaderType); loader.Create(mod, Value); Mods.Add(loader); } } }
public static Texture2D LoadTexture(String path, Boolean compress, Boolean upload, Boolean unreadable) { return(OnDemandStorage.LoadTexture(path, compress, upload, unreadable)); }
public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs) { // We need to get the body for Jool (to steal it's mesh) const Double R_SCALED_JOOL = 1000.0f; Double rMetersToScaledUnits = (Single)(R_SCALED_JOOL / body.Radius); // Generate a duplicate of the Jool mesh Mesh mesh = DuplicateMesh(Templates.ReferenceGeosphere); Logger.Active.Log(body); Logger.Active.Log(pqs); Logger.Active.Log(body.pqsController); // If this body has a PQS, we can create a more detailed object, otherwise just return the generic mesh if (pqs == null) { return(mesh); } // first we enable all maps OnDemandStorage.EnableBody(body.bodyName); // In order to generate the scaled space we have to enable the mods. Since this is // a prefab they don't get disabled as kill game performance. To resolve this we // clone the PQS, use it, and then delete it when done. At runtime we can simply use // the PQS that is active GameObject pqsVersionGameObject = Injector.IsInPrefab ? Instantiate(pqs.gameObject) : pqs.gameObject; PQS pqsVersion = pqsVersionGameObject.GetComponent <PQS>(); // Deactivate blacklisted Mods PQSMod[] mods = pqsVersion.GetComponentsInChildren <PQSMod>(true).OrderBy(m => m.order).ToArray(); for (Int32 i = 0; i < mods.Length; i++) { // Disable mods that don't belong to us if (mods[i].transform.parent != pqsVersion.transform) { mods[i].modEnabled = false; continue; } switch (mods[i]) { // Disable the OnDemand notifier case PQSMod_OnDemandHandler _: mods[i].modEnabled = false; continue; case PQSMod_FlattenArea _: typeof(PQSMod_FlattenArea).GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .First(f => f.FieldType == typeof(Boolean)).SetValue(mods[i], true); break; } } pqsVersion.StartUpSphere(); pqsVersion.isBuildingMaps = true; // If we were able to find PQS mods if (mods.Length > 0) { // Generate the PQS modifications Vector3[] vertices = mesh.vertices; for (Int32 i = 0; i < mesh.vertexCount; i++) { // Get the UV coordinate of this vertex Vector2 uv = mesh.uv[i]; // Since this is a geosphere, normalizing the vertex gives the direction from center center Vector3 direction = vertices[i]; direction.Normalize(); // Build the vertex data object for the PQS mods PQS.VertexBuildData vertex = new PQS.VertexBuildData { directionFromCenter = direction, vertHeight = body.Radius, u = uv.x, v = uv.y }; // Build from the PQS for (Int32 m = 0; m < mods.Length; m++) { // Don't build disabled mods if (!mods[m].modEnabled) { continue; } // Don't build mods that don't belong to us if (mods[m].transform.parent != pqsVersion.transform) { continue; } mods[m].OnVertexBuildHeight(vertex); } // Check for sea level if (pqsVersion.mapOcean) { vertex.vertHeight = Math.Max(vertex.vertHeight, body.Radius); } // Adjust the displacement vertices[i] = direction * (Single)(vertex.vertHeight * rMetersToScaledUnits); } mesh.vertices = vertices; mesh.RecalculateNormals(); mesh.RecalculateBounds(); RecalculateTangents(mesh); } // Cleanup pqsVersion.isBuildingMaps = false; pqsVersion.DeactivateSphere(); // If we are working with a copied PQS, clean it up if (Injector.IsInPrefab) { UnityEngine.Object.Destroy(pqsVersionGameObject); } OnDemandStorage.DisableBody(body.bodyName); // Return the generated scaled space mesh return(mesh); }
/// <summary> /// Parse the Value from a string /// </summary> public void SetFromString(String s) { // Should we use OnDemand? Boolean useOnDemand = OnDemandStorage.UseOnDemand; Boolean useOnDemandBiomes = OnDemandStorage.UseOnDemandBiomes; if (s.StartsWith("BUILTIN/")) { s = s.Substring(8); Value = Utility.FindMapSO <T>(s); } else { // are we on-demand? Don't load now. if (useOnDemand && typeof(T) == typeof(MapSO) || useOnDemandBiomes && typeof(T) == typeof(CBAttributeMapSO)) { if (!Utility.TextureExists(s)) { return; } String mapName = s; mapName = mapName.Substring(s.LastIndexOf('/') + 1); Int32 lastDot = mapName.LastIndexOf('.'); if (lastDot > 0) { mapName = mapName.Substring(0, lastDot); } if (typeof(T) == typeof(CBAttributeMapSO)) { CBAttributeMapSODemand cbMap = ScriptableObject.CreateInstance <CBAttributeMapSODemand>(); cbMap.Path = s; cbMap.Depth = MapSO.MapDepth.Greyscale; cbMap.name = mapName + " (CBG) for " + generatedBody.name; cbMap.AutoLoad = OnDemandStorage.OnDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, cbMap); Value = cbMap as T; } else { MapSODemand map = ScriptableObject.CreateInstance <MapSODemand>(); map.Path = s; map.Depth = MapSO.MapDepth.Greyscale; map.name = mapName + " (G) for " + generatedBody.name; map.AutoLoad = OnDemandStorage.OnDemandLoadOnMissing; OnDemandStorage.AddMap(generatedBody.name, map); Value = map as T; } } else // Load the texture { Texture2D map = OnDemandStorage.LoadTexture(s, false, false, false); if (map == null) { return; } // Create a new map script object Value = ScriptableObject.CreateInstance <T>(); Value.CreateMap(MapSO.MapDepth.Greyscale, map); Object.DestroyImmediate(map); } } }
public PQSLoader(CelestialBody body) { // Is this a spawned body? if (body?.scaledBody == null || Injector.IsInPrefab) { throw new InvalidOperationException("The body must be already spawned by the PSystemManager."); } if (body.pqsController != null) { // Save the PQSVersion Value = body.pqsController; // Get the required PQS information _transform = Value.GetComponentsInChildren <PQSMod_CelestialBodyTransform>(true) .FirstOrDefault(Mod => Mod.transform.parent == Value.transform); _collider = Value.GetComponentsInChildren <PQSMod_QuadMeshColliders>(true) .FirstOrDefault(Mod => Mod.transform.parent == Value.transform); // Clone the surface material of the PQS if (PQSMainOptimised.UsesSameShader(surfaceMaterial)) { PQSMainOptimisedLoader loader = new PQSMainOptimisedLoader(surfaceMaterial); loader.globalDensity = loader.globalDensity < 2 ? (Single)(-8E-06) : loader.globalDensity; surfaceMaterial = loader; } else if (PQSMainShader.UsesSameShader(surfaceMaterial)) { PQSMainShaderLoader loader = new PQSMainShaderLoader(surfaceMaterial); loader.globalDensity = loader.globalDensity < 2 ? (Single)(-8E-06) : loader.globalDensity; surfaceMaterial = loader; } else if (PQSProjectionAerialQuadRelative.UsesSameShader(surfaceMaterial)) { PQSProjectionAerialQuadRelativeLoader loader = new PQSProjectionAerialQuadRelativeLoader(surfaceMaterial); loader.globalDensity = loader.globalDensity < 2 ? (Single)(-8E-06) : loader.globalDensity; surfaceMaterial = loader; } else if (PQSProjectionSurfaceQuad.UsesSameShader(surfaceMaterial)) { surfaceMaterial = new PQSProjectionSurfaceQuadLoader(surfaceMaterial); } surfaceMaterial.name = Guid.NewGuid().ToString(); // Clone the fallback material of the PQS fallbackMaterial = new PQSProjectionFallbackLoader(fallbackMaterial); fallbackMaterial.name = Guid.NewGuid().ToString(); } else { // Create a new PQS GameObject controllerRoot = new GameObject(); controllerRoot.transform.parent = body.transform; Value = controllerRoot.AddComponent <PQS>(); // I (Teknoman) am at this time unable to determine some of the magic parameters which cause the PQS to work... // And I (Thomas) am at this time just too lazy to do it differently... PSystemBody Laythe = Utility.FindBody(Injector.StockSystemPrefab.rootBody, "Laythe"); Utility.CopyObjectFields(Laythe.pqsVersion, Value); Value.surfaceMaterial = Laythe.pqsVersion.surfaceMaterial; // Create the fallback material (always the same shader) fallbackMaterial = new PQSProjectionFallbackLoader(); Value.fallbackMaterial = fallbackMaterial; fallbackMaterial.name = Guid.NewGuid().ToString(); // Create the celestial body transform GameObject mod = new GameObject("_CelestialBody"); mod.transform.parent = controllerRoot.transform; _transform = mod.AddComponent <PQSMod_CelestialBodyTransform>(); _transform.sphere = Value; _transform.forceActivate = false; _transform.deactivateAltitude = 115000; _transform.forceRebuildOnTargetChange = false; _transform.planetFade = new PQSMod_CelestialBodyTransform.AltitudeFade(); _transform.planetFade.fadeFloatName = "_PlanetOpacity"; _transform.planetFade.fadeStart = 100000.0f; _transform.planetFade.fadeEnd = 110000.0f; _transform.planetFade.valueStart = 0.0f; _transform.planetFade.valueEnd = 1.0f; _transform.planetFade.secondaryRenderers = new List <GameObject>(); _transform.secondaryFades = new PQSMod_CelestialBodyTransform.AltitudeFade[0]; _transform.requirements = PQS.ModiferRequirements.Default; _transform.modEnabled = true; _transform.order = 10; // Create the material direction mod = new GameObject("_Material_SunLight"); mod.transform.parent = controllerRoot.gameObject.transform; PQSMod_MaterialSetDirection lightDirection = mod.AddComponent <PQSMod_MaterialSetDirection>(); lightDirection.sphere = Value; lightDirection.valueName = "_sunLightDirection"; lightDirection.requirements = PQS.ModiferRequirements.Default; lightDirection.modEnabled = true; lightDirection.order = 100; // Create the UV planet relative position mod = new GameObject("_Material_SurfaceQuads"); mod.transform.parent = controllerRoot.transform; PQSMod_UVPlanetRelativePosition uvs = mod.AddComponent <PQSMod_UVPlanetRelativePosition>(); uvs.sphere = Value; uvs.requirements = PQS.ModiferRequirements.Default; uvs.modEnabled = true; uvs.order = 999999; // Crete the quad mesh colliders mod = new GameObject("QuadMeshColliders"); mod.transform.parent = controllerRoot.gameObject.transform; _collider = mod.AddComponent <PQSMod_QuadMeshColliders>(); _collider.sphere = Value; _collider.maxLevelOffset = 0; _collider.requirements = PQS.ModiferRequirements.Default; _collider.modEnabled = true; _collider.order = 100; } // Assing the new PQS body.pqsController = Value; body.pqsController.name = body.transform.name; body.pqsController.transform.name = body.transform.name; body.pqsController.gameObject.name = body.transform.name; body.pqsController.radius = body.Radius; // Add an OnDemand Handler if (Value.GetComponentsInChildren <PQSMod_OnDemandHandler>(true).Length == 0) { OnDemandStorage.AddHandler(Value); } // Load existing mods foreach (PQSMod mod in Value.GetComponentsInChildren <PQSMod>(true) .Where(m => m.sphere == Value)) { Type modType = mod.GetType(); foreach (Type loaderType in Parser.ModTypes) { if (loaderType.BaseType == null) { continue; } if (loaderType.BaseType.Namespace != "Kopernicus.Configuration.ModLoader") { continue; } if (!loaderType.BaseType.Name.StartsWith("ModLoader")) { continue; } if (loaderType.BaseType.GetGenericArguments()[0] != modType) { continue; } // We found our loader type IModLoader loader = (IModLoader)Activator.CreateInstance(loaderType); loader.Create(mod, Value); mods.Add(loader); } } }
// Update the menu body private void Start() { if (!Templates.KopernicusMainMenu) { return; } // Select a random body? if (Templates.RandomMainMenuBodies.Any()) { Templates.MenuBody = Templates.RandomMainMenuBodies[new Random().Next(0, Templates.RandomMainMenuBodies.Count)]; } // Grab the main body CelestialBody planetCb = UBI.GetBody(Templates.MenuBody); if (planetCb == null) { planetCb = PSystemManager.Instance.localBodies.Find(b => b.isHomeWorld); } if (planetCb == null) { Debug.LogError("[Kopernicus] Could not find home world!"); return; } // Load Textures OnDemandStorage.EnableBody(Templates.MenuBody); // Get the MainMenu-Logic MainMenu main = FindObjectOfType <MainMenu>(); if (main == null) { Debug.LogError("[Kopernicus] No main menu object!"); return; } MainMenuEnvLogic logic = main.envLogic; // Set it to Space, because the Mun-Area won't work with sth else than Mun if (logic.areas.Length < 2) { Debug.LogError("[Kopernicus] Not enough bodies"); return; } // Get our active Space GameObject space = logic.areas[1]; // Deactivate Kerbins Transform Transform kerbin = space.transform.Find("Kerbin"); if (kerbin == null) { Debug.LogError("[Kopernicus] No Kerbin transform!"); return; } kerbin.gameObject.SetActive(false); // Deactivate Muns Transform Transform munPivot = space.transform.Find("MunPivot"); if (munPivot == null) { Debug.LogError("[Kopernicus] No MunPivot transform!"); return; } munPivot.gameObject.SetActive(false); // Activate the textures ScaledSpaceOnDemand od = planetCb.scaledBody.GetComponentInChildren <ScaledSpaceOnDemand>(); if (od != null) { od.Start(); od.LoadTextures(); } // Clone the scaledVersion and attach it to the Scene GameObject menuPlanet = Utility.Instantiate(Utility .FindBody(PSystemManager.Instance.systemPrefab.rootBody, planetCb.transform.name).scaledVersion, space.transform, true); menuPlanet.name = planetCb.transform.name; // Destroy stuff DestroyImmediate(menuPlanet.GetComponent <ScaledSpaceFader>()); DestroyImmediate(menuPlanet.GetComponent <SphereCollider>()); DestroyImmediate(menuPlanet.GetComponentInChildren <AtmosphereFromGround>()); DestroyImmediate(menuPlanet.GetComponent <MaterialSetDirection>()); // That sounds funny Rotato planetRotato = menuPlanet.AddComponent <Rotato>(); Rotato planetRefRotato = kerbin.GetComponent <Rotato>(); planetRotato.speed = planetRefRotato.speed * ((Single)planetCb.rotationPeriod / KERBIN_ROTATION_PERIOD); menuPlanet.transform.Rotate(0f, (Single)planetCb.initialRotation, 0f); // Scale the body menuPlanet.transform.localScale = kerbin.localScale; menuPlanet.transform.localPosition = kerbin.localPosition; menuPlanet.transform.position = kerbin.position; // And set it to layer 0 menuPlanet.layer = 0; Events.OnRuntimeUtilityUpdateMenu.Fire(); }
// Generate the scaled space mesh using PQS (all results use scale of 1) public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs) { // We need to get the body for Jool (to steal it's mesh) const Double rScaledJool = 1000.0f; Double rMetersToScaledUnits = (Single)(rScaledJool / body.Radius); // Generate a duplicate of the Jool mesh Mesh mesh = DuplicateMesh(Templates.ReferenceGeosphere); Logger.Active.Log(body); Logger.Active.Log(pqs); Logger.Active.Log(body.pqsController); // If this body has a PQS, we can create a more detailed object if (pqs != null) { // first we enable all maps OnDemandStorage.EnableBody(body.bodyName); // The game object the PQS is attached to GameObject pqsVersionGameObject = null; if (Injector.IsInPrefab) { // In order to generate the scaled space we have to enable the mods. Since this is // a prefab they don't get disabled as kill game performance. To resolve this we // clone the PQS, use it, and then delete it when done pqsVersionGameObject = UnityEngine.Object.Instantiate(pqs.gameObject); } else { // At runtime we simply use the PQS that is active pqsVersionGameObject = pqs.gameObject; } PQS pqsVersion = pqsVersionGameObject.GetComponent <PQS>(); // Load the PQS of the ocean PQS pqsOcean = pqs.ChildSpheres?.FirstOrDefault(); // Deactivate blacklisted Mods Type[] blacklist = { typeof(PQSMod_OnDemandHandler) }; foreach (PQSMod mod in pqsVersion.GetComponentsInChildren <PQSMod>(true) .Where(m => m.enabled && blacklist.Contains(m.GetType()))) { mod.modEnabled = false; } // Find the PQS mods and enable the PQS-sphere PQSMod[] mods = pqsVersion.GetComponentsInChildren <PQSMod>(true) .Where(m => m.modEnabled && m.transform.parent == pqsVersion.transform).OrderBy(m => m.order).ToArray(); foreach (PQSMod flatten in mods.Where(m => m is PQSMod_FlattenArea)) { flatten.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .First(f => f.FieldType == typeof(Boolean)).SetValue(flatten, true); } Logger.Active.Log(mods.Length); // Do the same for the ocean PQSMod[] oceanMods = new PQSMod[0]; if (pqsOcean != null) { oceanMods = pqsOcean.GetComponentsInChildren <PQSMod>(true) .Where(m => m.modEnabled && m.transform.parent == pqsOcean.transform).OrderBy(m => m.order).ToArray(); foreach (PQSMod flatten in oceanMods.Where(m => m is PQSMod_FlattenArea)) { flatten.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .First(f => f.FieldType == typeof(Boolean)).SetValue(flatten, true); } pqsOcean.StartUpSphere(); pqsOcean.isBuildingMaps = true; } pqsVersion.StartUpSphere(); pqsVersion.isBuildingMaps = true; // If we were able to find PQS mods if (mods.Any()) { // Generate the PQS modifications Vector3[] vertices = mesh.vertices; for (Int32 i = 0; i < mesh.vertexCount; i++) { // Get the UV coordinate of this vertex Vector2 uv = mesh.uv[i]; // Since this is a geosphere, normalizing the vertex gives the direction from center center Vector3 direction = vertices[i]; direction.Normalize(); // Build the vertex data object for the PQS mods PQS.VertexBuildData vertex = new PQS.VertexBuildData(); vertex.directionFromCenter = direction; vertex.vertHeight = body.Radius; vertex.u = uv.x; vertex.v = uv.y; // Build from the PQS foreach (PQSMod mod in mods) { mod.OnVertexBuildHeight(vertex); } // Check for sea level if (pqsOcean != null) { // Build the vertex data object for the ocean PQS.VertexBuildData vertexOcean = new PQS.VertexBuildData(); vertexOcean.directionFromCenter = direction; vertexOcean.vertHeight = body.Radius; vertexOcean.u = uv.x; vertexOcean.v = uv.y; // Build from the PQS foreach (PQSMod mod in oceanMods) { mod.OnVertexBuildHeight(vertexOcean); } vertex.vertHeight = Math.Max(vertex.vertHeight, vertexOcean.vertHeight); } // Adjust the displacement vertices[i] = direction * (Single)(vertex.vertHeight * rMetersToScaledUnits); } mesh.vertices = vertices; mesh.RecalculateNormals(); mesh.RecalculateBounds(); } // Cleanup if (pqsOcean != null) { pqsOcean.isBuildingMaps = false; pqsOcean.DeactivateSphere(); } pqsVersion.isBuildingMaps = false; pqsVersion.DeactivateSphere(); // If we are working with a copied PQS, clean it up if (Injector.IsInPrefab) { UnityEngine.Object.Destroy(pqsVersionGameObject); } OnDemandStorage.DisableBody(body.bodyName); } // Return the generated scaled space mesh return(mesh); }