Beispiel #1
0
        public IEnumerator CreateBrushMaterialWithRenderMaterial_ChangeRenderMaterial_ManagerOnlyKnowsNewMaterial()
        {
            using (var newBrushMaterial = new ChiselBrushMaterial())
            {
                var newRenderMaterial1 = new Material(Shader.Find("Specular"));
                var newRenderMaterial2 = new Material(Shader.Find("Specular"));

                newBrushMaterial.RenderMaterial = newRenderMaterial1;
                yield return(null);

                Assert.AreNotEqual(newRenderMaterial1, newRenderMaterial2);
                Assert.AreEqual(newRenderMaterial1, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial1.GetInstanceID(), false));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial1.GetInstanceID()));
                LogAssert.Expect(LogType.Error, new Regex("Could not find"));
                Assert.IsNull(ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial2.GetInstanceID(), false));
                newBrushMaterial.RenderMaterial = newRenderMaterial2;
                yield return(null);

                ChiselBrushMaterialManager.Update();

                LogAssert.Expect(LogType.Error, new Regex("Could not find"));
                Assert.IsNull(ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial1.GetInstanceID(), false));
                Assert.AreEqual(newRenderMaterial2, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial2.GetInstanceID(), false));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial2.GetInstanceID()));

                UnityEngine.Object.DestroyImmediate(newRenderMaterial1);
                UnityEngine.Object.DestroyImmediate(newRenderMaterial2);
            }
        }
Beispiel #2
0
        public IEnumerator RemoveAndAddRenderMaterialToAnotherBrushMaterial_MaterialStillRegistered()
        {
            using (ChiselBrushMaterial newBrushMaterial1 = new ChiselBrushMaterial(), newBrushMaterial2 = new ChiselBrushMaterial())
            {
                var newRenderMaterial1 = new Material(Shader.Find("Specular"));
                var newRenderMaterial2 = new Material(Shader.Find("Specular"));

                newBrushMaterial1.RenderMaterial = newRenderMaterial1;
                newBrushMaterial2.RenderMaterial = newRenderMaterial2;
                yield return(null);

                ChiselBrushMaterialManager.Update();

                Assert.AreEqual(newRenderMaterial1, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial1.GetInstanceID(), false));
                Assert.AreEqual(newRenderMaterial2, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial2.GetInstanceID(), false));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial1.GetInstanceID()));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial2.GetInstanceID()));
                newBrushMaterial1.RenderMaterial = newRenderMaterial2;
                newBrushMaterial2.RenderMaterial = newRenderMaterial1;
                yield return(null);

                ChiselBrushMaterialManager.Update();

                Assert.AreEqual(newRenderMaterial1, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial1.GetInstanceID(), false));
                Assert.AreEqual(newRenderMaterial2, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial2.GetInstanceID(), false));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial1.GetInstanceID()));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial2.GetInstanceID()));

                UnityEngine.Object.DestroyImmediate(newRenderMaterial1);
                UnityEngine.Object.DestroyImmediate(newRenderMaterial2);
            }
        }
        static readonly List <GeneratedMeshContents> __foundContents = new List <GeneratedMeshContents>(); // static to avoid allocations
        public void Update(ChiselModel model, GameObjectState state, GeneratedMeshDescription[] meshDescriptions, int startIndex, int endIndex)
        {
            bool meshIsModified = false;

            // Retrieve the generatedMeshes and its materials, combine them into a single Unity Mesh/Material array
            try
            {
                for (int i = startIndex; i < endIndex; i++)
                {
                    ref var meshDescription       = ref meshDescriptions[i];
                    var     generatedMeshContents = model.Node.GetGeneratedMesh(meshDescription);
                    if (generatedMeshContents == null)
                    {
                        continue;
                    }
                    if (generatedMeshContents.indices.Length == 0)
                    {
                        generatedMeshContents.Dispose();
                        continue;
                    }
                    var renderMaterial = ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(meshDescription.surfaceParameter);
                    __foundContents.Add(generatedMeshContents);
                    __foundMaterials.Add(renderMaterial);
                }
                triangleBrushes.Clear();
                if (__foundContents.Count == 0)
                {
                    if (sharedMesh.vertexCount > 0)
                    {
                        sharedMesh.Clear(keepVertexLayout: true);
                    }
                }
                else
                {
                    sharedMesh.CopyFrom(__foundContents, triangleBrushes);
#if UNITY_EDITOR
                    ChiselGeneratedComponentManager.SetHasLightmapUVs(sharedMesh, false);
#endif
                }
                if (renderMaterials != null &&
                    renderMaterials.Length == __foundMaterials.Count)
                {
                    __foundMaterials.CopyTo(renderMaterials);
                }
                else
                {
                    renderMaterials = __foundMaterials.ToArray();
                }
                if (meshFilter.sharedMesh != sharedMesh)
                {
                    meshFilter.sharedMesh = sharedMesh;
                    meshIsModified        = true;
                }
                meshRenderer.sharedMaterials = renderMaterials;
                meshRenderer.enabled         = sharedMesh.vertexCount > 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 int[brushIndicesArray.Length];
                }
                NativeArray <int> .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  = ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(meshDescription.surfaceParameter);

                        instance.renderMaterials[i] = renderMaterial;
                    }
                }
                instance.SetMaterialsIfModified(instance.meshRenderer, instance.renderMaterials);
            }
            Profiler.EndSample();
        }
Beispiel #5
0
        public IEnumerator CreateBrushMaterialWithRenderMaterial_ManagerKnowsMaterial()
        {
            using (var newBrushMaterial = new ChiselBrushMaterial())
            {
                var newRenderMaterial = new Material(Shader.Find("Specular"));

                newBrushMaterial.RenderMaterial = newRenderMaterial;
                yield return(null);

                ChiselBrushMaterialManager.Update();

                Assert.True(ChiselBrushMaterialManager.IsRegistered(newBrushMaterial));
                Assert.AreEqual(newRenderMaterial, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial.GetInstanceID(), false));
                Assert.AreEqual(1, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial.GetInstanceID()));

                UnityEngine.Object.DestroyImmediate(newRenderMaterial);
            }
        }
Beispiel #6
0
        public IEnumerator CreateTwoBrushMaterialsWithSameRenderMaterial_RefCountIsTwo()
        {
            using (ChiselBrushMaterial newBrushMaterial1 = new ChiselBrushMaterial(), newBrushMaterial2 = new ChiselBrushMaterial())
            {
                var newRenderMaterial = new Material(Shader.Find("Specular"));

                newBrushMaterial1.RenderMaterial = newRenderMaterial;
                newBrushMaterial2.RenderMaterial = newRenderMaterial;
                yield return(null);

                ChiselBrushMaterialManager.Update();

                Assert.AreEqual(newRenderMaterial, ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial.GetInstanceID(), false));
                Assert.AreEqual(2, ChiselBrushMaterialManager.GetRenderMaterialRefCountByInstanceID(newRenderMaterial.GetInstanceID()));

                UnityEngine.Object.DestroyImmediate(newRenderMaterial);
            }
        }
Beispiel #7
0
        public IEnumerator CreateBrushMaterialWithRenderMaterial_DestroyBrushMaterial_ManagerDoesNotKnowMaterial()
        {
            using (var newBrushMaterial = new ChiselBrushMaterial())
            {
                var newRenderMaterial = new Material(Shader.Find("Specular"));

                newBrushMaterial.RenderMaterial = newRenderMaterial;
                newBrushMaterial.Dispose();
                yield return(null);

                ChiselBrushMaterialManager.Update();

                LogAssert.Expect(LogType.Error, new Regex("Could not find"));
                Assert.IsNull(ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newRenderMaterial.GetInstanceID(), false));

                UnityEngine.Object.DestroyImmediate(newRenderMaterial);
            }
        }
Beispiel #8
0
        public IEnumerator CreateBrushMaterialWithPhysicMateriall_RetrieveRenderMaterialWithPhysicsMaterialInstanceID_ReturnsNull()
        {
            using (var newBrushMaterial = new ChiselBrushMaterial())
            {
                var newPhysicsMaterial = new PhysicMaterial();

                newBrushMaterial.PhysicsMaterial = newPhysicsMaterial;
                yield return(null);

                ChiselBrushMaterialManager.Update();

                Assert.True(ChiselBrushMaterialManager.IsRegistered(newBrushMaterial));
                LogAssert.Expect(LogType.Error, new Regex("Trying to use PhysicMaterial with"));
                Assert.IsNull(ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(newPhysicsMaterial.GetInstanceID(), false));

                UnityEngine.Object.DestroyImmediate(newPhysicsMaterial);
            }
        }
        internal void BuildComponents(ChiselModel model,
                                      ModelState modelState,
                                      ChiselGeneratedModelMesh generatedMesh)
        {
            Material       renderMaterial  = null;
            PhysicMaterial physicsMaterial = null;

            if (generatedMesh.meshDescription.surfaceParameter != 0)
            {
                var type      = generatedMesh.meshDescription.meshQuery.LayerParameterIndex;
                var parameter = generatedMesh.meshDescription.surfaceParameter;
                switch (type)
                {
                case LayerParameterIndex.LayerParameter1: renderMaterial = ChiselBrushMaterialManager.GetRenderMaterialByInstanceID(parameter);  break;

                case LayerParameterIndex.LayerParameter2: physicsMaterial = ChiselBrushMaterialManager.GetPhysicsMaterialByInstanceID(parameter); break;
                }
            }
            else
            {
                var type = generatedMesh.meshDescription.meshQuery.LayerParameterIndex;
                switch (type)
                {
                case LayerParameterIndex.LayerParameter1: renderMaterial = CSGMaterialManager.DefaultMaterial; break;

                case LayerParameterIndex.LayerParameter2: physicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; break;
                }
            }

            if (renderMaterial != null)
            {
                generatedMesh.renderComponents = null;
                List <ChiselRenderComponents> components;
                if (modelState.existingRenderComponents.TryGetValue(renderMaterial, out components))
                {
                    while (components.Count > 0)
                    {
                        var curComponents = components[0];
                        components.RemoveAt(0);

                        if (components.Count == 0)
                        {
                            modelState.existingRenderComponents.Remove(renderMaterial);
                            model.generatedComponents.Remove(curComponents.transform);
                        }

                        if (curComponents.meshRenderer && curComponents.meshFilter)
                        {
                            generatedMesh.renderComponents = curComponents;
                            break;
                        }
                    }
                }

                var forceUpdate = UpdateOrCreateRenderComponents(model, modelState, generatedMesh.meshDescription, ref generatedMesh.renderComponents);
                if (generatedMesh.renderComponents.meshRenderer.sharedMaterial != renderMaterial)
                {
                    generatedMesh.renderComponents.meshRenderer.sharedMaterial = renderMaterial;
                }
                if (generatedMesh.renderComponents.meshFilter.sharedMesh != generatedMesh.sharedMesh)
                {
                    generatedMesh.renderComponents.meshFilter.sharedMesh = generatedMesh.sharedMesh;
                }
                if (generatedMesh.needsUpdate || forceUpdate)
                {
#if UNITY_EDITOR
                    if ((modelState.staticFlags & UnityEditor.StaticEditorFlags.LightmapStatic) == UnityEditor.StaticEditorFlags.LightmapStatic)
                    {
                        generatedMesh.renderComponents.meshRenderer.realtimeLightmapIndex = -1;
                        generatedMesh.renderComponents.meshRenderer.lightmapIndex         = -1;
                        generatedMesh.renderComponents.uvLightmapUpdateTime = Time.realtimeSinceStartup;
                        haveUVsToUpdate = true;
                    }
#endif
                }
            }
            else
            if (physicsMaterial != null)
            {
                generatedMesh.colliderComponents = null;
                List <ChiselColliderComponents> components;
                if (modelState.existingMeshColliders.TryGetValue(physicsMaterial, out components))
                {
                    while (components.Count > 0)
                    {
                        var curComponents = components[0];
                        components.RemoveAt(0);
                        if (components.Count == 0)
                        {
                            modelState.existingMeshColliders.Remove(physicsMaterial);
                            model.generatedComponents.Remove(curComponents.transform);
                        }

                        if (curComponents.meshCollider)
                        {
                            generatedMesh.colliderComponents = curComponents;
                            break;
                        }
                    }
                }

                UpdateOrCreateColliderComponents(model, modelState, generatedMesh.meshDescription, ref generatedMesh.colliderComponents);
                if (generatedMesh.colliderComponents.meshCollider.sharedMesh != generatedMesh.sharedMesh)
                {
                    generatedMesh.colliderComponents.meshCollider.sharedMesh = generatedMesh.sharedMesh;
                }
                if (generatedMesh.colliderComponents.meshCollider.sharedMaterial != physicsMaterial)
                {
                    generatedMesh.colliderComponents.meshCollider.sharedMaterial = physicsMaterial;
                }
            }
            generatedMesh.needsUpdate = false;
        }