Esempio n. 1
0
        private static NativeArray <Voxel> LoadVoxels(DiggerSystem digger, Vector3i chunkPosition)
        {
            Utils.Profiler.BeginSample("[Dig] VoxelChunk.LoadVoxels");

            if (!digger.IsChunkBelongingToMe(chunkPosition))
            {
                var neighbor = digger.GetNeighborAt(chunkPosition);
                if (neighbor)
                {
                    var neighborChunkPosition = neighbor.ToChunkPosition(digger.ToWorldPosition(chunkPosition));
                    if (!neighbor.IsChunkBelongingToMe(neighborChunkPosition))
                    {
                        Debug.LogError(
                            $"neighborChunkPosition {neighborChunkPosition} should always belong to neighbor");
                        return(new NativeArray <Voxel>(1, Allocator.TempJob));
                    }

                    return(LoadVoxels(neighbor, neighborChunkPosition));
                }
            }

            if (digger.GetChunk(chunkPosition, out var chunk))
            {
                if (chunk.VoxelChunk.voxelArrayBeforeSmooth != null)
                {
                    return(new NativeArray <Voxel>(chunk.VoxelChunk.voxelArrayBeforeSmooth, Allocator.TempJob));
                }

                chunk.LazyLoad();
                return(new NativeArray <Voxel>(chunk.VoxelChunk.voxelArray, Allocator.TempJob));
            }

            return(new NativeArray <Voxel>(1, Allocator.TempJob));
        }
Esempio n. 2
0
        private static void SetupMicroSplatMaterial(DiggerSystem diggerSystem)
        {
            var microSplat = diggerSystem.Terrain.GetComponent <MicroSplatTerrain>();

            if (!microSplat)
            {
                Debug.LogError($"Could not find MicroSplatTerrain on terrain {diggerSystem.Terrain.name}");
                return;
            }

            var microSplatShader = MicroSplatUtilities.GetDiggerShader(microSplat);

            if (microSplatShader == null)
            {
                Debug.LogError($"Could not find MicroSplat Digger shader");
                return;
            }

            var material = new Material(microSplatShader);

            material.CopyPropertiesFromMaterial(microSplat.matInstance);

            var matPath = Path.Combine(diggerSystem.BasePathData, $"diggerMicroSplat.mat");

            material = EditorUtils.CreateOrReplaceAsset(material, matPath);
            AssetDatabase.ImportAsset(matPath, ImportAssetOptions.ForceUpdate);
            diggerSystem.Materials[0] = material;
        }
Esempio n. 3
0
        internal static VoxelChunk Create(DiggerSystem digger, Chunk chunk)
        {
            Utils.Profiler.BeginSample("VoxelChunk.Create");
            var go = new GameObject("VoxelChunk")
            {
                hideFlags = HideFlags.DontSaveInBuild
            };

            go.transform.parent        = chunk.transform;
            go.transform.position      = Vector3.zero;
            go.transform.localRotation = Quaternion.identity;
            go.transform.localScale    = Vector3.one;
            var voxelChunk = go.AddComponent <VoxelChunk>();

            voxelChunk.digger        = digger;
            voxelChunk.sizeVox       = digger.SizeVox;
            voxelChunk.sizeOfMesh    = digger.SizeOfMesh;
            voxelChunk.chunkPosition = chunk.ChunkPosition;
            voxelChunk.voxelPosition = chunk.VoxelPosition;
            voxelChunk.worldPosition = chunk.WorldPosition;
            voxelChunk.Load();

            Utils.Profiler.EndSample();
            return(voxelChunk);
        }
Esempio n. 4
0
        private static void SetupCTSMaterial(DiggerSystem diggerSystem)
        {
            if (!diggerSystem.Terrain.materialTemplate)
            {
                Debug.LogError("Could not setup CTS material for Digger because terrain.materialTemplate is null.");
                return;
            }

            if (diggerSystem.Materials == null || diggerSystem.Materials.Length != 1)
            {
                diggerSystem.Materials = new Material[1];
            }

            if (diggerSystem.Terrain.materialTemplate.shader.name.StartsWith("CTS/CTS Terrain Shader Basic"))
            {
                SetupCTSBasicMaterial(diggerSystem);
            }
            else if (diggerSystem.Terrain.materialTemplate.shader.name.StartsWith(
                         "CTS/CTS Terrain Shader Advanced Tess"))
            {
                SetupCTSAdvancedTessMaterial(diggerSystem);
            }
            else if (diggerSystem.Terrain.materialTemplate.shader.name.StartsWith("CTS/CTS Terrain Shader Advanced"))
            {
                SetupCTSAdvancedMaterial(diggerSystem);
            }
            else
            {
                Debug.LogError(
                    $"Could not setup CTS material for Digger because terrain shader was not a known CTS shader. Was {diggerSystem.Terrain.materialTemplate.shader.name}");
            }
        }
Esempio n. 5
0
        private static void SetupMicroSplatMaterials(DiggerSystem diggerSystem)
        {
            if (diggerSystem.Materials == null || diggerSystem.Materials.Length != 1)
            {
                diggerSystem.Materials = new Material[1];
            }

            var textures = new List <Texture2D>();
            var tData    = diggerSystem.Terrain.terrainData;

            for (var i = 0; i < tData.terrainLayers.Length && i < 28; i++)
            {
                var terrainLayer = tData.terrainLayers[i];
                if (terrainLayer == null || terrainLayer.diffuseTexture == null)
                {
                    continue;
                }

                textures.Add(terrainLayer.diffuseTexture);
            }

            diggerSystem.TerrainTextures = textures.ToArray();
#if __MICROSPLAT_DIGGER__
            CheckMicroSplatTerrainFeatures(diggerSystem);
            SetupMicroSplatMaterial(diggerSystem);
            SetupMicroSplatMaterialSyncEventHandler(diggerSystem);
#endif // __MICROSPLAT_DIGGER__
        }
Esempio n. 6
0
        private static void CheckMicroSplatTerrainFeatures(DiggerSystem diggerSystem)
        {
            var microSplat = diggerSystem.Terrain.GetComponent <MicroSplatTerrain>();

            if (!microSplat)
            {
                Debug.LogError($"Could not find MicroSplatTerrain on terrain {diggerSystem.Terrain.name}");
                return;
            }

#if !UNITY_2019_3_OR_NEWER
#if __MICROSPLAT_ALPHAHOLE__
            if (!microSplat.keywordSO.IsKeywordEnabled("_ALPHAHOLETEXTURE"))
            {
                microSplat.keywordSO.EnableKeyword("_ALPHAHOLETEXTURE");
            }
#else
            Debug.LogError("MicroSplat Digger integration requires the MicroSplat AlphaHole module unless you use Unity 2019.3+");
#endif
#endif

#if __MICROSPLAT_TRIPLANAR__
            if (!microSplat.keywordSO.IsKeywordEnabled("_TRIPLANAR"))
            {
                microSplat.keywordSO.EnableKeyword("_TRIPLANAR");
            }

            if (microSplat.keywordSO.IsKeywordEnabled("_TRIPLANARLOCALSPACE"))
            {
                microSplat.keywordSO.DisableKeyword("_TRIPLANARLOCALSPACE");
            }
#else
            Debug.LogError("MicroSplat Digger integration requires the MicroSplat Triplanar module.");
#endif
        }
Esempio n. 7
0
 private void Awake()
 {
     // For retro-compatibility
     if (!Digger)
     {
         Digger = GetComponentInParent <DiggerSystem>();
     }
 }
Esempio n. 8
0
 public void SaveMeshesAsAssets(DiggerSystem digger)
 {
     for (var i = 0; i < chunks.Length; i++)
     {
         var chunk = chunks[i];
         chunk.SaveMeshesAsAssets(digger, IndexToLod(i));
     }
 }
Esempio n. 9
0
        internal static ChunkLODGroup Create(Vector3i chunkPosition,
                                             Chunk chunk,
                                             DiggerSystem digger,
                                             Terrain terrain,
                                             Material[] materials,
                                             int layer,
                                             string tag)
        {
            Utils.Profiler.BeginSample("ChunkLODGroup.Create");
            var go = new GameObject(GetName(chunkPosition));

            go.layer                   = layer;
            go.tag                     = tag;
            go.transform.parent        = chunk.transform;
            go.transform.localPosition = Vector3.zero;
            go.transform.localRotation = Quaternion.identity;
            go.transform.localScale    = Vector3.one;

            var chunkLodGroup = go.AddComponent <ChunkLODGroup>();

            if (digger.CreateLODs)
            {
                var lodGroup = go.AddComponent <LODGroup>();
                chunkLodGroup.chunks = new[]
                {
                    ChunkObject.Create(1, chunkPosition, chunkLodGroup, digger.ColliderLodIndex == 0, digger, terrain,
                                       materials, layer, tag),
                    ChunkObject.Create(2, chunkPosition, chunkLodGroup, digger.ColliderLodIndex == 1, digger, terrain,
                                       materials, layer, tag),
                    ChunkObject.Create(4, chunkPosition, chunkLodGroup, digger.ColliderLodIndex == 2, digger, terrain,
                                       materials, layer, tag)
                };
                var renderers = new Renderer[chunkLodGroup.chunks.Length];
                for (var i = 0; i < renderers.Length; ++i)
                {
                    renderers[i] = chunkLodGroup.chunks[i].GetComponent <MeshRenderer>();
                }

                var lods = new[]
                {
                    new LOD(digger.ScreenRelativeTransitionHeightLod0, new[] { renderers[0] }),
                    new LOD(digger.ScreenRelativeTransitionHeightLod1, new[] { renderers[1] }),
                    new LOD(0f, new[] { renderers[2] })
                };
                lodGroup.SetLODs(lods);
                chunkLodGroup.lodGroup = lodGroup;
            }
            else
            {
                chunkLodGroup.chunks = new[]
                {
                    ChunkObject.Create(1, chunkPosition, chunkLodGroup, true, digger, terrain, materials, layer, tag)
                };
            }

            Utils.Profiler.EndSample();
            return(chunkLodGroup);
        }
Esempio n. 10
0
        private static void SetupURPTerrainMaterial(DiggerSystem diggerSystem, bool forceRefresh)
        {
            var terrainAlreadyHasDiggerMaterial = diggerSystem.Terrain.materialTemplate &&
                                                  diggerSystem.Terrain.materialTemplate.shader.name == "Digger/URP/Terrain/Lit";

            if (forceRefresh || !terrainAlreadyHasDiggerMaterial)
            {
                var terrainMaterial = new Material(Shader.Find("Digger/URP/Terrain/Lit"));
                terrainMaterial.SetFloat(TerrainWidthInvProperty, 1f / diggerSystem.Terrain.terrainData.size.x);
                terrainMaterial.SetFloat(TerrainHeightInvProperty, 1f / diggerSystem.Terrain.terrainData.size.z);
                if (diggerSystem.Terrain.materialTemplate && diggerSystem.Terrain.materialTemplate.IsKeywordEnabled("_TERRAIN_BLEND_HEIGHT"))
                {
                    terrainMaterial.EnableKeyword("_TERRAIN_BLEND_HEIGHT");
                    terrainMaterial.SetFloat(EnableHeightBlend, 1);
                }
                else
                {
                    terrainMaterial.DisableKeyword("_TERRAIN_BLEND_HEIGHT");
                    terrainMaterial.SetFloat(EnableHeightBlend, 0);
                }

                if (diggerSystem.Terrain.materialTemplate && diggerSystem.Terrain.materialTemplate.IsKeywordEnabled("ENABLE_TERRAIN_PERPIXEL_NORMAL"))
                {
                    terrainMaterial.EnableKeyword("ENABLE_TERRAIN_PERPIXEL_NORMAL");
                    terrainMaterial.SetFloat(EnableInstancedPerPixelNormal, 1);
                }
                else
                {
                    terrainMaterial.DisableKeyword("ENABLE_TERRAIN_PERPIXEL_NORMAL");
                    terrainMaterial.SetFloat(EnableInstancedPerPixelNormal, 0);
                }

                if (diggerSystem.Terrain.materialTemplate)
                {
                    terrainMaterial.SetFloat(HeightTransition, diggerSystem.Terrain.materialTemplate.GetFloat(HeightTransition));
                }

                terrainMaterial = EditorUtils.CreateOrReplaceAsset(terrainMaterial,
                                                                   Path.Combine(diggerSystem.BasePathData, "terrainMaterial.mat"));
                diggerSystem.Terrain.materialTemplate = terrainMaterial;
            }

            if (diggerSystem.Terrain.materialTemplate.shader.name != "Digger/URP/Terrain/Lit")
            {
                Debug.LogWarning("Looks like terrain material doesn't match cave meshes material.");
            }

            if (!terrainAlreadyHasDiggerMaterial)
            {
                EditorUtility.DisplayDialog("URP Version 10.2+",
                                            "If you use URP v10.2+ you must import the latest version of Digger URP shaders in Assets/Digger/Shaders folder. " +
                                            "Just double-click on DiggerURP10.unitypackage file.",
                                            "Ok");
            }
        }
Esempio n. 11
0
        private static void SetupHDRPMaterial(DiggerSystem diggerSystem, List <Texture2D> textures)
        {
            var material = new Material(Shader.Find("Digger/HDRP/Mesh/Lit"));


            var tData = diggerSystem.Terrain.terrainData;

            if (tData.terrainLayers.Length > 4)
            {
                material.EnableKeyword("_TERRAIN_8_LAYERS");
            }

            var enableMaskMap = false;

            for (var i = 0; i < tData.terrainLayers.Length && i < 8; i++)
            {
                var terrainLayer = tData.terrainLayers[i];
                if (terrainLayer == null || terrainLayer.diffuseTexture == null)
                {
                    continue;
                }

                if (terrainLayer.maskMapTexture)
                {
                    enableMaskMap = true;
                }

                material.SetFloat($"_NormalScale{i}", terrainLayer.normalScale);
                material.SetVector($"_MaskMapRemapOffset{i}", Vector4.zero);
                material.SetVector($"_MaskMapRemapScale{i}", Vector4.one);
                material.SetVector($"_DiffuseRemapScale{i}", Vector4.one);
                material.SetFloat($"_LayerHasMask{i}", terrainLayer.maskMapTexture ? 1f : 0f);
                material.SetFloat($"_Metallic{i}", terrainLayer.metallic);
                material.SetFloat($"_Smoothness{i}", terrainLayer.smoothness);
                material.SetTexture(SplatPrefixProperty + i, terrainLayer.diffuseTexture);
                material.SetTexture(NormalPrefixProperty + i, terrainLayer.normalMapTexture);
                material.SetTexture(MaskPrefixProperty + i, terrainLayer.maskMapTexture);
                material.SetTextureScale(SplatPrefixProperty + i,
                                         new Vector2(1f / terrainLayer.tileSize.x, 1f / terrainLayer.tileSize.y));
                material.SetTextureOffset(SplatPrefixProperty + i, terrainLayer.tileOffset);
                textures.Add(terrainLayer.diffuseTexture);
            }

            if (enableMaskMap)
            {
                material.EnableKeyword("_MASKMAP");
            }

            var matPath = Path.Combine(diggerSystem.BasePathData, $"meshMaterialPass.mat");

            material = EditorUtils.CreateOrReplaceAsset(material, matPath);
            AssetDatabase.ImportAsset(matPath, ImportAssetOptions.ForceUpdate);
            diggerSystem.Materials[0] = material;
        }
Esempio n. 12
0
        public static void UpgradeDiggerData(DiggerSystem diggerSystem)
        {
            var basePath     = diggerSystem.BasePathData;
            var internalPath = Path.Combine(basePath, ".internal");
            var internalDir  = new DirectoryInfo(internalPath);

            if (!internalDir.Exists)
            {
                Debug.Log(
                    $"No DiggerData found for '{diggerSystem.Terrain.name}' at '{internalDir.FullName}'. Nothing to upgrade.");
                return;
            }

            if (!HasLegacyFiles(diggerSystem))
            {
                return;
            }

            Debug.Log($"Legacy Digger files (vox2) detected for terrain '{diggerSystem.Terrain.name}' at '{internalDir.FullName}'. Upgrading...");
            BackupDirectory(new DirectoryInfo(basePath));

            foreach (var file in internalDir.GetFiles($"*.{DiggerSystem.VoxelFileExtensionLegacyV2}"))
            {
                if (file.Extension != $".{DiggerSystem.VoxelFileExtensionLegacyV2}")
                {
                    continue;
                }

                var     newPath    = file.FullName.Replace($".{DiggerSystem.VoxelFileExtensionLegacyV2}", $".{DiggerSystem.VoxelFileExtension}");
                var     rawBytes   = File.ReadAllBytes(file.FullName);
                Voxel[] voxelArray = null;
                UpgradeVoxels(diggerSystem.SizeVox, rawBytes, ref voxelArray);
                PersistUpgradedVoxels(newPath, voxelArray);
                file.Delete();
                Debug.Log($"Upgraded file '{file.FullName}' to '{newPath}'");
            }

            foreach (var file in internalDir.GetFiles($"*.{DiggerSystem.VoxelFileExtensionLegacyV2}_v*"))
            {
                if (!file.Extension.StartsWith($".{DiggerSystem.VoxelFileExtensionLegacyV2}_v"))
                {
                    continue;
                }

                var     newPath    = file.FullName.Replace($".{DiggerSystem.VoxelFileExtensionLegacyV2}_v", $".{DiggerSystem.VoxelFileExtension}_v");
                var     rawBytes   = File.ReadAllBytes(file.FullName);
                Voxel[] voxelArray = null;
                UpgradeVoxels(diggerSystem.SizeVox, rawBytes, ref voxelArray);
                PersistUpgradedVoxels(newPath, voxelArray);
                file.Delete();
                Debug.Log($"Upgraded file '{file.FullName}' to '{newPath}'");
            }
        }
Esempio n. 13
0
        private static void SetupMicroSplatMaterialSyncEventHandler(DiggerSystem diggerSystem)
        {
            var msSync = diggerSystem.gameObject.GetComponent <MicroSplatSync>();

            if (!msSync)
            {
                diggerSystem.gameObject.AddComponent <MicroSplatSync>();
            }
            else
            {
                msSync.OnDisable();
                msSync.OnEnable();
            }
        }
Esempio n. 14
0
        private static void SetupHDRPMaterials(DiggerSystem diggerSystem, bool forceRefresh)
        {
            SetupHDRPTerrainMaterial(diggerSystem, forceRefresh);

            if (diggerSystem.Materials == null || diggerSystem.Materials.Length != 1)
            {
                diggerSystem.Materials = new Material[1];
            }

            var textures = new List <Texture2D>();

            SetupHDRPMaterial(diggerSystem, textures);

            diggerSystem.TerrainTextures = textures.ToArray();
        }
Esempio n. 15
0
        private static void SetupURPMaterials(DiggerSystem diggerSystem, bool forceRefresh)
        {
            SetupURPTerrainMaterial(diggerSystem, forceRefresh);

            var tData     = diggerSystem.Terrain.terrainData;
            var passCount = GetPassCount(tData);

            if (diggerSystem.Materials == null || diggerSystem.Materials.Length != passCount)
            {
                diggerSystem.Materials = new Material[passCount];
            }

            var textures = new List <Texture2D>();

            for (var pass = 0; pass < passCount; ++pass)
            {
                SetupURPMaterial(pass, diggerSystem, textures);
            }

            var warnUseOpacityAsDensity = -1;

            for (var i = 0; i < tData.terrainLayers.Length; i++)
            {
                if (tData.terrainLayers[i].diffuseRemapMin.w > 0.1f)
                {
                    warnUseOpacityAsDensity = i;
                    break;
                }
            }

            if (warnUseOpacityAsDensity >= 0)
            {
                Debug.LogWarning($"The terrain layer \"{tData.terrainLayers[warnUseOpacityAsDensity].name}\" has \"Opacity as Density\" enabled. " +
                                 "This is not well supported by Digger.");
                if (forceRefresh)
                {
                    EditorUtility.DisplayDialog(
                        "Opacity as Density",
                        $"The terrain layer \"{tData.terrainLayers[warnUseOpacityAsDensity].name}\" has \"Opacity as Density\" enabled.\n\n" +
                        "This is not well supported by Digger as it may creates visual difference between Digger meshes and the terrain. It is recommended " +
                        "to disable it and click on \"Sync & Refresh\" again.",
                        "Ok");
                }
            }

            diggerSystem.TerrainTextures = textures.ToArray();
        }
Esempio n. 16
0
        public static bool HasLegacyFiles(DiggerSystem diggerSystem)
        {
            var basePath     = diggerSystem.BasePathData;
            var internalPath = Path.Combine(basePath, ".internal");
            var internalDir  = new DirectoryInfo(internalPath);

            if (!internalDir.Exists)
            {
                return(false);
            }

            return(!internalDir.EnumerateFiles($"*.{DiggerSystem.VoxelFileExtension}").Select(info => info.Extension == $".{DiggerSystem.VoxelFileExtension}").Any() &&
                   (internalDir.EnumerateFiles($"*.{DiggerSystem.VoxelFileExtensionLegacyV2}").Select(info => info.Extension == $".{DiggerSystem.VoxelFileExtensionLegacyV2}")
                    .Any() ||
                    internalDir.EnumerateFiles($"*.{DiggerSystem.VoxelFileExtensionLegacyV2}_v*")
                    .Select(info => info.Extension.StartsWith($".{DiggerSystem.VoxelFileExtensionLegacyV2}_v")).Any()));
        }
Esempio n. 17
0
        private static void SetupHDRPTerrainMaterial(DiggerSystem diggerSystem, bool forceRefresh)
        {
            if (forceRefresh || !diggerSystem.Terrain.materialTemplate ||
                diggerSystem.Terrain.materialTemplate.shader.name != "Digger/HDRP/Terrain/Lit")
            {
                var terrainMaterial = new Material(Shader.Find("Digger/HDRP/Terrain/Lit"));
                terrainMaterial = EditorUtils.CreateOrReplaceAsset(terrainMaterial,
                                                                   Path.Combine(diggerSystem.BasePathData, "terrainMaterial.mat"));
                terrainMaterial.SetFloat(TerrainWidthInvProperty, 1f / diggerSystem.Terrain.terrainData.size.x);
                terrainMaterial.SetFloat(TerrainHeightInvProperty, 1f / diggerSystem.Terrain.terrainData.size.z);
                diggerSystem.Terrain.materialTemplate = terrainMaterial;
            }

            if (diggerSystem.Terrain.materialTemplate.shader.name != "Digger/HDRP/Terrain/Lit")
            {
                Debug.LogWarning("Looks like terrain material doesn't match cave meshes material.");
            }
        }
Esempio n. 18
0
        private static void SetupMaterial(DiggerSystem diggerSystem, bool forceRefresh)
        {
            Utils.Profiler.BeginSample("[Dig] SetupMaterial");

            if (EditorUtils.CTSExists(diggerSystem.Terrain))
            {
                diggerSystem.MaterialType = TerrainMaterialType.CTS;
                Debug.Log("Setting up Digger with CTS shaders");
                SetupCTSMaterial(diggerSystem);
            }
            else if (EditorUtils.MicroSplatExists(diggerSystem.Terrain))
            {
                diggerSystem.MaterialType = TerrainMaterialType.MicroSplat;
                Debug.Log("Setting up Digger with MicroSplat shaders");
                SetupMicroSplatMaterials(diggerSystem);
            }
            else if (IsBuiltInURP())
            {
                diggerSystem.MaterialType = TerrainMaterialType.URP;
                Debug.Log("Setting up Digger with URP shaders");
                SetupURPMaterials(diggerSystem, forceRefresh);
            }
            else if (IsBuiltInLWRP())
            {
                diggerSystem.MaterialType = TerrainMaterialType.LWRP;
                Debug.Log("Setting up Digger with LWRP shaders");
                SetupLWRPMaterials(diggerSystem, forceRefresh);
            }
            else if (IsBuiltInHDRP())
            {
                diggerSystem.MaterialType = TerrainMaterialType.HDRP;
                Debug.Log("Setting up Digger with HDRP shaders");
                SetupHDRPMaterials(diggerSystem, forceRefresh);
            }
            else
            {
                diggerSystem.MaterialType = TerrainMaterialType.Standard;
                Debug.Log("Setting up Digger with standard shaders");
                SetupDefaultMaterials(diggerSystem, forceRefresh);
            }

            Utils.Profiler.EndSample();
        }
Esempio n. 19
0
        public void SaveMeshesAsAssets(DiggerSystem digger, int lod)
        {
            var sameMeshes = meshCollider && filter && meshCollider.sharedMesh == filter.sharedMesh;

            if (filter && filter.sharedMesh)
            {
                var mesh = EditorUtils.CreateOrReplaceAssetHard(filter.sharedMesh, Path.Combine(digger.BasePathData, $"{gameObject.name}_{lod}_mesh.asset"));
                filter.sharedMesh = mesh;
                if (sameMeshes)
                {
                    meshCollider.sharedMesh = mesh;
                }
            }

            if (meshCollider && meshCollider.sharedMesh && !sameMeshes)
            {
                meshCollider.sharedMesh =
                    EditorUtils.CreateOrReplaceAssetHard(meshCollider.sharedMesh, Path.Combine(digger.BasePathData, $"{gameObject.name}_{lod}_collisionMesh.asset"));
            }
        }
Esempio n. 20
0
        private static void SetupLWRPMaterials(DiggerSystem diggerSystem, bool forceRefresh)
        {
            SetupLWRPTerrainMaterial(diggerSystem, forceRefresh);

            var tData     = diggerSystem.Terrain.terrainData;
            var passCount = GetPassCount(tData);

            if (diggerSystem.Materials == null || diggerSystem.Materials.Length != passCount)
            {
                diggerSystem.Materials = new Material[passCount];
            }

            var textures = new List <Texture2D>();

            for (var pass = 0; pass < passCount; ++pass)
            {
                SetupLWRPMaterial(pass, diggerSystem, textures);
            }

            diggerSystem.TerrainTextures = textures.ToArray();
        }
Esempio n. 21
0
        public static void Init(DiggerSystem diggerSystem, bool forceRefresh)
        {
            if (!forceRefresh && diggerSystem.IsInitialized)
            {
                return;
            }

            diggerSystem.PreInit(true);

            if (diggerSystem.Materials == null || forceRefresh)
            {
                SetupMaterial(diggerSystem, forceRefresh);
            }

            diggerSystem.Init(forceRefresh ? LoadType.Minimal_and_LoadVoxels_and_SyncVoxelsWithTerrain_and_RebuildMeshes : LoadType.Minimal);
            if (forceRefresh)
            {
                diggerSystem.PersistDiggerVersion();
                diggerSystem.PersistAndRecordUndo(true, false);
            }
        }
Esempio n. 22
0
        private static void SetupStandardTerrainMaterial(DiggerSystem diggerSystem, bool forceRefresh)
        {
            if (forceRefresh || !diggerSystem.Terrain.materialTemplate ||
                diggerSystem.Terrain.materialTemplate.shader.name != "Nature/Terrain/Digger/Cuttable-Triplanar")
            {
#if !UNITY_2019_2_OR_NEWER
                diggerSystem.Terrain.materialType = Terrain.MaterialType.Custom;
#endif
                var terrainMaterial = new Material(Shader.Find("Nature/Terrain/Digger/Cuttable-Triplanar"));
                terrainMaterial = EditorUtils.CreateOrReplaceAsset(terrainMaterial,
                                                                   Path.Combine(diggerSystem.BasePathData, "terrainMaterial.mat"));
                terrainMaterial.SetFloat(TerrainWidthInvProperty, 1f / diggerSystem.Terrain.terrainData.size.x);
                terrainMaterial.SetFloat(TerrainHeightInvProperty, 1f / diggerSystem.Terrain.terrainData.size.z);
                diggerSystem.Terrain.materialTemplate = terrainMaterial;
            }

            if (diggerSystem.Terrain.materialTemplate.shader.name != "Nature/Terrain/Digger/Cuttable-Triplanar")
            {
                Debug.LogWarning("Looks like terrain material doesn't match cave meshes material.");
            }
        }
Esempio n. 23
0
        internal static Chunk CreateChunk(Vector3i chunkPosition,
                                          DiggerSystem digger,
                                          Terrain terrain,
                                          Material[] materials,
                                          int layer,
                                          string tag)
        {
            Utils.Profiler.BeginSample("CreateChunk");
            var voxelPosition = GetVoxelPosition(digger, chunkPosition);
            var worldPosition = (Vector3)voxelPosition;

            worldPosition.x *= digger.HeightmapScale.x;
            worldPosition.z *= digger.HeightmapScale.z;

            var go = new GameObject(GetName(chunkPosition));

            go.layer     = layer;
            go.hideFlags = digger.ShowDebug ? HideFlags.None : HideFlags.HideInHierarchy | HideFlags.HideInInspector;

            go.transform.parent        = digger.transform;
            go.transform.localPosition = worldPosition + Vector3.up * 0.001f;
            go.transform.localRotation = Quaternion.identity;
            go.transform.localScale    = Vector3.one;

            var chunk = go.AddComponent <Chunk>();

            chunk.digger        = digger;
            chunk.chunkPosition = chunkPosition;
            chunk.voxelPosition = voxelPosition;
            chunk.worldPosition = worldPosition;
            chunk.sizeInWorld   = digger.SizeOfMesh * digger.HeightmapScale;
            chunk.chunkPosition = chunkPosition;

            chunk.voxelChunk    = VoxelChunk.Create(digger, chunk);
            chunk.chunkLodGroup = ChunkLODGroup.Create(chunkPosition, chunk, digger, terrain, materials, layer, tag);
            chunk.UpdateStaticEditorFlags();

            Utils.Profiler.EndSample();
            return(chunk);
        }
Esempio n. 24
0
        private static void SetupLWRPMaterial(int pass, DiggerSystem diggerSystem, List <Texture2D> textures)
        {
            var material           = diggerSystem.Materials[pass];
            var expectedShaderName = $"Digger/LWRP/Mesh-Pass{pass}";

            if (!material || material.shader.name != expectedShaderName)
            {
                material = new Material(Shader.Find(expectedShaderName));
            }

            var tData  = diggerSystem.Terrain.terrainData;
            var offset = pass * TxtCountPerPass;

            for (var i = 0; i + offset < tData.terrainLayers.Length && i < TxtCountPerPass; i++)
            {
                var terrainLayer = tData.terrainLayers[i + offset];
                if (terrainLayer == null || terrainLayer.diffuseTexture == null)
                {
                    continue;
                }

                material.SetFloat($"_tiles{i}x", 1.0f / terrainLayer.tileSize.x);
                material.SetFloat($"_tiles{i}y", 1.0f / terrainLayer.tileSize.y);
                material.SetFloat($"_offset{i}x", terrainLayer.tileOffset.x);
                material.SetFloat($"_offset{i}y", terrainLayer.tileOffset.y);
                material.SetFloat($"_normalScale{i}", terrainLayer.normalScale);
                material.SetFloat($"_Metallic{i}", terrainLayer.metallic);
                material.SetFloat($"_Smoothness{i}", terrainLayer.smoothness);
                material.SetTexture(SplatPrefixProperty + i, terrainLayer.diffuseTexture);
                material.SetTexture(NormalPrefixProperty + i, terrainLayer.normalMapTexture);
                textures.Add(terrainLayer.diffuseTexture);
            }

            var matPath = Path.Combine(diggerSystem.BasePathData, $"meshMaterialPass{pass}.mat");

            material = EditorUtils.CreateOrReplaceAsset(material, matPath);
            AssetDatabase.ImportAsset(matPath, ImportAssetOptions.ForceUpdate);
            diggerSystem.Materials[pass] = material;
        }
Esempio n. 25
0
        private static void GenerateVoxels(DiggerSystem digger, float[] heightArray, int chunkAltitude,
                                           ref Voxel[] voxelArray)
        {
            Utils.Profiler.BeginSample("[Dig] VoxelChunk.GenerateVoxels");
            var sizeVox = digger.SizeVox;

            if (voxelArray == null)
            {
                voxelArray = new Voxel[sizeVox * sizeVox * sizeVox];
            }

            var heights = new NativeArray <float>(heightArray, Allocator.TempJob);
            var voxels  = new NativeArray <Voxel>(sizeVox * sizeVox * sizeVox, Allocator.TempJob,
                                                  NativeArrayOptions.UninitializedMemory);

            // Set up the job data
            var jobData = new VoxelGenerationJob
            {
                ChunkAltitude = chunkAltitude,
                Heights       = heights,
                Voxels        = voxels,
                SizeVox       = sizeVox,
                SizeVox2      = sizeVox * sizeVox
            };

            // Schedule the job
            var handle = jobData.Schedule(voxels.Length, 64);

            // Wait for the job to complete
            handle.Complete();

            voxels.CopyTo(voxelArray);
            heights.Dispose();
            voxels.Dispose();

            Utils.Profiler.EndSample();
        }
Esempio n. 26
0
        private static void SetupCTSAdvancedTessMaterial(DiggerSystem diggerSystem)
        {
            if (!diggerSystem.Materials[0] ||
                diggerSystem.Materials[0].shader.name != "CTS/CTS Terrain Shader Advanced Tess Mesh")
            {
                diggerSystem.Materials[0] = new Material(Shader.Find("CTS/CTS Terrain Shader Advanced Tess Mesh"));
            }

            if (!diggerSystem.Terrain.materialTemplate ||
                !diggerSystem.Terrain.materialTemplate.shader.name.StartsWith("CTS/CTS Terrain Shader Advanced Tess"))
            {
                Debug.LogWarning($"Looks like terrain material doesn\'t match cave meshes material. " +
                                 $"Expected \'CTS/CTS Terrain Shader Advanced Tess CutOut\', was {diggerSystem.Terrain.materialTemplate.shader.name}. " +
                                 $"Please fix this by assigning the right material to the terrain.");
                return;
            }

            diggerSystem.Materials[0].CopyPropertiesFromMaterial(diggerSystem.Terrain.materialTemplate);

            var matPath = Path.Combine(diggerSystem.BasePathData, "meshMaterial.mat");

            diggerSystem.Materials[0] = EditorUtils.CreateOrReplaceAsset(diggerSystem.Materials[0], matPath);
            AssetDatabase.ImportAsset(matPath, ImportAssetOptions.ForceUpdate);
        }
Esempio n. 27
0
        private static void FeedHeights(DiggerSystem digger, Vector3i chunkVoxelPosition, ref float[] heightArray)
        {
            Utils.Profiler.BeginSample("VoxelChunk.FeedHeights");
            var size = digger.SizeVox + 2; // we take heights more then chunk size

            if (heightArray == null)
            {
                heightArray = new float[size * size];
            }

            Utils.Profiler.BeginSample("VoxelChunk.FeedHeights>Loop");
            var heightFeeder = digger.HeightFeeder;

            for (var xi = 0; xi < size; ++xi)
            {
                for (var zi = 0; zi < size; ++zi)
                {
                    heightArray[xi * size + zi] = heightFeeder.GetHeight(chunkVoxelPosition.x + xi - 1, chunkVoxelPosition.z + zi - 1);
                }
            }

            Utils.Profiler.EndSample();
            Utils.Profiler.EndSample();
        }
Esempio n. 28
0
        private static void SetupURPMaterial(int pass, DiggerSystem diggerSystem, List <Texture2D> textures)
        {
            var material           = diggerSystem.Materials[pass];
            var expectedShaderName = $"Digger/URP/Mesh-Pass{pass}";

            if (!material || material.shader.name != expectedShaderName)
            {
                material = new Material(Shader.Find(expectedShaderName));
            }

            var tData = diggerSystem.Terrain.terrainData;

            if (tData.terrainLayers.Length <= 4 && diggerSystem.Terrain.materialTemplate.IsKeywordEnabled("_TERRAIN_BLEND_HEIGHT"))
            {
                material.EnableKeyword("_TERRAIN_BLEND_HEIGHT");
                material.SetFloat(EnableHeightBlend, 1);
                material.SetFloat(HeightTransition, diggerSystem.Terrain.materialTemplate.GetFloat("_HeightTransition"));
            }
            else
            {
                material.DisableKeyword("_TERRAIN_BLEND_HEIGHT");
                material.SetFloat(EnableHeightBlend, 0);
            }

            var normalmap = false;
            var maskmap   = false;
            var offset    = pass * TxtCountPerPass;

            for (var i = 0; i + offset < tData.terrainLayers.Length && i < TxtCountPerPass; i++)
            {
                var terrainLayer = tData.terrainLayers[i + offset];
                if (terrainLayer == null || terrainLayer.diffuseTexture == null)
                {
                    continue;
                }

                if (terrainLayer.normalMapTexture)
                {
                    normalmap = true;
                }
                if (terrainLayer.maskMapTexture)
                {
                    maskmap = true;
                }

                var importer = (TextureImporter)TextureImporter.GetAtPath(AssetDatabase.GetAssetPath(terrainLayer.diffuseTexture));

                material.SetFloat($"_NumLayersCount", tData.terrainLayers.Length);
                material.SetFloat($"_NormalScale{i}", terrainLayer.normalScale);
                material.SetFloat($"_Metallic{i}", terrainLayer.metallic);
                material.SetFloat($"_Smoothness{i}", importer && importer.DoesSourceTextureHaveAlpha() ? 1 : terrainLayer.smoothness);
                material.SetFloat($"_LayerHasMask{i}", terrainLayer.maskMapTexture ? 1 : 0);
                material.SetVector($"_DiffuseRemapScale{i}", terrainLayer.diffuseRemapMax - terrainLayer.diffuseRemapMin);
                material.SetVector($"_MaskMapRemapScale{i}", terrainLayer.maskMapRemapMax);
                material.SetVector($"_MaskMapRemapOffset{i}", terrainLayer.maskMapRemapMin);
                material.SetTexture(SplatPrefixProperty + i, terrainLayer.diffuseTexture);
                material.SetTexture(NormalPrefixProperty + i, terrainLayer.normalMapTexture);
                material.SetTexture(MaskPrefixProperty + i, terrainLayer.maskMapTexture);
                material.SetTextureScale(SplatPrefixProperty + i,
                                         new Vector2(1f / terrainLayer.tileSize.x, 1f / terrainLayer.tileSize.y));
                material.SetTextureOffset(SplatPrefixProperty + i, terrainLayer.tileOffset);
                textures.Add(terrainLayer.diffuseTexture);
            }

            if (normalmap)
            {
                material.EnableKeyword("_NORMALMAP");
            }
            else
            {
                material.DisableKeyword("_NORMALMAP");
            }

            if (maskmap)
            {
                material.EnableKeyword("_MASKMAP");
            }
            else
            {
                material.DisableKeyword("_MASKMAP");
            }

            var matPath = Path.Combine(diggerSystem.BasePathData, $"meshMaterialPass{pass}.mat");

            material = EditorUtils.CreateOrReplaceAsset(material, matPath);
            AssetDatabase.ImportAsset(matPath, ImportAssetOptions.ForceUpdate);
            diggerSystem.Materials[pass] = material;
        }
Esempio n. 29
0
        internal static ChunkObject Create(int lod,
                                           Vector3i chunkPosition,
                                           ChunkLODGroup chunkLodGroup,
                                           bool hasCollider,
                                           DiggerSystem digger,
                                           Terrain terrain,
                                           Material[] materials,
                                           int layer,
                                           string tag)
        {
            Utils.Profiler.BeginSample("ChunkObject.Create");
            var go = new GameObject(GetName(chunkPosition));

            go.layer     = layer;
            go.tag       = tag;
            go.hideFlags = digger.ShowDebug ? HideFlags.None : HideFlags.HideInHierarchy | HideFlags.HideInInspector;

            go.transform.parent        = chunkLodGroup.transform;
            go.transform.localPosition = Vector3.zero;
            go.transform.localRotation = Quaternion.identity;
            go.transform.localScale    = Vector3.one;

            var chunkObject = go.AddComponent <ChunkObject>();

            chunkObject.enabled      = false;
            chunkObject.hasCollider  = hasCollider;
            chunkObject.meshRenderer = go.AddComponent <MeshRenderer>();
            chunkObject.meshRenderer.lightmapScaleOffset         = digger.Terrain.lightmapScaleOffset;
            chunkObject.meshRenderer.realtimeLightmapScaleOffset = digger.Terrain.realtimeLightmapScaleOffset;
            chunkObject.meshRenderer.sharedMaterials             = materials ?? new Material[0];
            SetupMeshRenderer(digger.Terrain, chunkObject.meshRenderer);

            go.GetComponent <Renderer>().shadowCastingMode = ShadowCastingMode.On;
            go.GetComponent <Renderer>().receiveShadows    = true;
            chunkObject.filter = go.AddComponent <MeshFilter>();
            chunkObject.meshRenderer.enabled = false;

            if (hasCollider)
            {
                chunkObject.meshCollider = go.AddComponent <MeshCollider>();

#if !UNITY_2019_3_OR_NEWER
                var goCollider = new GameObject("ChunkTrigger");
                goCollider.transform.parent        = go.transform;
                goCollider.layer                   = layer;
                goCollider.transform.localPosition = Vector3.zero;
                var colliderHole = goCollider.AddComponent <TerrainColliderHoleComponent>();
                colliderHole.Digger          = digger;
                colliderHole.TerrainCollider = terrain.GetComponent <TerrainCollider>();

                chunkObject.holeCollider           = goCollider.AddComponent <BoxCollider>();
                chunkObject.holeCollider.isTrigger = true;
                chunkObject.holeCollider.enabled   = false;
#endif
            }

            chunkObject.UpdateStaticEditorFlags(lod, digger.EnableOcclusionCulling);

            Utils.Profiler.EndSample();
            return(chunkObject);
        }
Esempio n. 30
0
 public static Vector3i GetVoxelPosition(DiggerSystem digger, Vector3i chunkPosition)
 {
     return(chunkPosition * digger.SizeOfMesh);
 }