Sky sphere builder

This commit is contained in:
Joshua Thome 2022-07-23 18:19:04 -05:00
parent df4c5be913
commit 1aa01c865b
2 changed files with 147 additions and 1 deletions

View File

@ -1,12 +1,17 @@
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using NewHorizons.Utility; using NewHorizons.Utility;
using OWML.Common; using OWML.Common;
using System;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.StarSystem namespace NewHorizons.Builder.StarSystem
{ {
public class SkyboxBuilder public class SkyboxBuilder
{ {
private static int _skyboxLayer = -1;
private static Shader _unlitShader;
[Obsolete]
public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod) public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod)
{ {
Logger.Log("Building Skybox"); Logger.Log("Building Skybox");
@ -17,5 +22,134 @@ namespace NewHorizons.Builder.StarSystem
camera.clearFlags = CameraClearFlags.Skybox; camera.clearFlags = CameraClearFlags.Skybox;
} }
} }
public static void Make(StarSystemConfig.SkyboxModule module, IModBehaviour mod)
{
Logger.Log("Building Skybox");
BuildSkySphere(module, mod);
}
public static GameObject BuildSkySphere(StarSystemConfig.SkyboxModule module, IModBehaviour mod)
{
var skybox = SearchUtilities.Find("Skybox");
var rightTex = ImageUtilities.GetTexture(mod, module.rightPath);
var leftTex = ImageUtilities.GetTexture(mod, module.leftPath);
var topTex = ImageUtilities.GetTexture(mod, module.topPath);
var bottomTex = ImageUtilities.GetTexture(mod, module.bottomPath);
var frontTex = ImageUtilities.GetTexture(mod, module.frontPath);
var backTex = ImageUtilities.GetTexture(mod, module.backPath);
if (_skyboxLayer == -1) _skyboxLayer = LayerMask.NameToLayer("Skybox");
if (!_unlitShader) _unlitShader = Shader.Find("Unlit/Texture");
var mesh = BuildSkySphereFaceMesh(module.useCube ? 1 : 32);
var skySphere = new GameObject("Sky Sphere");
skySphere.transform.SetParent(skybox.transform, false);
skySphere.layer = _skyboxLayer;
skySphere.transform.localScale = Vector3.one * 5f;
BuildSkySphereFace(skySphere, "Right", Quaternion.Euler(0f, 90f, 0f), mesh, rightTex);
BuildSkySphereFace(skySphere, "Left", Quaternion.Euler(0f, 270f, 0f), mesh, leftTex);
BuildSkySphereFace(skySphere, "Top", Quaternion.Euler(270f, 0f, 0f), mesh, topTex);
BuildSkySphereFace(skySphere, "Bottom", Quaternion.Euler(90f, 0f, 0f), mesh, bottomTex);
BuildSkySphereFace(skySphere, "Front", Quaternion.Euler(0f, 0f, 0f), mesh, frontTex);
BuildSkySphereFace(skySphere, "Back", Quaternion.Euler(0f, 180f, 0f), mesh, backTex);
return skySphere;
}
public static GameObject BuildSkySphereFace(GameObject skySphere, string name, Quaternion rotation, Mesh mesh, Texture2D tex)
{
if (!tex)
{
Logger.LogError($"Failed to load texture for skybox {name.ToLower()} face");
return null;
}
var go = new GameObject(name)
{
layer = _skyboxLayer
};
var mf = go.AddComponent<MeshFilter>();
mf.sharedMesh = mesh;
var mat = new Material(_unlitShader)
{
name = $"Sky Sphere {name}",
mainTexture = tex
};
var mr = go.AddComponent<MeshRenderer>();
mr.sharedMaterial = mat;
var sr = go.AddComponent<SkyboxRenderer>();
Delay.RunWhen(() => SkyboxRenderer.s_active.Contains(sr), () =>
{
SkyboxRenderer.s_active.Remove(sr);
SkyboxRenderer.s_active.Insert(0, sr);
});
go.transform.SetParent(skySphere.transform, false);
go.transform.localRotation = rotation;
go.transform.localScale = Vector3.one;
return go;
}
public static Mesh BuildSkySphereFaceMesh(int quadsPerAxis)
{
var mesh = new Mesh
{
name = $"Sky Sphere Face"
};
var vertices = new Vector3[(quadsPerAxis + 1) * (quadsPerAxis + 1)];
var normals = new Vector3[vertices.Length];
var uvs = new Vector2[vertices.Length];
var tris = new int[quadsPerAxis * quadsPerAxis * 2 * 3];
for (var x = 0; x <= quadsPerAxis; x++)
{
for (var y = 0; y <= quadsPerAxis; y++)
{
var i = y * (quadsPerAxis + 1) + x;
var fx = (float)x / quadsPerAxis;
var fy = (float)y / quadsPerAxis;
vertices[i] = new Vector3(-0.5f + fx, -0.5f + fy, 0.5f).normalized;
normals[i] = -vertices[i].normalized;
uvs[i] = new Vector2(fx, fy);
}
}
int t = 0;
for (var x = 0; x < quadsPerAxis; x++)
{
for (var y = 0; y < quadsPerAxis; y++)
{
var i0 = (y + 1) * (quadsPerAxis + 1) + (x + 0);
var i1 = (y + 1) * (quadsPerAxis + 1) + (x + 1);
var i2 = (y + 0) * (quadsPerAxis + 1) + (x + 1);
var i3 = (y + 0) * (quadsPerAxis + 1) + (x + 0);
tris[t++] = i0;
tris[t++] = i1;
tris[t++] = i2;
tris[t++] = i2;
tris[t++] = i3;
tris[t++] = i0;
}
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uvs;
mesh.triangles = tris;
return mesh;
}
} }
} }

View File

@ -12,15 +12,27 @@ namespace NewHorizons.Handlers
{ {
var skybox = SearchUtilities.Find("Skybox/Starfield"); var skybox = SearchUtilities.Find("Skybox/Starfield");
if (system.Config.skybox?.destroyStarField ?? false) if (system.Config.Skybox?.destroyStarField ?? false)
{ {
Object.Destroy(skybox); Object.Destroy(skybox);
} }
if (system.Config.Skybox?.rightPath != null ||
system.Config.Skybox?.leftPath != null ||
system.Config.Skybox?.topPath != null ||
system.Config.Skybox?.bottomPath != null ||
system.Config.Skybox?.frontPath != null ||
system.Config.Skybox?.bottomPath != null)
{
SkyboxBuilder.Make(system.Config.Skybox, system.Mod);
}
#pragma warning disable CS0618, CS0612 // Type or member is obsolete
if (system.Config.skybox?.assetBundle != null && system.Config.skybox?.path != null) if (system.Config.skybox?.assetBundle != null && system.Config.skybox?.path != null)
{ {
SkyboxBuilder.Make(system.Config.skybox, system.Mod); SkyboxBuilder.Make(system.Config.skybox, system.Mod);
} }
#pragma warning restore CS0618, CS0612 // Type or member is obsolete
if (system.Config.enableTimeLoop) if (system.Config.enableTimeLoop)
{ {