Build simulation meshes

This commit is contained in:
Joshua Thome 2024-10-05 00:55:29 -05:00
parent 1be3bf209f
commit 6528d2c654
3 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,83 @@
using NewHorizons.Components.Props;
using NewHorizons.Utility;
using NewHorizons.Utility.OuterWilds;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Builder.Props.EchoesOfTheEye
{
public static class DreamSimulationBuilder
{
private static Material gridMaterial;
private static Material waterMaterial;
private readonly static string[] EXCLUDED_OBJECT_NAMES =
{
"Prefab_IP_SIM_",
"Props_IP_SIM_",
"Effects_IP_SIM_",
};
private readonly static string[] EXCLUDED_SHADER_NAMES =
{
"Fog",
"Simulation Bubble",
"Foliage",
"Flame",
};
public static void MakeDreamSimulationMeshes(GameObject go)
{
if (gridMaterial == null) gridMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Terrain_IP_DreamGrid_mat");
if (waterMaterial == null) waterMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Terrain_IP_DreamGrid_mat");
foreach (var mr in go.GetComponentsInChildren<MeshRenderer>(true))
{
if (mr.GetType() != typeof(MeshRenderer)) continue;
var mf = mr.GetComponent<MeshFilter>();
if (mf == null) continue;
if (!CheckMeshCreationHeuristic(mr.gameObject, mr.sharedMaterials)) continue;
var simMesh = new GameObject("SimulationMesh").AddComponent<DreamSimulationMesh>();
simMesh.Init(mr.transform, GetMeshMaterial(go, mr.sharedMaterials));
}
}
private static Material GetMeshMaterial(GameObject go, Material[] materials)
{
if (materials.Any(m => m.name.Contains("Ocean_Stencil_mat"))) return waterMaterial;
return gridMaterial;
}
private static bool CheckMeshCreationHeuristic(GameObject go, Material[] materials)
{
if (go.layer == Layer.DreamSimulation) return false;
var mr = go.GetComponent<MeshRenderer>();
if (EXCLUDED_SHADER_NAMES.Any(name => materials.Any(mat => mat.shader.name.Contains(name)))) return false;
if (go.transform.parent)
{
foreach (Transform c in go.transform.parent)
{
if (c && c.gameObject.layer == Layer.DreamSimulation) return false;
}
}
if (go.transform.parent.parent)
{
foreach (Transform c in go.transform.parent.parent)
{
if (c && c.gameObject.layer == Layer.DreamSimulation) return false;
}
}
var t = go.transform;
while (t != null)
{
if (EXCLUDED_OBJECT_NAMES.Any(t.name.Contains)) return false;
t = t.parent;
}
return true;
}
}
}

View File

@ -181,6 +181,11 @@ namespace NewHorizons.Builder.Props
} }
} }
} }
if (Main.HasDLC && config.Props.dreamArrivalPoints != null && config.Props.dreamArrivalPoints.Any(p => p.generateSimulationMeshes))
{
DreamSimulationBuilder.MakeDreamSimulationMeshes(sector ? sector.gameObject : go);
}
} }
private static bool _ignoreParent; private static bool _ignoreParent;

View File

@ -0,0 +1,76 @@
using NewHorizons.Utility.OuterWilds;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Components.Props
{
public class DreamSimulationMesh : MonoBehaviour
{
Transform target;
Material mat;
MeshFilter sourceMeshFilter;
MeshRenderer sourceMeshRenderer;
MeshFilter targetMeshFilter;
MeshRenderer targetMeshRenderer;
StreamingRenderMeshHandle streamingHandle;
bool initialized;
public void Init(Transform target, Material mat)
{
this.target = target;
this.mat = mat;
gameObject.layer = Layer.DreamSimulation;
sourceMeshFilter = target.GetComponent<MeshFilter>();
sourceMeshRenderer = target.GetComponent<MeshRenderer>();
targetMeshFilter = gameObject.AddComponent<MeshFilter>();
targetMeshRenderer = gameObject.AddComponent<MeshRenderer>();
transform.SetParent(target.transform, false);
streamingHandle = target.GetComponent<StreamingRenderMeshHandle>();
if (streamingHandle != null)
{
streamingHandle.OnMeshLoaded += OnMeshLoaded;
streamingHandle.OnMeshUnloaded += OnMeshUnloaded;
}
initialized = true;
Sync();
}
public void Sync()
{
if (!initialized) return;
targetMeshFilter.sharedMesh = sourceMeshFilter.sharedMesh;
targetMeshRenderer.sharedMaterials = sourceMeshRenderer.sharedMaterials.Select(_ => mat).ToArray();
targetMeshRenderer.enabled = sourceMeshRenderer.enabled;
}
void OnDestroy()
{
if (streamingHandle != null)
{
streamingHandle.OnMeshLoaded -= OnMeshLoaded;
streamingHandle.OnMeshUnloaded -= OnMeshUnloaded;
}
}
void OnMeshLoaded()
{
Sync();
}
void OnMeshUnloaded()
{
Sync();
}
}
}