Example #1
0
        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
        }
Example #2
0
        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
        }