1 #region Copyright Notice & License Information
30 using System.Collections;
31 using System.Threading;
32 using System.Collections.Generic;
39 [AddComponentMenu (
"Hydrogen/Singletons/Mesh Combiner")]
64 static readonly System.Object _syncRoot =
new System.Object ();
76 Dictionary<int, Transform> _parentLookup =
new Dictionary<int, Transform> ();
86 if (_staticInstance == null) {
91 if (_staticInstance == null) {
92 var go = GameObject.Find (Hydrogen.Components.DefaultSingletonName) ??
93 new GameObject (Hydrogen.Components.DefaultSingletonName);
95 go.AddComponent<hMeshCombiner> ();
96 _staticInstance = go.GetComponent<hMeshCombiner> ();
100 return _staticInstance;
109 return _staticInstance != null;
125 public void Combine (GameObject rootObject, Transform outputParent,
bool disableRootObject)
128 StartCoroutine (AddMeshes (rootObject, outputParent));
131 if (disableRootObject) {
132 rootObject.SetActive (
false);
143 public void ThreadCallback (
int hash, Hydrogen.Threading.Jobs.MeshCombiner.MeshOutput[] meshOutputs)
147 _threadRunning =
false;
148 StartCoroutine (CreateMeshes (hash, meshOutputs));
161 IEnumerator AddMeshes (GameObject rootObject, Transform outputParent)
164 MeshFilter[] meshFilters = rootObject.GetComponentsInChildren<MeshFilter> ();
167 for (
int x = 0; x < meshFilters.Length; x++) {
169 if (meshFilters [x].gameObject.activeSelf) {
170 Combiner.AddMesh (meshFilters [x],
171 meshFilters [x].renderer,
172 meshFilters [x].transform.localToWorldMatrix);
178 yield
return new WaitForEndOfFrame ();
184 _threadRunning =
true;
185 _parentLookup.Add (Combiner.Combine (
ThreadCallback), outputParent);
187 yield
return new WaitForEndOfFrame ();
197 DontDestroyOnLoad (gameObject);
206 IEnumerator CreateMeshes (
int hash, Hydrogen.Threading.Jobs.MeshCombiner.MeshOutput[] meshOutputs)
209 for (
int x = 0; x < meshOutputs.Length; x++) {
210 var meshObject =
new GameObject ();
212 var newMesh = Combiner.CreateMeshObject (meshOutputs [x],
true);
214 meshObject.name = newMesh.Mesh.name;
215 meshObject.AddComponent<MeshFilter> ().sharedMesh = newMesh.Mesh;
216 meshObject.AddComponent<MeshRenderer> ().sharedMaterials = newMesh.Materials;
218 if (_parentLookup.ContainsKey (hash)) {
219 meshObject.transform.parent = _parentLookup [hash];
222 meshObject.transform.position = Vector3.zero;
223 meshObject.transform.rotation = Quaternion.identity;
228 yield
return new WaitForEndOfFrame ();
232 if (_parentLookup.ContainsKey (hash)) {
233 _parentLookup.Remove (hash);
239 Combiner.ClearMeshes ();
248 if (_threadRunning) {
A Multi-Threaded Mesh Combiner that runs in another thread. (Yes! It is just that cool!) ...
A drop in implementation of how to interact with the Hydrogen.Threading.Jobs.MeshCombiner. This is meant really as an example of one way of using it, but you will probably want to create your own method to further optimize the workflow.
void Combine(GameObject rootObject, Transform outputParent, bool disableRootObject)
Combine all active meshes under the root object.
bool Persistent
Should this input manager survive scene switches?
static bool Exists()
Does an Input Manager already exist?
int ThrottleRate
This is used in our example to throttle things a bit when accessing Unity objects.
void Awake()
Unity's Awake Event
Hydrogen.Threading.Jobs.MeshCombiner Combiner
An instance of the MeshCombiner.
void ThreadCallback(int hash, Hydrogen.Threading.Jobs.MeshCombiner.MeshOutput[] meshOutputs)
This function is called in the example after the MeshCombiner has processed the meshes, it starts a Coroutine to create the actual meshes based on the flat data. This is the most optimal way to do this sadly as we cannot create or touch Unity based meshes outside of the main thread.
static hMeshCombiner Instance
Gets the input manager instance, creating one if none is found.