public override void OnInitialize()
        {
            base.OnInitialize();
            if (generated != null &&
                !generated.generatedDataContainer)
            {
                generated.Destroy();
            }

            if (generated == null)
            {
                generated = ChiselGeneratedObjects.Create(gameObject);
            }

            if (colliderSettings == null)
            {
                colliderSettings = new ChiselGeneratedColliderSettings();
                colliderSettings.Reset();
            }

            if (renderSettings == null)
            {
                renderSettings = new ChiselGeneratedRenderSettings();
                renderSettings.Reset();
            }

#if UNITY_EDITOR
            if (uvGenerationSettings == null)
            {
                uvGenerationSettings = new SerializableUnwrapParam();
                UnityEditor.UnwrapParam defaults;
                UnityEditor.UnwrapParam.SetDefaults(out defaults);
                uvGenerationSettings.angleError       = defaults.angleError;
                uvGenerationSettings.areaError        = defaults.areaError;
                uvGenerationSettings.hardAngle        = defaults.hardAngle;
                uvGenerationSettings.packMarginPixels = defaults.packMargin * 256;
            }
#else
            if (generated != null && generated.meshRenderers != null)
            {
                foreach (var renderable in generated.renderables)
                {
                    renderable.meshRenderer.forceRenderingOff = true;
                    renderable.meshRenderer.enabled           = renderable.sharedMesh.vertexCount == 0;
                }
            }
#endif

            // Legacy solution
            if (!IsDefaultModel &&
                name == ChiselGeneratedComponentManager.kGeneratedDefaultModelName)
            {
                IsDefaultModel = true;
            }

            initialized = true;
        }
        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);
        }
        public void Rebuild(ChiselModel model)
        {
            if (!model.IsInitialized)
            {
                model.OnInitialize();
            }

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

            UpdateModelFlags(model);
        }
        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);
        }
        public static bool IsValid(ChiselGeneratedObjects satelliteObjects)
        {
            if (satelliteObjects == null)
            {
                return(false);
            }

            if (!satelliteObjects.generatedDataContainer)
            {
                return(false);
            }

            if (!satelliteObjects.colliderContainer ||
                satelliteObjects.colliders == null)   // must be an array, even if 0 length
            {
                return(false);
            }

            if (satelliteObjects.renderables == null ||
                satelliteObjects.renderables.Length != kGeneratedMeshRenderCount ||
                satelliteObjects.meshRenderers == null ||
                satelliteObjects.meshRenderers.Length != kGeneratedMeshRendererCount)
            {
                return(false);
            }

            if (satelliteObjects.debugHelpers == null ||
                satelliteObjects.debugHelpers.Length != kDebugHelperCount ||
                satelliteObjects.debugMeshRenderers == null ||
                satelliteObjects.debugMeshRenderers.Length != kDebugHelperCount)
            {
                return(false);
            }

            // These queries are valid, and should never be null (We don't care about the other queries)
            if (satelliteObjects.renderables[1] == null ||
                satelliteObjects.renderables[2] == null ||
                satelliteObjects.renderables[3] == null ||
                satelliteObjects.renderables[5] == null ||
                satelliteObjects.renderables[7] == null)
            {
                return(false);
            }

            // These queries are valid, and should never be null (We don't care about the other queries)
            for (int i = 0; i < kDebugHelperCount; i++)
            {
                if (satelliteObjects.debugHelpers[i] == null)
                {
                    return(false);
                }
            }

            satelliteObjects.renderables[0].invalid = true;
            satelliteObjects.renderables[1].invalid = false;
            satelliteObjects.renderables[2].invalid = false;
            satelliteObjects.renderables[3].invalid = false;
            satelliteObjects.renderables[4].invalid = true;
            satelliteObjects.renderables[5].invalid = false;
            satelliteObjects.renderables[6].invalid = true;
            satelliteObjects.renderables[7].invalid = false;

            for (int i = 0; i < kDebugHelperCount; i++)
            {
                satelliteObjects.debugHelpers[i].invalid = false;
            }

            for (int i = 0; i < satelliteObjects.renderables.Length; i++)
            {
                if (satelliteObjects.renderables[i] == null ||
                    satelliteObjects.renderables[i].invalid)
                {
                    continue;
                }
                if (!ChiselRenderObjects.IsValid(satelliteObjects.renderables[i]))
                {
                    return(false);
                }
            }

            for (int i = 0; i < satelliteObjects.debugHelpers.Length; i++)
            {
                if (satelliteObjects.debugHelpers[i] == null)
                {
                    continue;
                }
                if (!ChiselRenderObjects.IsValid(satelliteObjects.debugHelpers[i]))
                {
                    return(false);
                }
            }

            for (int i = 0; i < satelliteObjects.colliders.Length; i++)
            {
                if (!ChiselColliderObjects.IsValid(satelliteObjects.colliders[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
 static void BeginMeshUpdates()
 {
     s_UpdatedModels.Clear();
     ChiselGeneratedObjects.BeginMeshUpdates();
 }