public static ChiselRenderObjects Create(string name, Transform parent, GameObjectState state, LayerUsageFlags query)
        {
            var renderContainer = ChiselObjectUtility.CreateGameObject(name, parent, state);
            var sharedMesh      = new Mesh {
                name = name
            };

#if UNITY_EDITOR
            var partialMesh = new Mesh {
                name = name
            };
            partialMesh.hideFlags = HideFlags.DontSave;
#endif
            var meshFilter   = renderContainer.AddComponent <MeshFilter>();
            var meshRenderer = renderContainer.AddComponent <MeshRenderer>();
            meshRenderer.enabled = false;

            var renderObjects = new ChiselRenderObjects
            {
                query        = query,
                container    = renderContainer,
                meshFilter   = meshFilter,
                meshRenderer = meshRenderer,
                sharedMesh   = sharedMesh,
#if UNITY_EDITOR
                partialMesh = partialMesh,
#endif
                renderMaterials = new Material[0]
            };
            renderObjects.Initialize();
            return(renderObjects);
        }
 public void Destroy()
 {
     if (colliders != null)
     {
         foreach (var collider in colliders)
         {
             if (collider != null)
             {
                 collider.Destroy();
             }
         }
         colliders = null;
     }
     if (renderables != null)
     {
         foreach (var renderable in renderables)
         {
             if (renderable != null)
             {
                 renderable.Destroy();
             }
         }
         renderables = null;
     }
     ChiselObjectUtility.SafeDestroy(colliderContainer, ignoreHierarchyEvents: true);
     ChiselObjectUtility.SafeDestroy(generatedDataContainer, ignoreHierarchyEvents: true);
     generatedDataContainer = null;
     colliderContainer      = null;
 }
 public void RemoveContainerFlags()
 {
     if (colliders != null)
     {
         foreach (var collider in colliders)
         {
             if (collider != null)
             {
                 collider.RemoveContainerFlags();
             }
         }
     }
     if (renderables != null)
     {
         foreach (var renderable in renderables)
         {
             if (renderable != null)
             {
                 renderable.RemoveContainerFlags();
             }
         }
     }
     if (debugHelpers != null)
     {
         foreach (var debugHelper in debugHelpers)
         {
             if (debugHelper != null)
             {
                 debugHelper.RemoveContainerFlags();
             }
         }
     }
     ChiselObjectUtility.RemoveContainerFlags(colliderContainer);
     ChiselObjectUtility.RemoveContainerFlags(generatedDataContainer);
 }
        private static void UpdateModelFlags(ChiselModel model)
        {
            if (!IsDefaultModel(model))
            {
                return;
            }

            const HideFlags DefaultGameObjectHideFlags = HideFlags.NotEditable;
            const HideFlags DefaultTransformHideFlags  = HideFlags.NotEditable; // | HideFlags.HideInInspector;

            var gameObject = model.gameObject;
            var transform  = model.transform;

            if (gameObject.hideFlags != DefaultGameObjectHideFlags)
            {
                gameObject.hideFlags = DefaultGameObjectHideFlags;
            }
            if (transform.hideFlags != DefaultTransformHideFlags)
            {
                transform.hideFlags = DefaultTransformHideFlags;
            }

            if (transform.parent != null)
            {
                transform.SetParent(null, false);
                ChiselObjectUtility.ResetTransform(transform);
            }
        }
Exemple #5
0
 public void Destroy()
 {
     ChiselObjectUtility.SafeDestroy(meshCollider);
     ChiselObjectUtility.SafeDestroy(sharedMesh);
     sharedMesh      = null;
     meshCollider    = null;
     physicsMaterial = null;
 }
        internal void DestroyAllRegisteredGeneratedComponentsInModel(ChiselModel model)
        {
            GameObject modelGameObject = null;

            if (model)
            {
                modelGameObject = model.gameObject;
            }

            __uniqueGameObjects.Clear();
            foreach (var components in model.generatedRenderComponents.Values)
            {
                foreach (var component in components)
                {
                    if (component == null)
                    {
                        continue;
                    }

                    if (component.gameObject)
                    {
                        var gameObject = component.gameObject;
                        if (gameObject != modelGameObject)
                        {
                            __uniqueGameObjects.Add(gameObject);
                        }
                    }
                }
            }
            foreach (var components in model.generatedMeshColliders.Values)
            {
                foreach (var component in components)
                {
                    if (component == null)
                    {
                        continue;
                    }

                    if (component.gameObject)
                    {
                        var gameObject = component.gameObject;
                        if (gameObject != modelGameObject)
                        {
                            __uniqueGameObjects.Add(gameObject);
                        }
                    }
                }
            }
            foreach (var gameObject in __uniqueGameObjects)
            {
                ChiselObjectUtility.SafeDestroy(gameObject);
            }

            __uniqueGameObjects.Clear();
            model.generatedRenderComponents.Clear();
            model.generatedMeshColliders.Clear();
            model.generatedComponents.Clear();
        }
Exemple #7
0
        public void DestroyWithUndo()
        {
            if (invalid)
            {
                return;
            }
#if UNITY_EDITOR
            ChiselObjectUtility.SafeDestroyWithUndo(partialMesh);
#endif
            ChiselObjectUtility.SafeDestroyWithUndo(sharedMesh);
            ChiselObjectUtility.SafeDestroyWithUndo(container, ignoreHierarchyEvents: true);
        }
 private void RemoveContainerGameObject(ChiselModel model)
 {
     if (model.GeneratedDataTransform)
     {
         model.GeneratedDataContainer.hideFlags            = HideFlags.None;
         model.GeneratedDataTransform.hideFlags            = HideFlags.None;
         CSGNodeHierarchyManager.ignoreNextChildrenChanged = true;
         ChiselObjectUtility.SafeDestroy(model.GeneratedDataContainer);
         CSGNodeHierarchyManager.ignoreNextChildrenChanged = false;
         model.GeneratedDataContainer = null;
         model.GeneratedDataTransform = null;
     }
 }
        public void Destroy()
        {
#if UNITY_EDITOR
            ChiselObjectUtility.SafeDestroy(partialMesh);
            partialMesh = null;
#endif
            ChiselObjectUtility.SafeDestroy(sharedMesh);
            ChiselObjectUtility.SafeDestroy(container, ignoreHierarchyEvents: true);
            container       = null;
            sharedMesh      = null;
            meshFilter      = null;
            meshRenderer    = null;
            renderMaterials = null;
        }
        static List <GameObject> __rootGameObjects = new List <GameObject>(); // static to avoid allocations
        internal static ChiselModel CreateDefaultModel(ChiselSceneHierarchy sceneHierarchy)
        {
            var currentScene = sceneHierarchy.Scene;

            currentScene.GetRootGameObjects(__rootGameObjects);
            for (int i = 0; i < __rootGameObjects.Count; i++)
            {
                if (!IsDefaultModel(__rootGameObjects[i]))
                {
                    continue;
                }

                var gameObject = __rootGameObjects[i];
                var model      = gameObject.GetComponent <ChiselModel>();
                if (model)
                {
                    return(model);
                }

                var transform = gameObject.GetComponent <Transform>();
                ChiselObjectUtility.ResetTransform(transform);

                model = gameObject.AddComponent <ChiselModel>();
                UpdateModelFlags(model);
                return(model);
            }


            var oldActiveScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();

            if (currentScene != oldActiveScene)
            {
                UnityEngine.SceneManagement.SceneManager.SetActiveScene(currentScene);
            }

            try
            {
                var model = ChiselComponentFactory.Create <ChiselModel>(kGeneratedDefaultModelName);
                model.IsDefaultModel = true;
                UpdateModelFlags(model);
                return(model);
            }
            finally
            {
                if (currentScene != oldActiveScene)
                {
                    UnityEngine.SceneManagement.SceneManager.SetActiveScene(oldActiveScene);
                }
            }
        }
Exemple #11
0
        public static ChiselModelGeneratedObjects Create(ChiselModel model)
        {
            // Make sure there's not a dangling container out there from a previous version
            var existingContainer = model.FindChildByName(kGeneratedContainerName);

            ChiselObjectUtility.SafeDestroy(existingContainer, ignoreHierarchyEvents: true);

            var modelState         = GameObjectState.Create(model);
            var parent             = model.transform;
            var container          = ChiselObjectUtility.CreateGameObject(kGeneratedContainerName, parent, modelState);
            var containerTransform = container.transform;
            var colliderContainer  = ChiselObjectUtility.CreateGameObject(kGeneratedMeshColliderName, containerTransform, modelState);

            Debug.Assert((int)LayerUsageFlags.Renderable == 1);
            Debug.Assert((int)LayerUsageFlags.CastShadows == 2);
            Debug.Assert((int)LayerUsageFlags.ReceiveShadows == 4);
            Debug.Assert((int)LayerUsageFlags.RenderReceiveCastShadows == (1 | 2 | 4));

            var renderables = new ChiselRenderObjects[]
            {
                null,//ChiselRenderObjects Create(kGeneratedMeshRendererNames[0], containerTransform, modelState, LayerUsageFlags.None),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[1], containerTransform, modelState, LayerUsageFlags.Renderable),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[2], containerTransform, modelState, LayerUsageFlags.CastShadows),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[3], containerTransform, modelState, LayerUsageFlags.Renderable | LayerUsageFlags.CastShadows),
                null, //ChiselRenderObjects.Create(kGeneratedMeshRendererNames[4], containerTransform, modelState,                                                     LayerUsageFlags.ReceiveShadows),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[5], containerTransform, modelState, LayerUsageFlags.Renderable | LayerUsageFlags.ReceiveShadows),
                null, //ChiselRenderObjects.Create(kGeneratedMeshRendererNames[6], containerTransform, modelState,                       LayerUsageFlags.CastShadows | LayerUsageFlags.ReceiveShadows),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[7], containerTransform, modelState, LayerUsageFlags.Renderable | LayerUsageFlags.CastShadows | LayerUsageFlags.ReceiveShadows),
            };

            var meshRenderers = new MeshRenderer[]
            {
                renderables[1].meshRenderer,
                renderables[2].meshRenderer,
                renderables[3].meshRenderer,
                renderables[5].meshRenderer,
                renderables[7].meshRenderer
            };

            return(new ChiselModelGeneratedObjects
            {
                generatedDataContainer = container,
                colliderContainer = colliderContainer,
                colliders = new ChiselColliderObjects[0],
                renderables = renderables,
                meshRenderers = meshRenderers
            });
        }
Exemple #12
0
        // Destroy all Unity Meshes that aren't used and haven't been recycled
        public void DestroyNonRecycledUnusedUnityMeshes()
        {
            // Remove our garbage
            for (int i = 0; i < garbage.Count; i++)
            {
                refCountedMeshes.Remove(garbage[i]);
            }
            garbage.Clear();

            // Make sure we destroy the leftover meshes
            for (int i = 0; i < garbageMeshes.Count; i++)
            {
                ChiselObjectUtility.SafeDestroy(garbageMeshes[i]);
            }
            garbageMeshes.Clear();
        }
        public void DestroyWithUndo()
        {
            if (!generatedDataContainer)
            {
                return;
            }

            if (colliders != null)
            {
                foreach (var collider in colliders)
                {
                    if (collider != null)
                    {
                        collider.DestroyWithUndo();
                    }
                }
            }
            if (renderables != null)
            {
                foreach (var renderable in renderables)
                {
                    if (renderable != null)
                    {
                        renderable.DestroyWithUndo();
                    }
                }
            }
            if (debugHelpers != null)
            {
                foreach (var debugHelper in debugHelpers)
                {
                    if (debugHelper != null)
                    {
                        debugHelper.DestroyWithUndo();
                    }
                }
            }
            ChiselObjectUtility.SafeDestroyWithUndo(colliderContainer, ignoreHierarchyEvents: true);
            ChiselObjectUtility.SafeDestroyWithUndo(generatedDataContainer, ignoreHierarchyEvents: true);
        }
Exemple #14
0
        public static ChiselRenderObjects Create(string name, Transform parent, GameObjectState state, LayerUsageFlags query, bool debugHelperRenderer = false)
        {
            var renderContainer = ChiselObjectUtility.CreateGameObject(name, parent, state, debugHelperRenderer: debugHelperRenderer);
            var meshFilter      = renderContainer.AddComponent <MeshFilter>();
            var meshRenderer    = renderContainer.AddComponent <MeshRenderer>();

            meshRenderer.enabled = false;

            var renderObjects = new ChiselRenderObjects
            {
                invalid             = false,
                query               = query,
                container           = renderContainer,
                meshFilter          = meshFilter,
                meshRenderer        = meshRenderer,
                renderMaterials     = new Material[0],
                debugHelperRenderer = debugHelperRenderer
            };

            renderObjects.EnsureMeshesAllocated();
            renderObjects.Initialize();
            return(renderObjects);
        }
        public static void Reset()
        {
            Clear();
            var usedContainers = new HashSet <ChiselBrushContainerAsset>();
            var chiselNodes    = Resources.FindObjectsOfTypeAll <ChiselNode>();

            foreach (var chiselNode in chiselNodes)
            {
                var usedAssets = chiselNode.GetUsedGeneratedBrushes();
                if (usedAssets == null)
                {
                    continue;
                }
                foreach (var asset in usedAssets)
                {
                    usedContainers.Add(asset);
                }
            }
            var brushContainerAssets = Resources.FindObjectsOfTypeAll <ChiselBrushContainerAsset>();

            foreach (var brushContainerAsset in brushContainerAssets)
            {
                if (!usedContainers.Contains(brushContainerAsset))
                {
#if UNITY_EDITOR
                    var path = UnityEditor.AssetDatabase.GetAssetPath(brushContainerAsset);
                    if (string.IsNullOrEmpty(path))
#endif
                    {
                        ChiselObjectUtility.SafeDestroy(brushContainerAsset);
                        continue;
                    }
                }
                Register(brushContainerAsset);
                brushContainerAsset.CreateInstances();
            }
        }
Exemple #16
0
 public void DestroyWithUndo()
 {
     ChiselObjectUtility.SafeDestroyWithUndo(meshCollider);
     ChiselObjectUtility.SafeDestroyWithUndo(sharedMesh);
 }
Exemple #17
0
 public void RemoveContainerFlags()
 {
     ChiselObjectUtility.RemoveContainerFlags(meshFilter);
     ChiselObjectUtility.RemoveContainerFlags(meshRenderer);
     ChiselObjectUtility.RemoveContainerFlags(container);
 }
        static readonly ModelState __modelState = new ModelState(); // static to avoid allocations
        public void Rebuild(ChiselModel model)
        {
            if (model.generatedMeshes == null ||
                model.generatedMeshes.Length == 0)
            {
                // Destroy leftover components in model lookups
                DestroyAllRegisteredGeneratedComponentsInModel(model);
                RemoveContainerGameObject(model);
            }
            else
            {
                if (!model.IsInitialized)
                {
                    model.OnInitialize();
                }

                if (!model.GeneratedDataTransform)
                {
                    DestroyAllRegisteredGeneratedComponentsInModel(model);
                    CreateContainerGameObject(model);
                }

                var modelGameObject = model.gameObject;
    #if UNITY_EDITOR
                __modelState.staticFlags = UnityEditor.GameObjectUtility.GetStaticEditorFlags(modelGameObject);
    #endif
                __modelState.modelGameObject          = modelGameObject;
                __modelState.modelTransform           = model.hierarchyItem.Transform;
                __modelState.layer                    = modelGameObject.layer;
                __modelState.containerGameObject      = model.GeneratedDataContainer;
                __modelState.containerTransform       = model.GeneratedDataTransform;
                __modelState.existingRenderComponents = model.generatedRenderComponents;
                __modelState.existingMeshColliders    = model.generatedMeshColliders;

                UpdateModelFlags(model);
                UpdateContainerFlags(model, __modelState);
                // Build components for generatedMesh, re-use existing components if they're available (& remove from lookups)


                updateMeshRenderers.Clear();
                updateMeshColliders.Clear();
                for (int i = 0; i < model.generatedMeshes.Length; i++)
                {
                    var generatedMesh = model.generatedMeshes[i];
                    BuildComponents(model, __modelState, generatedMesh);
                }
                UpdateComponents(model, updateMeshRenderers, updateMeshColliders);
                updateMeshRenderers.Clear();
                updateMeshColliders.Clear();


                // Destroy leftover components in model lookups
                DestroyAllRegisteredGeneratedComponentsInModel(model);

                // Rebuild component lookup tables used by generatedMeshes
                BuildGeneratedComponentLookupTables(model);

                var containerTransform = __modelState.containerTransform;
                for (int c = containerTransform.childCount - 1; c >= 0; c--)
                {
                    var child = containerTransform.GetChild(c);
                    if (!model.generatedComponents.Contains(child))
                    {
                        ChiselObjectUtility.SafeDestroy(child.gameObject);
                    }
                }
            }


            // to avoid dangling memory
            __modelState.modelGameObject     = null;
            __modelState.modelTransform      = null;
            __modelState.containerGameObject = null;
            __modelState.containerTransform  = null;
        }
        public static ChiselGeneratedObjects Create(GameObject parentGameObject)
        {
            var parentTransform = parentGameObject.transform;

            // Make sure there's not a dangling container out there from a previous version
            var existingContainer = parentTransform.FindChildByName(kGeneratedContainerName);

            ChiselObjectUtility.SafeDestroy(existingContainer, ignoreHierarchyEvents: true);

            var gameObjectState    = GameObjectState.Create(parentGameObject);
            var container          = ChiselObjectUtility.CreateGameObject(kGeneratedContainerName, parentTransform, gameObjectState);
            var containerTransform = container.transform;
            var colliderContainer  = ChiselObjectUtility.CreateGameObject(kGeneratedMeshColliderName, containerTransform, gameObjectState);

            Debug.Assert((int)LayerUsageFlags.Renderable == 1);
            Debug.Assert((int)LayerUsageFlags.CastShadows == 2);
            Debug.Assert((int)LayerUsageFlags.ReceiveShadows == 4);
            Debug.Assert((int)LayerUsageFlags.RenderReceiveCastShadows == (1 | 2 | 4));

            var renderables = new ChiselRenderObjects[]
            {
                new ChiselRenderObjects()
                {
                    invalid = true
                },
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[1], containerTransform, gameObjectState, LayerUsageFlags.Renderable),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[2], containerTransform, gameObjectState, LayerUsageFlags.CastShadows),
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[3], containerTransform, gameObjectState, LayerUsageFlags.Renderable | LayerUsageFlags.CastShadows),
                new ChiselRenderObjects()
                {
                    invalid = true
                },
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[5], containerTransform, gameObjectState, LayerUsageFlags.Renderable | LayerUsageFlags.ReceiveShadows),
                new ChiselRenderObjects()
                {
                    invalid = true
                },
                ChiselRenderObjects.Create(kGeneratedMeshRendererNames[7], containerTransform, gameObjectState, LayerUsageFlags.Renderable | LayerUsageFlags.CastShadows | LayerUsageFlags.ReceiveShadows),
            };

            var meshRenderers = new MeshRenderer[]
            {
                renderables[1].meshRenderer,
                renderables[2].meshRenderer,
                renderables[3].meshRenderer,
                renderables[5].meshRenderer,
                renderables[7].meshRenderer
            };

            renderables[1].invalid = false;
            renderables[2].invalid = false;
            renderables[3].invalid = false;
            renderables[5].invalid = false;
            renderables[7].invalid = false;

            var debugHelpers       = new ChiselRenderObjects[kDebugHelperCount];
            var debugMeshRenderers = new MeshRenderer[kDebugHelperCount];

            for (int i = 0; i < kDebugHelperCount; i++)
            {
                debugHelpers[i]         = ChiselRenderObjects.Create(kGeneratedDebugRendererNames[i], containerTransform, gameObjectState, AssignMeshesJob.kGeneratedDebugRendererFlags[i].Item1, debugHelperRenderer: true);
                debugMeshRenderers[i]   = debugHelpers[0].meshRenderer;
                debugHelpers[i].invalid = false;
            }

            var result = new ChiselGeneratedObjects
            {
                generatedDataContainer = container,
                colliderContainer      = colliderContainer,
                colliders          = new ChiselColliderObjects[0],
                renderables        = renderables,
                meshRenderers      = meshRenderers,
                debugHelpers       = debugHelpers,
                debugMeshRenderers = debugMeshRenderers
            };

            Debug.Assert(IsValid(result));

            return(result);
        }
        // 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);
        }
        public void Update(ChiselModel model, GeneratedMeshDescription[] meshDescriptions)
        {
            var modelState = GameObjectState.Create(model);

            ChiselObjectUtility.UpdateContainerFlags(generatedDataContainer, modelState);

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

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

            for (int i = 0; i < renderables.Length; i++)
            {
                if (renderables[i] == null)
                {
                    continue;
                }
                var renderableContainer = renderables[i].container;
                ChiselObjectUtility.UpdateContainerFlags(renderableContainer, modelState);
                ChiselObjectUtility.ResetTransform(renderableContainer.transform, requiredParent: containerTransform);
            }

            Debug.Assert(LayerParameterIndex.LayerParameter1 < LayerParameterIndex.LayerParameter2);
            Debug.Assert((LayerParameterIndex.LayerParameter1 + 1) == LayerParameterIndex.LayerParameter2);
            Debug.Assert(meshDescriptions[0].meshQuery.LayerParameterIndex >= LayerParameterIndex.LayerParameter1);

            int descriptionIndex = 0;

            ChiselRenderObjects.UpdateProperties(model, meshRenderers);
            ChiselColliderObjects.UpdateColliders(model, colliders);

            renderMaterials.Clear();

            // Loop through all meshDescriptions with LayerParameter1, and create renderable meshes from them
            if (meshDescriptions[0].meshQuery.LayerParameterIndex == LayerParameterIndex.LayerParameter1)
            {
                var prevQuery  = meshDescriptions[0].meshQuery;
                var startIndex = 0;
                for (; descriptionIndex < meshDescriptions.Length; descriptionIndex++)
                {
                    ref var meshDescriptionIterator = ref meshDescriptions[descriptionIndex];
                    // Exit when layerParameterIndex is no longer LayerParameter1
                    if (meshDescriptionIterator.meshQuery.LayerParameterIndex != LayerParameterIndex.LayerParameter1)
                    {
                        break;
                    }

                    var currQuery = meshDescriptionIterator.meshQuery;
                    if (prevQuery == currQuery)
                    {
                        continue;
                    }

                    prevQuery = currQuery;
                    var renderIndex = (int)(prevQuery.LayerQueryMask & LayerUsageFlags.RenderReceiveCastShadows);

                    // Group by all meshDescriptions with same query
                    renderables[renderIndex].Update(model, modelState, meshDescriptions, startIndex, descriptionIndex);
                    renderMaterials.AddRange(renderables[renderIndex].renderMaterials);
                    startIndex = descriptionIndex;
                }

                {
                    var renderIndex = (int)(prevQuery.LayerQueryMask & LayerUsageFlags.RenderReceiveCastShadows);

                    // Group by all meshDescriptions with same query
                    renderables[renderIndex].Update(model, modelState, meshDescriptions, startIndex, descriptionIndex);
                    renderMaterials.AddRange(renderables[renderIndex].renderMaterials);
                }
            }
        // 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);
        }
Exemple #23
0
 public void RemoveContainerFlags()
 {
     ChiselObjectUtility.RemoveContainerFlags(meshCollider);
 }