diff --git a/NewHorizons/Builder/Body/HeightMapBuilder.cs b/NewHorizons/Builder/Body/HeightMapBuilder.cs index 6c505c04..71b9ecca 100644 --- a/NewHorizons/Builder/Body/HeightMapBuilder.cs +++ b/NewHorizons/Builder/Body/HeightMapBuilder.cs @@ -1,5 +1,7 @@ using NewHorizons.Builder.Body.Geometry; +using NewHorizons.External.Configs; using NewHorizons.External.Modules; +using NewHorizons.Handlers; using NewHorizons.Utility; using OWML.Common; using System; @@ -11,7 +13,7 @@ namespace NewHorizons.Builder.Body { public static Shader PlanetShader; - public static void Make(GameObject planetGO, Sector sector, HeightMapModule module, IModBehaviour mod, int resolution) + public static void Make(GameObject planetGO, Sector sector, HeightMapModule module, IModBehaviour mod, int resolution, bool useLOD = false) { var deleteHeightmapFlag = false; @@ -51,24 +53,35 @@ namespace NewHorizons.Builder.Body GameObject cubeSphere = new GameObject("CubeSphere"); cubeSphere.SetActive(false); cubeSphere.transform.parent = sector?.transform ?? planetGO.transform; - cubeSphere.transform.rotation = Quaternion.Euler(90, 0, 0); - - Vector3 stretch = module.stretch != null ? (Vector3)module.stretch : Vector3.one; - Mesh mesh = CubeSphere.Build(resolution, heightMap, module.minHeight, module.maxHeight, stretch); - - cubeSphere.AddComponent(); - cubeSphere.GetComponent().mesh = mesh; if (PlanetShader == null) PlanetShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); - var cubeSphereMR = cubeSphere.AddComponent(); - var material = new Material(PlanetShader); - cubeSphereMR.material = material; - material.name = textureMap.name; - material.mainTexture = textureMap; + Vector3 stretch = module.stretch != null ? (Vector3)module.stretch : Vector3.one; + + var level1 = MakeLODTerrain(cubeSphere, heightMap, textureMap, module.minHeight, module.maxHeight, resolution, stretch); var cubeSphereMC = cubeSphere.AddComponent(); - cubeSphereMC.sharedMesh = mesh; + cubeSphereMC.sharedMesh = level1.gameObject.GetComponent().mesh; + + if (useLOD) + { + var level2Res = (int)Mathf.Clamp(resolution / 2f, 35, 100); + var level2 = MakeLODTerrain(cubeSphere, heightMap, textureMap, module.minHeight, module.maxHeight, level2Res, stretch); + + var LODGroup = cubeSphere.AddComponent(); + LODGroup.size = module.maxHeight; + + LODGroup.SetLODs(new LOD[] + { + new LOD(0.5f, new Renderer[] { level1 }), + new LOD(0.33f, new Renderer[] { level2 }) + }); + + level1.transform.name += "1"; + level2.transform.name += "2"; + + LODGroup.RecalculateBounds(); + } var cubeSphereSC = cubeSphere.AddComponent(); cubeSphereSC.radius = Mathf.Min(module.minHeight, module.maxHeight); @@ -86,5 +99,26 @@ namespace NewHorizons.Builder.Body // Now that we've made the mesh we can delete the heightmap texture if (deleteHeightmapFlag) ImageUtilities.DeleteTexture(mod, module.heightMap, heightMap); } + + public static MeshRenderer MakeLODTerrain(GameObject root, Texture2D heightMap, Texture2D textureMap, float minHeight, float maxHeight, int resolution, Vector3 stretch) + { + var LODCubeSphere = new GameObject("LODCubeSphere"); + + Mesh mesh = CubeSphere.Build(resolution, heightMap, minHeight, maxHeight, stretch); + + LODCubeSphere.AddComponent(); + LODCubeSphere.GetComponent().mesh = mesh; + + var cubeSphereMR = LODCubeSphere.AddComponent(); + var material = new Material(PlanetShader); + cubeSphereMR.material = material; + material.name = textureMap.name; + material.mainTexture = textureMap; + + LODCubeSphere.transform.parent = root.transform; + LODCubeSphere.transform.localPosition = Vector3.zero; + + return cubeSphereMR; + } } } diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 8529e994..91b10b3f 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -469,7 +469,7 @@ namespace NewHorizons.Handlers // resolution = tris on edge per face // divide by 4 to account for all the way around the equator var res = body.Config.HeightMap.resolution / 4; - HeightMapBuilder.Make(go, sector, body.Config.HeightMap, body.Mod, res); + HeightMapBuilder.Make(go, sector, body.Config.HeightMap, body.Mod, res, true); } if (body.Config.ProcGen != null)