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)); }
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; }
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); }
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}"); } }
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__ }
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 }
private void Awake() { // For retro-compatibility if (!Digger) { Digger = GetComponentInParent <DiggerSystem>(); } }
public void SaveMeshesAsAssets(DiggerSystem digger) { for (var i = 0; i < chunks.Length; i++) { var chunk = chunks[i]; chunk.SaveMeshesAsAssets(digger, IndexToLod(i)); } }
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); }
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"); } }
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; }
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}'"); } }
private static void SetupMicroSplatMaterialSyncEventHandler(DiggerSystem diggerSystem) { var msSync = diggerSystem.gameObject.GetComponent <MicroSplatSync>(); if (!msSync) { diggerSystem.gameObject.AddComponent <MicroSplatSync>(); } else { msSync.OnDisable(); msSync.OnEnable(); } }
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(); }
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(); }
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())); }
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."); } }
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(); }
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")); } }
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(); }
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); } }
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."); } }
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); }
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; }
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(); }
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); }
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(); }
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; }
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); }
public static Vector3i GetVoxelPosition(DiggerSystem digger, Vector3i chunkPosition) { return(chunkPosition * digger.SizeOfMesh); }