summaryrefslogtreecommitdiff
path: root/Thronefall_v1.0/Decompile/GPUInstancingManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Thronefall_v1.0/Decompile/GPUInstancingManager.cs')
-rw-r--r--Thronefall_v1.0/Decompile/GPUInstancingManager.cs119
1 files changed, 119 insertions, 0 deletions
diff --git a/Thronefall_v1.0/Decompile/GPUInstancingManager.cs b/Thronefall_v1.0/Decompile/GPUInstancingManager.cs
new file mode 100644
index 0000000..99d9dab
--- /dev/null
+++ b/Thronefall_v1.0/Decompile/GPUInstancingManager.cs
@@ -0,0 +1,119 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class GPUInstancingManager : MonoBehaviour
+{
+ private struct MaterialMeshPair
+ {
+ public Material material;
+
+ public Mesh mesh;
+ }
+
+ private struct TransformMatrixPair
+ {
+ public List<Transform> transforms;
+
+ public List<Matrix4x4> matrices;
+ }
+
+ public static GPUInstancingManager Instance;
+
+ [Tooltip("Do not change this during runtime!")]
+ [SerializeField]
+ private bool gpuInstancingEnabled = true;
+
+ [SerializeField]
+ private bool debugLogs;
+
+ private Dictionary<MaterialMeshPair, TransformMatrixPair> matMeshPairToRenderersDictionary;
+
+ private List<Matrix4x4> transformMatricesBuffer = new List<Matrix4x4>();
+
+ private void Awake()
+ {
+ if (gpuInstancingEnabled)
+ {
+ Instance = this;
+ }
+ else
+ {
+ Instance = null;
+ }
+ matMeshPairToRenderersDictionary = new Dictionary<MaterialMeshPair, TransformMatrixPair>();
+ }
+
+ private void Update()
+ {
+ int num = 0;
+ int num2 = 0;
+ foreach (KeyValuePair<MaterialMeshPair, TransformMatrixPair> item in matMeshPairToRenderersDictionary)
+ {
+ TransformMatrixPair value = item.Value;
+ for (int i = 0; i < value.transforms.Count; i++)
+ {
+ if (value.transforms[i] != null)
+ {
+ value.matrices[i] = value.transforms[i].localToWorldMatrix;
+ }
+ }
+ if (value.matrices.Count >= 1024)
+ {
+ Debug.LogWarning("Drawing too many meshes with mesh: " + item.Key.mesh.ToString());
+ }
+ try
+ {
+ Graphics.DrawMeshInstanced(item.Key.mesh, 0, item.Key.material, value.matrices);
+ }
+ catch
+ {
+ Debug.LogError("GPU instancing with material failed: " + item.Key.material.ToString());
+ }
+ num += value.transforms.Count;
+ num2++;
+ }
+ }
+
+ public void AddVirtualMeshRenderer(Mesh mesh, Material material, Transform transform)
+ {
+ MaterialMeshPair key = default(MaterialMeshPair);
+ key.material = material;
+ key.mesh = mesh;
+ if (!matMeshPairToRenderersDictionary.TryGetValue(key, out var value))
+ {
+ TransformMatrixPair transformMatrixPair = default(TransformMatrixPair);
+ transformMatrixPair.transforms = new List<Transform>();
+ transformMatrixPair.matrices = new List<Matrix4x4>();
+ value = transformMatrixPair;
+ matMeshPairToRenderersDictionary[key] = value;
+ }
+ value.transforms.Add(transform);
+ value.matrices.Add(transform.localToWorldMatrix);
+ }
+
+ public void RemoveVirtualMeshRenderer(Mesh mesh, Material material, Transform transform)
+ {
+ MaterialMeshPair key = default(MaterialMeshPair);
+ key.material = material;
+ key.mesh = mesh;
+ if (matMeshPairToRenderersDictionary.TryGetValue(key, out var value))
+ {
+ int num = value.transforms.IndexOf(transform);
+ if (num != -1)
+ {
+ value.transforms.RemoveAt(num);
+ value.matrices.RemoveAt(num);
+ }
+ if (value.transforms.Count == 0)
+ {
+ matMeshPairToRenderersDictionary.Remove(key);
+ }
+ }
+ }
+
+ public void UpdateVirtualMeshRenderer(Mesh oldMesh, Material oldMaterial, Mesh newMesh, Material newMaterial, Transform transform)
+ {
+ RemoveVirtualMeshRenderer(oldMesh, oldMaterial, transform);
+ AddVirtualMeshRenderer(newMesh, newMaterial, transform);
+ }
+}