Example #1
0
        public static void GenerateMesh(OceanRenderer ocean, float baseVertDensity, 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];
            for (int i = 0; i < (int)PatchType.Count; i++)
            {
                meshInsts[i] = BuildOceanPatch((PatchType)i, baseVertDensity);
            }

            // create the shape cameras
            ocean._camsAnimWaves    = new Camera[lodCount];
            ocean._lodDataAnimWaves = new LodDataAnimatedWaves[lodCount];
            ocean._camsFoam         = new Camera[lodCount];
            ocean._camsFlow         = new Camera[lodCount];
            ocean._camsDynWaves     = new Camera[lodCount];

            var cachedSettings = new Dictionary <System.Type, SimSettingsBase>();
            if (ocean._simSettingsFoam != null)
            {
                cachedSettings.Add(typeof(LodDataFoam), ocean._simSettingsFoam);
            }
            if (ocean._simSettingsDynamicWaves != null)
            {
                cachedSettings.Add(typeof(LodDataDynamicWaves), ocean._simSettingsDynamicWaves);
            }
            if (ocean._simSettingsShadow != null)
            {
                cachedSettings.Add(typeof(LodDataShadow), ocean._simSettingsShadow);
            }

            for (int i = 0; i < lodCount; i++)
            {
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.AnimatedWaves, cachedSettings);
                    ocean._camsAnimWaves[i]    = go.GetComponent <Camera>();
                    ocean._lodDataAnimWaves[i] = go.GetComponent <LodDataAnimatedWaves>();

                    if (ocean._createShadowData)
                    {
                        // add lod data to same GO
                        LodData.CreateLodData(i, lodCount, go, baseVertDensity, LodData.SimType.Shadow, cachedSettings);
                    }
                }

                if (ocean._createFoamSim)
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.Foam, cachedSettings);
                    ocean._camsFoam[i] = go.GetComponent <Camera>();
                }

                if (ocean._createFlowSim)
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.Flow, cachedSettings);
                    ocean._camsFlow[i] = go.GetComponent <Camera>();
                }

                if (ocean._createDynamicWaveSim)
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.DynamicWaves, cachedSettings);
                    ocean._camsDynWaves[i] = go.GetComponent <Camera>();
                }
            }

            // 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, baseVertDensity, 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
        }
        public static void GenerateMesh(OceanRenderer ocean, float baseVertDensity, 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];
            for (int i = 0; i < (int)PatchType.Count; i++)
            {
                meshInsts[i] = BuildOceanPatch((PatchType)i, baseVertDensity);
            }

            // create the shape cameras
            ocean._camsAnimWaves    = new Camera[lodCount];
            ocean._lodDataAnimWaves = new LodDataAnimatedWaves[lodCount];
            ocean._camsFoam         = new Camera[lodCount];
            ocean._camsFlow         = new Camera[lodCount];
            ocean._camsDynWaves     = new Camera[lodCount];

            var cachedSettings = new Dictionary <System.Type, SimSettingsBase>();

            // If a settings asset was assigned, add it to a dictionary so that all components can use it.
            AddSettings <LodDataAnimatedWaves>(ocean._simSettingsAnimatedWaves, cachedSettings);
            AddSettings <LodDataFoam>(ocean._simSettingsFoam, cachedSettings);
            AddSettings <LodDataDynamicWaves>(ocean._simSettingsDynamicWaves, cachedSettings);
            AddSettings <LodDataShadow>(ocean._simSettingsShadow, cachedSettings);
            AddSettings <LodDataFlow>(ocean._simSettingsFlow, cachedSettings);

            for (int i = 0; i < lodCount; i++)
            {
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.AnimatedWaves, cachedSettings);
                    ocean._camsAnimWaves[i]    = go.GetComponent <Camera>();
                    ocean._lodDataAnimWaves[i] = go.GetComponent <LodDataAnimatedWaves>();

                    if (ocean._createSeaFloorDepthData)
                    {
                        LodData.CreateLodData(i, lodCount, go, baseVertDensity, LodData.SimType.SeaFloorDepth, cachedSettings);
                    }

                    if (ocean._createShadowData)
                    {
                        // add lod data to same GO
                        LodData.CreateLodData(i, lodCount, go, baseVertDensity, LodData.SimType.Shadow, cachedSettings);
                    }
                }

                if (ocean._createFoamSim)
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.Foam, cachedSettings);
                    ocean._camsFoam[i] = go.GetComponent <Camera>();
                }

                if (ocean._createFlowSim)
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.Flow, cachedSettings);
                    ocean._camsFlow[i] = go.GetComponent <Camera>();
                }

                if (ocean._createDynamicWaveSim)
                {
                    var go = LodData.CreateLodData(i, lodCount, null, baseVertDensity, LodData.SimType.DynamicWaves, cachedSettings);
                    ocean._camsDynWaves[i] = go.GetComponent <Camera>();
                }
            }

            // If no settings asset was assigned, the Create() methods will create a default settings object. Assign this back to the
            // ocean script so that it can be easily accessed.
            PopulateSettings <LodDataAnimatedWaves, SimSettingsAnimatedWaves>(cachedSettings, ref ocean._simSettingsAnimatedWaves);
            PopulateSettings <LodDataDynamicWaves, SimSettingsWave>(cachedSettings, ref ocean._simSettingsDynamicWaves);
            PopulateSettings <LodDataFlow, SimSettingsFlow>(cachedSettings, ref ocean._simSettingsFlow);
            PopulateSettings <LodDataFoam, SimSettingsFoam>(cachedSettings, ref ocean._simSettingsFoam);
            PopulateSettings <LodDataShadow, SimSettingsShadow>(cachedSettings, ref ocean._simSettingsShadow);

            // Add any required GPU readbacks
            {
                var ssaw = cachedSettings[typeof(LodDataAnimatedWaves)] as SimSettingsAnimatedWaves;
                if (ssaw && ssaw.CollisionSource == SimSettingsAnimatedWaves.CollisionSources.OceanDisplacementTexturesGPU)
                {
                    ocean.gameObject.AddComponent <GPUReadbackDisps>();
                }

                if (ocean._createFlowSim)
                {
                    var ssf = cachedSettings[typeof(LodDataFlow)] as 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, baseVertDensity, 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
        }