summaryrefslogtreecommitdiff
path: root/Thronefall_1_57/Decompile/NGS.MeshFusionPro
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-05-19 16:05:58 +0800
committerchai <215380520@qq.com>2024-05-19 16:05:58 +0800
commit8e13e7e2874adc8982e16d1d2ed2e28d7480b45f (patch)
tree63ef85c460288891f5a593d69afeca16cba050b3 /Thronefall_1_57/Decompile/NGS.MeshFusionPro
parentc5f145786f4c6d2fe4bea831dfc16e52228920a5 (diff)
+1.57
Diffstat (limited to 'Thronefall_1_57/Decompile/NGS.MeshFusionPro')
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/AfterCombineAction.cs8
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTree.cs156
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeDrawer.cs22
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeNode.cs48
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/BoundsHelper.cs39
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineErrorStrategy.cs7
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineMethod.cs6
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineSource.cs92
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTree.cs112
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTreeNode.cs45
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroup.cs265
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupMatcher.cs20
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupPart.cs49
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMesh.cs86
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshData.cs17
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshDataInternal.cs124
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshFactory.cs43
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPart.cs26
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPartInternal.cs16
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObject.cs209
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectMatcher.cs10
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectPart.cs35
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombineSource.cs70
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObject.cs155
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectMatcher.cs39
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPart.cs44
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPartInternal.cs61
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicMeshFusionSource.cs130
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicObjectsCombiner.cs42
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/IAsyncCombinedMeshMover.cs10
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/IBinaryTreeNode.cs20
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombineSource.cs25
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshFactory.cs8
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshMover.cs10
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObject.cs16
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObjectPart.cs18
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCombiner.cs9
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCutter.cs11
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshToolsFactory.cs8
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMovableCombinedMeshFactory.cs6
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ISourceTrackingStrategy.cs6
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverLW.cs139
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverSTD.cs144
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshLWFactory.cs18
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshSTDFactory.cs18
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupCombineSource.cs106
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupSettings.cs63
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupsCombiner.cs34
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODMeshFusionSource.cs141
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/LightweightVertex.cs95
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MatrixHelper.cs18
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombineInfo.cs43
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerBase.cs44
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleLW.cs29
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleSTD.cs42
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleLW.cs66
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleSTD.cs138
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCuttingInfo.cs20
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataListsSTD.cs83
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysLW.cs131
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysSTD.cs104
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshFusionSource.cs333
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshSeparatorSimple.cs130
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshType.cs7
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/MoveMethod.cs7
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/ObjectsCombiner.cs155
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/PartMoveInfo.cs16
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererHelper.cs20
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererSettings.cs43
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/RigidbodyTrackingStrategy.cs62
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/RuntimeMeshFusion.cs197
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMeshMoverSTD.cs62
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMovableMeshSTDFactory.cs18
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsLWFactory.cs14
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsSTDFactory.cs14
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceCombineStatus.cs10
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceTracker.cs161
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticCombinedObjectMatcher.cs39
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticMeshFusionSource.cs131
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticObjectsCombiner.cs42
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/TrackingTarget.cs7
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/TransformTrackingStrategy.cs30
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/UniversalObjectsCombiner.cs102
-rw-r--r--Thronefall_1_57/Decompile/NGS.MeshFusionPro/VertexBufferUtil.cs124
84 files changed, 5323 insertions, 0 deletions
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/AfterCombineAction.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/AfterCombineAction.cs
new file mode 100644
index 0000000..f586b15
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/AfterCombineAction.cs
@@ -0,0 +1,8 @@
+namespace NGS.MeshFusionPro;
+
+public enum AfterCombineAction
+{
+ DisableComponents,
+ DestroyGameObject,
+ DoNothing
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTree.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTree.cs
new file mode 100644
index 0000000..b7eddf1
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTree.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public abstract class BinaryTree<TNode, TData> where TNode : BinaryTreeNode<TData>
+{
+ private Dictionary<TData, List<TNode>> _dataToNodes;
+
+ public IBinaryTreeNode Root => RootInternal;
+
+ public int Height { get; private set; }
+
+ protected TNode RootInternal { get; private set; }
+
+ public BinaryTree()
+ {
+ Height = 0;
+ _dataToNodes = new Dictionary<TData, List<TNode>>();
+ }
+
+ public void Add(TData data)
+ {
+ if (Root == null)
+ {
+ RootInternal = CreateRoot(data);
+ Height = 1;
+ }
+ if (!Includes(RootInternal, data))
+ {
+ GrowTreeUp(data);
+ }
+ AddData(RootInternal, data, 1);
+ }
+
+ public bool Remove(TData data)
+ {
+ if (!_dataToNodes.TryGetValue(data, out var value))
+ {
+ return false;
+ }
+ foreach (TNode item in value)
+ {
+ item.Remove(data);
+ }
+ return _dataToNodes.Remove(data);
+ }
+
+ protected void GrowTreeUp(TData target)
+ {
+ if (!Includes(RootInternal, target))
+ {
+ RootInternal = ExpandRoot(RootInternal, target);
+ Height++;
+ GrowTreeUp(target);
+ }
+ }
+
+ protected void GrowTreeDown(TNode node, TData target, int depth)
+ {
+ if (node.HasChilds)
+ {
+ throw new Exception("GrowTreeDown::" + depth + " node already has childs");
+ }
+ Bounds bounds = node.Bounds;
+ Vector3 vector;
+ Vector3 size;
+ if (bounds.size.x > bounds.size.y || bounds.size.x > bounds.size.z)
+ {
+ vector = new Vector3(bounds.size.x / 4f, 0f, 0f);
+ size = new Vector3(bounds.size.x / 2f, bounds.size.y, bounds.size.z);
+ }
+ else if (bounds.size.y > bounds.size.x || bounds.size.y > bounds.size.z)
+ {
+ vector = new Vector3(0f, bounds.size.y / 4f, 0f);
+ size = new Vector3(bounds.size.x, bounds.size.y / 2f, bounds.size.z);
+ }
+ else
+ {
+ vector = new Vector3(0f, 0f, bounds.size.z / 4f);
+ size = new Vector3(bounds.size.x, bounds.size.y, bounds.size.z / 2f);
+ }
+ bool flag = depth == Height;
+ TNode val = CreateNode(bounds.center - vector, size, flag);
+ TNode val2 = CreateNode(bounds.center + vector, size, flag);
+ node.SetChilds(val, val2);
+ if (!flag)
+ {
+ if (Intersects(val, target))
+ {
+ GrowTreeDown(val, target, depth + 1);
+ }
+ if (Intersects(val2, target))
+ {
+ GrowTreeDown(val2, target, depth + 1);
+ }
+ }
+ }
+
+ protected void AddData(TNode node, TData data, int depth)
+ {
+ if (node.IsLeaf)
+ {
+ node.Add(data);
+ if (!_dataToNodes.TryGetValue(data, out var value))
+ {
+ value = new List<TNode>();
+ _dataToNodes.Add(data, value);
+ }
+ if (!value.Contains(node))
+ {
+ value.Add(node);
+ }
+ return;
+ }
+ if (!node.HasChilds)
+ {
+ GrowTreeDown(node, data, depth + 1);
+ }
+ TNode node2 = (TNode)node.Left;
+ TNode node3 = (TNode)node.Right;
+ if (Intersects(node2, data))
+ {
+ AddData(node2, data, depth + 1);
+ }
+ if (Intersects(node3, data))
+ {
+ AddData(node3, data, depth + 1);
+ }
+ }
+
+ protected void TreeTraversal(Func<TNode, int, bool> func)
+ {
+ TreeTraversal(RootInternal, 1, func);
+ }
+
+ protected void TreeTraversal(TNode current, int depth, Func<TNode, int, bool> func)
+ {
+ if (func(current, depth) && current.HasChilds)
+ {
+ TreeTraversal((TNode)current.Left, depth + 1, func);
+ TreeTraversal((TNode)current.Right, depth + 1, func);
+ }
+ }
+
+ protected abstract TNode CreateRoot(TData data);
+
+ protected abstract TNode ExpandRoot(TNode root, TData target);
+
+ protected abstract TNode CreateNode(Vector3 center, Vector3 size, bool isLeaf);
+
+ protected abstract bool Intersects(TNode node, TData data);
+
+ protected abstract bool Includes(TNode node, TData data);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeDrawer.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeDrawer.cs
new file mode 100644
index 0000000..87776a2
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeDrawer.cs
@@ -0,0 +1,22 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class BinaryTreeDrawer<TData>
+{
+ public void DrawGizmo(IBinaryTreeNode root, Color color)
+ {
+ Gizmos.color = color;
+ DrawNode(root);
+ }
+
+ private void DrawNode(IBinaryTreeNode node)
+ {
+ Gizmos.DrawWireCube(node.Center, node.Size);
+ if (node.HasChilds)
+ {
+ DrawNode(node.GetLeft());
+ DrawNode(node.GetRight());
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeNode.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeNode.cs
new file mode 100644
index 0000000..4558519
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BinaryTreeNode.cs
@@ -0,0 +1,48 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public abstract class BinaryTreeNode<TData> : IBinaryTreeNode
+{
+ public BinaryTreeNode<TData> Left { get; private set; }
+
+ public BinaryTreeNode<TData> Right { get; private set; }
+
+ public bool IsLeaf { get; private set; }
+
+ public bool HasChilds => Left != null;
+
+ public Vector3 Center { get; private set; }
+
+ public Vector3 Size { get; private set; }
+
+ public Bounds Bounds { get; private set; }
+
+ public BinaryTreeNode(Vector3 center, Vector3 size, bool isLeaf)
+ {
+ Center = center;
+ Size = size;
+ Bounds = new Bounds(center, size);
+ IsLeaf = isLeaf;
+ }
+
+ public IBinaryTreeNode GetLeft()
+ {
+ return Left;
+ }
+
+ public IBinaryTreeNode GetRight()
+ {
+ return Right;
+ }
+
+ public void SetChilds(BinaryTreeNode<TData> left, BinaryTreeNode<TData> right)
+ {
+ Left = left;
+ Right = right;
+ }
+
+ public abstract void Add(TData data);
+
+ public abstract void Remove(TData data);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BoundsHelper.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BoundsHelper.cs
new file mode 100644
index 0000000..012a350
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/BoundsHelper.cs
@@ -0,0 +1,39 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public static class BoundsHelper
+{
+ public static Bounds Transform(this Bounds bounds, Matrix4x4 transform)
+ {
+ Vector3 min = bounds.min;
+ Vector3 max = bounds.max;
+ Vector4 column = transform.GetColumn(3);
+ Vector3 vector = column;
+ Vector3 vector2 = column;
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ float num = transform[i, j];
+ float num2 = num * min[j];
+ float num3 = num * max[j];
+ vector[i] += ((num2 < num3) ? num2 : num3);
+ vector2[i] += ((num2 < num3) ? num3 : num2);
+ }
+ }
+ Bounds result = default(Bounds);
+ result.center = transform.MultiplyPoint3x4(bounds.center);
+ result.size = vector2 - vector;
+ return result;
+ }
+
+ public static bool Contains(this Bounds bounds, Bounds target)
+ {
+ if (bounds.Contains(target.min))
+ {
+ return bounds.Contains(target.max);
+ }
+ return false;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineErrorStrategy.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineErrorStrategy.cs
new file mode 100644
index 0000000..89cfbe3
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineErrorStrategy.cs
@@ -0,0 +1,7 @@
+namespace NGS.MeshFusionPro;
+
+public enum CombineErrorStrategy
+{
+ UndoCombining,
+ Ignore
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineMethod.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineMethod.cs
new file mode 100644
index 0000000..e30d53e
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineMethod.cs
@@ -0,0 +1,6 @@
+namespace NGS.MeshFusionPro;
+
+public enum CombineMethod
+{
+ Simple
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineSource.cs
new file mode 100644
index 0000000..f010062
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineSource.cs
@@ -0,0 +1,92 @@
+using System;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombineSource : ICombineSource<CombinedObject, CombinedObjectPart>, ICombineSource
+{
+ public Vector3 Position { get; private set; }
+
+ public Bounds Bounds { get; private set; }
+
+ public MeshCombineInfo CombineInfo { get; private set; }
+
+ public RendererSettings RendererSettings { get; private set; }
+
+ public event Action<ICombinedObject, ICombinedObjectPart> onCombined;
+
+ public event Action<ICombinedObject, string> onCombineError;
+
+ public event Action<ICombinedObject> onCombineFailed;
+
+ public event Action<CombinedObject, CombinedObjectPart> onCombinedTyped;
+
+ public event Action<CombinedObject, string> onCombineErrorTyped;
+
+ public event Action<CombinedObject> onCombineFailedTyped;
+
+ public CombineSource(GameObject go, int submeshIndex = 0)
+ : this(go.GetComponent<MeshFilter>().mesh, go.GetComponent<MeshRenderer>(), submeshIndex)
+ {
+ }
+
+ public CombineSource(Mesh mesh, MeshRenderer renderer, int submeshIndex = 0)
+ {
+ if (mesh == null)
+ {
+ throw new ArgumentException("Mesh is null");
+ }
+ if (renderer == null)
+ {
+ throw new ArgumentException("Mesh Renderer is null");
+ }
+ if (submeshIndex >= mesh.subMeshCount)
+ {
+ throw new ArgumentException("Submesh index is greater the submeshCount");
+ }
+ MeshCombineInfo info = new MeshCombineInfo(mesh, renderer.localToWorldMatrix, renderer.lightmapScaleOffset, renderer.realtimeLightmapScaleOffset, submeshIndex);
+ RendererSettings settings = new RendererSettings(renderer, submeshIndex);
+ Construct(info, settings, renderer.bounds);
+ }
+
+ public CombineSource(MeshCombineInfo info, RendererSettings settings)
+ : this(info, settings, info.mesh.bounds.Transform(info.transformMatrix))
+ {
+ }
+
+ public CombineSource(MeshCombineInfo info, RendererSettings settings, Bounds bounds)
+ {
+ Construct(info, settings, bounds);
+ }
+
+ private void Construct(MeshCombineInfo info, RendererSettings settings, Bounds bounds)
+ {
+ CombineInfo = info;
+ RendererSettings = settings;
+ Position = info.transformMatrix.GetTranslation();
+ Bounds = bounds;
+ }
+
+ public void Combined(CombinedObject root, CombinedObjectPart part)
+ {
+ this.onCombined?.Invoke(root, part);
+ this.onCombinedTyped?.Invoke(root, part);
+ }
+
+ public void CombineError(CombinedObject root, string errorMessage)
+ {
+ if (this.onCombineError == null && this.onCombinedTyped == null)
+ {
+ Debug.Log("Error during combine " + root.name + ", reason :" + errorMessage);
+ return;
+ }
+ this.onCombineError?.Invoke(root, errorMessage);
+ this.onCombineErrorTyped?.Invoke(root, errorMessage);
+ }
+
+ public void CombineFailed(CombinedObject root)
+ {
+ this.onCombineFailed?.Invoke(root);
+ this.onCombineFailedTyped?.Invoke(root);
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTree.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTree.cs
new file mode 100644
index 0000000..2fd39af
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTree.cs
@@ -0,0 +1,112 @@
+using System;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombineTree : BinaryTree<CombineTreeNode, ICombineSource>
+{
+ private ICombinedMeshFactory _factory;
+
+ private float _leafSize;
+
+ private int _vertexLimit;
+
+ public float LeafSize => _leafSize;
+
+ public int VertexLimit => _vertexLimit;
+
+ public ICombinedMeshFactory CombinedMeshFactory => _factory;
+
+ public event Action<CombinedObject> onStaticCombinedObjectCreated;
+
+ public event Action<DynamicCombinedObject> onDynamicCombinedObjectCreated;
+
+ public event Action<CombinedLODGroup> onCombinedLODGroupCreated;
+
+ public CombineTree(ICombinedMeshFactory factory, float leafSize, int vertexLimit)
+ {
+ _factory = factory;
+ _leafSize = leafSize;
+ _vertexLimit = vertexLimit;
+ }
+
+ public void Combine()
+ {
+ TreeTraversal(delegate(CombineTreeNode node, int depth)
+ {
+ node.Combine();
+ return true;
+ });
+ }
+
+ protected override CombineTreeNode CreateRoot(ICombineSource source)
+ {
+ return CreateNode(source.Position, Vector3.one * _leafSize, isLeaf: true);
+ }
+
+ protected override CombineTreeNode CreateNode(Vector3 center, Vector3 size, bool isLeaf)
+ {
+ CombineTreeNode combineTreeNode = new CombineTreeNode(this, center, size, isLeaf);
+ combineTreeNode.onStaticCombinedObjectCreated += this.onStaticCombinedObjectCreated;
+ combineTreeNode.onDynamicCombinedObjectCreated += this.onDynamicCombinedObjectCreated;
+ combineTreeNode.onCombinedLODGroupCreated += this.onCombinedLODGroupCreated;
+ return combineTreeNode;
+ }
+
+ protected override CombineTreeNode ExpandRoot(CombineTreeNode root, ICombineSource target)
+ {
+ Bounds bounds = root.Bounds;
+ Bounds bounds2 = target.Bounds;
+ Vector3 center = Vector3.zero;
+ Vector3 size = Vector3.zero;
+ Vector3 center2 = Vector3.zero;
+ bool flag = false;
+ for (int i = 0; i < 3; i++)
+ {
+ if (bounds2.min[i] < bounds.min[i])
+ {
+ size = bounds.size;
+ size[i] *= 2f;
+ center = bounds.center;
+ center[i] -= bounds.size[i] / 2f;
+ center2 = bounds.center;
+ center2[i] -= bounds.size[i];
+ break;
+ }
+ if (bounds2.max[i] > bounds.max[i])
+ {
+ size = bounds.size;
+ size[i] *= 2f;
+ center = bounds.center;
+ center[i] += bounds.size[i] / 2f;
+ center2 = bounds.center;
+ center2[i] += bounds.size[i];
+ flag = true;
+ break;
+ }
+ }
+ CombineTreeNode combineTreeNode = CreateNode(center, size, isLeaf: false);
+ CombineTreeNode combineTreeNode2 = CreateNode(center2, bounds.size, root.IsLeaf);
+ if (flag)
+ {
+ combineTreeNode.SetChilds(base.RootInternal, combineTreeNode2);
+ }
+ else
+ {
+ combineTreeNode.SetChilds(combineTreeNode2, base.RootInternal);
+ }
+ return combineTreeNode;
+ }
+
+ protected override bool Includes(CombineTreeNode node, ICombineSource source)
+ {
+ Bounds bounds = node.Bounds;
+ Bounds bounds2 = source.Bounds;
+ return bounds.Contains(bounds2);
+ }
+
+ protected override bool Intersects(CombineTreeNode node, ICombineSource source)
+ {
+ return node.Bounds.Contains(source.Position);
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTreeNode.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTreeNode.cs
new file mode 100644
index 0000000..ca4c318
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombineTreeNode.cs
@@ -0,0 +1,45 @@
+using System;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombineTreeNode : BinaryTreeNode<ICombineSource>
+{
+ private CombineTree _tree;
+
+ private UniversalObjectsCombiner _combiner;
+
+ public event Action<CombinedObject> onStaticCombinedObjectCreated;
+
+ public event Action<DynamicCombinedObject> onDynamicCombinedObjectCreated;
+
+ public event Action<CombinedLODGroup> onCombinedLODGroupCreated;
+
+ public CombineTreeNode(CombineTree tree, Vector3 center, Vector3 size, bool isLeaf)
+ : base(center, size, isLeaf)
+ {
+ _tree = tree;
+ }
+
+ public override void Add(ICombineSource source)
+ {
+ if (_combiner == null)
+ {
+ _combiner = new UniversalObjectsCombiner(_tree.CombinedMeshFactory, _tree.VertexLimit);
+ _combiner.onStaticCombinedObjectCreated += this.onStaticCombinedObjectCreated;
+ _combiner.onDynamicCombinedObjectCreated += this.onDynamicCombinedObjectCreated;
+ _combiner.onCombinedLODGroupCreated += this.onCombinedLODGroupCreated;
+ }
+ _combiner.AddSource(source);
+ }
+
+ public override void Remove(ICombineSource source)
+ {
+ _combiner.RemoveSource(source);
+ }
+
+ public void Combine()
+ {
+ _combiner?.Combine();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroup.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroup.cs
new file mode 100644
index 0000000..e5f2a93
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroup.cs
@@ -0,0 +1,265 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedLODGroup : MonoBehaviour, ICombinedObject<CombinedLODGroupPart, LODGroupCombineSource>, ICombinedObject
+{
+ private class LevelOfDetailCombiner : StaticObjectsCombiner
+ {
+ private Transform _transform;
+
+ private CombinedLODGroup _group;
+
+ private Renderer[] _renderers;
+
+ private int _level;
+
+ public LevelOfDetailCombiner(int level, CombinedLODGroup group, ICombinedMeshFactory factory, int vertexLimit)
+ : base(factory, vertexLimit)
+ {
+ _level = level;
+ _group = group;
+ _transform = new GameObject("LOD" + _level).transform;
+ _transform.parent = group.transform;
+ _transform.localPosition = Vector3.zero;
+ }
+
+ public Renderer[] GetRenderers()
+ {
+ if (_renderers == null || _renderers.Length != base.CombinedObjects.Count)
+ {
+ UpdateRenderersList();
+ }
+ return _renderers;
+ }
+
+ public Bounds CalculateBounds()
+ {
+ Bounds result = new Bounds(_group.transform.position, Vector3.zero);
+ GetRenderers();
+ for (int i = 0; i < _renderers.Length; i++)
+ {
+ if (base.CombinedObjects[i].Parts.Count > 0)
+ {
+ result.Encapsulate(_renderers[i].bounds);
+ }
+ }
+ return result;
+ }
+
+ protected override CombinedObject CreateCombinedObject(CombineSource source)
+ {
+ CombinedObject combinedObject = base.CreateCombinedObject(source);
+ combinedObject.transform.parent = _transform;
+ _group._updateLODs = true;
+ return combinedObject;
+ }
+
+ private void UpdateRenderersList()
+ {
+ _renderers = base.CombinedObjects.Select((CombinedObject r) => r.GetComponent<Renderer>()).ToArray();
+ }
+ }
+
+ private LODGroup _group;
+
+ private List<CombinedLODGroupPart> _parts;
+
+ private LevelOfDetailCombiner[] _levelCombiners;
+
+ private LOD[] _lods;
+
+ private Bounds _localBounds;
+
+ private int _lodCount;
+
+ private LODGroupSettings _originalSettings;
+
+ private float _originalBoundsSize;
+
+ private bool _updateLODs;
+
+ IReadOnlyList<ICombinedObjectPart> ICombinedObject.Parts => _parts;
+
+ public IReadOnlyList<CombinedLODGroupPart> Parts => _parts;
+
+ public LODGroupSettings Settings => _originalSettings;
+
+ public Bounds Bounds
+ {
+ get
+ {
+ Bounds localBounds = _localBounds;
+ localBounds.center += base.transform.position;
+ return localBounds;
+ }
+ }
+
+ public static CombinedLODGroup Create(MeshType meshType, CombineMethod combineMethod, LODGroupSettings settings, int vertexLimit = 45000)
+ {
+ return Create(new CombinedMeshFactory(meshType, combineMethod), settings, vertexLimit);
+ }
+
+ public static CombinedLODGroup Create(ICombinedMeshFactory factory, LODGroupSettings settings, int vertexLimit = 45000)
+ {
+ CombinedLODGroup combinedLODGroup = new GameObject("CombinedLODGroup").AddComponent<CombinedLODGroup>();
+ combinedLODGroup.Construct(settings, factory, vertexLimit);
+ return combinedLODGroup;
+ }
+
+ private void Construct(LODGroupSettings settings, ICombinedMeshFactory factory, int vertexLimit)
+ {
+ if (factory == null)
+ {
+ throw new ArgumentException("CombinedLODGroup::factory is null");
+ }
+ _group = base.gameObject.AddComponent<LODGroup>();
+ _parts = new List<CombinedLODGroupPart>();
+ _group.fadeMode = settings.fadeMode;
+ _group.animateCrossFading = settings.animateCrossFading;
+ _originalSettings = settings;
+ _lodCount = _originalSettings.lodCount;
+ _levelCombiners = new LevelOfDetailCombiner[_lodCount];
+ _lods = new LOD[_originalSettings.lodCount];
+ for (int i = 0; i < _originalSettings.lodCount; i++)
+ {
+ _levelCombiners[i] = new LevelOfDetailCombiner(i, this, factory, vertexLimit);
+ _lods[i] = new LOD
+ {
+ fadeTransitionWidth = _originalSettings.fadeTransitionsWidth[i],
+ screenRelativeTransitionHeight = _originalSettings.screenTransitionsHeight[i],
+ renderers = null
+ };
+ }
+ }
+
+ public void Combine(IEnumerable<ICombineSource> sources)
+ {
+ Combine(sources.Select((ICombineSource s) => (LODGroupCombineSource)s));
+ }
+
+ public void Combine(IEnumerable<LODGroupCombineSource> sourceGroups)
+ {
+ if (sourceGroups == null || sourceGroups.Count() == 0)
+ {
+ throw new ArgumentException("CombinedLODGroup::sources is null");
+ }
+ LODGroupCombineSource[] array = sourceGroups.ToArray();
+ if (_parts.Count == 0)
+ {
+ InitBeforeFirstCombine(array);
+ }
+ List<CombinedObjectPart>[] combinedParts = FillCombinersAndCreateBaseParts(array);
+ for (int i = 0; i < _lodCount; i++)
+ {
+ _levelCombiners[i].Combine();
+ }
+ RecalculateBounds();
+ if (_updateLODs)
+ {
+ UpdateLODs();
+ _updateLODs = false;
+ }
+ CreatePartsAndNotifySources(array, combinedParts);
+ }
+
+ public void Destroy(CombinedLODGroupPart part, IList<CombinedObjectPart> baseParts)
+ {
+ if (_parts.Remove(part))
+ {
+ for (int i = 0; i < baseParts.Count; i++)
+ {
+ baseParts[i].Destroy();
+ }
+ RecalculateBounds();
+ }
+ }
+
+ private void InitBeforeFirstCombine(LODGroupCombineSource[] sources)
+ {
+ Vector3 zero = Vector3.zero;
+ for (int i = 0; i < sources.Length; i++)
+ {
+ zero += sources[i].Position;
+ }
+ base.transform.position = zero / sources.Length;
+ _originalBoundsSize = sources[0].Bounds.size.magnitude;
+ }
+
+ private List<CombinedObjectPart>[] FillCombinersAndCreateBaseParts(LODGroupCombineSource[] sourceGroups)
+ {
+ List<CombinedObjectPart>[] parts = new List<CombinedObjectPart>[sourceGroups.Length];
+ for (int i = 0; i < sourceGroups.Length; i++)
+ {
+ LODGroupCombineSource sourceGroup = sourceGroups[i];
+ parts[i] = new List<CombinedObjectPart>();
+ for (int j = 0; j < _lodCount; j++)
+ {
+ CombineSource[] array = sourceGroup.BaseSources[j];
+ foreach (CombineSource obj in array)
+ {
+ int g = i;
+ obj.onCombinedTyped += delegate(CombinedObject o, CombinedObjectPart p)
+ {
+ parts[g].Add(p);
+ };
+ obj.onCombineErrorTyped += delegate(CombinedObject root, string msg)
+ {
+ sourceGroup.CombineError(this, msg);
+ };
+ }
+ _levelCombiners[j].AddSources(array);
+ }
+ }
+ return parts;
+ }
+
+ private void RecalculateBounds()
+ {
+ _localBounds = new Bounds(base.transform.position, Vector3.zero);
+ for (int i = 0; i < _levelCombiners.Length; i++)
+ {
+ _localBounds.Encapsulate(_levelCombiners[i].CalculateBounds());
+ }
+ _localBounds.center -= base.transform.position;
+ }
+
+ private void UpdateLODs()
+ {
+ float value = _localBounds.size.magnitude / _originalBoundsSize;
+ float num = 1f;
+ value = Mathf.Clamp(value, 1f, 100f);
+ for (int i = 0; i < _lodCount; i++)
+ {
+ LOD lOD = _lods[i];
+ lOD.renderers = _levelCombiners[i].GetRenderers();
+ lOD.screenRelativeTransitionHeight = _originalSettings.screenTransitionsHeight[i] * value;
+ if (lOD.screenRelativeTransitionHeight >= num)
+ {
+ num = (lOD.screenRelativeTransitionHeight = num - 0.03f);
+ }
+ _lods[i] = lOD;
+ }
+ _group.SetLODs(_lods);
+ }
+
+ private void CreatePartsAndNotifySources(LODGroupCombineSource[] sourceGroups, List<CombinedObjectPart>[] combinedParts)
+ {
+ for (int i = 0; i < sourceGroups.Length; i++)
+ {
+ LODGroupCombineSource lODGroupCombineSource = sourceGroups[i];
+ List<CombinedObjectPart> list = combinedParts[i];
+ if (list.Count == 0)
+ {
+ lODGroupCombineSource.CombineFailed(this);
+ continue;
+ }
+ CombinedLODGroupPart combinedLODGroupPart = new CombinedLODGroupPart(this, list);
+ _parts.Add(combinedLODGroupPart);
+ lODGroupCombineSource.Combined(this, combinedLODGroupPart);
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupMatcher.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupMatcher.cs
new file mode 100644
index 0000000..ef1b3c7
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupMatcher.cs
@@ -0,0 +1,20 @@
+namespace NGS.MeshFusionPro;
+
+public class CombinedLODGroupMatcher : CombinedObjectMatcher<CombinedLODGroup, LODGroupCombineSource>
+{
+ private LODGroupSettings _settings;
+
+ public override void StartMatching(CombinedLODGroup combinedObject)
+ {
+ _settings = combinedObject.Settings;
+ }
+
+ public override bool CanAddSource(LODGroupCombineSource source)
+ {
+ return source.Settings.IsEqual(_settings, 0.01f, 0.01f);
+ }
+
+ public override void SourceAdded(LODGroupCombineSource source)
+ {
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupPart.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupPart.cs
new file mode 100644
index 0000000..95c9c00
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedLODGroupPart.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedLODGroupPart : ICombinedObjectPart<CombinedLODGroup>, ICombinedObjectPart
+{
+ private List<CombinedObjectPart> _baseParts;
+
+ private Bounds _localBounds;
+
+ ICombinedObject ICombinedObjectPart.Root => Root;
+
+ public CombinedLODGroup Root { get; private set; }
+
+ public Bounds LocalBounds => _localBounds;
+
+ public Bounds Bounds
+ {
+ get
+ {
+ Bounds localBounds = _localBounds;
+ localBounds.center += Root.transform.position;
+ return localBounds;
+ }
+ }
+
+ public CombinedLODGroupPart(CombinedLODGroup root, List<CombinedObjectPart> baseParts)
+ {
+ Root = root;
+ _baseParts = baseParts;
+ CalculateLocalBounds();
+ }
+
+ public void Destroy()
+ {
+ Root.Destroy(this, _baseParts);
+ }
+
+ private void CalculateLocalBounds()
+ {
+ _localBounds = _baseParts[0].Bounds;
+ for (int i = 1; i < _baseParts.Count; i++)
+ {
+ _localBounds.Encapsulate(_baseParts[i].Bounds);
+ }
+ _localBounds.center -= Root.transform.position;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMesh.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMesh.cs
new file mode 100644
index 0000000..fd9933b
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMesh.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedMesh : IDisposable
+{
+ private Mesh _mesh;
+
+ private CombinedMeshDataInternal _meshData;
+
+ private IMeshCombiner _combiner;
+
+ private IMeshCutter _cutter;
+
+ public Mesh Mesh => _mesh;
+
+ public CombinedMeshData MeshData => _meshData;
+
+ public CombinedMesh(IMeshCombiner combiner, IMeshCutter cutter)
+ {
+ if (combiner == null)
+ {
+ throw new ArgumentNullException("MeshCombiner not assigned");
+ }
+ if (cutter == null)
+ {
+ throw new ArgumentNullException("MeshCutter not assigned");
+ }
+ _mesh = new Mesh();
+ _mesh.MarkDynamic();
+ _combiner = combiner;
+ _cutter = cutter;
+ _meshData = CreateMeshData();
+ _meshData.Initialize(this);
+ }
+
+ public CombinedMeshPart[] Combine(IList<MeshCombineInfo> infos)
+ {
+ _combiner.Combine(_mesh, infos);
+ return _meshData.CreateParts(infos);
+ }
+
+ public void Cut(IList<CombinedMeshPart> parts)
+ {
+ MeshCuttingInfo[] array = new MeshCuttingInfo[parts.Count];
+ for (int i = 0; i < parts.Count; i++)
+ {
+ CombinedMeshPart combinedMeshPart = parts[i];
+ array[i] = new MeshCuttingInfo
+ {
+ vertexStart = combinedMeshPart.VertexStart,
+ vertexCount = combinedMeshPart.VertexCount,
+ triangleStart = combinedMeshPart.TrianglesStart,
+ triangleCount = combinedMeshPart.TrianglesCount
+ };
+ }
+ _cutter.Cut(_mesh, array);
+ _meshData.RemoveParts(parts);
+ }
+
+ public void Dispose()
+ {
+ _meshData.Dispose();
+ }
+
+ protected virtual CombinedMeshDataInternal CreateMeshData()
+ {
+ return new CombinedMeshDataInternal();
+ }
+}
+public class CombinedMesh<TCombinedMeshData> : CombinedMesh where TCombinedMeshData : CombinedMeshDataInternal, new()
+{
+ public TCombinedMeshData MeshDataInternal => (TCombinedMeshData)base.MeshData;
+
+ public CombinedMesh(IMeshCombiner combiner, IMeshCutter cutter)
+ : base(combiner, cutter)
+ {
+ }
+
+ protected override CombinedMeshDataInternal CreateMeshData()
+ {
+ return new TCombinedMeshData();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshData.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshData.cs
new file mode 100644
index 0000000..06afc2b
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshData.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public abstract class CombinedMeshData
+{
+ public abstract int PartsCount { get; }
+
+ public abstract int VertexCount { get; }
+
+ public abstract Bounds GetBounds();
+
+ public abstract Bounds GetBounds(CombinedMeshPart part);
+
+ public abstract IEnumerable<CombinedMeshPart> GetParts();
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshDataInternal.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshDataInternal.cs
new file mode 100644
index 0000000..c055f95
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshDataInternal.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedMeshDataInternal : CombinedMeshData, IDisposable
+{
+ private CombinedMesh _root;
+
+ private List<CombinedMeshPartInternal> _parts;
+
+ private int _vertexCount;
+
+ private int _trianglesCount;
+
+ private List<Bounds> _partsBounds;
+
+ private Bounds _boundingBox;
+
+ public override int PartsCount => _parts.Count;
+
+ public override int VertexCount => _vertexCount;
+
+ protected CombinedMesh Root => _root;
+
+ public void Initialize(CombinedMesh root)
+ {
+ _root = root;
+ _parts = new List<CombinedMeshPartInternal>();
+ OnInitialized();
+ }
+
+ public override Bounds GetBounds()
+ {
+ return _boundingBox;
+ }
+
+ public override Bounds GetBounds(CombinedMeshPart part)
+ {
+ return _partsBounds[part.Index];
+ }
+
+ public override IEnumerable<CombinedMeshPart> GetParts()
+ {
+ for (int i = 0; i < _parts.Count; i++)
+ {
+ yield return _parts[i];
+ }
+ }
+
+ public void Dispose()
+ {
+ OnDispose();
+ }
+
+ public CombinedMeshPart[] CreateParts(IList<MeshCombineInfo> infos)
+ {
+ CombinedMeshPart[] array = new CombinedMeshPart[infos.Count];
+ for (int i = 0; i < array.Length; i++)
+ {
+ MeshCombineInfo meshCombineInfo = infos[i];
+ Mesh mesh = meshCombineInfo.mesh;
+ Matrix4x4 transformMatrix = meshCombineInfo.transformMatrix;
+ int vertexCount = _vertexCount;
+ int vertexCount2 = meshCombineInfo.vertexCount;
+ int trianglesCount = _trianglesCount;
+ int trianglesCount2 = meshCombineInfo.trianglesCount;
+ CombinedMeshPartInternal combinedMeshPartInternal = new CombinedMeshPartInternal(_root, _parts.Count, vertexCount, vertexCount2, trianglesCount, trianglesCount2);
+ _parts.Add(combinedMeshPartInternal);
+ array[i] = combinedMeshPartInternal;
+ _vertexCount += vertexCount2;
+ _trianglesCount += trianglesCount2;
+ OnAddPart(combinedMeshPartInternal, mesh, transformMatrix);
+ }
+ OnMeshUpdated();
+ return array;
+ }
+
+ public void RemoveParts(IList<CombinedMeshPart> parts)
+ {
+ for (int i = 0; i < parts.Count; i++)
+ {
+ CombinedMeshPartInternal combinedMeshPartInternal = (CombinedMeshPartInternal)parts[i];
+ OnRemovePart(combinedMeshPartInternal);
+ int num = _parts.IndexOf(combinedMeshPartInternal);
+ int vertexCount = combinedMeshPartInternal.VertexCount;
+ int trianglesCount = combinedMeshPartInternal.TrianglesCount;
+ for (int j = num + 1; j < _parts.Count; j++)
+ {
+ CombinedMeshPartInternal combinedMeshPartInternal2 = _parts[j];
+ combinedMeshPartInternal2.Offset(newVertexStart: combinedMeshPartInternal2.VertexStart - vertexCount, newTrianglesStart: combinedMeshPartInternal2.TrianglesStart - trianglesCount, newIndex: combinedMeshPartInternal2.Index - 1);
+ }
+ _parts.Remove(combinedMeshPartInternal);
+ _vertexCount -= combinedMeshPartInternal.VertexCount;
+ _trianglesCount -= combinedMeshPartInternal.TrianglesCount;
+ }
+ OnMeshUpdated();
+ }
+
+ protected virtual void OnInitialized()
+ {
+ _partsBounds = new List<Bounds>();
+ }
+
+ protected virtual void OnAddPart(CombinedMeshPart part, Mesh mesh, Matrix4x4 transform)
+ {
+ _partsBounds.Add(mesh.bounds.Transform(transform));
+ }
+
+ protected virtual void OnRemovePart(CombinedMeshPart part)
+ {
+ _partsBounds.RemoveAt(part.Index);
+ }
+
+ protected virtual void OnMeshUpdated()
+ {
+ _boundingBox = _root.Mesh.bounds;
+ }
+
+ protected virtual void OnDispose()
+ {
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshFactory.cs
new file mode 100644
index 0000000..850efd8
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshFactory.cs
@@ -0,0 +1,43 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedMeshFactory : ICombinedMeshFactory
+{
+ private IMeshToolsFactory _tools;
+
+ private IMovableCombinedMeshFactory _movableMeshFactory;
+
+ public CombinedMeshFactory(MeshType meshType, CombineMethod combineMethod, MoveMethod moveMethod = MoveMethod.Simple)
+ {
+ if (meshType == MeshType.Standard)
+ {
+ _tools = new SimpleToolsSTDFactory();
+ if (moveMethod == MoveMethod.Simple)
+ {
+ _movableMeshFactory = new SimpleMovableMeshSTDFactory(_tools);
+ }
+ else
+ {
+ _movableMeshFactory = new JobsMovableMeshSTDFactory(_tools);
+ }
+ return;
+ }
+ _tools = new SimpleToolsLWFactory();
+ if (moveMethod == MoveMethod.Simple)
+ {
+ Debug.Log("Simple mover not implemented yet for lightweight meshes. Jobs mover will be used instead");
+ }
+ _movableMeshFactory = new JobsMovableMeshLWFactory(_tools);
+ }
+
+ public CombinedMesh CreateCombinedMesh()
+ {
+ return new CombinedMesh(_tools.CreateMeshCombiner(), _tools.CreateMeshCutter());
+ }
+
+ public CombinedMesh CreateMovableCombinedMesh(out ICombinedMeshMover mover)
+ {
+ return _movableMeshFactory.CreateMovableMesh(out mover);
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPart.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPart.cs
new file mode 100644
index 0000000..9034a26
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPart.cs
@@ -0,0 +1,26 @@
+namespace NGS.MeshFusionPro;
+
+public class CombinedMeshPart
+{
+ public CombinedMesh Root { get; private set; }
+
+ public int Index { get; protected set; }
+
+ public int VertexStart { get; protected set; }
+
+ public int VertexCount { get; protected set; }
+
+ public int TrianglesStart { get; protected set; }
+
+ public int TrianglesCount { get; protected set; }
+
+ public CombinedMeshPart(CombinedMesh root, int index, int vertexStart, int vertexCount, int trianglesStart, int trianglesCount)
+ {
+ Root = root;
+ Index = index;
+ VertexStart = vertexStart;
+ VertexCount = vertexCount;
+ TrianglesStart = trianglesStart;
+ TrianglesCount = trianglesCount;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPartInternal.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPartInternal.cs
new file mode 100644
index 0000000..9bc07cd
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedMeshPartInternal.cs
@@ -0,0 +1,16 @@
+namespace NGS.MeshFusionPro;
+
+public class CombinedMeshPartInternal : CombinedMeshPart
+{
+ public CombinedMeshPartInternal(CombinedMesh root, int index, int vertexStart, int vertexCount, int trianglesStart, int trianglesCount)
+ : base(root, index, vertexStart, vertexCount, trianglesStart, trianglesCount)
+ {
+ }
+
+ public void Offset(int newIndex, int newVertexStart, int newTrianglesStart)
+ {
+ base.Index = newIndex;
+ base.VertexStart = newVertexStart;
+ base.TrianglesStart = newTrianglesStart;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObject.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObject.cs
new file mode 100644
index 0000000..5a7bc43
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObject.cs
@@ -0,0 +1,209 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedObject : MonoBehaviour, ICombinedObject<CombinedObjectPart, CombineSource>, ICombinedObject
+{
+ private CombinedMesh _combinedMesh;
+
+ private CombinedMeshDataInternal _meshData;
+
+ private List<CombinedObjectPart> _parts;
+
+ private List<CombinedMeshPart> _destroyedMeshParts;
+
+ private RendererSettings _rendererSettings;
+
+ private bool _updating;
+
+ IReadOnlyList<ICombinedObjectPart> ICombinedObject.Parts => _parts;
+
+ public IReadOnlyList<CombinedObjectPart> Parts => _parts;
+
+ public RendererSettings RendererSettings => _rendererSettings;
+
+ public Bounds Bounds
+ {
+ get
+ {
+ Bounds localBounds = LocalBounds;
+ localBounds.center += base.transform.position;
+ return localBounds;
+ }
+ }
+
+ public Bounds LocalBounds => _combinedMesh.MeshData.GetBounds();
+
+ public int VertexCount => _combinedMesh.MeshData.VertexCount;
+
+ public bool Updating
+ {
+ get
+ {
+ return _updating;
+ }
+ set
+ {
+ _updating = value;
+ base.enabled = value;
+ }
+ }
+
+ private void Update()
+ {
+ if (!Updating)
+ {
+ base.enabled = false;
+ return;
+ }
+ ForceUpdate();
+ base.enabled = false;
+ }
+
+ private void OnDestroy()
+ {
+ _combinedMesh.Dispose();
+ }
+
+ public static CombinedObject Create(MeshType meshType, CombineMethod combineType, RendererSettings settings)
+ {
+ return Create(new CombinedMeshFactory(meshType, combineType), settings);
+ }
+
+ public static CombinedObject Create(ICombinedMeshFactory factory, RendererSettings settings)
+ {
+ return Create(factory.CreateCombinedMesh(), settings);
+ }
+
+ public static CombinedObject Create(CombinedMesh combinedMesh, RendererSettings settings)
+ {
+ CombinedObject combinedObject = new GameObject("Combined Object").AddComponent<CombinedObject>();
+ combinedObject.Construct(combinedMesh, settings);
+ return combinedObject;
+ }
+
+ private void Construct(CombinedMesh combinedMesh, RendererSettings settings)
+ {
+ _combinedMesh = combinedMesh;
+ _meshData = (CombinedMeshDataInternal)_combinedMesh.MeshData;
+ _parts = new List<CombinedObjectPart>();
+ _destroyedMeshParts = new List<CombinedMeshPart>();
+ _rendererSettings = settings;
+ _updating = true;
+ if (combinedMesh.MeshData.PartsCount > 0)
+ {
+ foreach (CombinedMeshPart part in combinedMesh.MeshData.GetParts())
+ {
+ _parts.Add(new CombinedObjectPart(this, part));
+ }
+ }
+ CreateMeshFilter(_combinedMesh.Mesh);
+ CreateMeshRenderer(settings);
+ }
+
+ public void ForceUpdate()
+ {
+ if (_destroyedMeshParts.Count > 0)
+ {
+ _combinedMesh.Cut(_destroyedMeshParts);
+ _destroyedMeshParts.Clear();
+ }
+ }
+
+ public Bounds GetLocalBounds(CombinedObjectPart part)
+ {
+ return _meshData.GetBounds(part.MeshPart);
+ }
+
+ public Bounds GetBounds(CombinedObjectPart part)
+ {
+ Bounds localBounds = GetLocalBounds(part);
+ localBounds.center += base.transform.position;
+ return localBounds;
+ }
+
+ public void Combine(IEnumerable<ICombineSource> sources)
+ {
+ Combine(sources.Select((ICombineSource s) => (CombineSource)s));
+ }
+
+ public void Combine(IEnumerable<CombineSource> sources)
+ {
+ if (_parts.Count == 0)
+ {
+ base.transform.position = GetAveragePosition(sources);
+ }
+ Vector3 position = base.transform.position;
+ int num = sources.Count();
+ int num2 = 0;
+ MeshCombineInfo[] array = new MeshCombineInfo[num];
+ foreach (CombineSource source in sources)
+ {
+ MeshCombineInfo combineInfo = source.CombineInfo;
+ combineInfo.transformMatrix = combineInfo.transformMatrix.SetTranslation(source.Position - position);
+ array[num2++] = combineInfo;
+ }
+ try
+ {
+ CombinedMeshPart[] array2 = _combinedMesh.Combine(array);
+ num2 = 0;
+ foreach (CombineSource source2 in sources)
+ {
+ CombinedObjectPart combinedObjectPart = new CombinedObjectPart(this, array2[num2]);
+ _parts.Add(combinedObjectPart);
+ source2.Combined(this, combinedObjectPart);
+ num2++;
+ }
+ }
+ catch (Exception ex)
+ {
+ string errorMessage = ex.Message + ex.StackTrace;
+ foreach (CombineSource source3 in sources)
+ {
+ source3.CombineError(this, errorMessage);
+ source3.CombineFailed(this);
+ }
+ }
+ }
+
+ public void Destroy(CombinedObjectPart part)
+ {
+ if (_parts.Remove(part))
+ {
+ _destroyedMeshParts.Add(part.MeshPart);
+ base.enabled = true;
+ }
+ }
+
+ private void CreateMeshFilter(Mesh mesh)
+ {
+ base.gameObject.AddComponent<MeshFilter>().sharedMesh = mesh;
+ }
+
+ private void CreateMeshRenderer(RendererSettings settings)
+ {
+ MeshRenderer meshRenderer = base.gameObject.AddComponent<MeshRenderer>();
+ meshRenderer.sharedMaterial = settings.material;
+ meshRenderer.shadowCastingMode = settings.shadowMode;
+ meshRenderer.receiveShadows = settings.receiveShadows;
+ meshRenderer.lightmapIndex = settings.lightmapIndex;
+ meshRenderer.realtimeLightmapIndex = settings.realtimeLightmapIndex;
+ meshRenderer.tag = settings.tag;
+ meshRenderer.gameObject.layer = settings.layer;
+ }
+
+ private Vector3 GetAveragePosition(IEnumerable<CombineSource> sources)
+ {
+ Vector3 zero = Vector3.zero;
+ int num = 0;
+ foreach (CombineSource source in sources)
+ {
+ zero += source.Position;
+ num++;
+ }
+ return zero / num;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectMatcher.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectMatcher.cs
new file mode 100644
index 0000000..57e39b7
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectMatcher.cs
@@ -0,0 +1,10 @@
+namespace NGS.MeshFusionPro;
+
+public abstract class CombinedObjectMatcher<TCombinedObject, TCombineSource> where TCombinedObject : ICombinedObject where TCombineSource : ICombineSource
+{
+ public abstract void StartMatching(TCombinedObject combinedObject);
+
+ public abstract bool CanAddSource(TCombineSource source);
+
+ public abstract void SourceAdded(TCombineSource source);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectPart.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectPart.cs
new file mode 100644
index 0000000..ca434ff
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/CombinedObjectPart.cs
@@ -0,0 +1,35 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class CombinedObjectPart : ICombinedObjectPart<CombinedObject>, ICombinedObjectPart
+{
+ private bool _destroyed;
+
+ ICombinedObject ICombinedObjectPart.Root => Root;
+
+ public CombinedObject Root { get; private set; }
+
+ public CombinedMeshPart MeshPart { get; private set; }
+
+ public Bounds LocalBounds => Root.GetLocalBounds(this);
+
+ public Bounds Bounds => Root.GetBounds(this);
+
+ public CombinedObjectPart(CombinedObject root, CombinedMeshPart meshPart)
+ {
+ Root = root;
+ MeshPart = meshPart;
+ }
+
+ public void Destroy()
+ {
+ if (_destroyed)
+ {
+ Debug.Log("CombinedPart already destroyed");
+ return;
+ }
+ Root.Destroy(this);
+ _destroyed = true;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombineSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombineSource.cs
new file mode 100644
index 0000000..dcbf244
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombineSource.cs
@@ -0,0 +1,70 @@
+using System;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class DynamicCombineSource : ICombineSource<DynamicCombinedObject, DynamicCombinedObjectPart>, ICombineSource
+{
+ private CombineSource _base;
+
+ public CombineSource Base => _base;
+
+ public Vector3 Position => _base.Position;
+
+ public Bounds Bounds => _base.Bounds;
+
+ public event Action<ICombinedObject, ICombinedObjectPart> onCombined;
+
+ public event Action<ICombinedObject, string> onCombineError;
+
+ public event Action<ICombinedObject> onCombineFailed;
+
+ public event Action<DynamicCombinedObject, DynamicCombinedObjectPart> onCombinedTyped;
+
+ public event Action<DynamicCombinedObject, string> onCombineErrorTyped;
+
+ public event Action<DynamicCombinedObject> onCombineFailedTyped;
+
+ public DynamicCombineSource(GameObject go, int submeshIndex = 0)
+ {
+ _base = new CombineSource(go, submeshIndex);
+ }
+
+ public DynamicCombineSource(Mesh mesh, MeshRenderer renderer, int submeshIndex = 0)
+ {
+ _base = new CombineSource(mesh, renderer, submeshIndex);
+ }
+
+ public DynamicCombineSource(MeshCombineInfo info, RendererSettings settings)
+ {
+ _base = new CombineSource(info, settings);
+ }
+
+ public DynamicCombineSource(MeshCombineInfo info, RendererSettings settings, Bounds bounds)
+ {
+ _base = new CombineSource(info, settings, bounds);
+ }
+
+ public void Combined(DynamicCombinedObject root, DynamicCombinedObjectPart part)
+ {
+ this.onCombined?.Invoke(root, part);
+ this.onCombinedTyped?.Invoke(root, part);
+ }
+
+ public void CombineError(DynamicCombinedObject root, string errorMessage)
+ {
+ if (this.onCombineError == null && this.onCombineErrorTyped == null)
+ {
+ Debug.Log("Error during combine " + root.name + ", reason :" + errorMessage);
+ return;
+ }
+ this.onCombineError?.Invoke(root, errorMessage);
+ this.onCombineErrorTyped?.Invoke(root, errorMessage);
+ }
+
+ public void CombineFailed(DynamicCombinedObject root)
+ {
+ this.onCombineFailed?.Invoke(root);
+ this.onCombineFailedTyped?.Invoke(root);
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObject.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObject.cs
new file mode 100644
index 0000000..464bee8
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObject.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class DynamicCombinedObject : MonoBehaviour, ICombinedObject<DynamicCombinedObjectPart, DynamicCombineSource>, ICombinedObject
+{
+ private CombinedObject _baseObject;
+
+ private List<DynamicCombinedObjectPart> _parts;
+
+ private ICombinedMeshMover _meshMover;
+
+ private List<DynamicCombinedObjectPartInternal> _movedParts;
+
+ private List<PartMoveInfo> _movedPartsData;
+
+ private bool _partsMoved;
+
+ IReadOnlyList<ICombinedObjectPart> ICombinedObject.Parts => _parts;
+
+ public IReadOnlyList<DynamicCombinedObjectPart> Parts => _parts;
+
+ public RendererSettings RendererSettings => _baseObject.RendererSettings;
+
+ public Bounds Bounds => _baseObject.Bounds;
+
+ public Bounds LocalBounds => _baseObject.LocalBounds;
+
+ public int VertexCount => _baseObject.VertexCount;
+
+ private void Update()
+ {
+ if (_movedParts.Count > 0)
+ {
+ if (_meshMover is IAsyncCombinedMeshMover asyncCombinedMeshMover)
+ {
+ asyncCombinedMeshMover.MovePartsAsync(_movedPartsData);
+ }
+ else
+ {
+ _meshMover.MoveParts(_movedPartsData);
+ }
+ for (int i = 0; i < _movedParts.Count; i++)
+ {
+ _movedParts[i].PositionUpdated();
+ }
+ _movedParts.Clear();
+ _movedPartsData.Clear();
+ _partsMoved = true;
+ }
+ }
+
+ private void LateUpdate()
+ {
+ if (_partsMoved)
+ {
+ if (_meshMover is IAsyncCombinedMeshMover asyncCombinedMeshMover)
+ {
+ asyncCombinedMeshMover.FinishAsyncMoving();
+ }
+ _meshMover.ApplyData();
+ _partsMoved = false;
+ }
+ _baseObject.ForceUpdate();
+ if (_movedParts.Count == 0)
+ {
+ base.enabled = false;
+ }
+ }
+
+ private void OnDestroy()
+ {
+ if (_meshMover is IDisposable disposable)
+ {
+ disposable.Dispose();
+ }
+ }
+
+ public static DynamicCombinedObject Create(MeshType meshType, CombineMethod combineMethod, MoveMethod moveMethod, RendererSettings settings)
+ {
+ return Create(new CombinedMeshFactory(meshType, combineMethod, moveMethod), settings);
+ }
+
+ public static DynamicCombinedObject Create(ICombinedMeshFactory factory, RendererSettings settings)
+ {
+ ICombinedMeshMover mover;
+ CombinedObject combinedObject = CombinedObject.Create(factory.CreateMovableCombinedMesh(out mover), settings);
+ DynamicCombinedObject dynamicCombinedObject = combinedObject.gameObject.AddComponent<DynamicCombinedObject>();
+ dynamicCombinedObject.Construct(combinedObject, mover);
+ return dynamicCombinedObject;
+ }
+
+ private void Construct(CombinedObject baseObject, ICombinedMeshMover mover)
+ {
+ base.gameObject.name = "Dynamic Combined Object";
+ _baseObject = baseObject;
+ _meshMover = mover;
+ _parts = new List<DynamicCombinedObjectPart>();
+ _movedParts = new List<DynamicCombinedObjectPartInternal>();
+ _movedPartsData = new List<PartMoveInfo>();
+ _baseObject.Updating = false;
+ }
+
+ public void Combine(IEnumerable<ICombineSource> sources)
+ {
+ Combine(sources.Select((ICombineSource s) => (DynamicCombineSource)s));
+ }
+
+ public void Combine(IEnumerable<DynamicCombineSource> sources)
+ {
+ int num = sources.Count();
+ CombineSource[] array = new CombineSource[num];
+ _ = new DynamicCombinedObjectPart[num];
+ int num2 = 0;
+ foreach (DynamicCombineSource source in sources)
+ {
+ CombineSource baseSource = source.Base;
+ array[num2++] = baseSource;
+ baseSource.onCombinedTyped += delegate(CombinedObject root, CombinedObjectPart part)
+ {
+ DynamicCombinedObjectPart dynamicCombinedObjectPart = new DynamicCombinedObjectPartInternal(this, part, baseSource.CombineInfo.transformMatrix);
+ _parts.Add(dynamicCombinedObjectPart);
+ source.Combined(this, dynamicCombinedObjectPart);
+ };
+ baseSource.onCombineErrorTyped += delegate(CombinedObject root, string message)
+ {
+ source.CombineError(this, message);
+ };
+ baseSource.onCombineFailedTyped += delegate
+ {
+ source.CombineFailed(this);
+ };
+ }
+ _baseObject.Combine(array);
+ }
+
+ public void UpdatePart(DynamicCombinedObjectPartInternal part)
+ {
+ _movedParts.Add(part);
+ _movedPartsData.Add(part.CreateMoveInfo());
+ base.enabled = true;
+ }
+
+ public void Destroy(DynamicCombinedObjectPart dynamicPart, CombinedObjectPart basePart)
+ {
+ if (_parts.Remove(dynamicPart))
+ {
+ basePart.Destroy();
+ base.enabled = true;
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectMatcher.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectMatcher.cs
new file mode 100644
index 0000000..cf76052
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectMatcher.cs
@@ -0,0 +1,39 @@
+namespace NGS.MeshFusionPro;
+
+public class DynamicCombinedObjectMatcher : CombinedObjectMatcher<DynamicCombinedObject, DynamicCombineSource>
+{
+ private RendererSettings _settings;
+
+ private int _vertexCount;
+
+ private int _vertexLimit;
+
+ public DynamicCombinedObjectMatcher(int vertexLimit)
+ {
+ _vertexLimit = vertexLimit;
+ }
+
+ public override void StartMatching(DynamicCombinedObject combinedObject)
+ {
+ _settings = combinedObject.RendererSettings;
+ _vertexCount = combinedObject.VertexCount;
+ }
+
+ public override bool CanAddSource(DynamicCombineSource source)
+ {
+ if (!_settings.Equals(source.Base.RendererSettings))
+ {
+ return false;
+ }
+ if (_vertexCount + source.Base.CombineInfo.vertexCount > _vertexLimit)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public override void SourceAdded(DynamicCombineSource source)
+ {
+ _vertexCount += source.Base.CombineInfo.vertexCount;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPart.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPart.cs
new file mode 100644
index 0000000..c2ff95d
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPart.cs
@@ -0,0 +1,44 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public abstract class DynamicCombinedObjectPart : ICombinedObjectPart<DynamicCombinedObject>, ICombinedObjectPart
+{
+ protected DynamicCombinedObject _root;
+
+ protected CombinedObjectPart _basePart;
+
+ private bool _destroyed;
+
+ ICombinedObject ICombinedObjectPart.Root => Root;
+
+ public DynamicCombinedObject Root => _root;
+
+ public Bounds LocalBounds => _basePart.LocalBounds;
+
+ public Bounds Bounds => _basePart.Bounds;
+
+ public DynamicCombinedObjectPart(DynamicCombinedObject root, CombinedObjectPart basePart, Matrix4x4 transformMatrix)
+ {
+ _root = root;
+ _basePart = basePart;
+ }
+
+ public abstract void Move(Vector3 position, Quaternion rotation, Vector3 scale);
+
+ public abstract void Move(Matrix4x4 transform);
+
+ public abstract void MoveLocal(Matrix4x4 localTransform);
+
+ public void Destroy()
+ {
+ if (_destroyed)
+ {
+ Debug.Log("Part already destroyed");
+ }
+ else
+ {
+ _root.Destroy(this, _basePart);
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPartInternal.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPartInternal.cs
new file mode 100644
index 0000000..d7a0c1c
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicCombinedObjectPartInternal.cs
@@ -0,0 +1,61 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class DynamicCombinedObjectPartInternal : DynamicCombinedObjectPart
+{
+ private Matrix4x4 _localTransform;
+
+ private Matrix4x4 _targetLocalTransform;
+
+ private Matrix4x4 _worldToLocalMatrix;
+
+ private bool _inMove;
+
+ public DynamicCombinedObjectPartInternal(DynamicCombinedObject root, CombinedObjectPart basePart, Matrix4x4 transformMatrix)
+ : base(root, basePart, transformMatrix)
+ {
+ Vector3 pos = transformMatrix.GetTranslation() - root.transform.position;
+ _localTransform = transformMatrix.SetTranslation(pos);
+ _worldToLocalMatrix = base.Root.transform.worldToLocalMatrix;
+ }
+
+ public override void Move(Vector3 position, Quaternion rotation, Vector3 scale)
+ {
+ Move(Matrix4x4.TRS(position, rotation, scale));
+ }
+
+ public override void Move(Matrix4x4 transform)
+ {
+ Matrix4x4 localTransform = _worldToLocalMatrix * transform;
+ MoveLocal(localTransform);
+ }
+
+ public override void MoveLocal(Matrix4x4 localTransform)
+ {
+ if (!_inMove)
+ {
+ _targetLocalTransform = localTransform;
+ _root.UpdatePart(this);
+ _inMove = true;
+ }
+ }
+
+ public PartMoveInfo CreateMoveInfo()
+ {
+ CombinedMeshPart meshPart = _basePart.MeshPart;
+ PartMoveInfo result = default(PartMoveInfo);
+ result.partIndex = meshPart.Index;
+ result.vertexStart = meshPart.VertexStart;
+ result.vertexCount = meshPart.VertexCount;
+ result.currentTransform = _localTransform;
+ result.targetTransform = _targetLocalTransform;
+ return result;
+ }
+
+ public void PositionUpdated()
+ {
+ _localTransform = _targetLocalTransform;
+ _inMove = false;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicMeshFusionSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicMeshFusionSource.cs
new file mode 100644
index 0000000..bf92aec
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicMeshFusionSource.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class DynamicMeshFusionSource : MeshFusionSource
+{
+ [SerializeField]
+ [HideInInspector]
+ private MeshRenderer _renderer;
+
+ [SerializeField]
+ [HideInInspector]
+ private MeshFilter _filter;
+
+ [SerializeField]
+ [HideInInspector]
+ private Mesh _mesh;
+
+ private DynamicCombineSource[] _sources;
+
+ private DynamicCombinedObjectPart[] _parts;
+
+ public override bool TryGetBounds(ref Bounds bounds)
+ {
+ if (_renderer != null)
+ {
+ bounds = _renderer.bounds;
+ return true;
+ }
+ return false;
+ }
+
+ protected override void OnSourceCombinedInternal(ICombinedObject root, ICombinedObjectPart part)
+ {
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ if (_parts[i] == null)
+ {
+ _parts[i] = (DynamicCombinedObjectPart)part;
+ return;
+ }
+ }
+ throw new Exception("Unexpected Behaviour");
+ }
+
+ protected override bool CheckCompatibilityAndGetComponents(out string incompatibilityReason)
+ {
+ incompatibilityReason = "";
+ return CanCreateCombineSource(base.gameObject, ref incompatibilityReason, ref _renderer, ref _filter, ref _mesh);
+ }
+
+ protected override void CreateSources()
+ {
+ if (_sources == null)
+ {
+ _sources = new DynamicCombineSource[_mesh.subMeshCount];
+ }
+ if (_parts == null)
+ {
+ _parts = new DynamicCombinedObjectPart[_mesh.subMeshCount];
+ }
+ for (int i = 0; i < _sources.Length; i++)
+ {
+ _sources[i] = new DynamicCombineSource(_mesh, _renderer, i);
+ }
+ }
+
+ protected override IEnumerable<ICombineSource> GetCombineSources()
+ {
+ if (_sources == null)
+ {
+ yield break;
+ }
+ for (int i = 0; i < _sources.Length; i++)
+ {
+ DynamicCombineSource dynamicCombineSource = _sources[i];
+ if (dynamicCombineSource == null)
+ {
+ break;
+ }
+ yield return dynamicCombineSource;
+ }
+ }
+
+ protected override IEnumerable<ICombinedObjectPart> GetCombinedParts()
+ {
+ if (_parts == null)
+ {
+ yield break;
+ }
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ DynamicCombinedObjectPart dynamicCombinedObjectPart = _parts[i];
+ if (dynamicCombinedObjectPart == null)
+ {
+ break;
+ }
+ yield return dynamicCombinedObjectPart;
+ }
+ }
+
+ protected override void ClearSources()
+ {
+ if (_sources != null)
+ {
+ for (int i = 0; i < _sources.Length && _sources[i] != null; i++)
+ {
+ _sources[i] = null;
+ }
+ }
+ }
+
+ protected override void ClearParts()
+ {
+ if (_parts != null)
+ {
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ _parts[i] = null;
+ }
+ }
+ }
+
+ protected override void ToggleComponents(bool enabled)
+ {
+ _renderer.enabled = enabled;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicObjectsCombiner.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicObjectsCombiner.cs
new file mode 100644
index 0000000..a7d6115
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/DynamicObjectsCombiner.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public class DynamicObjectsCombiner : ObjectsCombiner<DynamicCombinedObject, DynamicCombineSource>
+{
+ private ICombinedMeshFactory _factory;
+
+ private DynamicCombinedObjectMatcher _matcher;
+
+ private int _vertexLimit;
+
+ public DynamicObjectsCombiner(ICombinedMeshFactory factory, int vertexLimit)
+ {
+ _factory = factory;
+ _matcher = new DynamicCombinedObjectMatcher(vertexLimit);
+ _vertexLimit = vertexLimit;
+ }
+
+ public override void AddSource(DynamicCombineSource source)
+ {
+ if (source.Base.CombineInfo.vertexCount < _vertexLimit)
+ {
+ base.AddSource(source);
+ }
+ }
+
+ protected override void CombineSources(DynamicCombinedObject root, IList<DynamicCombineSource> sources)
+ {
+ root.Combine(sources);
+ }
+
+ protected override DynamicCombinedObject CreateCombinedObject(DynamicCombineSource source)
+ {
+ return DynamicCombinedObject.Create(_factory, source.Base.RendererSettings);
+ }
+
+ protected override CombinedObjectMatcher<DynamicCombinedObject, DynamicCombineSource> GetMatcher()
+ {
+ return _matcher;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IAsyncCombinedMeshMover.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IAsyncCombinedMeshMover.cs
new file mode 100644
index 0000000..07f0de8
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IAsyncCombinedMeshMover.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public interface IAsyncCombinedMeshMover : ICombinedMeshMover
+{
+ void MovePartsAsync(IList<PartMoveInfo> moveInfos);
+
+ void FinishAsyncMoving();
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IBinaryTreeNode.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IBinaryTreeNode.cs
new file mode 100644
index 0000000..c25beae
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IBinaryTreeNode.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public interface IBinaryTreeNode
+{
+ Vector3 Center { get; }
+
+ Vector3 Size { get; }
+
+ Bounds Bounds { get; }
+
+ bool HasChilds { get; }
+
+ bool IsLeaf { get; }
+
+ IBinaryTreeNode GetLeft();
+
+ IBinaryTreeNode GetRight();
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombineSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombineSource.cs
new file mode 100644
index 0000000..2b147b7
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombineSource.cs
@@ -0,0 +1,25 @@
+using System;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public interface ICombineSource
+{
+ Vector3 Position { get; }
+
+ Bounds Bounds { get; }
+
+ event Action<ICombinedObject, ICombinedObjectPart> onCombined;
+
+ event Action<ICombinedObject, string> onCombineError;
+
+ event Action<ICombinedObject> onCombineFailed;
+}
+public interface ICombineSource<TCombinedObject, TCombinedPart> : ICombineSource where TCombinedObject : ICombinedObject where TCombinedPart : ICombinedObjectPart
+{
+ event Action<TCombinedObject, TCombinedPart> onCombinedTyped;
+
+ event Action<TCombinedObject, string> onCombineErrorTyped;
+
+ event Action<TCombinedObject> onCombineFailedTyped;
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshFactory.cs
new file mode 100644
index 0000000..98d71f7
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshFactory.cs
@@ -0,0 +1,8 @@
+namespace NGS.MeshFusionPro;
+
+public interface ICombinedMeshFactory
+{
+ CombinedMesh CreateCombinedMesh();
+
+ CombinedMesh CreateMovableCombinedMesh(out ICombinedMeshMover mover);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshMover.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshMover.cs
new file mode 100644
index 0000000..05560a1
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedMeshMover.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public interface ICombinedMeshMover
+{
+ void MoveParts(IList<PartMoveInfo> moveInfos);
+
+ void ApplyData();
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObject.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObject.cs
new file mode 100644
index 0000000..5c2bb55
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObject.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public interface ICombinedObject
+{
+ IReadOnlyList<ICombinedObjectPart> Parts { get; }
+
+ void Combine(IEnumerable<ICombineSource> sources);
+}
+public interface ICombinedObject<TCombinedPart, TCombinedSource> : ICombinedObject where TCombinedPart : ICombinedObjectPart where TCombinedSource : ICombineSource
+{
+ new IReadOnlyList<TCombinedPart> Parts { get; }
+
+ void Combine(IEnumerable<TCombinedSource> sources);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObjectPart.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObjectPart.cs
new file mode 100644
index 0000000..b5a0f08
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ICombinedObjectPart.cs
@@ -0,0 +1,18 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public interface ICombinedObjectPart
+{
+ ICombinedObject Root { get; }
+
+ Bounds Bounds { get; }
+
+ Bounds LocalBounds { get; }
+
+ void Destroy();
+}
+public interface ICombinedObjectPart<TCombinedObject> : ICombinedObjectPart where TCombinedObject : ICombinedObject
+{
+ new TCombinedObject Root { get; }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCombiner.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCombiner.cs
new file mode 100644
index 0000000..ccd84ce
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCombiner.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public interface IMeshCombiner
+{
+ void Combine(Mesh mesh, IList<MeshCombineInfo> combineInfos);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCutter.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCutter.cs
new file mode 100644
index 0000000..f9af704
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshCutter.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public interface IMeshCutter
+{
+ void Cut(Mesh mesh, MeshCuttingInfo cuttingInfo);
+
+ void Cut(Mesh mesh, IList<MeshCuttingInfo> cuttingInfos);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshToolsFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshToolsFactory.cs
new file mode 100644
index 0000000..2d670e2
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMeshToolsFactory.cs
@@ -0,0 +1,8 @@
+namespace NGS.MeshFusionPro;
+
+public interface IMeshToolsFactory
+{
+ IMeshCombiner CreateMeshCombiner();
+
+ IMeshCutter CreateMeshCutter();
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMovableCombinedMeshFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMovableCombinedMeshFactory.cs
new file mode 100644
index 0000000..555d632
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/IMovableCombinedMeshFactory.cs
@@ -0,0 +1,6 @@
+namespace NGS.MeshFusionPro;
+
+public interface IMovableCombinedMeshFactory
+{
+ CombinedMesh CreateMovableMesh(out ICombinedMeshMover mover);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ISourceTrackingStrategy.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ISourceTrackingStrategy.cs
new file mode 100644
index 0000000..ba5db36
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ISourceTrackingStrategy.cs
@@ -0,0 +1,6 @@
+namespace NGS.MeshFusionPro;
+
+public interface ISourceTrackingStrategy
+{
+ bool OnUpdate();
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverLW.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverLW.cs
new file mode 100644
index 0000000..b2ea31d
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverLW.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Collections.Generic;
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Jobs;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class JobsMeshMoverLW : IAsyncCombinedMeshMover, ICombinedMeshMover, IDisposable
+{
+ [BurstCompile]
+ private struct MovePartsJob : IJobParallelFor
+ {
+ [NativeDisableParallelForRestriction]
+ public NativeArray<LightweightVertex> vertices;
+
+ [ReadOnly]
+ public NativeArray<LightweightVertex> localVertices;
+
+ [WriteOnly]
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Bounds> bounds;
+
+ [ReadOnly]
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Bounds> localBounds;
+
+ [ReadOnly]
+ public NativeList<PartMoveInfo> moveInfos;
+
+ public void Execute(int idx)
+ {
+ PartMoveInfo partMoveInfo = moveInfos[idx];
+ int partIndex = partMoveInfo.partIndex;
+ int vertexStart = partMoveInfo.vertexStart;
+ int num = vertexStart + partMoveInfo.vertexCount;
+ Matrix4x4 targetTransform = partMoveInfo.targetTransform;
+ for (int i = vertexStart; i < num; i++)
+ {
+ LightweightVertex lightweightVertex = localVertices[i];
+ float w = lightweightVertex.tanW;
+ Vector3 normalized = targetTransform.MultiplyVector(lightweightVertex.Normal).normalized;
+ Vector4 tangent = targetTransform.MultiplyVector(lightweightVertex.Tangent).normalized;
+ tangent.w = w;
+ LightweightVertex lightweightVertex2 = default(LightweightVertex);
+ lightweightVertex2.Position = targetTransform.MultiplyPoint3x4(lightweightVertex.Position);
+ lightweightVertex2.Normal = normalized;
+ lightweightVertex2.Tangent = tangent;
+ lightweightVertex2.uv = lightweightVertex.uv;
+ lightweightVertex2.uv2 = lightweightVertex.uv2;
+ LightweightVertex value = lightweightVertex2;
+ vertices[i] = value;
+ }
+ bounds[partIndex] = localBounds[partIndex].Transform(targetTransform);
+ }
+ }
+
+ [BurstCompile]
+ private struct RecalculateBoundsJob : IJob
+ {
+ public NativeArray<Bounds> bounds;
+
+ public NativeArray<Bounds> boundingBox;
+
+ public void Execute()
+ {
+ Bounds value = boundingBox[0];
+ value.size = Vector3.zero;
+ for (int i = 0; i < bounds.Length; i++)
+ {
+ value.Encapsulate(bounds[i]);
+ }
+ boundingBox[0] = value;
+ }
+ }
+
+ private MeshDataNativeArraysLW _meshData;
+
+ private NativeList<PartMoveInfo> _moveInfos;
+
+ private JobHandle _handle;
+
+ public JobsMeshMoverLW(MeshDataNativeArraysLW meshData)
+ {
+ _meshData = meshData;
+ _moveInfos = new NativeList<PartMoveInfo>(Allocator.Persistent);
+ }
+
+ public void MoveParts(IList<PartMoveInfo> moveInfos)
+ {
+ MovePartsAsync(moveInfos);
+ FinishAsyncMoving();
+ }
+
+ public void MovePartsAsync(IList<PartMoveInfo> moveInfos)
+ {
+ NativeArray<Bounds> bounds = _meshData.Bounds;
+ bounds[0] = new Bounds(_meshData.GetBounds().center, Vector3.zero);
+ _moveInfos.Clear();
+ for (int i = 0; i < moveInfos.Count; i++)
+ {
+ ref NativeList<PartMoveInfo> moveInfos2 = ref _moveInfos;
+ PartMoveInfo value = moveInfos[i];
+ moveInfos2.Add(in value);
+ }
+ MovePartsJob movePartsJob = default(MovePartsJob);
+ movePartsJob.vertices = _meshData.Vertices;
+ movePartsJob.bounds = _meshData.PartsBounds;
+ movePartsJob.localVertices = _meshData.VerticesLocal;
+ movePartsJob.localBounds = _meshData.PartsBoundsLocal;
+ movePartsJob.moveInfos = _moveInfos;
+ MovePartsJob jobData = movePartsJob;
+ RecalculateBoundsJob recalculateBoundsJob = default(RecalculateBoundsJob);
+ recalculateBoundsJob.bounds = _meshData.PartsBounds;
+ recalculateBoundsJob.boundingBox = bounds;
+ RecalculateBoundsJob jobData2 = recalculateBoundsJob;
+ _handle = jobData2.Schedule(IJobParallelForExtensions.Schedule(jobData, _moveInfos.Length, 4));
+ }
+
+ public void FinishAsyncMoving()
+ {
+ _handle.Complete();
+ }
+
+ public void ApplyData()
+ {
+ if (!_handle.IsCompleted)
+ {
+ FinishAsyncMoving();
+ }
+ _meshData.ApplyDataToMesh();
+ }
+
+ public void Dispose()
+ {
+ _moveInfos.Dispose();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverSTD.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverSTD.cs
new file mode 100644
index 0000000..535b8af
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMeshMoverSTD.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Jobs;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class JobsMeshMoverSTD : IAsyncCombinedMeshMover, ICombinedMeshMover, IDisposable
+{
+ [BurstCompile]
+ private struct MovePartsJob : IJobParallelFor
+ {
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Vector3> vertices;
+
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Vector3> normals;
+
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Vector4> tangents;
+
+ [WriteOnly]
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Bounds> bounds;
+
+ [ReadOnly]
+ [NativeDisableParallelForRestriction]
+ public NativeArray<Bounds> localBounds;
+
+ [ReadOnly]
+ public NativeList<PartMoveInfo> moveInfos;
+
+ public void Execute(int idx)
+ {
+ PartMoveInfo partMoveInfo = moveInfos[idx];
+ int partIndex = partMoveInfo.partIndex;
+ int vertexStart = partMoveInfo.vertexStart;
+ int num = vertexStart + partMoveInfo.vertexCount;
+ Matrix4x4 targetTransform = partMoveInfo.targetTransform;
+ Matrix4x4 inverse = partMoveInfo.currentTransform.inverse;
+ for (int i = vertexStart; i < num; i++)
+ {
+ Vector3 point = vertices[i];
+ Vector3 vector = normals[i];
+ Vector4 vector2 = tangents[i];
+ float w = vector2.w;
+ point = inverse.MultiplyPoint3x4(point);
+ point = targetTransform.MultiplyPoint3x4(point);
+ vector = inverse.MultiplyVector(vector);
+ vector = targetTransform.MultiplyVector(vector);
+ vector2 = inverse.MultiplyVector(vector2);
+ vector2 = targetTransform.MultiplyVector(vector2);
+ vector2.w = w;
+ vertices[i] = point;
+ normals[i] = vector;
+ tangents[i] = vector2;
+ }
+ bounds[partIndex] = localBounds[partIndex].Transform(targetTransform);
+ }
+ }
+
+ [BurstCompile]
+ private struct RecalculateBoundsJob : IJob
+ {
+ public NativeArray<Bounds> bounds;
+
+ public NativeArray<Bounds> boundingBox;
+
+ public void Execute()
+ {
+ Bounds value = boundingBox[0];
+ for (int i = 0; i < bounds.Length; i++)
+ {
+ value.Encapsulate(bounds[i]);
+ }
+ boundingBox[0] = value;
+ }
+ }
+
+ private MeshDataNativeArraysSTD _meshData;
+
+ private NativeList<PartMoveInfo> _moveInfos;
+
+ private JobHandle _handle;
+
+ public JobsMeshMoverSTD(MeshDataNativeArraysSTD meshData)
+ {
+ _meshData = meshData;
+ _moveInfos = new NativeList<PartMoveInfo>(Allocator.Persistent);
+ }
+
+ public void MoveParts(IList<PartMoveInfo> moveInfos)
+ {
+ MovePartsAsync(moveInfos);
+ FinishAsyncMoving();
+ }
+
+ public void MovePartsAsync(IList<PartMoveInfo> moveInfos)
+ {
+ NativeArray<Bounds> bounds = _meshData.Bounds;
+ bounds[0] = new Bounds(_meshData.GetBounds().center, Vector3.zero);
+ _moveInfos.Clear();
+ for (int i = 0; i < moveInfos.Count; i++)
+ {
+ ref NativeList<PartMoveInfo> moveInfos2 = ref _moveInfos;
+ PartMoveInfo value = moveInfos[i];
+ moveInfos2.Add(in value);
+ }
+ MovePartsJob movePartsJob = default(MovePartsJob);
+ movePartsJob.vertices = _meshData.Vertices;
+ movePartsJob.normals = _meshData.Normals;
+ movePartsJob.tangents = _meshData.Tangents;
+ movePartsJob.bounds = _meshData.PartsBounds;
+ movePartsJob.localBounds = _meshData.PartsBoundsLocal;
+ movePartsJob.moveInfos = _moveInfos;
+ MovePartsJob jobData = movePartsJob;
+ RecalculateBoundsJob recalculateBoundsJob = default(RecalculateBoundsJob);
+ recalculateBoundsJob.bounds = _meshData.PartsBounds;
+ recalculateBoundsJob.boundingBox = bounds;
+ RecalculateBoundsJob jobData2 = recalculateBoundsJob;
+ _handle = jobData2.Schedule(IJobParallelForExtensions.Schedule(jobData, _moveInfos.Length, 4));
+ }
+
+ public void FinishAsyncMoving()
+ {
+ _handle.Complete();
+ }
+
+ public void ApplyData()
+ {
+ if (!_handle.IsCompleted)
+ {
+ FinishAsyncMoving();
+ }
+ _meshData.ApplyDataToMesh();
+ }
+
+ public void Dispose()
+ {
+ _moveInfos.Dispose();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshLWFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshLWFactory.cs
new file mode 100644
index 0000000..4790976
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshLWFactory.cs
@@ -0,0 +1,18 @@
+namespace NGS.MeshFusionPro;
+
+public class JobsMovableMeshLWFactory : IMovableCombinedMeshFactory
+{
+ private IMeshToolsFactory _tools;
+
+ public JobsMovableMeshLWFactory(IMeshToolsFactory tools)
+ {
+ _tools = tools;
+ }
+
+ public CombinedMesh CreateMovableMesh(out ICombinedMeshMover mover)
+ {
+ CombinedMesh<MeshDataNativeArraysLW> combinedMesh = new CombinedMesh<MeshDataNativeArraysLW>(_tools.CreateMeshCombiner(), _tools.CreateMeshCutter());
+ mover = new JobsMeshMoverLW(combinedMesh.MeshDataInternal);
+ return combinedMesh;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshSTDFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshSTDFactory.cs
new file mode 100644
index 0000000..36402f5
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/JobsMovableMeshSTDFactory.cs
@@ -0,0 +1,18 @@
+namespace NGS.MeshFusionPro;
+
+public class JobsMovableMeshSTDFactory : IMovableCombinedMeshFactory
+{
+ private IMeshToolsFactory _tools;
+
+ public JobsMovableMeshSTDFactory(IMeshToolsFactory tools)
+ {
+ _tools = tools;
+ }
+
+ public CombinedMesh CreateMovableMesh(out ICombinedMeshMover mover)
+ {
+ CombinedMesh<MeshDataNativeArraysSTD> combinedMesh = new CombinedMesh<MeshDataNativeArraysSTD>(_tools.CreateMeshCombiner(), _tools.CreateMeshCutter());
+ mover = new JobsMeshMoverSTD(combinedMesh.MeshDataInternal);
+ return combinedMesh;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupCombineSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupCombineSource.cs
new file mode 100644
index 0000000..66c640b
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupCombineSource.cs
@@ -0,0 +1,106 @@
+using System;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class LODGroupCombineSource : ICombineSource<CombinedLODGroup, CombinedLODGroupPart>, ICombineSource
+{
+ private Bounds _bounds;
+
+ private LODGroupSettings _settings;
+
+ private CombineSource[][] _sources;
+
+ public Vector3 Position { get; private set; }
+
+ public Bounds Bounds => _bounds;
+
+ public LODGroup LODGroup { get; private set; }
+
+ public LODGroupSettings Settings => _settings;
+
+ public CombineSource[][] BaseSources => _sources;
+
+ public event Action<ICombinedObject, ICombinedObjectPart> onCombined;
+
+ public event Action<ICombinedObject, string> onCombineError;
+
+ public event Action<ICombinedObject> onCombineFailed;
+
+ public event Action<CombinedLODGroup, CombinedLODGroupPart> onCombinedTyped;
+
+ public event Action<CombinedLODGroup, string> onCombineErrorTyped;
+
+ public event Action<CombinedLODGroup> onCombineFailedTyped;
+
+ public LODGroupCombineSource(LODGroup group)
+ {
+ LODGroup = group;
+ Position = group.transform.position;
+ LOD[] lODs = group.GetLODs();
+ _settings = new LODGroupSettings(group);
+ _sources = new CombineSource[_settings.lodCount][];
+ _bounds = new Bounds(group.localReferencePoint + Position, Vector3.zero);
+ for (int i = 0; i < lODs.Length; i++)
+ {
+ Renderer[] renderers = lODs[i].renderers;
+ CreateSourcesArray(i, renderers);
+ FillSources(i, renderers);
+ }
+ }
+
+ public void Combined(CombinedLODGroup root, CombinedLODGroupPart part)
+ {
+ this.onCombined?.Invoke(root, part);
+ this.onCombinedTyped?.Invoke(root, part);
+ }
+
+ public void CombineError(CombinedLODGroup root, string errorMessage)
+ {
+ if (this.onCombineError == null && this.onCombineErrorTyped == null)
+ {
+ Debug.Log("Combine error occured : " + root.name + ", reason : " + errorMessage);
+ return;
+ }
+ this.onCombineError?.Invoke(root, errorMessage);
+ this.onCombineErrorTyped?.Invoke(root, errorMessage);
+ }
+
+ public void CombineFailed(CombinedLODGroup root)
+ {
+ this.onCombineFailed?.Invoke(root);
+ this.onCombineFailedTyped?.Invoke(root);
+ }
+
+ private void CreateSourcesArray(int level, Renderer[] renderers)
+ {
+ int num = 0;
+ for (int i = 0; i < renderers.Length; i++)
+ {
+ if (!(renderers[i] == null))
+ {
+ num += renderers[i].sharedMaterials.Length;
+ }
+ }
+ _sources[level] = new CombineSource[num];
+ }
+
+ private void FillSources(int level, Renderer[] renderers)
+ {
+ int num = 0;
+ for (int i = 0; i < renderers.Length; i++)
+ {
+ MeshRenderer meshRenderer = (MeshRenderer)renderers[i];
+ if (!(meshRenderer == null))
+ {
+ Mesh sharedMesh = meshRenderer.GetComponent<MeshFilter>().sharedMesh;
+ for (int j = 0; j < sharedMesh.subMeshCount; j++)
+ {
+ _sources[level][num] = new CombineSource(sharedMesh, meshRenderer, j);
+ num++;
+ }
+ _bounds.Encapsulate(meshRenderer.bounds);
+ }
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupSettings.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupSettings.cs
new file mode 100644
index 0000000..b0d123f
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupSettings.cs
@@ -0,0 +1,63 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public struct LODGroupSettings
+{
+ public float size;
+
+ public int lodCount;
+
+ public LODFadeMode fadeMode;
+
+ public bool animateCrossFading;
+
+ public float[] screenTransitionsHeight;
+
+ public float[] fadeTransitionsWidth;
+
+ public LODGroupSettings(LODGroup group)
+ {
+ size = group.size;
+ lodCount = group.lodCount;
+ fadeMode = group.fadeMode;
+ animateCrossFading = group.animateCrossFading;
+ screenTransitionsHeight = new float[lodCount];
+ fadeTransitionsWidth = new float[lodCount];
+ LOD[] lODs = group.GetLODs();
+ for (int i = 0; i < lodCount; i++)
+ {
+ LOD lOD = lODs[i];
+ screenTransitionsHeight[i] = lOD.screenRelativeTransitionHeight;
+ fadeTransitionsWidth[i] = lOD.fadeTransitionWidth;
+ }
+ }
+
+ public bool IsEqual(LODGroupSettings settings, float screenHeightThreshold = 0.0001f, float fadeWidthThreshold = 0.0001f)
+ {
+ if (lodCount != settings.lodCount)
+ {
+ return false;
+ }
+ if (fadeMode != settings.fadeMode)
+ {
+ return false;
+ }
+ if (animateCrossFading != settings.animateCrossFading)
+ {
+ return false;
+ }
+ for (int i = 0; i < lodCount; i++)
+ {
+ if (Mathf.Abs(screenTransitionsHeight[i] - settings.screenTransitionsHeight[i]) > screenHeightThreshold)
+ {
+ return false;
+ }
+ if (Mathf.Abs(fadeTransitionsWidth[i] - settings.fadeTransitionsWidth[i]) > fadeWidthThreshold)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupsCombiner.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupsCombiner.cs
new file mode 100644
index 0000000..961bf28
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODGroupsCombiner.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public class LODGroupsCombiner : ObjectsCombiner<CombinedLODGroup, LODGroupCombineSource>
+{
+ private ICombinedMeshFactory _factory;
+
+ private CombinedLODGroupMatcher _matcher;
+
+ private int _vertexLimit;
+
+ public LODGroupsCombiner(ICombinedMeshFactory factory, int vertexLimit)
+ {
+ _factory = factory;
+ _matcher = new CombinedLODGroupMatcher();
+ _vertexLimit = vertexLimit;
+ }
+
+ protected override CombinedLODGroup CreateCombinedObject(LODGroupCombineSource source)
+ {
+ return CombinedLODGroup.Create(_factory, source.Settings, _vertexLimit);
+ }
+
+ protected override void CombineSources(CombinedLODGroup root, IList<LODGroupCombineSource> sources)
+ {
+ root.Combine(sources);
+ }
+
+ protected override CombinedObjectMatcher<CombinedLODGroup, LODGroupCombineSource> GetMatcher()
+ {
+ return _matcher;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODMeshFusionSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODMeshFusionSource.cs
new file mode 100644
index 0000000..4b941b9
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LODMeshFusionSource.cs
@@ -0,0 +1,141 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class LODMeshFusionSource : MeshFusionSource
+{
+ [SerializeField]
+ [HideInInspector]
+ private LODGroup _group;
+
+ private LODGroupCombineSource _source;
+
+ private CombinedLODGroupPart _part;
+
+ private Bounds? _savedBounds;
+
+ public override bool TryGetBounds(ref Bounds bounds)
+ {
+ if (_source != null)
+ {
+ bounds = _source.Bounds;
+ return true;
+ }
+ if (_part != null)
+ {
+ bounds = _part.Bounds;
+ return true;
+ }
+ if (_savedBounds.HasValue)
+ {
+ bounds = _savedBounds.Value;
+ return true;
+ }
+ if (base.IsIncompatible)
+ {
+ return false;
+ }
+ LOD[] lODs = _group.GetLODs();
+ bounds = new Bounds(base.transform.position, Vector3.zero);
+ for (int i = 0; i < lODs.Length; i++)
+ {
+ Renderer[] renderers = lODs[i].renderers;
+ for (int j = 0; j < renderers.Length; j++)
+ {
+ if (!(renderers[j] == null))
+ {
+ bounds.Encapsulate(renderers[j].bounds);
+ }
+ }
+ }
+ _savedBounds = bounds;
+ return true;
+ }
+
+ protected override void OnSourceCombinedInternal(ICombinedObject root, ICombinedObjectPart part)
+ {
+ _part = (CombinedLODGroupPart)part;
+ }
+
+ protected override bool CheckCompatibilityAndGetComponents(out string incompatibilityReason)
+ {
+ if (_group == null)
+ {
+ _group = GetComponent<LODGroup>();
+ }
+ if (_group == null)
+ {
+ incompatibilityReason = "LODGroup not found";
+ return false;
+ }
+ incompatibilityReason = "";
+ MeshFilter filter = null;
+ Mesh mesh = null;
+ LOD[] lODs = _group.GetLODs();
+ for (int i = 0; i < lODs.Length; i++)
+ {
+ Renderer[] renderers = lODs[i].renderers;
+ for (int j = 0; j < renderers.Length; j++)
+ {
+ MeshRenderer renderer = renderers[j] as MeshRenderer;
+ if (!(renderer == null) && !CanCreateCombineSource(renderer.gameObject, ref incompatibilityReason, ref renderer, ref filter, ref mesh))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ protected override void CreateSources()
+ {
+ _source = new LODGroupCombineSource(_group);
+ }
+
+ protected override IEnumerable<ICombineSource> GetCombineSources()
+ {
+ if (_source != null)
+ {
+ yield return _source;
+ }
+ }
+
+ protected override IEnumerable<ICombinedObjectPart> GetCombinedParts()
+ {
+ if (_part != null)
+ {
+ yield return _part;
+ }
+ }
+
+ protected override void ClearSources()
+ {
+ if (_source != null)
+ {
+ _source = null;
+ }
+ }
+
+ protected override void ClearParts()
+ {
+ if (_part != null)
+ {
+ _part = null;
+ }
+ }
+
+ protected override void ToggleComponents(bool enabled)
+ {
+ LOD[] lODs = _group.GetLODs();
+ for (int i = 0; i < lODs.Length; i++)
+ {
+ Renderer[] renderers = lODs[i].renderers;
+ for (int j = 0; j < renderers.Length; j++)
+ {
+ renderers[j].enabled = enabled;
+ }
+ }
+ _group.enabled = enabled;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LightweightVertex.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LightweightVertex.cs
new file mode 100644
index 0000000..5c5de9e
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/LightweightVertex.cs
@@ -0,0 +1,95 @@
+using Unity.Mathematics;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public struct LightweightVertex
+{
+ public float3 pos;
+
+ public sbyte normX;
+
+ public sbyte normY;
+
+ public sbyte normZ;
+
+ public sbyte normW;
+
+ public sbyte tanX;
+
+ public sbyte tanY;
+
+ public sbyte tanZ;
+
+ public sbyte tanW;
+
+ public half2 uv;
+
+ public half2 uv2;
+
+ public Vector3 Position
+ {
+ get
+ {
+ return pos;
+ }
+ set
+ {
+ pos = value;
+ }
+ }
+
+ public Vector3 Normal
+ {
+ get
+ {
+ return new Vector3((float)normX / 127f, (float)normY / 127f, (float)normZ / 127f);
+ }
+ set
+ {
+ normX = (sbyte)(value.x * 127f);
+ normY = (sbyte)(value.y * 127f);
+ normZ = (sbyte)(value.z * 127f);
+ normW = 1;
+ }
+ }
+
+ public Vector4 Tangent
+ {
+ get
+ {
+ return new Vector4((float)tanX / 127f, (float)tanY / 127f, (float)tanZ / 127f, (float)tanW / 127f);
+ }
+ set
+ {
+ tanX = (sbyte)(value.x * 127f);
+ tanY = (sbyte)(value.y * 127f);
+ tanZ = (sbyte)(value.z * 127f);
+ tanW = (sbyte)(value.w * 127f);
+ }
+ }
+
+ public Vector2 UV
+ {
+ get
+ {
+ return new Vector2(uv.x, uv.y);
+ }
+ set
+ {
+ uv = new half2((half)value.x, (half)value.y);
+ }
+ }
+
+ public Vector2 UV2
+ {
+ get
+ {
+ return new Vector2(uv2.x, uv2.y);
+ }
+ set
+ {
+ uv2 = new half2((half)value.x, (half)value.y);
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MatrixHelper.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MatrixHelper.cs
new file mode 100644
index 0000000..feb92b1
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MatrixHelper.cs
@@ -0,0 +1,18 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public static class MatrixHelper
+{
+ public static Vector3 GetTranslation(this Matrix4x4 matrix)
+ {
+ return matrix.GetColumn(3);
+ }
+
+ public static Matrix4x4 SetTranslation(this Matrix4x4 matrix, Vector3 pos)
+ {
+ Matrix4x4 result = matrix;
+ result.SetColumn(3, new Vector4(pos.x, pos.y, pos.z, 1f));
+ return result;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombineInfo.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombineInfo.cs
new file mode 100644
index 0000000..ed879cb
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombineInfo.cs
@@ -0,0 +1,43 @@
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace NGS.MeshFusionPro;
+
+public struct MeshCombineInfo
+{
+ public Mesh mesh;
+
+ public Matrix4x4 transformMatrix;
+
+ public Vector4 lightmapScaleOffset;
+
+ public Vector4 realtimeLightmapScaleOffset;
+
+ public int submeshIndex;
+
+ public readonly int vertexCount;
+
+ public readonly int trianglesCount;
+
+ public MeshCombineInfo(Mesh mesh, int submeshIndex = 0)
+ : this(mesh, Matrix4x4.identity, submeshIndex)
+ {
+ }
+
+ public MeshCombineInfo(Mesh mesh, Matrix4x4 transformMatrix, int submeshIndex = 0)
+ : this(mesh, transformMatrix, new Vector4(1f, 1f, 0f, 0f), new Vector4(1f, 1f, 0f, 0f), submeshIndex)
+ {
+ }
+
+ public MeshCombineInfo(Mesh mesh, Matrix4x4 transformMatrix, Vector4 lightmapScaleOffset, Vector4 realtimeLightmapScaleOffset, int submeshIndex = 0)
+ {
+ this.mesh = mesh;
+ this.transformMatrix = transformMatrix;
+ this.lightmapScaleOffset = lightmapScaleOffset;
+ this.realtimeLightmapScaleOffset = realtimeLightmapScaleOffset;
+ this.submeshIndex = submeshIndex;
+ SubMeshDescriptor subMesh = mesh.GetSubMesh(submeshIndex);
+ vertexCount = subMesh.vertexCount;
+ trianglesCount = subMesh.indexCount;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerBase.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerBase.cs
new file mode 100644
index 0000000..34804fd
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerBase.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public abstract class MeshCombinerBase : IMeshCombiner
+{
+ public void Combine(Mesh mesh, IList<MeshCombineInfo> infos)
+ {
+ ValidateMesh(mesh);
+ ValidateCombineInfos(infos);
+ CombineInternal(mesh, infos);
+ }
+
+ protected abstract void CombineInternal(Mesh mesh, IList<MeshCombineInfo> infos);
+
+ protected virtual void ValidateMesh(Mesh mesh)
+ {
+ if (mesh == null)
+ {
+ throw new ArgumentNullException("mesh");
+ }
+ if (mesh.subMeshCount > 1)
+ {
+ throw new ArgumentException("BaseMeshCombiner::input 'mesh' should have 1 submesh");
+ }
+ }
+
+ protected virtual void ValidateCombineInfos(IList<MeshCombineInfo> infos)
+ {
+ if (infos == null)
+ {
+ throw new ArgumentNullException("MeshCombineInfos is null");
+ }
+ for (int i = 0; i < infos.Count; i++)
+ {
+ if (infos[i].mesh == null)
+ {
+ throw new ArgumentNullException("MeshCombineInfo.mesh is null");
+ }
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleLW.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleLW.cs
new file mode 100644
index 0000000..50e6031
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleLW.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshCombinerSimpleLW : MeshCombinerBase
+{
+ private MeshCombinerSimpleSTD _stdCombiner;
+
+ public MeshCombinerSimpleLW()
+ {
+ _stdCombiner = new MeshCombinerSimpleSTD();
+ }
+
+ protected override void CombineInternal(Mesh mesh, IList<MeshCombineInfo> infos)
+ {
+ VertexBufferUtil.ToStandardBuffer(mesh);
+ try
+ {
+ _stdCombiner.Combine(mesh, infos);
+ VertexBufferUtil.ToLightweightBuffer(mesh);
+ }
+ catch
+ {
+ VertexBufferUtil.ToLightweightBuffer(mesh);
+ throw;
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleSTD.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleSTD.cs
new file mode 100644
index 0000000..3e9fb86
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCombinerSimpleSTD.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshCombinerSimpleSTD : MeshCombinerBase
+{
+ private MeshSeparatorSimple _meshSeparator;
+
+ public MeshCombinerSimpleSTD()
+ {
+ _meshSeparator = new MeshSeparatorSimple();
+ }
+
+ protected override void CombineInternal(Mesh mesh, IList<MeshCombineInfo> infos)
+ {
+ CombineInstance[] array = new CombineInstance[infos.Count + 1];
+ Mesh mesh2 = Object.Instantiate(mesh);
+ array[0] = CreateCombineInstance(new MeshCombineInfo(mesh2));
+ for (int i = 0; i < infos.Count; i++)
+ {
+ array[i + 1] = CreateCombineInstance(infos[i]);
+ }
+ mesh.CombineMeshes(array, mergeSubMeshes: true, useMatrices: true, hasLightmapData: true);
+ }
+
+ private CombineInstance CreateCombineInstance(MeshCombineInfo info)
+ {
+ Mesh mesh = info.mesh;
+ if (mesh.subMeshCount > 1)
+ {
+ mesh = _meshSeparator.GetSubmesh(mesh, info.submeshIndex);
+ }
+ CombineInstance result = default(CombineInstance);
+ result.mesh = mesh;
+ result.subMeshIndex = 0;
+ result.transform = info.transformMatrix;
+ result.lightmapScaleOffset = info.lightmapScaleOffset;
+ result.realtimeLightmapScaleOffset = info.realtimeLightmapScaleOffset;
+ return result;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleLW.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleLW.cs
new file mode 100644
index 0000000..4a70c56
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleLW.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Unity.Collections;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshCutterSimpleLW : IMeshCutter
+{
+ private static List<int> _triangles;
+
+ static MeshCutterSimpleLW()
+ {
+ _triangles = new List<int>();
+ }
+
+ public void Cut(Mesh mesh, MeshCuttingInfo info)
+ {
+ Cut(mesh, new MeshCuttingInfo[1] { info });
+ }
+
+ public void Cut(Mesh mesh, IList<MeshCuttingInfo> infos)
+ {
+ ValidateMeshOrThrowException(mesh);
+ mesh.GetTriangles(_triangles, 0);
+ using (Mesh.MeshDataArray meshDataArray = Mesh.AcquireReadOnlyMeshData(mesh))
+ {
+ NativeArray<LightweightVertex> other = meshDataArray[0].GetVertexData<LightweightVertex>();
+ NativeList<LightweightVertex> nativeList = new NativeList<LightweightVertex>(Allocator.Temp);
+ nativeList.CopyFrom(in other);
+ foreach (MeshCuttingInfo item in infos.OrderByDescending((MeshCuttingInfo i) => i.triangleStart))
+ {
+ nativeList.RemoveRange(item.vertexStart, item.vertexCount);
+ _triangles.RemoveRange(item.triangleStart, item.triangleCount);
+ OffsetTriangles(item);
+ }
+ mesh.SetTriangles(_triangles, 0);
+ mesh.SetVertexBufferData<LightweightVertex>(nativeList, 0, 0, nativeList.Length);
+ }
+ _triangles.Clear();
+ }
+
+ private void ValidateMeshOrThrowException(Mesh mesh)
+ {
+ if (mesh == null)
+ {
+ throw new ArgumentNullException("mesh");
+ }
+ if (mesh.subMeshCount > 1)
+ {
+ throw new ArgumentException("SimpleMeshCutter::'mesh' should has only 1 submesh");
+ }
+ }
+
+ private void OffsetTriangles(MeshCuttingInfo info)
+ {
+ int vertexCount = info.vertexCount;
+ int triangleStart = info.triangleStart;
+ int count = _triangles.Count;
+ for (int i = triangleStart; i < count; i++)
+ {
+ _triangles[i] -= vertexCount;
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleSTD.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleSTD.cs
new file mode 100644
index 0000000..950f0e9
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCutterSimpleSTD.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshCutterSimpleSTD : IMeshCutter
+{
+ private static List<Vector3> _vertices;
+
+ private static List<Vector3> _normals;
+
+ private static List<Vector4> _tangents;
+
+ private static List<int> _triangles;
+
+ private static List<Vector2>[] _uvs;
+
+ private static int _maxUVsCount;
+
+ static MeshCutterSimpleSTD()
+ {
+ _maxUVsCount = 4;
+ _vertices = new List<Vector3>();
+ _normals = new List<Vector3>();
+ _tangents = new List<Vector4>();
+ _triangles = new List<int>();
+ _uvs = new List<Vector2>[_maxUVsCount];
+ for (int i = 0; i < _maxUVsCount; i++)
+ {
+ _uvs[i] = new List<Vector2>();
+ }
+ }
+
+ public void Cut(Mesh mesh, MeshCuttingInfo info)
+ {
+ Cut(mesh, new MeshCuttingInfo[1] { info });
+ }
+
+ public void Cut(Mesh mesh, IList<MeshCuttingInfo> infos)
+ {
+ ValidateMeshOrThrowException(mesh);
+ CollectData(mesh);
+ foreach (MeshCuttingInfo item in infos.OrderByDescending((MeshCuttingInfo i) => i.triangleStart))
+ {
+ RemoveData(item);
+ OffsetTriangles(item);
+ }
+ ApplyDataToMesh(mesh);
+ ClearData();
+ }
+
+ private void ValidateMeshOrThrowException(Mesh mesh)
+ {
+ if (mesh == null)
+ {
+ throw new ArgumentNullException("mesh is null");
+ }
+ if (mesh.subMeshCount > 1)
+ {
+ throw new ArgumentException("SimpleMeshCutter::'mesh' should has only 1 submesh");
+ }
+ }
+
+ private void CollectData(Mesh mesh)
+ {
+ mesh.GetVertices(_vertices);
+ mesh.GetNormals(_normals);
+ mesh.GetTangents(_tangents);
+ mesh.GetTriangles(_triangles, 0);
+ for (int i = 0; i < _maxUVsCount; i++)
+ {
+ mesh.GetUVs(i, _uvs[i]);
+ }
+ }
+
+ private void RemoveData(MeshCuttingInfo cuttingInfo)
+ {
+ int vertexStart = cuttingInfo.vertexStart;
+ int vertexCount = cuttingInfo.vertexCount;
+ _vertices.RemoveRange(vertexStart, vertexCount);
+ if (_normals.Count > 0)
+ {
+ _normals.RemoveRange(vertexStart, vertexCount);
+ }
+ if (_tangents.Count > 0)
+ {
+ _tangents.RemoveRange(vertexStart, vertexCount);
+ }
+ _triangles.RemoveRange(cuttingInfo.triangleStart, cuttingInfo.triangleCount);
+ for (int i = 0; i < _uvs.Length; i++)
+ {
+ if (_uvs[i].Count > 0)
+ {
+ _uvs[i].RemoveRange(vertexStart, vertexCount);
+ }
+ }
+ }
+
+ private void OffsetTriangles(MeshCuttingInfo info)
+ {
+ int vertexCount = info.vertexCount;
+ int triangleStart = info.triangleStart;
+ int count = _triangles.Count;
+ for (int i = triangleStart; i < count; i++)
+ {
+ _triangles[i] -= vertexCount;
+ }
+ }
+
+ private void ApplyDataToMesh(Mesh mesh)
+ {
+ mesh.SetTriangles(_triangles, 0);
+ mesh.SetVertices(_vertices);
+ mesh.SetNormals(_normals);
+ mesh.SetTangents(_tangents);
+ for (int i = 0; i < _maxUVsCount; i++)
+ {
+ if (_uvs[i].Count > 0)
+ {
+ mesh.SetUVs(i, _uvs[i]);
+ }
+ }
+ }
+
+ private void ClearData()
+ {
+ _vertices.Clear();
+ _normals.Clear();
+ _tangents.Clear();
+ _triangles.Clear();
+ for (int i = 0; i < _maxUVsCount; i++)
+ {
+ _uvs[i].Clear();
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCuttingInfo.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCuttingInfo.cs
new file mode 100644
index 0000000..a295571
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshCuttingInfo.cs
@@ -0,0 +1,20 @@
+namespace NGS.MeshFusionPro;
+
+public struct MeshCuttingInfo
+{
+ public int vertexStart;
+
+ public int vertexCount;
+
+ public int triangleStart;
+
+ public int triangleCount;
+
+ public MeshCuttingInfo(int vertexStart, int vertexCount, int triangleStart, int triangleCount)
+ {
+ this.vertexStart = vertexStart;
+ this.vertexCount = vertexCount;
+ this.triangleStart = triangleStart;
+ this.triangleCount = triangleCount;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataListsSTD.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataListsSTD.cs
new file mode 100644
index 0000000..1bf34eb
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataListsSTD.cs
@@ -0,0 +1,83 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshDataListsSTD : CombinedMeshDataInternal
+{
+ private CombinedMesh _root;
+
+ private List<Vector3> _vertices;
+
+ private List<Vector3> _normals;
+
+ private List<Vector4> _tangents;
+
+ private List<Bounds> _partsBounds;
+
+ private List<Bounds> _partsBoundsLocal;
+
+ public List<Vector3> Vertices => _vertices;
+
+ public List<Vector3> Normals => _normals;
+
+ public List<Vector4> Tangents => _tangents;
+
+ public List<Bounds> PartsBounds => _partsBounds;
+
+ public List<Bounds> PartsBoundsLocal => _partsBoundsLocal;
+
+ public Bounds Bounds { get; set; }
+
+ public override Bounds GetBounds()
+ {
+ return Bounds;
+ }
+
+ public override Bounds GetBounds(CombinedMeshPart part)
+ {
+ return _partsBounds[part.Index];
+ }
+
+ public void ApplyDataToMesh()
+ {
+ Mesh mesh = _root.Mesh;
+ mesh.SetVertices(_vertices);
+ mesh.SetNormals(_normals);
+ mesh.SetTangents(_tangents);
+ mesh.bounds = Bounds;
+ }
+
+ protected override void OnInitialized()
+ {
+ _root = base.Root;
+ _vertices = new List<Vector3>();
+ _normals = new List<Vector3>();
+ _tangents = new List<Vector4>();
+ _partsBounds = new List<Bounds>();
+ _partsBoundsLocal = new List<Bounds>();
+ }
+
+ protected override void OnAddPart(CombinedMeshPart part, Mesh mesh, Matrix4x4 transform)
+ {
+ Bounds bounds = mesh.bounds;
+ Bounds item = bounds.Transform(transform);
+ _partsBounds.Add(item);
+ _partsBoundsLocal.Add(bounds);
+ }
+
+ protected override void OnRemovePart(CombinedMeshPart part)
+ {
+ _partsBounds.RemoveAt(part.Index);
+ _partsBoundsLocal.RemoveAt(part.Index);
+ }
+
+ protected override void OnMeshUpdated()
+ {
+ Mesh mesh = _root.Mesh;
+ mesh.GetVertices(_vertices);
+ mesh.GetNormals(_normals);
+ mesh.GetTangents(_tangents);
+ Bounds = mesh.bounds;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysLW.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysLW.cs
new file mode 100644
index 0000000..939d022
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysLW.cs
@@ -0,0 +1,131 @@
+using System.Collections.Generic;
+using Unity.Collections;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshDataNativeArraysLW : CombinedMeshDataInternal
+{
+ private CombinedMesh _root;
+
+ private NativeList<LightweightVertex> _vertices;
+
+ private NativeList<Bounds> _partsBounds;
+
+ private NativeArray<Bounds> _bounds;
+
+ private NativeList<LightweightVertex> _verticesLocal;
+
+ private NativeList<Bounds> _partsBoundsLocal;
+
+ private List<Vector3> _tempVertices;
+
+ private List<Vector3> _tempNormals;
+
+ private List<Vector4> _tempTangents;
+
+ private List<Vector2> _tempUV;
+
+ private List<Vector2> _tempUV2;
+
+ public NativeArray<LightweightVertex> Vertices => _vertices;
+
+ public NativeArray<Bounds> PartsBounds => _partsBounds;
+
+ public NativeArray<Bounds> Bounds => _bounds;
+
+ public NativeArray<LightweightVertex> VerticesLocal => _verticesLocal;
+
+ public NativeArray<Bounds> PartsBoundsLocal => _partsBoundsLocal;
+
+ public override Bounds GetBounds()
+ {
+ return _bounds[0];
+ }
+
+ public override Bounds GetBounds(CombinedMeshPart part)
+ {
+ return _partsBounds[part.Index];
+ }
+
+ public void ApplyDataToMesh()
+ {
+ Mesh mesh = _root.Mesh;
+ mesh.SetVertexBufferData(Vertices, 0, 0, _vertices.Length);
+ mesh.bounds = _bounds[0];
+ }
+
+ protected override void OnInitialized()
+ {
+ _root = base.Root;
+ VertexBufferUtil.ToLightweightBuffer(_root.Mesh);
+ _vertices = new NativeList<LightweightVertex>(Allocator.Persistent);
+ _partsBounds = new NativeList<Bounds>(Allocator.Persistent);
+ _bounds = new NativeArray<Bounds>(1, Allocator.Persistent);
+ _verticesLocal = new NativeList<LightweightVertex>(Allocator.Persistent);
+ _partsBoundsLocal = new NativeList<Bounds>(Allocator.Persistent);
+ _tempVertices = new List<Vector3>();
+ _tempNormals = new List<Vector3>();
+ _tempTangents = new List<Vector4>();
+ _tempUV = new List<Vector2>();
+ _tempUV2 = new List<Vector2>();
+ }
+
+ protected override void OnAddPart(CombinedMeshPart part, Mesh mesh, Matrix4x4 transform)
+ {
+ Bounds value = mesh.bounds;
+ Bounds value2 = value.Transform(transform);
+ _partsBounds.Add(in value2);
+ _partsBoundsLocal.Add(in value);
+ mesh.GetVertices(_tempVertices);
+ mesh.GetNormals(_tempNormals);
+ mesh.GetTangents(_tempTangents);
+ mesh.GetUVs(0, _tempUV);
+ mesh.GetUVs(1, _tempUV2);
+ int vertexCount = mesh.vertexCount;
+ for (int i = 0; i < vertexCount; i++)
+ {
+ LightweightVertex value3 = default(LightweightVertex);
+ value3.Position = _tempVertices[i];
+ value3.Normal = _tempNormals[i];
+ value3.Tangent = _tempTangents[i];
+ if (_tempUV.Count > 0)
+ {
+ value3.UV = _tempUV[i];
+ }
+ if (_tempUV2.Count > 0)
+ {
+ value3.UV2 = _tempUV2[i];
+ }
+ _verticesLocal.Add(in value3);
+ }
+ }
+
+ protected override void OnRemovePart(CombinedMeshPart part)
+ {
+ _partsBounds.RemoveAt(part.Index);
+ _verticesLocal.RemoveRange(part.VertexStart, part.VertexCount);
+ _partsBoundsLocal.RemoveAt(part.Index);
+ }
+
+ protected override void OnMeshUpdated()
+ {
+ Mesh mesh = _root.Mesh;
+ using (Mesh.MeshDataArray meshDataArray = Mesh.AcquireReadOnlyMeshData(mesh))
+ {
+ Mesh.MeshData meshData = meshDataArray[0];
+ _vertices.Clear();
+ _vertices.AddRange(meshData.GetVertexData<LightweightVertex>());
+ }
+ _bounds[0] = mesh.bounds;
+ }
+
+ protected override void OnDispose()
+ {
+ _vertices.Dispose();
+ _partsBounds.Dispose();
+ _bounds.Dispose();
+ _verticesLocal.Dispose();
+ _partsBoundsLocal.Dispose();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysSTD.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysSTD.cs
new file mode 100644
index 0000000..3063894
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshDataNativeArraysSTD.cs
@@ -0,0 +1,104 @@
+using Unity.Collections;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshDataNativeArraysSTD : CombinedMeshDataInternal
+{
+ private CombinedMesh _root;
+
+ private NativeList<Vector3> _vertices;
+
+ private NativeList<Vector3> _normals;
+
+ private NativeList<Vector4> _tangents;
+
+ private NativeList<Bounds> _partsBounds;
+
+ private NativeList<Bounds> _partsBoundsLocal;
+
+ private NativeArray<Bounds> _bounds;
+
+ public NativeArray<Vector3> Vertices => _vertices;
+
+ public NativeArray<Vector3> Normals => _normals;
+
+ public NativeArray<Vector4> Tangents => _tangents;
+
+ public NativeArray<Bounds> PartsBounds => _partsBounds;
+
+ public NativeArray<Bounds> PartsBoundsLocal => _partsBoundsLocal;
+
+ public NativeArray<Bounds> Bounds => _bounds;
+
+ public override Bounds GetBounds()
+ {
+ return _bounds[0];
+ }
+
+ public override Bounds GetBounds(CombinedMeshPart part)
+ {
+ return _partsBounds[part.Index];
+ }
+
+ public void ApplyDataToMesh()
+ {
+ Mesh mesh = _root.Mesh;
+ mesh.SetVertices(Vertices);
+ mesh.SetNormals(Normals);
+ mesh.SetTangents(Tangents);
+ mesh.bounds = _bounds[0];
+ }
+
+ protected override void OnInitialized()
+ {
+ _root = base.Root;
+ _vertices = new NativeList<Vector3>(Allocator.Persistent);
+ _normals = new NativeList<Vector3>(Allocator.Persistent);
+ _tangents = new NativeList<Vector4>(Allocator.Persistent);
+ _partsBounds = new NativeList<Bounds>(Allocator.Persistent);
+ _partsBoundsLocal = new NativeList<Bounds>(Allocator.Persistent);
+ _bounds = new NativeArray<Bounds>(1, Allocator.Persistent);
+ }
+
+ protected override void OnAddPart(CombinedMeshPart part, Mesh mesh, Matrix4x4 transform)
+ {
+ Bounds value = mesh.bounds;
+ Bounds value2 = value.Transform(transform);
+ _partsBounds.Add(in value2);
+ _partsBoundsLocal.Add(in value);
+ }
+
+ protected override void OnRemovePart(CombinedMeshPart part)
+ {
+ _partsBounds.RemoveAt(part.Index);
+ _partsBoundsLocal.RemoveAt(part.Index);
+ }
+
+ protected override void OnMeshUpdated()
+ {
+ Mesh mesh = _root.Mesh;
+ int vertexCount = mesh.vertexCount;
+ _vertices.ResizeUninitialized(vertexCount);
+ _normals.ResizeUninitialized(vertexCount);
+ _tangents.ResizeUninitialized(vertexCount);
+ using (Mesh.MeshDataArray meshDataArray = Mesh.AcquireReadOnlyMeshData(mesh))
+ {
+ Mesh.MeshData meshData = meshDataArray[0];
+ meshData.GetVertices(_vertices);
+ meshData.GetNormals(_normals);
+ meshData.GetTangents(_tangents);
+ }
+ _bounds[0] = mesh.bounds;
+ }
+
+ protected override void OnDispose()
+ {
+ _vertices.Dispose();
+ _normals.Dispose();
+ _tangents.Dispose();
+ _partsBounds.Dispose();
+ _partsBoundsLocal.Dispose();
+ _bounds.Dispose();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshFusionSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshFusionSource.cs
new file mode 100644
index 0000000..555f9e8
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshFusionSource.cs
@@ -0,0 +1,333 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+[DisallowMultipleComponent]
+public abstract class MeshFusionSource : MonoBehaviour
+{
+ private RuntimeMeshFusion _controller;
+
+ private int _combinedSourcesCount;
+
+ private int _failedSourcesCount;
+
+ private int _totalSourcesCount;
+
+ [field: SerializeField]
+ public SourceCombineStatus CombineStatus { get; private set; }
+
+ [field: SerializeField]
+ public int ControllerIndex { get; set; }
+
+ [field: SerializeField]
+ [field: HideInInspector]
+ public bool CombineAtStart { get; set; } = true;
+
+
+ [field: SerializeField]
+ [field: HideInInspector]
+ public CombineErrorStrategy CombineErrorStrategy { get; set; }
+
+ [field: SerializeField]
+ public AfterCombineAction AfterCombineAction { get; set; }
+
+ [field: SerializeField]
+ public bool IsIncompatible { get; private set; }
+
+ [field: SerializeField]
+ public string IncompatibilityReason { get; private set; }
+
+ [field: SerializeField]
+ public bool HasCombineErrors { get; private set; }
+
+ [field: SerializeField]
+ public string CombineErrors { get; private set; }
+
+ public event Action<MeshFusionSource, IEnumerable<ICombinedObjectPart>> onCombineFinished;
+
+ private void Reset()
+ {
+ CheckCompatibility();
+ }
+
+ private void Start()
+ {
+ if (CombineAtStart)
+ {
+ AssignToController();
+ }
+ }
+
+ private void OnDestroy()
+ {
+ Unfreeze();
+ }
+
+ public void Unfreeze()
+ {
+ if (CombineStatus == SourceCombineStatus.AssignedToController)
+ {
+ UnassignFromController();
+ }
+ ClearSourcesAndUnsubscribe();
+ }
+
+ public abstract bool TryGetBounds(ref Bounds bounds);
+
+ public bool CheckCompatibility()
+ {
+ try
+ {
+ string incompatibilityReason;
+ bool flag = CheckCompatibilityAndGetComponents(out incompatibilityReason);
+ IsIncompatible = !flag;
+ IncompatibilityReason = incompatibilityReason;
+ return flag;
+ }
+ catch (Exception ex)
+ {
+ IsIncompatible = true;
+ IncompatibilityReason += $"\n{ex.Message}{ex.StackTrace}";
+ return false;
+ }
+ }
+
+ public bool AssignToController()
+ {
+ try
+ {
+ if (CombineStatus != 0)
+ {
+ return false;
+ }
+ if (!CheckCompatibility())
+ {
+ return false;
+ }
+ _controller = RuntimeMeshFusion.FindByIndex(ControllerIndex);
+ if (_controller == null)
+ {
+ throw new NullReferenceException("RuntimeMeshFusion with index " + ControllerIndex + " not found");
+ }
+ CreateSourcesAndSubscribe();
+ HasCombineErrors = false;
+ CombineErrors = "";
+ _combinedSourcesCount = 0;
+ _failedSourcesCount = 0;
+ _totalSourcesCount = 0;
+ foreach (ICombineSource combineSource in GetCombineSources())
+ {
+ _totalSourcesCount++;
+ _controller.AddSource(combineSource);
+ }
+ CombineStatus = SourceCombineStatus.AssignedToController;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ HasCombineErrors = true;
+ CombineErrors += $"\n{ex.Message}\n{ex.StackTrace}";
+ UnassignFromController();
+ CombineStatus = SourceCombineStatus.FailedToCombine;
+ return false;
+ }
+ }
+
+ public void UndoCombine()
+ {
+ try
+ {
+ foreach (ICombinedObjectPart combinedPart in GetCombinedParts())
+ {
+ combinedPart.Destroy();
+ }
+ foreach (ICombineSource combineSource in GetCombineSources())
+ {
+ combineSource.onCombined += delegate(ICombinedObject root, ICombinedObjectPart part)
+ {
+ part.Destroy();
+ };
+ }
+ UnassignFromController();
+ ClearSourcesAndUnsubscribe();
+ ClearParts();
+ _combinedSourcesCount = 0;
+ _failedSourcesCount = 0;
+ ToggleComponents(enabled: true);
+ CombineStatus = SourceCombineStatus.NotCombined;
+ }
+ catch (Exception ex)
+ {
+ HasCombineErrors = true;
+ CombineErrors += $"\n{ex.Message}\n{ex.StackTrace}";
+ CombineStatus = SourceCombineStatus.FailedToCombine;
+ }
+ }
+
+ private void CreateSourcesAndSubscribe()
+ {
+ CreateSources();
+ foreach (ICombineSource combineSource in GetCombineSources())
+ {
+ combineSource.onCombined += OnSourceCombinedHandler;
+ combineSource.onCombineError += OnCombineErrorHandler;
+ combineSource.onCombineFailed += OnFailedCombineSourceHandler;
+ }
+ }
+
+ private void ClearSourcesAndUnsubscribe()
+ {
+ foreach (ICombineSource combineSource in GetCombineSources())
+ {
+ combineSource.onCombined -= OnSourceCombinedHandler;
+ combineSource.onCombineError -= OnCombineErrorHandler;
+ combineSource.onCombineFailed -= OnFailedCombineSourceHandler;
+ }
+ ClearSources();
+ }
+
+ private void UnassignFromController()
+ {
+ if (_controller != null)
+ {
+ foreach (ICombineSource combineSource in GetCombineSources())
+ {
+ _controller.RemoveSource(combineSource);
+ }
+ }
+ _controller = null;
+ }
+
+ private void OnSourceCombinedHandler(ICombinedObject root, ICombinedObjectPart part)
+ {
+ CombineStatus = SourceCombineStatus.CombinedPartially;
+ _combinedSourcesCount++;
+ OnSourceCombinedInternal(root, part);
+ if (_combinedSourcesCount + _failedSourcesCount == _totalSourcesCount)
+ {
+ OnCombineFinishedHandler();
+ }
+ }
+
+ private void OnCombineErrorHandler(ICombinedObject root, string errorMessage)
+ {
+ HasCombineErrors = true;
+ CombineErrors = CombineErrors + errorMessage + "\n";
+ OnCombineErrorInternal(root, errorMessage);
+ if (CombineErrorStrategy == CombineErrorStrategy.UndoCombining)
+ {
+ UndoCombine();
+ }
+ }
+
+ private void OnFailedCombineSourceHandler(ICombinedObject root)
+ {
+ _failedSourcesCount++;
+ OnFailedCombineSourceInternal(root);
+ if (_combinedSourcesCount + _failedSourcesCount == _totalSourcesCount)
+ {
+ OnCombineFinishedHandler();
+ }
+ }
+
+ private void OnCombineFinishedHandler()
+ {
+ ClearSourcesAndUnsubscribe();
+ if (_combinedSourcesCount == _totalSourcesCount)
+ {
+ CombineStatus = SourceCombineStatus.Combined;
+ }
+ else if (_failedSourcesCount == _totalSourcesCount)
+ {
+ CombineStatus = SourceCombineStatus.FailedToCombine;
+ return;
+ }
+ OnCombineFinishedInternal();
+ this.onCombineFinished?.Invoke(this, GetCombinedParts());
+ if (AfterCombineAction == AfterCombineAction.DisableComponents)
+ {
+ ToggleComponents(enabled: false);
+ }
+ else if (AfterCombineAction == AfterCombineAction.DestroyGameObject)
+ {
+ UnityEngine.Object.Destroy(base.gameObject);
+ }
+ }
+
+ protected virtual void OnSourceCombinedInternal(ICombinedObject root, ICombinedObjectPart part)
+ {
+ }
+
+ protected virtual void OnCombineErrorInternal(ICombinedObject root, string errorMessage)
+ {
+ }
+
+ protected virtual void OnFailedCombineSourceInternal(ICombinedObject root)
+ {
+ }
+
+ protected virtual void OnCombineFinishedInternal()
+ {
+ }
+
+ protected bool CanCreateCombineSource(GameObject go, ref string incompatibilityReason, ref MeshRenderer renderer, ref MeshFilter filter, ref Mesh mesh)
+ {
+ if (renderer == null)
+ {
+ renderer = go.GetComponent<MeshRenderer>();
+ }
+ if (renderer == null)
+ {
+ incompatibilityReason = "MeshRenderer not found";
+ return false;
+ }
+ if (renderer.isPartOfStaticBatch)
+ {
+ incompatibilityReason = "MeshRenderer is PartOfStaticBatching\nDisable Static Batching";
+ return false;
+ }
+ if (filter == null)
+ {
+ filter = go.GetComponent<MeshFilter>();
+ }
+ if (filter == null)
+ {
+ incompatibilityReason = "MeshFilter not found";
+ return false;
+ }
+ mesh = filter.sharedMesh;
+ if (mesh == null)
+ {
+ incompatibilityReason = "Mesh not found";
+ return false;
+ }
+ if (!mesh.isReadable)
+ {
+ incompatibilityReason = "Mesh is not readable. Enable Read/Write in import settings";
+ return false;
+ }
+ if (mesh.subMeshCount != renderer.sharedMaterials.Length)
+ {
+ incompatibilityReason = "Submesh count and Materials count isn't equal";
+ return false;
+ }
+ incompatibilityReason = "";
+ return true;
+ }
+
+ protected abstract bool CheckCompatibilityAndGetComponents(out string incompatibilityReason);
+
+ protected abstract void CreateSources();
+
+ protected abstract void ClearSources();
+
+ protected abstract void ClearParts();
+
+ protected abstract IEnumerable<ICombineSource> GetCombineSources();
+
+ protected abstract IEnumerable<ICombinedObjectPart> GetCombinedParts();
+
+ protected abstract void ToggleComponents(bool enabled);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshSeparatorSimple.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshSeparatorSimple.cs
new file mode 100644
index 0000000..6c79a16
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshSeparatorSimple.cs
@@ -0,0 +1,130 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace NGS.MeshFusionPro;
+
+public class MeshSeparatorSimple
+{
+ private const int MAX_UV_CHANNELS = 4;
+
+ private static Dictionary<Mesh, Mesh[]> _meshToSubmeshes;
+
+ private static List<Vector3> _srcVertices;
+
+ private static List<Vector3> _srcNormals;
+
+ private static List<Vector4> _srcTangents;
+
+ private static List<Vector2> _srcUV;
+
+ private static List<int> _triangles;
+
+ private static List<Vector3> _vertices;
+
+ private static List<Vector3> _normals;
+
+ private static List<Vector4> _tangents;
+
+ private static List<Vector2> _uv;
+
+ static MeshSeparatorSimple()
+ {
+ _meshToSubmeshes = new Dictionary<Mesh, Mesh[]>();
+ _srcVertices = new List<Vector3>();
+ _srcNormals = new List<Vector3>();
+ _srcTangents = new List<Vector4>();
+ _srcUV = new List<Vector2>();
+ _triangles = new List<int>();
+ _vertices = new List<Vector3>();
+ _normals = new List<Vector3>();
+ _tangents = new List<Vector4>();
+ _uv = new List<Vector2>();
+ }
+
+ public Mesh GetSubmesh(Mesh source, int submesh)
+ {
+ if (!_meshToSubmeshes.TryGetValue(source, out var value))
+ {
+ value = Separate(source);
+ _meshToSubmeshes.Add(source, value);
+ }
+ return value[submesh];
+ }
+
+ private Mesh[] Separate(Mesh mesh)
+ {
+ int subMeshCount = mesh.subMeshCount;
+ Mesh[] array = new Mesh[subMeshCount];
+ CollectMeshData(mesh);
+ for (int i = 0; i < subMeshCount; i++)
+ {
+ array[i] = CreateFromSubmesh(mesh, i);
+ }
+ ClearData();
+ return array;
+ }
+
+ private void CollectMeshData(Mesh mesh)
+ {
+ mesh.GetVertices(_srcVertices);
+ mesh.GetNormals(_srcNormals);
+ mesh.GetTangents(_srcTangents);
+ }
+
+ private Mesh CreateFromSubmesh(Mesh mesh, int submesh)
+ {
+ SubMeshDescriptor subMesh = mesh.GetSubMesh(submesh);
+ Mesh mesh2 = new Mesh();
+ int indexCount = subMesh.indexCount;
+ int vertexCount = subMesh.vertexCount;
+ int firstVertex = subMesh.firstVertex;
+ int num = firstVertex + vertexCount;
+ _vertices.Clear();
+ _normals.Clear();
+ _tangents.Clear();
+ mesh.GetIndices(_triangles, submesh);
+ for (int i = firstVertex; i < num; i++)
+ {
+ _vertices.Add(_srcVertices[i]);
+ _normals.Add(_srcNormals[i]);
+ _tangents.Add(_srcTangents[i]);
+ }
+ for (int j = 0; j < indexCount; j++)
+ {
+ _triangles[j] -= firstVertex;
+ }
+ mesh2.SetVertices(_vertices);
+ mesh2.SetNormals(_normals);
+ mesh2.SetTangents(_tangents);
+ mesh2.SetTriangles(_triangles, 0, calculateBounds: false);
+ mesh2.bounds = subMesh.bounds;
+ for (int k = 0; k < 4; k++)
+ {
+ mesh.GetUVs(k, _srcUV);
+ if (_srcUV.Count != 0)
+ {
+ _uv.Clear();
+ for (int l = firstVertex; l < num; l++)
+ {
+ _uv.Add(_srcUV[l]);
+ }
+ mesh2.SetUVs(k, _uv);
+ }
+ }
+ return mesh2;
+ }
+
+ private void ClearData()
+ {
+ _srcVertices.Clear();
+ _srcNormals.Clear();
+ _srcTangents.Clear();
+ _srcUV.Clear();
+ _triangles.Clear();
+ _vertices.Clear();
+ _normals.Clear();
+ _tangents.Clear();
+ _uv.Clear();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshType.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshType.cs
new file mode 100644
index 0000000..63cafe1
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MeshType.cs
@@ -0,0 +1,7 @@
+namespace NGS.MeshFusionPro;
+
+public enum MeshType
+{
+ Standard,
+ Lightweight
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MoveMethod.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MoveMethod.cs
new file mode 100644
index 0000000..27d690f
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/MoveMethod.cs
@@ -0,0 +1,7 @@
+namespace NGS.MeshFusionPro;
+
+public enum MoveMethod
+{
+ Simple,
+ Jobs
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ObjectsCombiner.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ObjectsCombiner.cs
new file mode 100644
index 0000000..6cf2299
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/ObjectsCombiner.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public abstract class ObjectsCombiner<TCombinedObject, TCombineSource> where TCombinedObject : ICombinedObject where TCombineSource : ICombineSource
+{
+ private List<TCombinedObject> _combinedObjects;
+
+ private List<TCombineSource> _sources;
+
+ private List<TCombineSource> _sourcesForCombine;
+
+ public IReadOnlyList<TCombinedObject> CombinedObjects => _combinedObjects;
+
+ public bool ContainSources => _sources.Count > 0;
+
+ public event Action<TCombinedObject> onCombinedObjectCreated;
+
+ protected ObjectsCombiner()
+ {
+ _sources = new List<TCombineSource>();
+ _combinedObjects = new List<TCombinedObject>();
+ _sourcesForCombine = new List<TCombineSource>();
+ }
+
+ public virtual void AddSource(TCombineSource source)
+ {
+ _sources.Add(source);
+ }
+
+ public void AddSources(IEnumerable<TCombineSource> sources)
+ {
+ foreach (TCombineSource source in sources)
+ {
+ AddSource(source);
+ }
+ }
+
+ public void RemoveSource(TCombineSource source)
+ {
+ _sources.Remove(source);
+ }
+
+ public void Combine()
+ {
+ if (_sources.Count != 0)
+ {
+ CleanEmptyData();
+ CombineInternal();
+ _sources.Clear();
+ }
+ }
+
+ private void CleanEmptyData()
+ {
+ int num = 0;
+ while (num < _combinedObjects.Count)
+ {
+ if (_combinedObjects[num] == null)
+ {
+ _combinedObjects.RemoveAt(num);
+ }
+ else
+ {
+ num++;
+ }
+ }
+ num = 0;
+ while (num < _sources.Count)
+ {
+ if (_sources[num] == null)
+ {
+ _sources.RemoveAt(num);
+ }
+ else
+ {
+ num++;
+ }
+ }
+ }
+
+ private void CombineInternal()
+ {
+ _sourcesForCombine.Clear();
+ int num = 0;
+ while (num <= _combinedObjects.Count && _sources.Count != 0)
+ {
+ bool flag = false;
+ TCombinedObject val;
+ if (num == _combinedObjects.Count)
+ {
+ try
+ {
+ val = CreateCombinedObject(_sources[0]);
+ _combinedObjects.Add(val);
+ flag = true;
+ }
+ catch (Exception ex)
+ {
+ Debug.Log("Unable to create CombinedObject : " + ex.Message + ex.StackTrace);
+ _sources.RemoveAt(0);
+ continue;
+ }
+ }
+ else
+ {
+ val = _combinedObjects[num];
+ }
+ CombinedObjectMatcher<TCombinedObject, TCombineSource> matcher = GetMatcher();
+ matcher.StartMatching(val);
+ int num2 = 0;
+ while (num2 < _sources.Count)
+ {
+ TCombineSource val2 = _sources[num2];
+ if (matcher.CanAddSource(val2))
+ {
+ _sourcesForCombine.Add(val2);
+ matcher.SourceAdded(val2);
+ _sources.RemoveAt(num2);
+ }
+ else
+ {
+ num2++;
+ }
+ }
+ if (_sourcesForCombine.Count > 0)
+ {
+ try
+ {
+ CombineSources(val, _sourcesForCombine);
+ _sourcesForCombine.Clear();
+ }
+ catch (Exception ex2)
+ {
+ Debug.Log("Unable to combine sources in ObjectsCombiner : " + ex2.Message + ex2.StackTrace);
+ _sourcesForCombine.Clear();
+ continue;
+ }
+ }
+ if (flag)
+ {
+ this.onCombinedObjectCreated?.Invoke(val);
+ }
+ num++;
+ }
+ }
+
+ protected abstract CombinedObjectMatcher<TCombinedObject, TCombineSource> GetMatcher();
+
+ protected abstract TCombinedObject CreateCombinedObject(TCombineSource source);
+
+ protected abstract void CombineSources(TCombinedObject root, IList<TCombineSource> sources);
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/PartMoveInfo.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/PartMoveInfo.cs
new file mode 100644
index 0000000..776f8ad
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/PartMoveInfo.cs
@@ -0,0 +1,16 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public struct PartMoveInfo
+{
+ public int partIndex;
+
+ public int vertexStart;
+
+ public int vertexCount;
+
+ public Matrix4x4 currentTransform;
+
+ public Matrix4x4 targetTransform;
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererHelper.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererHelper.cs
new file mode 100644
index 0000000..f513a90
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererHelper.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public static class RendererHelper
+{
+ private static List<Material> _materials;
+
+ static RendererHelper()
+ {
+ _materials = new List<Material>();
+ }
+
+ public static Material GetSharedMaterialWithoutAlloc(this Renderer renderer, int index)
+ {
+ renderer.GetSharedMaterials(_materials);
+ return _materials[index];
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererSettings.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererSettings.cs
new file mode 100644
index 0000000..8d29b8c
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RendererSettings.cs
@@ -0,0 +1,43 @@
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace NGS.MeshFusionPro;
+
+public struct RendererSettings
+{
+ public string tag;
+
+ public int layer;
+
+ public Material material;
+
+ public ShadowCastingMode shadowMode;
+
+ public bool receiveShadows;
+
+ public int lightmapIndex;
+
+ public int realtimeLightmapIndex;
+
+ public RendererSettings(Material material, ShadowCastingMode shadowMode = ShadowCastingMode.On, bool receiveShadows = true, int lightmapIndex = -1, int realtimeLightmapIndex = -1, string tag = "Untagged", int layer = 0)
+ {
+ this.material = material;
+ this.shadowMode = shadowMode;
+ this.receiveShadows = receiveShadows;
+ this.lightmapIndex = lightmapIndex;
+ this.realtimeLightmapIndex = realtimeLightmapIndex;
+ this.tag = tag;
+ this.layer = layer;
+ }
+
+ public RendererSettings(Renderer renderer, int materialIndex = 0)
+ {
+ material = renderer.GetSharedMaterialWithoutAlloc(materialIndex);
+ shadowMode = renderer.shadowCastingMode;
+ receiveShadows = renderer.receiveShadows;
+ lightmapIndex = renderer.lightmapIndex;
+ realtimeLightmapIndex = renderer.realtimeLightmapIndex;
+ tag = renderer.tag;
+ layer = renderer.gameObject.layer;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RigidbodyTrackingStrategy.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RigidbodyTrackingStrategy.cs
new file mode 100644
index 0000000..763f666
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RigidbodyTrackingStrategy.cs
@@ -0,0 +1,62 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class RigidbodyTrackingStrategy : ISourceTrackingStrategy
+{
+ private Rigidbody _rigidbody;
+
+ private Transform _transform;
+
+ private DynamicCombinedObjectPart[] _parts;
+
+ private float _velocityThreashold = 0.5f;
+
+ private float _angularVelocityThreashold = 0.3f;
+
+ public float VelocityThreashold
+ {
+ get
+ {
+ return _velocityThreashold;
+ }
+ set
+ {
+ _velocityThreashold = Mathf.Max(0f, value);
+ }
+ }
+
+ public float AngularVelocityThreashold
+ {
+ get
+ {
+ return _angularVelocityThreashold;
+ }
+ set
+ {
+ _angularVelocityThreashold = Mathf.Max(0f, value);
+ }
+ }
+
+ public RigidbodyTrackingStrategy(Rigidbody target, DynamicCombinedObjectPart[] parts)
+ {
+ _rigidbody = target;
+ _transform = target.transform;
+ _parts = parts;
+ }
+
+ public bool OnUpdate()
+ {
+ float magnitude = _rigidbody.velocity.magnitude;
+ float magnitude2 = _rigidbody.angularVelocity.magnitude;
+ if (magnitude > _velocityThreashold || magnitude2 > _angularVelocityThreashold)
+ {
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ _parts[i].Move(_transform.localToWorldMatrix);
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RuntimeMeshFusion.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RuntimeMeshFusion.cs
new file mode 100644
index 0000000..38c811b
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/RuntimeMeshFusion.cs
@@ -0,0 +1,197 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class RuntimeMeshFusion : MonoBehaviour
+{
+ private static List<RuntimeMeshFusion> _Instances;
+
+ [SerializeField]
+ [HideInInspector]
+ private int _controllerIndex;
+
+ [SerializeField]
+ [HideInInspector]
+ private bool _drawGizmo;
+
+ [SerializeField]
+ [HideInInspector]
+ private int _cellSize = 80;
+
+ [SerializeField]
+ [HideInInspector]
+ private int _maxVerticesPerObject = 40000;
+
+ [SerializeField]
+ [HideInInspector]
+ private MeshType _meshType;
+
+ [SerializeField]
+ [HideInInspector]
+ private MoveMethod _moveMethod = MoveMethod.Jobs;
+
+ private CombineTree _combineTree;
+
+ private bool _sourceAdded;
+
+ private BinaryTreeDrawer<ICombineSource> _treeDrawer;
+
+ public int ControllerIndex
+ {
+ get
+ {
+ return _controllerIndex;
+ }
+ set
+ {
+ if (!Application.isPlaying)
+ {
+ _controllerIndex = value;
+ }
+ }
+ }
+
+ public bool DrawGizmo
+ {
+ get
+ {
+ return _drawGizmo;
+ }
+ set
+ {
+ _drawGizmo = value;
+ }
+ }
+
+ public int CellSize
+ {
+ get
+ {
+ return _cellSize;
+ }
+ set
+ {
+ if (!Application.isPlaying)
+ {
+ _cellSize = Mathf.Max(1, value);
+ }
+ }
+ }
+
+ public int MaxVertices
+ {
+ get
+ {
+ return _maxVerticesPerObject;
+ }
+ set
+ {
+ if (!Application.isPlaying)
+ {
+ _maxVerticesPerObject = Mathf.Clamp(value, 500, 65000);
+ }
+ }
+ }
+
+ public MeshType MeshType
+ {
+ get
+ {
+ return _meshType;
+ }
+ set
+ {
+ if (!Application.isPlaying)
+ {
+ _meshType = value;
+ }
+ }
+ }
+
+ public MoveMethod MoveMethod
+ {
+ get
+ {
+ return _moveMethod;
+ }
+ set
+ {
+ if (!Application.isPlaying)
+ {
+ _moveMethod = value;
+ }
+ }
+ }
+
+ private void Awake()
+ {
+ if (_Instances == null)
+ {
+ _Instances = new List<RuntimeMeshFusion>();
+ }
+ _Instances.Add(this);
+ ICombinedMeshFactory factory = new CombinedMeshFactory(_meshType, CombineMethod.Simple, _moveMethod);
+ _combineTree = new CombineTree(factory, _cellSize, _maxVerticesPerObject);
+ _treeDrawer = new BinaryTreeDrawer<ICombineSource>();
+ Transform parent = new GameObject("CombinedObjects").transform;
+ _combineTree.onStaticCombinedObjectCreated += delegate(CombinedObject r)
+ {
+ r.transform.parent = parent;
+ };
+ _combineTree.onDynamicCombinedObjectCreated += delegate(DynamicCombinedObject r)
+ {
+ r.transform.parent = parent;
+ };
+ _combineTree.onCombinedLODGroupCreated += delegate(CombinedLODGroup r)
+ {
+ r.transform.parent = parent;
+ };
+ }
+
+ private void Update()
+ {
+ if (_sourceAdded)
+ {
+ _combineTree.Combine();
+ _sourceAdded = false;
+ }
+ }
+
+ private void OnDrawGizmos()
+ {
+ if (Application.isPlaying && _drawGizmo && _combineTree != null && _combineTree.Root != null)
+ {
+ _treeDrawer.DrawGizmo(_combineTree.Root, Color.white);
+ }
+ }
+
+ private void OnDestroy()
+ {
+ _Instances.Remove(this);
+ }
+
+ public static RuntimeMeshFusion FindByIndex(int index)
+ {
+ for (int i = 0; i < _Instances.Count; i++)
+ {
+ RuntimeMeshFusion runtimeMeshFusion = _Instances[i];
+ if (runtimeMeshFusion.ControllerIndex == index)
+ {
+ return runtimeMeshFusion;
+ }
+ }
+ throw new KeyNotFoundException("MeshFusionController with index : " + index + " not found");
+ }
+
+ public void AddSource(ICombineSource source)
+ {
+ _combineTree.Add(source);
+ _sourceAdded = true;
+ }
+
+ public void RemoveSource(ICombineSource source)
+ {
+ _combineTree.Remove(source);
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMeshMoverSTD.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMeshMoverSTD.cs
new file mode 100644
index 0000000..5a56ec3
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMeshMoverSTD.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class SimpleMeshMoverSTD : ICombinedMeshMover
+{
+ private MeshDataListsSTD _meshData;
+
+ public SimpleMeshMoverSTD(MeshDataListsSTD meshData)
+ {
+ _meshData = meshData;
+ }
+
+ public void MoveParts(IList<PartMoveInfo> moveInfos)
+ {
+ List<Vector3> vertices = _meshData.Vertices;
+ List<Vector3> normals = _meshData.Normals;
+ List<Vector4> tangents = _meshData.Tangents;
+ List<Bounds> partsBounds = _meshData.PartsBounds;
+ List<Bounds> partsBoundsLocal = _meshData.PartsBoundsLocal;
+ Bounds bounds = _meshData.GetBounds();
+ bounds.size = Vector3.zero;
+ for (int i = 0; i < moveInfos.Count; i++)
+ {
+ PartMoveInfo partMoveInfo = moveInfos[i];
+ int partIndex = partMoveInfo.partIndex;
+ int vertexStart = partMoveInfo.vertexStart;
+ int num = vertexStart + partMoveInfo.vertexCount;
+ Matrix4x4 targetTransform = partMoveInfo.targetTransform;
+ Matrix4x4 inverse = partMoveInfo.currentTransform.inverse;
+ for (int j = vertexStart; j < num; j++)
+ {
+ Vector3 point = vertices[j];
+ Vector3 vector = normals[j];
+ Vector4 vector2 = tangents[j];
+ float w = vector2.w;
+ point = inverse.MultiplyPoint3x4(point);
+ point = targetTransform.MultiplyPoint3x4(point);
+ vector = inverse.MultiplyVector(vector);
+ vector = targetTransform.MultiplyVector(vector);
+ vector2 = inverse.MultiplyVector(vector2);
+ vector2 = targetTransform.MultiplyVector(vector2);
+ vector2.w = w;
+ vertices[j] = point;
+ normals[j] = vector;
+ tangents[j] = vector2;
+ }
+ partsBounds[partIndex] = partsBoundsLocal[partIndex].Transform(targetTransform);
+ }
+ for (int k = 0; k < partsBounds.Count; k++)
+ {
+ bounds.Encapsulate(partsBounds[k]);
+ }
+ _meshData.Bounds = bounds;
+ }
+
+ public void ApplyData()
+ {
+ _meshData.ApplyDataToMesh();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMovableMeshSTDFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMovableMeshSTDFactory.cs
new file mode 100644
index 0000000..3454e5e
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleMovableMeshSTDFactory.cs
@@ -0,0 +1,18 @@
+namespace NGS.MeshFusionPro;
+
+public class SimpleMovableMeshSTDFactory : IMovableCombinedMeshFactory
+{
+ private IMeshToolsFactory _tools;
+
+ public SimpleMovableMeshSTDFactory(IMeshToolsFactory tools)
+ {
+ _tools = tools;
+ }
+
+ public CombinedMesh CreateMovableMesh(out ICombinedMeshMover mover)
+ {
+ CombinedMesh<MeshDataListsSTD> combinedMesh = new CombinedMesh<MeshDataListsSTD>(_tools.CreateMeshCombiner(), _tools.CreateMeshCutter());
+ mover = new SimpleMeshMoverSTD(combinedMesh.MeshDataInternal);
+ return combinedMesh;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsLWFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsLWFactory.cs
new file mode 100644
index 0000000..cedbde2
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsLWFactory.cs
@@ -0,0 +1,14 @@
+namespace NGS.MeshFusionPro;
+
+public class SimpleToolsLWFactory : IMeshToolsFactory
+{
+ public IMeshCombiner CreateMeshCombiner()
+ {
+ return new MeshCombinerSimpleLW();
+ }
+
+ public IMeshCutter CreateMeshCutter()
+ {
+ return new MeshCutterSimpleLW();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsSTDFactory.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsSTDFactory.cs
new file mode 100644
index 0000000..ee1ce77
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SimpleToolsSTDFactory.cs
@@ -0,0 +1,14 @@
+namespace NGS.MeshFusionPro;
+
+public class SimpleToolsSTDFactory : IMeshToolsFactory
+{
+ public IMeshCombiner CreateMeshCombiner()
+ {
+ return new MeshCombinerSimpleSTD();
+ }
+
+ public IMeshCutter CreateMeshCutter()
+ {
+ return new MeshCutterSimpleSTD();
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceCombineStatus.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceCombineStatus.cs
new file mode 100644
index 0000000..8aab0cd
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceCombineStatus.cs
@@ -0,0 +1,10 @@
+namespace NGS.MeshFusionPro;
+
+public enum SourceCombineStatus
+{
+ NotCombined,
+ AssignedToController,
+ CombinedPartially,
+ Combined,
+ FailedToCombine
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceTracker.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceTracker.cs
new file mode 100644
index 0000000..571d46d
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/SourceTracker.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+[DisallowMultipleComponent]
+[RequireComponent(typeof(MeshFusionSource))]
+public class SourceTracker : MonoBehaviour
+{
+ [SerializeField]
+ private MeshFusionSource _source;
+
+ [SerializeField]
+ private bool _isDynamicObject;
+
+ [SerializeField]
+ private Rigidbody _rigidbody;
+
+ private IEnumerable<ICombinedObjectPart> _parts;
+
+ private ISourceTrackingStrategy _trackingStrategy;
+
+ private float _idleTime;
+
+ private Action _updateFunc;
+
+ public bool IsDynamicObject => _isDynamicObject;
+
+ [field: SerializeField]
+ public TrackingTarget TrackingTarget { get; set; }
+
+ [field: SerializeField]
+ public bool DisableWhenIdle { get; set; } = true;
+
+
+ [field: SerializeField]
+ [field: Min(0.01f)]
+ public float MaxIdleTime { get; set; } = 5f;
+
+
+ [field: SerializeField]
+ public bool WakeUpWhenCollision { get; set; } = true;
+
+
+ [field: SerializeField]
+ public bool TrackingDestroy { get; set; } = true;
+
+
+ public void WakeUp()
+ {
+ base.enabled = true;
+ _idleTime = 0f;
+ }
+
+ private void Reset()
+ {
+ _source = GetComponent<MeshFusionSource>();
+ _isDynamicObject = _source is DynamicMeshFusionSource;
+ if (TryGetComponent<Rigidbody>(out _rigidbody))
+ {
+ TrackingTarget = TrackingTarget.Rigidbody;
+ }
+ }
+
+ private void Awake()
+ {
+ if (_source == null)
+ {
+ _source = GetComponent<MeshFusionSource>();
+ _isDynamicObject = _source is DynamicMeshFusionSource;
+ }
+ _source.onCombineFinished += OnCombineFinished;
+ base.enabled = false;
+ }
+
+ private void Update()
+ {
+ try
+ {
+ _updateFunc?.Invoke();
+ }
+ catch
+ {
+ if (!_isDynamicObject)
+ {
+ base.enabled = false;
+ return;
+ }
+ throw;
+ }
+ }
+
+ private void OnCollisionEnter(Collision collision)
+ {
+ if (_isDynamicObject && WakeUpWhenCollision && _parts != null)
+ {
+ WakeUp();
+ }
+ }
+
+ private void OnDestroy()
+ {
+ if (!base.gameObject.scene.isLoaded || !TrackingDestroy || _parts == null)
+ {
+ return;
+ }
+ foreach (ICombinedObjectPart part in _parts)
+ {
+ if (part != null && part.Root != null)
+ {
+ part.Destroy();
+ }
+ }
+ }
+
+ private void OnCombineFinished(MeshFusionSource source, IEnumerable<ICombinedObjectPart> parts)
+ {
+ _parts = parts;
+ _source.onCombineFinished -= OnCombineFinished;
+ if (!_isDynamicObject)
+ {
+ return;
+ }
+ _updateFunc = UpdateMoveTracker;
+ if (TrackingTarget == TrackingTarget.Rigidbody && _rigidbody != null)
+ {
+ _trackingStrategy = new RigidbodyTrackingStrategy(_rigidbody, parts.Select((ICombinedObjectPart p) => (DynamicCombinedObjectPart)p).ToArray());
+ if (DisableWhenIdle)
+ {
+ _updateFunc = UpdateMoveTrackerAndCheckIdle;
+ }
+ }
+ else
+ {
+ _trackingStrategy = new TransformTrackingStrategy(base.transform, parts.Select((ICombinedObjectPart p) => (DynamicCombinedObjectPart)p).ToArray());
+ }
+ base.enabled = true;
+ }
+
+ private void UpdateMoveTracker()
+ {
+ _trackingStrategy.OnUpdate();
+ }
+
+ private void UpdateMoveTrackerAndCheckIdle()
+ {
+ if (_trackingStrategy.OnUpdate())
+ {
+ _idleTime = 0f;
+ return;
+ }
+ _idleTime += Time.deltaTime;
+ if (_idleTime > MaxIdleTime)
+ {
+ _idleTime = 0f;
+ base.enabled = false;
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticCombinedObjectMatcher.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticCombinedObjectMatcher.cs
new file mode 100644
index 0000000..60ea49c
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticCombinedObjectMatcher.cs
@@ -0,0 +1,39 @@
+namespace NGS.MeshFusionPro;
+
+public class StaticCombinedObjectMatcher : CombinedObjectMatcher<CombinedObject, CombineSource>
+{
+ private RendererSettings _settings;
+
+ private int _vertexCount;
+
+ private int _vertexLimit;
+
+ public StaticCombinedObjectMatcher(int vertexLimit)
+ {
+ _vertexLimit = vertexLimit;
+ }
+
+ public override void StartMatching(CombinedObject combinedObject)
+ {
+ _settings = combinedObject.RendererSettings;
+ _vertexCount = combinedObject.VertexCount;
+ }
+
+ public override bool CanAddSource(CombineSource source)
+ {
+ if (!_settings.Equals(source.RendererSettings))
+ {
+ return false;
+ }
+ if (_vertexCount + source.CombineInfo.vertexCount > _vertexLimit)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public override void SourceAdded(CombineSource source)
+ {
+ _vertexCount += source.CombineInfo.vertexCount;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticMeshFusionSource.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticMeshFusionSource.cs
new file mode 100644
index 0000000..fbd86b3
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticMeshFusionSource.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class StaticMeshFusionSource : MeshFusionSource
+{
+ [SerializeField]
+ [HideInInspector]
+ private MeshRenderer _renderer;
+
+ [SerializeField]
+ [HideInInspector]
+ private MeshFilter _filter;
+
+ [SerializeField]
+ [HideInInspector]
+ private Mesh _mesh;
+
+ private CombineSource[] _sources;
+
+ private CombinedObjectPart[] _parts;
+
+ public override bool TryGetBounds(ref Bounds bounds)
+ {
+ if (_renderer != null)
+ {
+ bounds = _renderer.bounds;
+ return true;
+ }
+ return false;
+ }
+
+ protected override void OnSourceCombinedInternal(ICombinedObject root, ICombinedObjectPart part)
+ {
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ if (_parts[i] == null)
+ {
+ _parts[i] = (CombinedObjectPart)part;
+ return;
+ }
+ }
+ throw new Exception("Unexpected Behaviour");
+ }
+
+ protected override bool CheckCompatibilityAndGetComponents(out string incompatibilityReason)
+ {
+ incompatibilityReason = "";
+ return CanCreateCombineSource(base.gameObject, ref incompatibilityReason, ref _renderer, ref _filter, ref _mesh);
+ }
+
+ protected override void CreateSources()
+ {
+ if (_sources == null)
+ {
+ _sources = new CombineSource[_mesh.subMeshCount];
+ }
+ if (_parts == null)
+ {
+ _parts = new CombinedObjectPart[_mesh.subMeshCount];
+ }
+ for (int i = 0; i < _sources.Length; i++)
+ {
+ CombineSource combineSource = new CombineSource(_mesh, _renderer, i);
+ _sources[i] = combineSource;
+ }
+ }
+
+ protected override IEnumerable<ICombineSource> GetCombineSources()
+ {
+ if (_sources == null)
+ {
+ yield break;
+ }
+ for (int i = 0; i < _sources.Length; i++)
+ {
+ CombineSource combineSource = _sources[i];
+ if (combineSource == null)
+ {
+ break;
+ }
+ yield return combineSource;
+ }
+ }
+
+ protected override IEnumerable<ICombinedObjectPart> GetCombinedParts()
+ {
+ if (_parts == null)
+ {
+ yield break;
+ }
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ CombinedObjectPart combinedObjectPart = _parts[i];
+ if (combinedObjectPart == null)
+ {
+ break;
+ }
+ yield return combinedObjectPart;
+ }
+ }
+
+ protected override void ClearSources()
+ {
+ if (_sources != null)
+ {
+ for (int i = 0; i < _sources.Length; i++)
+ {
+ _sources[i] = null;
+ }
+ }
+ }
+
+ protected override void ClearParts()
+ {
+ if (_parts != null)
+ {
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ _parts[i] = null;
+ }
+ }
+ }
+
+ protected override void ToggleComponents(bool enabled)
+ {
+ _renderer.enabled = enabled;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticObjectsCombiner.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticObjectsCombiner.cs
new file mode 100644
index 0000000..e1cc19a
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/StaticObjectsCombiner.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public class StaticObjectsCombiner : ObjectsCombiner<CombinedObject, CombineSource>
+{
+ private ICombinedMeshFactory _factory;
+
+ private StaticCombinedObjectMatcher _matcher;
+
+ private int _vertexLimit;
+
+ public StaticObjectsCombiner(ICombinedMeshFactory factory, int vertexLimit)
+ {
+ _factory = factory;
+ _matcher = new StaticCombinedObjectMatcher(vertexLimit);
+ _vertexLimit = vertexLimit;
+ }
+
+ public override void AddSource(CombineSource source)
+ {
+ if (source.CombineInfo.vertexCount < _vertexLimit)
+ {
+ base.AddSource(source);
+ }
+ }
+
+ protected override void CombineSources(CombinedObject root, IList<CombineSource> sources)
+ {
+ root.Combine(sources);
+ }
+
+ protected override CombinedObject CreateCombinedObject(CombineSource source)
+ {
+ return CombinedObject.Create(_factory, source.RendererSettings);
+ }
+
+ protected override CombinedObjectMatcher<CombinedObject, CombineSource> GetMatcher()
+ {
+ return _matcher;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/TrackingTarget.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/TrackingTarget.cs
new file mode 100644
index 0000000..3c2276b
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/TrackingTarget.cs
@@ -0,0 +1,7 @@
+namespace NGS.MeshFusionPro;
+
+public enum TrackingTarget
+{
+ Transform,
+ Rigidbody
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/TransformTrackingStrategy.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/TransformTrackingStrategy.cs
new file mode 100644
index 0000000..2a5f282
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/TransformTrackingStrategy.cs
@@ -0,0 +1,30 @@
+using UnityEngine;
+
+namespace NGS.MeshFusionPro;
+
+public class TransformTrackingStrategy : ISourceTrackingStrategy
+{
+ private Transform _transform;
+
+ private DynamicCombinedObjectPart[] _parts;
+
+ public TransformTrackingStrategy(Transform target, DynamicCombinedObjectPart[] parts)
+ {
+ _transform = target;
+ _parts = parts;
+ }
+
+ public bool OnUpdate()
+ {
+ if (_transform.hasChanged)
+ {
+ for (int i = 0; i < _parts.Length; i++)
+ {
+ _parts[i].Move(_transform.localToWorldMatrix);
+ }
+ _transform.hasChanged = false;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/UniversalObjectsCombiner.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/UniversalObjectsCombiner.cs
new file mode 100644
index 0000000..ae5189f
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/UniversalObjectsCombiner.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+
+namespace NGS.MeshFusionPro;
+
+public class UniversalObjectsCombiner
+{
+ private StaticObjectsCombiner _staticCombiner;
+
+ private DynamicObjectsCombiner _dynamicCombiner;
+
+ private LODGroupsCombiner _lodCombiner;
+
+ public event Action<CombinedObject> onStaticCombinedObjectCreated;
+
+ public event Action<DynamicCombinedObject> onDynamicCombinedObjectCreated;
+
+ public event Action<CombinedLODGroup> onCombinedLODGroupCreated;
+
+ public UniversalObjectsCombiner(ICombinedMeshFactory factory, int vertexLimit)
+ {
+ _staticCombiner = new StaticObjectsCombiner(factory, vertexLimit);
+ _dynamicCombiner = new DynamicObjectsCombiner(factory, vertexLimit);
+ _lodCombiner = new LODGroupsCombiner(factory, vertexLimit);
+ _staticCombiner.onCombinedObjectCreated += delegate(CombinedObject r)
+ {
+ this.onStaticCombinedObjectCreated?.Invoke(r);
+ };
+ _dynamicCombiner.onCombinedObjectCreated += delegate(DynamicCombinedObject r)
+ {
+ this.onDynamicCombinedObjectCreated?.Invoke(r);
+ };
+ _lodCombiner.onCombinedObjectCreated += delegate(CombinedLODGroup r)
+ {
+ this.onCombinedLODGroupCreated?.Invoke(r);
+ };
+ }
+
+ public void AddSource(ICombineSource source)
+ {
+ if (source is CombineSource source2)
+ {
+ _staticCombiner.AddSource(source2);
+ return;
+ }
+ if (source is DynamicCombineSource source3)
+ {
+ _dynamicCombiner.AddSource(source3);
+ return;
+ }
+ if (source is LODGroupCombineSource source4)
+ {
+ _lodCombiner.AddSource(source4);
+ return;
+ }
+ throw new NotImplementedException("Unknown Combine Source");
+ }
+
+ public void AddSources(IEnumerable<ICombineSource> sources)
+ {
+ foreach (ICombineSource source in sources)
+ {
+ AddSource(source);
+ }
+ }
+
+ public void RemoveSource(ICombineSource source)
+ {
+ if (source is CombineSource source2)
+ {
+ _staticCombiner.RemoveSource(source2);
+ return;
+ }
+ if (source is DynamicCombineSource source3)
+ {
+ _dynamicCombiner.RemoveSource(source3);
+ return;
+ }
+ if (source is LODGroupCombineSource source4)
+ {
+ _lodCombiner.RemoveSource(source4);
+ return;
+ }
+ throw new NotImplementedException("Unknown Combine Source");
+ }
+
+ public void Combine()
+ {
+ if (_staticCombiner.ContainSources)
+ {
+ _staticCombiner.Combine();
+ }
+ if (_dynamicCombiner.ContainSources)
+ {
+ _dynamicCombiner.Combine();
+ }
+ if (_lodCombiner.ContainSources)
+ {
+ _lodCombiner.Combine();
+ }
+ }
+}
diff --git a/Thronefall_1_57/Decompile/NGS.MeshFusionPro/VertexBufferUtil.cs b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/VertexBufferUtil.cs
new file mode 100644
index 0000000..e409ce5
--- /dev/null
+++ b/Thronefall_1_57/Decompile/NGS.MeshFusionPro/VertexBufferUtil.cs
@@ -0,0 +1,124 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace NGS.MeshFusionPro;
+
+public static class VertexBufferUtil
+{
+ private static readonly Dictionary<VertexAttribute, VertexAttributeDescriptor> StandardAttributesMap;
+
+ private static readonly VertexAttributeDescriptor[] LightweightAttributesLayout;
+
+ private static List<VertexAttributeDescriptor> _meshAttributes;
+
+ static VertexBufferUtil()
+ {
+ LightweightAttributesLayout = new VertexAttributeDescriptor[5]
+ {
+ new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3, 0),
+ new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.SNorm8, 4),
+ new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.SNorm8, 4),
+ new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float16, 2),
+ new VertexAttributeDescriptor(VertexAttribute.TexCoord1, VertexAttributeFormat.Float16, 2)
+ };
+ StandardAttributesMap = new Dictionary<VertexAttribute, VertexAttributeDescriptor>
+ {
+ {
+ VertexAttribute.Position,
+ new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3, 0)
+ },
+ {
+ VertexAttribute.Normal,
+ new VertexAttributeDescriptor(VertexAttribute.Normal)
+ },
+ {
+ VertexAttribute.Tangent,
+ new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4)
+ },
+ {
+ VertexAttribute.TexCoord0,
+ new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2)
+ },
+ {
+ VertexAttribute.TexCoord1,
+ new VertexAttributeDescriptor(VertexAttribute.TexCoord1, VertexAttributeFormat.Float32, 2)
+ },
+ {
+ VertexAttribute.TexCoord2,
+ new VertexAttributeDescriptor(VertexAttribute.TexCoord2, VertexAttributeFormat.Float32, 2)
+ },
+ {
+ VertexAttribute.TexCoord3,
+ new VertexAttributeDescriptor(VertexAttribute.TexCoord3, VertexAttributeFormat.Float32, 2)
+ }
+ };
+ _meshAttributes = new List<VertexAttributeDescriptor>();
+ }
+
+ public static bool IsStandardBuffer(Mesh mesh)
+ {
+ mesh.GetVertexAttributes(_meshAttributes);
+ for (int i = 0; i < _meshAttributes.Count; i++)
+ {
+ VertexAttributeDescriptor vertexAttributeDescriptor = _meshAttributes[i];
+ VertexAttributeDescriptor vertexAttributeDescriptor2 = StandardAttributesMap[vertexAttributeDescriptor.attribute];
+ if (vertexAttributeDescriptor.format != vertexAttributeDescriptor2.format)
+ {
+ return false;
+ }
+ if (vertexAttributeDescriptor.dimension != vertexAttributeDescriptor2.dimension)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static bool IsLightweightBuffer(Mesh mesh)
+ {
+ mesh.GetVertexAttributes(_meshAttributes);
+ if (_meshAttributes.Count != LightweightAttributesLayout.Length)
+ {
+ return false;
+ }
+ for (int i = 0; i < _meshAttributes.Count; i++)
+ {
+ VertexAttributeDescriptor vertexAttributeDescriptor = _meshAttributes[i];
+ VertexAttributeDescriptor vertexAttributeDescriptor2 = LightweightAttributesLayout[i];
+ if (vertexAttributeDescriptor.attribute != vertexAttributeDescriptor2.attribute)
+ {
+ return false;
+ }
+ if (vertexAttributeDescriptor.format != vertexAttributeDescriptor2.format)
+ {
+ return false;
+ }
+ if (vertexAttributeDescriptor.dimension != vertexAttributeDescriptor2.dimension)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void ToStandardBuffer(Mesh mesh)
+ {
+ if (!IsStandardBuffer(mesh))
+ {
+ for (int i = 0; i < _meshAttributes.Count; i++)
+ {
+ _meshAttributes[i] = StandardAttributesMap[_meshAttributes[i].attribute];
+ }
+ mesh.SetVertexBufferParams(mesh.vertexCount, _meshAttributes.ToArray());
+ }
+ }
+
+ public static void ToLightweightBuffer(Mesh mesh)
+ {
+ if (!IsLightweightBuffer(mesh))
+ {
+ mesh.SetVertexBufferParams(mesh.vertexCount, LightweightAttributesLayout);
+ }
+ }
+}