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); } }
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(); }
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); } }
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); } }
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); } }
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; }