diff --git a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs index 05e07ee8..c6594b48 100644 --- a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs @@ -1,227 +1,227 @@ -using NewHorizons.External.Modules; -using NewHorizons.Utility; -using OWML.Common; -using System; -using UnityEngine; -using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Builder.Atmosphere -{ - public static class CloudsBuilder - { - private static Shader _sphereShader = null; +using NewHorizons.External.Modules; +using NewHorizons.Utility; +using OWML.Common; +using System; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; +namespace NewHorizons.Builder.Atmosphere +{ + public static class CloudsBuilder + { + private static Shader _sphereShader = null; private static Material[] _gdCloudMaterials; private static Material[] _qmCloudMaterials; - private static GameObject _lightningPrefab; - private static Texture2D _colorRamp; - private static readonly int Color1 = Shader.PropertyToID("_Color"); - private static readonly int TintColor = Shader.PropertyToID("_TintColor"); - private static readonly int MainTex = Shader.PropertyToID("_MainTex"); - private static readonly int RampTex = Shader.PropertyToID("_RampTex"); - private static readonly int CapTex = Shader.PropertyToID("_CapTex"); - private static readonly int ColorRamp = Shader.PropertyToID("_ColorRamp"); - - public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, IModBehaviour mod) - { + private static GameObject _lightningPrefab; + private static Texture2D _colorRamp; + private static readonly int Color1 = Shader.PropertyToID("_Color"); + private static readonly int TintColor = Shader.PropertyToID("_TintColor"); + private static readonly int MainTex = Shader.PropertyToID("_MainTex"); + private static readonly int RampTex = Shader.PropertyToID("_RampTex"); + private static readonly int CapTex = Shader.PropertyToID("_CapTex"); + private static readonly int ColorRamp = Shader.PropertyToID("_ColorRamp"); + + public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, IModBehaviour mod) + { if (_lightningPrefab == null) _lightningPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Clouds_GD/LightningGenerator_GD"); - if (_colorRamp == null) _colorRamp = ImageUtilities.GetTexture(Main.Instance, "AssetBundle/textures/Clouds_Bottom_ramp.png"); - - GameObject cloudsMainGO = new GameObject("Clouds"); - cloudsMainGO.SetActive(false); - cloudsMainGO.transform.parent = sector?.transform ?? planetGO.transform; - - MakeTopClouds(cloudsMainGO, atmo, mod); - - GameObject cloudsBottomGO = new GameObject("BottomClouds"); - cloudsBottomGO.SetActive(false); - cloudsBottomGO.transform.parent = cloudsMainGO.transform; - cloudsBottomGO.transform.localScale = Vector3.one * atmo.clouds.innerCloudRadius; - - TessellatedSphereRenderer bottomTSR = cloudsBottomGO.AddComponent(); + if (_colorRamp == null) _colorRamp = ImageUtilities.GetTexture(Main.Instance, "AssetBundle/textures/Clouds_Bottom_ramp.png"); + + GameObject cloudsMainGO = new GameObject("Clouds"); + cloudsMainGO.SetActive(false); + cloudsMainGO.transform.parent = sector?.transform ?? planetGO.transform; + + MakeTopClouds(cloudsMainGO, atmo, mod); + + GameObject cloudsBottomGO = new GameObject("BottomClouds"); + cloudsBottomGO.SetActive(false); + cloudsBottomGO.transform.parent = cloudsMainGO.transform; + cloudsBottomGO.transform.localScale = Vector3.one * atmo.clouds.innerCloudRadius; + + TessellatedSphereRenderer bottomTSR = cloudsBottomGO.AddComponent(); bottomTSR.tessellationMeshGroup = SearchUtilities.Find("CloudsBottomLayer_QM").GetComponent().tessellationMeshGroup; var bottomTSRMaterials = SearchUtilities.Find("CloudsBottomLayer_QM").GetComponent().sharedMaterials; - - // If they set a colour apply it to all the materials else keep the default QM one - if (atmo.clouds.tint != null) - { - var bottomColor = atmo.clouds.tint.ToColor(); - - var bottomTSRTempArray = new Material[2]; - - bottomTSRTempArray[0] = new Material(bottomTSRMaterials[0]); - bottomTSRTempArray[0].SetColor(Color1, bottomColor); - bottomTSRTempArray[0].SetColor(TintColor, bottomColor); - bottomTSRTempArray[0].SetTexture(ColorRamp, ImageUtilities.TintImage(_colorRamp, bottomColor)); - - bottomTSRTempArray[1] = new Material(bottomTSRMaterials[1]); - - bottomTSR.sharedMaterials = bottomTSRTempArray; - } - else - { - bottomTSR.sharedMaterials = bottomTSRMaterials; - } - - bottomTSR.maxLOD = 6; - bottomTSR.LODBias = 0; - bottomTSR.LODRadius = 1f; - - TessSphereSectorToggle bottomTSST = cloudsBottomGO.AddComponent(); - bottomTSST._sector = sector; - - GameObject cloudsFluidGO = new GameObject("CloudsFluid"); - cloudsFluidGO.SetActive(false); - cloudsFluidGO.layer = 17; - cloudsFluidGO.transform.parent = cloudsMainGO.transform; - - SphereCollider fluidSC = cloudsFluidGO.AddComponent(); - fluidSC.isTrigger = true; - fluidSC.radius = atmo.size; - - OWShellCollider fluidOWSC = cloudsFluidGO.AddComponent(); - fluidOWSC._innerRadius = atmo.size * 0.9f; - - CloudLayerFluidVolume fluidCLFV = cloudsFluidGO.AddComponent(); - fluidCLFV._layer = 5; - fluidCLFV._priority = 1; - fluidCLFV._density = 1.2f; - - var fluidType = FluidVolume.Type.CLOUD; - - try - { - fluidType = (FluidVolume.Type)Enum.Parse(typeof(FluidVolume.Type), Enum.GetName(typeof(CloudFluidType), atmo.clouds.fluidType).ToUpper()); - } - catch (Exception ex) - { - Logger.LogError($"Couldn't parse fluid volume type [{atmo.clouds.fluidType}]: {ex.Message}, {ex.StackTrace}"); - } - - fluidCLFV._fluidType = fluidType; - fluidCLFV._allowShipAutoroll = true; - fluidCLFV._disableOnStart = false; - - // Fix the rotations once the rest is done - cloudsMainGO.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(0, 0, 0)); - // For the base shader it has to be rotated idk - if (atmo.clouds.useBasicCloudShader) cloudsMainGO.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(90, 0, 0)); - - // Lightning - if (atmo.clouds.hasLightning) - { - var lightning = _lightningPrefab.InstantiateInactive(); - lightning.transform.parent = cloudsMainGO.transform; - lightning.transform.localPosition = Vector3.zero; - - var lightningGenerator = lightning.GetComponent(); - lightningGenerator._altitude = (atmo.clouds.outerCloudRadius + atmo.clouds.innerCloudRadius) / 2f; - lightningGenerator._audioSector = sector; - if (atmo.clouds.lightningGradient != null) - { - var gradient = new GradientColorKey[atmo.clouds.lightningGradient.Length]; - - for(int i = 0; i < atmo.clouds.lightningGradient.Length; i++) - { - var pair = atmo.clouds.lightningGradient[i]; - gradient[i] = new GradientColorKey(pair.tint.ToColor(), pair.time); - } - - lightningGenerator._lightColor.colorKeys = gradient; - } - lightning.SetActive(true); - } - - cloudsMainGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); - cloudsBottomGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); - cloudsFluidGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); - - cloudsBottomGO.SetActive(true); - cloudsFluidGO.SetActive(true); - cloudsMainGO.SetActive(true); - } - - public static GameObject MakeTopClouds(GameObject rootObject, AtmosphereModule atmo, IModBehaviour mod) - { - Color cloudTint = atmo.clouds.tint?.ToColor() ?? Color.white; - - Texture2D image, cap, ramp; - - try - { - image = ImageUtilities.GetTexture(mod, atmo.clouds.texturePath); - - if (atmo.clouds.capPath == null) cap = ImageUtilities.ClearTexture(128, 128); - else cap = ImageUtilities.GetTexture(mod, atmo.clouds.capPath); - if (atmo.clouds.rampPath == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height); - else ramp = ImageUtilities.GetTexture(mod, atmo.clouds.rampPath); - } - catch (Exception e) - { - Logger.LogError($"Couldn't load Cloud textures for [{rootObject.name}], {e.Message}, {e.StackTrace}"); - return null; - } - - GameObject cloudsTopGO = new GameObject("TopClouds"); - cloudsTopGO.SetActive(false); - cloudsTopGO.transform.parent = rootObject.transform; - cloudsTopGO.transform.localScale = Vector3.one * atmo.clouds.outerCloudRadius; - - MeshFilter topMF = cloudsTopGO.AddComponent(); + + // If they set a colour apply it to all the materials else keep the default QM one + if (atmo.clouds.tint != null) + { + var bottomColor = atmo.clouds.tint.ToColor(); + + var bottomTSRTempArray = new Material[2]; + + bottomTSRTempArray[0] = new Material(bottomTSRMaterials[0]); + bottomTSRTempArray[0].SetColor(Color1, bottomColor); + bottomTSRTempArray[0].SetColor(TintColor, bottomColor); + bottomTSRTempArray[0].SetTexture(ColorRamp, ImageUtilities.TintImage(_colorRamp, bottomColor)); + + bottomTSRTempArray[1] = new Material(bottomTSRMaterials[1]); + + bottomTSR.sharedMaterials = bottomTSRTempArray; + } + else + { + bottomTSR.sharedMaterials = bottomTSRMaterials; + } + + bottomTSR.maxLOD = 6; + bottomTSR.LODBias = 0; + bottomTSR.LODRadius = 1f; + + TessSphereSectorToggle bottomTSST = cloudsBottomGO.AddComponent(); + bottomTSST._sector = sector; + + GameObject cloudsFluidGO = new GameObject("CloudsFluid"); + cloudsFluidGO.SetActive(false); + cloudsFluidGO.layer = 17; + cloudsFluidGO.transform.parent = cloudsMainGO.transform; + + SphereCollider fluidSC = cloudsFluidGO.AddComponent(); + fluidSC.isTrigger = true; + fluidSC.radius = atmo.size; + + OWShellCollider fluidOWSC = cloudsFluidGO.AddComponent(); + fluidOWSC._innerRadius = atmo.size * 0.9f; + + CloudLayerFluidVolume fluidCLFV = cloudsFluidGO.AddComponent(); + fluidCLFV._layer = 5; + fluidCLFV._priority = 1; + fluidCLFV._density = 1.2f; + + var fluidType = FluidVolume.Type.CLOUD; + + try + { + fluidType = (FluidVolume.Type)Enum.Parse(typeof(FluidVolume.Type), Enum.GetName(typeof(CloudFluidType), atmo.clouds.fluidType).ToUpper()); + } + catch (Exception ex) + { + Logger.LogError($"Couldn't parse fluid volume type [{atmo.clouds.fluidType}]: {ex.Message}, {ex.StackTrace}"); + } + + fluidCLFV._fluidType = fluidType; + fluidCLFV._allowShipAutoroll = true; + fluidCLFV._disableOnStart = false; + + // Fix the rotations once the rest is done + cloudsMainGO.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(0, 0, 0)); + // For the base shader it has to be rotated idk + if (atmo.clouds.useBasicCloudShader) cloudsMainGO.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(90, 0, 0)); + + // Lightning + if (atmo.clouds.hasLightning) + { + var lightning = _lightningPrefab.InstantiateInactive(); + lightning.transform.parent = cloudsMainGO.transform; + lightning.transform.localPosition = Vector3.zero; + + var lightningGenerator = lightning.GetComponent(); + lightningGenerator._altitude = (atmo.clouds.outerCloudRadius + atmo.clouds.innerCloudRadius) / 2f; + lightningGenerator._audioSector = sector; + if (atmo.clouds.lightningGradient != null) + { + var gradient = new GradientColorKey[atmo.clouds.lightningGradient.Length]; + + for(int i = 0; i < atmo.clouds.lightningGradient.Length; i++) + { + var pair = atmo.clouds.lightningGradient[i]; + gradient[i] = new GradientColorKey(pair.tint.ToColor(), pair.time); + } + + lightningGenerator._lightColor.colorKeys = gradient; + } + lightning.SetActive(true); + } + + cloudsMainGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); + cloudsBottomGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); + cloudsFluidGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); + + cloudsBottomGO.SetActive(true); + cloudsFluidGO.SetActive(true); + cloudsMainGO.SetActive(true); + } + + public static GameObject MakeTopClouds(GameObject rootObject, AtmosphereModule atmo, IModBehaviour mod) + { + Color cloudTint = atmo.clouds.tint?.ToColor() ?? Color.white; + + Texture2D image, cap, ramp; + + try + { + image = ImageUtilities.GetTexture(mod, atmo.clouds.texturePath); + + if (atmo.clouds.capPath == null) cap = ImageUtilities.ClearTexture(128, 128); + else cap = ImageUtilities.GetTexture(mod, atmo.clouds.capPath); + if (atmo.clouds.rampPath == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height); + else ramp = ImageUtilities.GetTexture(mod, atmo.clouds.rampPath); + } + catch (Exception e) + { + Logger.LogError($"Couldn't load Cloud textures for [{rootObject.name}], {e.Message}, {e.StackTrace}"); + return null; + } + + GameObject cloudsTopGO = new GameObject("TopClouds"); + cloudsTopGO.SetActive(false); + cloudsTopGO.transform.parent = rootObject.transform; + cloudsTopGO.transform.localScale = Vector3.one * atmo.clouds.outerCloudRadius; + + MeshFilter topMF = cloudsTopGO.AddComponent(); topMF.mesh = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent().mesh; - - MeshRenderer topMR = cloudsTopGO.AddComponent(); - - if (_sphereShader == null) _sphereShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); + + MeshRenderer topMR = cloudsTopGO.AddComponent(); + + if (_sphereShader == null) _sphereShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); if (_gdCloudMaterials == null) _gdCloudMaterials = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent().sharedMaterials; if (_qmCloudMaterials == null) _qmCloudMaterials = SearchUtilities.Find("CloudsTopLayer_QM").GetComponent().sharedMaterials; Material[] prefabMaterials = atmo.clouds.cloudsPrefab == CloudPrefabType.GiantsDeep ? _gdCloudMaterials : _qmCloudMaterials; - var tempArray = new Material[2]; - - if (atmo.clouds.useBasicCloudShader) - { - var material = new Material(_sphereShader); - if (atmo.clouds.unlit) material.renderQueue = 2550; - material.name = atmo.clouds.unlit ? "BasicCloud" : "BasicShadowCloud"; - - tempArray[0] = material; - } - else - { + var tempArray = new Material[2]; + + if (atmo.clouds.cloudsPrefab == CloudPrefabType.Basic) + { + var material = new Material(_sphereShader); + if (atmo.clouds.unlit) material.renderQueue = 2550; + material.name = atmo.clouds.unlit ? "BasicCloud" : "BasicShadowCloud"; + + tempArray[0] = material; + } + else + { var material = new Material(prefabMaterials[0]); - if (atmo.clouds.unlit) material.renderQueue = 2550; - material.name = atmo.clouds.unlit ? "AdvancedCloud" : "AdvancedShadowCloud"; - tempArray[0] = material; - } - - // This is the stencil material for the fog under the clouds + if (atmo.clouds.unlit) material.renderQueue = 2550; + material.name = atmo.clouds.unlit ? "AdvancedCloud" : "AdvancedShadowCloud"; + tempArray[0] = material; + } + + // This is the stencil material for the fog under the clouds tempArray[1] = new Material(prefabMaterials[1]); - topMR.sharedMaterials = tempArray; - - foreach (var material in topMR.sharedMaterials) - { - material.SetColor(Color1, cloudTint); - material.SetColor(TintColor, cloudTint); - - material.SetTexture(MainTex, image); - material.SetTexture(RampTex, ramp); - material.SetTexture(CapTex, cap); - } - - if (atmo.clouds.unlit) - { - cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun"); - } - - RotateTransform topRT = cloudsTopGO.AddComponent(); - // Idk why but the axis is weird - topRT._localAxis = atmo.clouds.useBasicCloudShader ? Vector3.forward : Vector3.up; - topRT._degreesPerSecond = 10; - topRT._randomizeRotationRate = false; - - cloudsTopGO.transform.localPosition = Vector3.zero; - - cloudsTopGO.SetActive(true); - - return cloudsTopGO; - } - } -} + topMR.sharedMaterials = tempArray; + + foreach (var material in topMR.sharedMaterials) + { + material.SetColor(Color1, cloudTint); + material.SetColor(TintColor, cloudTint); + + material.SetTexture(MainTex, image); + material.SetTexture(RampTex, ramp); + material.SetTexture(CapTex, cap); + } + + if (atmo.clouds.unlit) + { + cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun"); + } + + RotateTransform topRT = cloudsTopGO.AddComponent(); + // Idk why but the axis is weird + topRT._localAxis = atmo.clouds.useBasicCloudShader ? Vector3.forward : Vector3.up; + topRT._degreesPerSecond = 10; + topRT._randomizeRotationRate = false; + + cloudsTopGO.transform.localPosition = Vector3.zero; + + cloudsTopGO.SetActive(true); + + return cloudsTopGO; + } + } +} diff --git a/NewHorizons/External/Configs/PlanetConfig.cs b/NewHorizons/External/Configs/PlanetConfig.cs index ee652297..98876470 100644 --- a/NewHorizons/External/Configs/PlanetConfig.cs +++ b/NewHorizons/External/Configs/PlanetConfig.cs @@ -234,7 +234,11 @@ namespace NewHorizons.External.Configs // Former is obsolete, latter is to validate if (Atmosphere.hasAtmosphere || Atmosphere.atmosphereTint != null) - Atmosphere.useAtmosphereShader = true; + Atmosphere.useAtmosphereShader = true; + + // useBasicCloudShader is obsolete + if (Atmosphere.clouds != null && Atmosphere.clouds.useBasicCloudShader) + Atmosphere.clouds.cloudsPrefab = CloudPrefabType.Basic; } if (Props?.tornados != null) diff --git a/NewHorizons/External/Modules/AtmosphereModule.cs b/NewHorizons/External/Modules/AtmosphereModule.cs index e9be6bd6..926b65fd 100644 --- a/NewHorizons/External/Modules/AtmosphereModule.cs +++ b/NewHorizons/External/Modules/AtmosphereModule.cs @@ -27,7 +27,9 @@ namespace NewHorizons.External.Modules { [EnumMember(Value = @"giantsDeep")] GiantsDeep = 0, - [EnumMember(Value = @"quantumMoon")] QuantumMoon = 1, + [EnumMember(Value = @"quantumMoon")] QuantumMoon = 1, + + [EnumMember(Value = @"basic")] Basic = 2, } [JsonObject] @@ -151,11 +153,19 @@ namespace NewHorizons.External.Modules /// If the top layer shouldn't have shadows. Set to true if you're making a brown dwarf for example. /// public bool unlit; + + + + #region Obsolete /// /// Set to `false` in order to use Giant's Deep's shader. Set to `true` to just apply the cloud texture as is. /// + [Obsolete("useBasicCloudShader is deprecated, please use cloudsPrefab=\"basic\" instead")] public bool useBasicCloudShader; + + #endregion Obsolete + }