public static void GenerateMesh(OceanRenderer ocean, int lodDataResolution, int geoDownSampleFactor, int lodCount) { if (lodCount < 1) { Debug.LogError("Invalid LOD count: " + lodCount.ToString(), ocean); return; } #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying) { Debug.LogError("Ocean mesh meant to be (re)generated in play mode", ocean); return; } #endif int oceanLayer = LayerMask.NameToLayer(ocean.LayerName); if (oceanLayer == -1) { Debug.LogError("Invalid ocean layer: " + ocean.LayerName + " please add this layer.", ocean); oceanLayer = 0; } #if PROFILE_CONSTRUCTION System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif // create mesh data Mesh[] meshInsts = new Mesh[(int)PatchType.Count]; // 4 tiles across a LOD, and support lowering density by a factor var tileResolution = Mathf.Round(0.25f * lodDataResolution / geoDownSampleFactor); for (int i = 0; i < (int)PatchType.Count; i++) { meshInsts[i] = BuildOceanPatch((PatchType)i, tileResolution); } ocean._lodTransform = ocean.gameObject.AddComponent <LodTransform>(); ocean._lodTransform.InitLODData(lodCount); // Create the LOD data managers ocean._lodDataAnimWaves = LodDataMgr.Create <LodDataMgrAnimWaves, SimSettingsAnimatedWaves>(ocean.gameObject, ref ocean._simSettingsAnimatedWaves); if (ocean.CreateDynamicWaveSim) { ocean._lodDataDynWaves = LodDataMgr.Create <LodDataMgrDynWaves, SimSettingsWave>(ocean.gameObject, ref ocean._simSettingsDynamicWaves); } if (ocean.CreateFlowSim) { ocean._lodDataFlow = LodDataMgr.Create <LodDataMgrFlow, SimSettingsFlow>(ocean.gameObject, ref ocean._simSettingsFlow); } if (ocean.CreateFoamSim) { ocean._lodDataFoam = LodDataMgr.Create <LodDataMgrFoam, SimSettingsFoam>(ocean.gameObject, ref ocean._simSettingsFoam); } if (ocean.CreateShadowData) { ocean._lodDataShadow = LodDataMgr.Create <LodDataMgrShadow, SimSettingsShadow>(ocean.gameObject, ref ocean._simSettingsShadow); } if (ocean.CreateSeaFloorDepthData) { ocean._lodDataSeaDepths = ocean.gameObject.AddComponent <LodDataMgrSeaFloorDepth>(); } if (ocean.CreateClipSurfaceData) { ocean._lodDataClipSurface = ocean.gameObject.AddComponent <LodDataMgrClipSurface>(); } // Add any required GPU readbacks { var ssaw = ocean._simSettingsAnimatedWaves; if (ssaw && ssaw.CollisionSource == SimSettingsAnimatedWaves.CollisionSources.ComputeShaderQueries) { ocean.gameObject.AddComponent <QueryDisplacements>(); } if (ocean.CreateFlowSim) { ocean.gameObject.AddComponent <QueryFlow>(); } } // Remove existing LODs for (int i = 0; i < ocean.transform.childCount; i++) { var child = ocean.transform.GetChild(i); if (child.name.StartsWith("Tile_L")) { child.parent = null; Object.Destroy(child.gameObject); i--; } } for (int i = 0; i < lodCount; i++) { CreateLOD(ocean, i, lodCount, meshInsts, lodDataResolution, geoDownSampleFactor, oceanLayer); } #if PROFILE_CONSTRUCTION sw.Stop(); Debug.Log("Finished generating " + lodCount.ToString() + " LODs, time: " + (1000.0 * sw.Elapsed.TotalSeconds).ToString(".000") + "ms"); #endif }
public static void GenerateMesh(OceanRenderer ocean, int lodDataResolution, int geoDownSampleFactor, int lodCount) { if (lodCount < 1) { Debug.LogError("Invalid LOD count: " + lodCount.ToString(), ocean); return; } #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying) { Debug.LogError("Ocean mesh meant to be (re)generated in play mode", ocean); return; } #endif int oceanLayer = LayerMask.NameToLayer(ocean.LayerName); if (oceanLayer == -1) { Debug.LogError("Invalid ocean layer: " + ocean.LayerName + " please add this layer.", ocean); oceanLayer = 0; } #if PROFILE_CONSTRUCTION System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif // create mesh data Mesh[] meshInsts = new Mesh[(int)PatchType.Count]; // 4 tiles across a LOD, and support lowering density by a factor var tileResolution = Mathf.Round(0.25f * lodDataResolution / geoDownSampleFactor); for (int i = 0; i < (int)PatchType.Count; i++) { meshInsts[i] = BuildOceanPatch((PatchType)i, tileResolution); } ocean._lods = new LodTransform[lodCount]; // Create the LOD data managers ocean._lodDataAnimWaves = LodDataMgr.Create <LodDataMgrAnimWaves, SimSettingsAnimatedWaves>(ocean.gameObject, ref ocean._simSettingsAnimatedWaves); if (ocean.CreateDynamicWaveSim) { ocean._lodDataDynWaves = LodDataMgr.Create <LodDataMgrDynWaves, SimSettingsWave>(ocean.gameObject, ref ocean._simSettingsDynamicWaves); } if (ocean.CreateFlowSim) { ocean._lodDataFlow = LodDataMgr.Create <LodDataMgrFlow, SimSettingsFlow>(ocean.gameObject, ref ocean._simSettingsFlow); } if (ocean.CreateFoamSim) { ocean._lodDataFoam = LodDataMgr.Create <LodDataMgrFoam, SimSettingsFoam>(ocean.gameObject, ref ocean._simSettingsFoam); } if (ocean.CreateShadowData) { ocean._lodDataShadow = LodDataMgr.Create <LodDataMgrShadow, SimSettingsShadow>(ocean.gameObject, ref ocean._simSettingsShadow); } if (ocean.CreateSeaFloorDepthData) { ocean._lodDataSeaDepths = ocean.gameObject.AddComponent <LodDataMgrSeaFloorDepth>(); } // Add any required GPU readbacks { var ssaw = ocean._simSettingsAnimatedWaves; if (ssaw && ssaw.CollisionSource == SimSettingsAnimatedWaves.CollisionSources.OceanDisplacementTexturesGPU) { ocean.gameObject.AddComponent <GPUReadbackDisps>(); } if (ocean.CreateFlowSim) { var ssf = ocean._simSettingsFlow; if (ssf && ssf._readbackData) { ocean.gameObject.AddComponent <GPUReadbackFlow>(); } } } // Remove existing LODs for (int i = 0; i < ocean.transform.childCount; i++) { var child = ocean.transform.GetChild(i); if (child.name.StartsWith("LOD")) { child.parent = null; Object.Destroy(child.gameObject); i--; } } int startLevel = 0; for (int i = 0; i < lodCount; i++) { bool biggestLOD = i == lodCount - 1; GameObject nextLod = CreateLOD(ocean, i, lodCount, biggestLOD, meshInsts, lodDataResolution, geoDownSampleFactor, oceanLayer); nextLod.transform.parent = ocean.transform; // scale only horizontally, otherwise culling bounding box will be scaled up in y float horizScale = Mathf.Pow(2f, (float)(i + startLevel)); nextLod.transform.localScale = new Vector3(horizScale, 1f, horizScale); } #if PROFILE_CONSTRUCTION sw.Stop(); Debug.Log("Finished generating " + parms._lodCount.ToString() + " LODs, time: " + (1000.0 * sw.Elapsed.TotalSeconds).ToString(".000") + "ms"); #endif }