static int FinishMeshUpdates(CSGTree tree,
                                     ref VertexBufferContents vertexBufferContents,
                                     ref Mesh.MeshDataArray meshDataArray,
                                     NativeList <ChiselMeshUpdate> colliderMeshUpdates,
                                     NativeList <ChiselMeshUpdate> debugHelperMeshes,
                                     NativeList <ChiselMeshUpdate> renderMeshes,
                                     JobHandle dependencies)
        {
            ChiselModel model = null;

            for (int m = 0; m < registeredModels.Count; m++)
            {
                if (!registeredModels[m])
                {
                    continue;
                }

                if (registeredModels[m].Node == tree)
                {
                    model = registeredModels[m];
                }
            }

            if (model == null)
            {
                if (meshDataArray.Length > 0)
                {
                    meshDataArray.Dispose();
                }
                meshDataArray = default;
                return(0);
            }

            if (!ChiselGeneratedObjects.IsValid(model.generated))
            {
                if (model.generated != null)
                {
                    model.generated.Destroy();
                }
                model.generated = ChiselGeneratedObjects.Create(model.gameObject);
            }

            var count = model.generated.FinishMeshUpdates(model, model.gameObject, ref meshDataArray, ref vertexBufferContents,
                                                          colliderMeshUpdates, debugHelperMeshes, renderMeshes,
                                                          dependencies);

            componentGenerator.Rebuild(model);
            PostUpdateModel?.Invoke(model);
            return(count);
        }
        static JobHandle PerformMeshUpdate(CSGTree tree, ref VertexBufferContents vertexBufferContents, JobHandle dependencies)
        {
            ChiselModel model = null;

            for (int m = 0; m < registeredModels.Count; m++)
            {
                if (!registeredModels[m])
                {
                    continue;
                }

                if (registeredModels[m].Node == tree)
                {
                    model = registeredModels[m];
                }
            }
            if (model == null)
            {
                return((JobHandle) default);
Example #3
0
        public static void UpdateSettings(List <ChiselMeshUpdate> meshUpdates, List <ChiselRenderObjectUpdate> objectUpdates, Dictionary <ChiselModel, GameObjectState> gameObjectStates, ref VertexBufferContents vertexBufferContents)
        {
            Profiler.BeginSample("UpdateSettings");
            for (int u = 0; u < objectUpdates.Count; u++)
            {
                var objectUpdate  = objectUpdates[u];
                var meshUpdate    = meshUpdates[u];
                var instance      = objectUpdate.instance;
                var contentsIndex = meshUpdate.contentsIndex;
                var sharedMesh    = instance.sharedMesh;

                if (sharedMesh.subMeshCount > 0)
                {
                    var bounds = sharedMesh.GetSubMesh(0).bounds;
                    for (int s = 1; s < sharedMesh.subMeshCount; s++)
                    {
                        bounds.Encapsulate(sharedMesh.GetSubMesh(s).bounds);
                    }
                    sharedMesh.bounds = bounds;
                }

                if (instance.meshFilter.sharedMesh != sharedMesh)
                {
                    instance.meshFilter.sharedMesh = sharedMesh;
                    objectUpdate.meshIsModified    = true;
                    objectUpdates[u] = objectUpdate;
                }

                var expectedEnabled = vertexBufferContents.triangleBrushIndices[contentsIndex].Length > 0;
                if (instance.meshRenderer.enabled != expectedEnabled)
                {
                    instance.meshRenderer.enabled = expectedEnabled;
                }

                var gameObjectState = gameObjectStates[objectUpdate.model];
                instance.UpdateSettings(objectUpdate.model, gameObjectState, objectUpdate.meshIsModified);
            }
            Profiler.EndSample();
        }
Example #4
0
        public static void UpdateMaterials(List <ChiselMeshUpdate> meshUpdates, List <ChiselRenderObjectUpdate> objectUpdates, ref VertexBufferContents vertexBufferContents)
        {
            Profiler.BeginSample("SetTriangleBrushes");
            for (int u = 0; u < objectUpdates.Count; u++)
            {
                var meshUpdate        = meshUpdates[u];
                var objectUpdate      = objectUpdates[u];
                var instance          = objectUpdate.instance;
                var brushIndicesArray = vertexBufferContents.triangleBrushIndices[meshUpdate.contentsIndex].AsArray();
                if (instance.triangleBrushes.Length < brushIndicesArray.Length)
                {
                    instance.triangleBrushes = new CompactNodeID[brushIndicesArray.Length];
                }
                NativeArray <CompactNodeID> .Copy(brushIndicesArray, instance.triangleBrushes, brushIndicesArray.Length);
            }
            Profiler.EndSample();

            Profiler.BeginSample("UpdateMaterials");
            for (int u = 0; u < objectUpdates.Count; u++)
            {
                var meshUpdate       = meshUpdates[u];
                var objectUpdate     = objectUpdates[u];
                var instance         = objectUpdate.instance;
                var contentsIndex    = meshUpdate.contentsIndex;
                var materialOverride = objectUpdate.materialOverride;
                var startIndex       = vertexBufferContents.subMeshSections[contentsIndex].startIndex;
                var endIndex         = vertexBufferContents.subMeshSections[contentsIndex].endIndex;
                var desiredCapacity  = endIndex - startIndex;
                if (instance.renderMaterials == null || instance.renderMaterials.Length != desiredCapacity)
                {
                    instance.renderMaterials = new Material[desiredCapacity];
                }
                if (materialOverride)
                {
                    for (int i = 0; i < instance.renderMaterials.Length; i++)
                    {
                        instance.renderMaterials[i] = materialOverride;
                    }
                }
                else
                {
                    for (int i = 0; i < desiredCapacity; i++)
                    {
                        var meshDescription = vertexBufferContents.meshDescriptions[startIndex + i];
                        var renderMaterial  = ChiselMaterialManager.Instance.GetMaterial(meshDescription.surfaceParameter);
                        //ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(meshDescription.surfaceParameter);

                        instance.renderMaterials[i] = renderMaterial;
                    }
                }
                instance.SetMaterialsIfModified(instance.meshRenderer, instance.renderMaterials);
            }
            Profiler.EndSample();
        }
        // in between UpdateMeshes and FinishMeshUpdates our jobs should be force completed, so we can now upload our meshes to unity Meshes

        public int FinishMeshUpdates(ChiselModel model, GameObject parentGameObject,
                                     Mesh.MeshDataArray meshDataArray,
                                     ref VertexBufferContents vertexBufferContents,
                                     NativeList <ChiselMeshUpdate> colliderMeshUpdates,
                                     NativeList <ChiselMeshUpdate> debugHelperMeshes,
                                     NativeList <ChiselMeshUpdate> renderMeshes,
                                     JobHandle dependencies)
        {
            gameObjectStates.Clear();
            colliderObjectUpdates.Clear();
            renderMeshUpdates.Clear();
            renderObjectUpdates.Clear();
            colliderObjects.Clear();
            foundMeshes.Clear();

            GameObjectState gameObjectState;

            {
                Profiler.BeginSample("Setup");
                var parentTransform = parentGameObject.transform;
                gameObjectState = GameObjectState.Create(parentGameObject);
                ChiselObjectUtility.UpdateContainerFlags(generatedDataContainer, gameObjectState);

                var containerTransform = generatedDataContainer.transform;
                var colliderTransform  = colliderContainer.transform;

                // Make sure we're always a child of the model
                ChiselObjectUtility.ResetTransform(containerTransform, requiredParent: parentTransform);
                ChiselObjectUtility.ResetTransform(colliderTransform, requiredParent: containerTransform);
                ChiselObjectUtility.UpdateContainerFlags(colliderContainer, gameObjectState);

                for (int i = 0; i < renderables.Length; i++)
                {
                    if (renderables[i] == null || renderables[i].invalid)
                    {
                        continue;
                    }

                    bool isRenderable        = (renderables[i].query & LayerUsageFlags.Renderable) == LayerUsageFlags.Renderable;
                    var  renderableContainer = renderables[i].container;
                    ChiselObjectUtility.UpdateContainerFlags(renderableContainer, gameObjectState, isRenderable: isRenderable);
                    ChiselObjectUtility.ResetTransform(renderableContainer.transform, requiredParent: containerTransform);
                }

                for (int i = 0; i < debugHelpers.Length; i++)
                {
                    if (debugHelpers[i] == null || debugHelpers[i].invalid)
                    {
                        continue;
                    }
                    var renderableContainer = debugHelpers[i].container;
                    ChiselObjectUtility.UpdateContainerFlags(renderableContainer, gameObjectState, isRenderable: true, debugHelperRenderer: true);
                    ChiselObjectUtility.ResetTransform(renderableContainer.transform, requiredParent: containerTransform);
                }
                gameObjectStates.Add(model, gameObjectState);
                Profiler.EndSample();
            }

            Debug.Assert(LayerParameterIndex.LayerParameter1 < LayerParameterIndex.LayerParameter2);
            Debug.Assert((LayerParameterIndex.LayerParameter1 + 1) == LayerParameterIndex.LayerParameter2);

            dependencies.Complete();

            Debug.Assert(!vertexBufferContents.meshDescriptions.IsCreated ||
                         vertexBufferContents.meshDescriptions.Length == 0 ||
                         vertexBufferContents.meshDescriptions[0].meshQuery.LayerParameterIndex >= LayerParameterIndex.None);


            Profiler.BeginSample("Init");
            var colliderCount = colliderMeshUpdates.Length;

            if (colliderObjects.Capacity < colliderCount)
            {
                colliderObjects.Capacity = colliderCount;
            }
            for (int i = 0; i < colliderCount; i++)
            {
                colliderObjects.Add(null);
            }
            for (int i = 0; i < debugHelperMeshes.Length; i++)
            {
                renderMeshUpdates.Add(debugHelperMeshes[i]);
            }
            for (int i = 0; i < renderMeshes.Length; i++)
            {
                renderMeshUpdates.Add(renderMeshes[i]);
            }
            renderMeshUpdates.Sort(delegate(ChiselMeshUpdate x, ChiselMeshUpdate y)
            {
                return(x.contentsIndex - y.contentsIndex);
            });
            Profiler.EndSample();



            // Now do all kinds of book-keeping code that we might as well do while our jobs are running on other threads
            Profiler.BeginSample("new_ChiselDebugObjectUpdate");
            usedDebugHelpers.Clear();
            for (int i = 0; i < debugHelperMeshes.Length; i++)
            {
                var debugHelperMeshUpdate = debugHelperMeshes[i];
                usedDebugHelpers.Add(debugHelperMeshUpdate.objectIndex);
                var instance = debugHelpers[debugHelperMeshUpdate.objectIndex];
                foundMeshes.Add(instance.sharedMesh);
                renderObjectUpdates.Add(new ChiselRenderObjectUpdate
                {
                    meshIndex        = debugHelperMeshUpdate.meshIndex,
                    materialOverride = ChiselMaterialManager.HelperMaterials[debugHelperMeshUpdate.objectIndex],
                    instance         = instance,
                    model            = model
                });
            }
            Profiler.EndSample();

            Profiler.BeginSample("new_ChiselRenderObjectUpdate");
            usedRenderMeshes.Clear();
            for (int i = 0; i < renderMeshes.Length; i++)
            {
                var renderMeshUpdate = renderMeshes[i];
                usedRenderMeshes.Add(renderMeshUpdate.objectIndex);
                var instance = renderables[renderMeshUpdate.objectIndex];
                foundMeshes.Add(instance.sharedMesh);
                renderObjectUpdates.Add(new ChiselRenderObjectUpdate
                {
                    meshIndex        = renderMeshUpdate.meshIndex,
                    materialOverride = null,
                    instance         = instance,
                    model            = model
                });
            }
            Profiler.EndSample();

            Profiler.BeginSample("new_ChiselPhysicsObjectUpdate");
            for (int i = 0; i < colliderMeshUpdates.Length; i++)
            {
                var colliderMeshUpdate = colliderMeshUpdates[i];

                var surfaceParameter = colliderMeshUpdate.objectIndex;
                var colliderIndex    = colliderMeshUpdate.colliderIndex;

                // TODO: optimize
                for (int j = 0; j < colliders.Length; j++)
                {
                    if (colliders[j] == null)
                    {
                        continue;
                    }
                    if (colliders[j].surfaceParameter != surfaceParameter)
                    {
                        continue;
                    }

                    colliderObjects[colliderIndex] = colliders[j];
                    colliders[j] = null;
                    break;
                }

                Profiler.BeginSample("Create.Colliders");
                if (colliderObjects[colliderIndex] == null)
                {
                    colliderObjects[colliderIndex] = ChiselColliderObjects.Create(colliderContainer, surfaceParameter);
                }
                Profiler.EndSample();

                var instance = colliderObjects[colliderIndex];
                foundMeshes.Add(instance.sharedMesh);
                colliderObjectUpdates.Add(new ChiselColliderObjectUpdate
                {
                    meshIndex = colliderMeshUpdate.meshIndex
                });
            }
            Profiler.EndSample();

            Profiler.BeginSample("Renderers.UpdateMaterials");
            ChiselRenderObjects.UpdateMaterials(renderMeshUpdates, renderObjectUpdates, ref vertexBufferContents);
            Profiler.EndSample();


            Profiler.BeginSample("CleanUp.Colliders");
            for (int j = 0; j < colliders.Length; j++)
            {
                if (colliders[j] != null)
                {
                    colliders[j].Destroy();
                }
            }
            Profiler.EndSample();

            Profiler.BeginSample("Assign.Colliders");
            if (colliders.Length != colliderCount)
            {
                colliders = new ChiselColliderObjects[colliderCount];
            }
            for (int i = 0; i < colliderCount; i++)
            {
                colliders[i] = colliderObjects[i];
            }
            Profiler.EndSample();

            Profiler.BeginSample("Renderers.Update");
            ChiselRenderObjects.UpdateSettings(renderMeshUpdates, renderObjectUpdates, gameObjectStates, ref vertexBufferContents);
            Profiler.EndSample();

            Debug.Assert(foundMeshes.Count <= meshDataArray.Length);

            var realMeshDataArraySize = meshDataArray.Length;

            {
                // This is a hack to ensure foundMeshes is the same exact length as meshDataArray
                // (All these need to be set to empty anyway)

                // TODO: figure out why the maximum meshDataArray.Length does not match the maximum used meshes?

                int meshDataArrayOffset = foundMeshes.Count;
                for (int i = 0; i < renderables.Length; i++)
                {
                    if (usedRenderMeshes.Contains(i))
                    {
                        continue;
                    }

                    var instance = renderables[i];
                    if (instance.meshRenderer &&
                        instance.meshRenderer.enabled)
                    {
                        instance.meshRenderer.enabled = false;
                    }
                    if (foundMeshes.Count < meshDataArray.Length)
                    {
                        var sharedMesh = instance.sharedMesh;
                        if (!sharedMesh || foundMeshes.Contains(sharedMesh))
                        {
                            continue;
                        }

                        foundMeshes.Add(sharedMesh);
                        meshDataArray[meshDataArrayOffset].SetIndexBufferParams(0, IndexFormat.UInt32);
                        meshDataArray[meshDataArrayOffset].SetVertexBufferParams(0, VertexBufferContents.s_RenderDescriptors);
                        meshDataArrayOffset++;
                    }
                }

                for (int i = 0; i < debugHelpers.Length; i++)
                {
                    if (usedDebugHelpers.Contains(i))
                    {
                        continue;
                    }

                    var instance = debugHelpers[i];
                    if (instance.meshRenderer &&
                        instance.meshRenderer.enabled)
                    {
                        instance.meshRenderer.enabled = false;
                    }
                    if (foundMeshes.Count < meshDataArray.Length)
                    {
                        var sharedMesh = instance.sharedMesh;
                        if (!sharedMesh || foundMeshes.Contains(sharedMesh))
                        {
                            continue;
                        }

                        foundMeshes.Add(sharedMesh);
                        meshDataArray[meshDataArrayOffset].SetIndexBufferParams(0, IndexFormat.UInt32);
                        meshDataArray[meshDataArrayOffset].SetVertexBufferParams(0, VertexBufferContents.s_RenderDescriptors);
                        meshDataArrayOffset++;
                    }
                }
            }

            Profiler.BeginSample("UpdateMeshRenderers");
            ChiselRenderObjects.UpdateProperties(model, this.meshRenderers);
            Profiler.EndSample();

            // Updates the Unity Mesh-es that are used in our MeshRenderers and MeshColliders
            // MeshUpdateFlags => Bounds are never updated no matter what flag you use
            Profiler.BeginSample("ApplyAndDisposeWritableMeshData");
            Mesh.ApplyAndDisposeWritableMeshData(meshDataArray, foundMeshes,
                                                 UnityEngine.Rendering.MeshUpdateFlags.DontRecalculateBounds);
            Profiler.EndSample();

            // TODO: user meshDataArray data to determine if colliders are visible or not, then we can move this before the Apply
            Profiler.BeginSample("UpdateColliders");
            ChiselColliderObjects.UpdateProperties(model, this.colliders);
            Profiler.EndSample();

            // So we need to update the bounds ourselves
            Profiler.BeginSample("Mesh.UpdateBounds");
            ChiselRenderObjects.UpdateBounds(renderObjectUpdates);
            // TODO: user meshDataArray data to determine the bounds and set it directly
            for (int i = 0; i < colliders.Length; i++)
            {
                colliders[i].sharedMesh.RecalculateBounds();
            }
            Profiler.EndSample();

            Profiler.BeginSample("Schedule Collider bake");
            ChiselColliderObjects.ScheduleColliderBake(model, this.colliders);
            Profiler.EndSample();

            this.needVisibilityMeshUpdate = true;
            gameObjectStates.Clear();
            renderMeshUpdates.Clear();
            renderObjectUpdates.Clear();
            colliderObjects.Clear();

            var foundMeshCount = foundMeshes.Count;

            foundMeshes.Clear();
            return(foundMeshCount);
        }
        // in between UpdateMeshes and FinishMeshUpdates our jobs should be force completed, so we can now upload our meshes to unity Meshes

        public int FinishMeshUpdates(ChiselModel model, GameObject parentGameObject,
                                     List <Mesh.MeshDataArray> meshDataArrays,
                                     ref VertexBufferContents vertexBufferContents,
                                     NativeList <ChiselMeshUpdate> colliderMeshUpdates,
                                     NativeList <ChiselMeshUpdate> debugHelperMeshes,
                                     NativeList <ChiselMeshUpdate> renderMeshes,
                                     JobHandle dependencies)
        {
            gameObjectStates.Clear();
            colliderObjectUpdates.Clear();
            renderMeshUpdates.Clear();
            renderObjectUpdates.Clear();
            colliderObjects.Clear();
            foundMeshes.Clear();

            GameObjectState gameObjectState;

            {
                Profiler.BeginSample("Setup");
                var parentTransform = parentGameObject.transform;
                gameObjectState = GameObjectState.Create(parentGameObject);
                ChiselObjectUtility.UpdateContainerFlags(generatedDataContainer, gameObjectState);

                var containerTransform = generatedDataContainer.transform;
                var colliderTransform  = colliderContainer.transform;

                // Make sure we're always a child of the model
                ChiselObjectUtility.ResetTransform(containerTransform, requiredParent: parentTransform);
                ChiselObjectUtility.ResetTransform(colliderTransform, requiredParent: containerTransform);
                ChiselObjectUtility.UpdateContainerFlags(colliderContainer, gameObjectState);

                for (int i = 0; i < renderables.Length; i++)
                {
                    if (renderables[i] == null || renderables[i].invalid)
                    {
                        continue;
                    }

                    bool isRenderable        = (renderables[i].query & LayerUsageFlags.Renderable) == LayerUsageFlags.Renderable;
                    var  renderableContainer = renderables[i].container;
                    ChiselObjectUtility.UpdateContainerFlags(renderableContainer, gameObjectState, isRenderable: isRenderable);
                    ChiselObjectUtility.ResetTransform(renderableContainer.transform, requiredParent: containerTransform);
                }

                for (int i = 0; i < debugHelpers.Length; i++)
                {
                    if (debugHelpers[i] == null || debugHelpers[i].invalid)
                    {
                        continue;
                    }
                    var renderableContainer = debugHelpers[i].container;
                    ChiselObjectUtility.UpdateContainerFlags(renderableContainer, gameObjectState, isRenderable: true, debugHelperRenderer: true);
                    ChiselObjectUtility.ResetTransform(renderableContainer.transform, requiredParent: containerTransform);
                }
                gameObjectStates.Add(model, gameObjectState);
                Profiler.EndSample();
            }

            Debug.Assert(LayerParameterIndex.LayerParameter1 < LayerParameterIndex.LayerParameter2);
            Debug.Assert((LayerParameterIndex.LayerParameter1 + 1) == LayerParameterIndex.LayerParameter2);

            dependencies.Complete();

            Debug.Assert(!vertexBufferContents.meshDescriptions.IsCreated ||
                         vertexBufferContents.meshDescriptions.Length == 0 ||
                         vertexBufferContents.meshDescriptions[0].meshQuery.LayerParameterIndex >= LayerParameterIndex.None);


            Profiler.BeginSample("Init");
            var colliderCount = colliderMeshUpdates.Length;

            if (colliderObjects.Capacity < colliderCount)
            {
                colliderObjects.Capacity = colliderCount;
            }
            for (int i = 0; i < colliderCount; i++)
            {
                colliderObjects.Add(null);
            }

            for (int i = 0; i < renderMeshes.Length; i++)
            {
                renderMeshUpdates.Add(renderMeshes[i]);
            }

            for (int i = 0; i < debugHelperMeshes.Length; i++)
            {
                renderMeshUpdates.Add(debugHelperMeshes[i]);
            }
            renderMeshUpdates.Sort(delegate(ChiselMeshUpdate x, ChiselMeshUpdate y)
            {
                return(x.contentsIndex - y.contentsIndex);
            });
            Profiler.EndSample();



            // Now do all kinds of book-keeping code that we might as well do while our jobs are running on other threads
            Profiler.BeginSample("new ChiselRenderObjectUpdate");
            for (int i = 0; i < debugHelperMeshes.Length; i++)
            {
                var debugHelperMeshUpdate = debugHelperMeshes[i];
                var instance = debugHelpers[debugHelperMeshUpdate.objectIndex];
                foundMeshes.Add(instance.sharedMesh);
                renderObjectUpdates.Add(new ChiselRenderObjectUpdate
                {
                    meshIndex        = debugHelperMeshUpdate.meshIndex,
                    meshDataArray    = meshDataArrays[debugHelperMeshUpdate.meshIndex],
                    materialOverride = ChiselMaterialManager.HelperMaterials[debugHelperMeshUpdate.objectIndex],
                    instance         = instance,
                    model            = model
                });
            }
            Profiler.EndSample();

            Profiler.BeginSample("new ChiselRenderObjectUpdate");
            for (int i = 0; i < renderMeshes.Length; i++)
            {
                var renderMeshUpdate = renderMeshes[i];
                var instance         = renderables[renderMeshUpdate.objectIndex];
                foundMeshes.Add(instance.sharedMesh);
                renderObjectUpdates.Add(new ChiselRenderObjectUpdate
                {
                    meshIndex        = renderMeshUpdate.meshIndex,
                    meshDataArray    = meshDataArrays[renderMeshUpdate.meshIndex],
                    materialOverride = null,
                    instance         = instance,
                    model            = model
                });
            }
            Profiler.EndSample();

            Profiler.BeginSample("new ChiselPhysicsObjectUpdate");
            for (int i = 0; i < colliderMeshUpdates.Length; i++)
            {
                var colliderMeshUpdate = colliderMeshUpdates[i];

                var surfaceParameter = colliderMeshUpdate.objectIndex;
                var colliderIndex    = colliderMeshUpdate.contentsIndex;

                // TODO: optimize
                for (int j = 0; j < colliders.Length; j++)
                {
                    if (colliders[j] == null)
                    {
                        continue;
                    }
                    if (colliders[j].surfaceParameter != surfaceParameter)
                    {
                        continue;
                    }

                    colliderObjects[colliderIndex] = colliders[j];
                    colliders[j] = null;
                    break;
                }

                Profiler.BeginSample("Create.Colliders");
                if (colliderObjects[colliderIndex] == null)
                {
                    colliderObjects[colliderIndex] = ChiselColliderObjects.Create(colliderContainer, surfaceParameter);
                }
                Profiler.EndSample();

                var instance = colliderObjects[colliderIndex];
                foundMeshes.Add(instance.sharedMesh);
                colliderObjectUpdates.Add(new ChiselColliderObjectUpdate
                {
                    meshIndex     = colliderMeshUpdate.meshIndex,
                    meshDataArray = meshDataArrays[colliderMeshUpdate.meshIndex],
                });
            }
            Profiler.EndSample();

            Profiler.BeginSample("Renderers.UpdateMaterials");
            ChiselRenderObjects.UpdateMaterials(renderMeshUpdates, renderObjectUpdates, ref vertexBufferContents);
            Profiler.EndSample();


            Profiler.BeginSample("CleanUp.Colliders");
            for (int j = 0; j < colliders.Length; j++)
            {
                if (colliders[j] != null)
                {
                    colliders[j].Destroy();
                }
            }
            Profiler.EndSample();

            Profiler.BeginSample("Assign.Colliders");
            if (colliders.Length != colliderCount)
            {
                colliders = new ChiselColliderObjects[colliderCount];
            }
            for (int i = 0; i < colliderCount; i++)
            {
                colliders[i] = colliderObjects[i];
            }
            Profiler.EndSample();

            Profiler.BeginSample("Renderers.Update");
            ChiselRenderObjects.UpdateSettings(this.renderMeshUpdates, this.renderObjectUpdates, this.gameObjectStates, ref vertexBufferContents);
            Profiler.EndSample();

            Profiler.BeginSample("ApplyAndDisposeWritableMeshData");
            for (int i = 0; i < this.renderObjectUpdates.Count; i++)
            {
                var update    = this.renderObjectUpdates[i];
                var meshIndex = update.meshIndex;
                if (update.meshDataArray.Length > 0)
                {
                    Mesh.ApplyAndDisposeWritableMeshData(update.meshDataArray,
                                                         foundMeshes[meshIndex],
                                                         UnityEngine.Rendering.MeshUpdateFlags.DontRecalculateBounds);
                }
                update.meshDataArray        = default;
                this.renderObjectUpdates[i] = update;
            }
            for (int i = 0; i < this.colliderObjectUpdates.Count; i++)
            {
                var update    = this.colliderObjectUpdates[i];
                var meshIndex = update.meshIndex;
                if (update.meshDataArray.Length > 0)
                {
                    Mesh.ApplyAndDisposeWritableMeshData(update.meshDataArray,
                                                         foundMeshes[meshIndex],
                                                         UnityEngine.Rendering.MeshUpdateFlags.DontRecalculateBounds);
                }
                update.meshDataArray          = default;
                this.colliderObjectUpdates[i] = update;
            }
            Profiler.EndSample();

            Profiler.BeginSample("UpdateProperties");
            ChiselRenderObjects.UpdateProperties(model, this.meshRenderers);
            Profiler.EndSample();

            Profiler.BeginSample("UpdateColliders");
            ChiselColliderObjects.UpdateProperties(model, this.colliders);
            Profiler.EndSample();

            this.needVisibilityMeshUpdate = true;
            this.gameObjectStates.Clear();
            this.renderMeshUpdates.Clear();
            this.renderObjectUpdates.Clear();
            this.colliderObjects.Clear();

            var foundMeshCount = foundMeshes.Count;

            foundMeshes.Clear();
            return(foundMeshCount);
        }