예제 #1
0
        protected override void Init()
        {
            seaLevelAlignedWithInt   = (waterLevel / (float)maxHeight);
            beachLevelAlignedWithInt = (waterLevel + 1f) / maxHeight;
            if (steps != null)
            {
                for (int k = 0; k < steps.Length; k++)
                {
                    if (steps [k].noiseTexture != null)
                    {
                        bool repeated = false;
                        for (int j = 0; j < k - 1; j++)
                        {
                            if (steps [k].noiseTexture == steps [k].noiseTexture)
                            {
                                steps [k].noiseValues      = steps [j].noiseValues;
                                steps [k].noiseTextureSize = steps [j].noiseTextureSize;
                                repeated = true;
                                break;
                            }
                        }
                        if (!repeated && (steps [k].noiseTextureSize == 0 || steps [k].noiseValues == null || steps [k].lastTextureLoaded == null || steps [k].noiseTexture != steps [k].lastTextureLoaded))
                        {
                            steps [k].lastTextureLoaded = steps [k].noiseTexture;
                            steps [k].noiseValues       = NoiseTools.LoadNoiseTexture(steps [k].noiseTexture, out steps [k].noiseTextureSize);
                        }
                    }
                    // Validate references
                    if (steps [k].inputIndex0 < 0 || steps [k].inputIndex0 >= steps.Length)
                    {
                        steps [k].inputIndex0 = 0;
                    }
                    if (steps [k].inputIndex1 < 0 || steps [k].inputIndex1 >= steps.Length)
                    {
                        steps [k].inputIndex1 = 0;
                    }
                }
            }
            if (moisture != null && (noiseMoistureTextureSize == 0 || moistureValues == null || lastMoistureTextureLoaded == null || lastMoistureTextureLoaded != moisture))
            {
                lastMoistureTextureLoaded = moisture;
                moistureValues            = NoiseTools.LoadNoiseTexture(moisture, out noiseMoistureTextureSize);
            }
            if (waterVoxel == null)
            {
                waterVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/Water/VoxelWaterSea");
            }
            paintShore = shoreVoxel != null;

            if (heightChunkData == null)
            {
                heightChunkData = new HeightMapInfo[16 * 16];
            }


            // Ensure voxels are available
            env.AddVoxelDefinition(shoreVoxel);
            env.AddVoxelDefinition(waterVoxel);
            env.AddVoxelDefinition(bedrockVoxel);
        }
        void GeneratePerlinNoise(ref float minValue, ref float maxValue)
        {
            Vector2[] pows = new Vector2[octaves];
            for (int k = 0; k < pows.Length; k++)
            {
                pows [k].x = Mathf.Max(1f, Mathf.Pow(lacunarity, (k + 1)));
                pows [k].y = Mathf.Pow(persistance, k);
            }
            float offsetValue = offset * size;

            for (int index = 0, y = 0; y < size; y++)
            {
                float yf = (float)y / size;
                for (int x = 0; x < size; x++)
                {
                    float xf = (float)x / size;
                    float v  = 1f;
                    for (int o = 0; o < octaves; o++)
                    {
                        int   frequency = (int)pows [o].x;
                        float amplitude = pows [o].y;
                        float xx        = xf * frequency + offsetValue;
                        float yy        = yf * frequency + offsetValue;
                        float ov        = NoiseTools.GetTilablePerlinValue(xx, yy, frequency, frequency) + 0.5f;
                        v += amplitude * ov;
                    }
                    values [index++] = v;
                    if (v < minValue)
                    {
                        minValue = v;
                    }
                    if (v > maxValue)
                    {
                        maxValue = v;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Gets the altitude and moisture (in 0-1 range).
        /// </summary>
        /// <param name="x">The x coordinate.</param>
        /// <param name="z">The z coordinate.</param>
        /// <param name="altitude">Altitude.</param>
        /// <param name="moisture">Moisture.</param>
        public override void GetHeightAndMoisture(float x, float z, out float altitude, out float moisture)
        {
            if (!isInitialized)
            {
                Initialize();
            }

            bool allowBeach = true;

            altitude = 0;
            if (steps != null && steps.Length > 0)
            {
                float value = 0;
                for (int k = 0; k < steps.Length; k++)
                {
                    if (steps [k].enabled)
                    {
                        switch (steps [k].operation)
                        {
                        case TerrainStepType.SampleHeightMapTexture:
                            value = NoiseTools.GetNoiseValueBilinear(steps [k].noiseValues, steps [k].noiseTextureSize, x * steps [k].frecuency, z * steps [k].frecuency);
                            value = value * (steps [k].noiseRangeMax - steps [k].noiseRangeMin) + steps [k].noiseRangeMin;
                            break;

                        case TerrainStepType.SampleRidgeNoiseFromTexture:
                            value = NoiseTools.GetNoiseValueBilinear(steps [k].noiseValues, steps [k].noiseTextureSize, x * steps [k].frecuency, z * steps [k].frecuency, true);
                            value = value * (steps [k].noiseRangeMax - steps [k].noiseRangeMin) + steps [k].noiseRangeMin;
                            break;

                        case TerrainStepType.Shift:
                            value += steps [k].param;
                            break;

                        case TerrainStepType.BeachMask:
                        {
                            int i1 = steps [k].inputIndex0;
                            if (steps [i1].value > steps [k].threshold)
                            {
                                allowBeach = false;
                            }
                        }
                        break;

                        case TerrainStepType.AddAndMultiply:
                            value = (value + steps [k].param) * steps [k].param2;
                            break;

                        case TerrainStepType.MultiplyAndAdd:
                            value = (value * steps [k].param) + steps [k].param2;
                            break;

                        case TerrainStepType.Exponential:
                            if (value < 0)
                            {
                                value = 0;
                            }
                            value = (float)System.Math.Pow(value, steps [k].param);
                            break;

                        case TerrainStepType.Constant:
                            value = steps [k].param;
                            break;

                        case TerrainStepType.Invert:
                            value = 1f - value;
                            break;

                        case TerrainStepType.Copy:
                        {
                            int i1 = steps [k].inputIndex0;
                            value = steps [i1].value;
                        }
                        break;

                        case TerrainStepType.Random:
                            value = WorldRand.GetValue(x, z);
                            break;

                        case TerrainStepType.BlendAdditive:
                        {
                            int i1 = steps [k].inputIndex0;
                            int i2 = steps [k].inputIndex1;
                            value = steps [i1].value * steps [k].weight0 + steps [i2].value * steps [k].weight1;
                        }
                        break;

                        case TerrainStepType.BlendMultiply:
                        {
                            int i1 = steps [k].inputIndex0;
                            int i2 = steps [k].inputIndex1;
                            value = steps [i1].value * steps [i2].value;
                        }
                        break;

                        case TerrainStepType.Threshold:
                        {
                            int i1 = steps [k].inputIndex0;
                            if (steps [i1].value >= steps [k].threshold)
                            {
                                value = steps [i1].value + steps [k].thresholdShift;
                            }
                            else
                            {
                                value = steps [k].thresholdParam;
                            }
                        }
                        break;

                        case TerrainStepType.FlattenOrRaise:
                            if (value >= steps [k].threshold)
                            {
                                value = (value - steps [k].threshold) * steps [k].thresholdParam + steps [k].threshold;
                            }
                            break;

                        case TerrainStepType.Clamp:
                            if (value < steps [k].min)
                            {
                                value = steps [k].min;
                            }
                            else if (value > steps [k].max)
                            {
                                value = steps [k].max;
                            }
                            break;

                        case TerrainStepType.Select:
                        {
                            int i1 = steps [k].inputIndex0;
                            if (steps [i1].value < steps [k].min)
                            {
                                value = steps [k].thresholdParam;
                            }
                            else if (steps [i1].value > steps [k].max)
                            {
                                value = steps [k].thresholdParam;
                            }
                            else
                            {
                                value = steps [i1].value;
                            }
                        }
                        break;

                        case TerrainStepType.Fill:
                        {
                            int i1 = steps [k].inputIndex0;
                            if (steps [i1].value >= steps [k].min && steps [i1].value <= steps [k].max)
                            {
                                value = steps [k].thresholdParam;
                            }
                        }
                        break;

                        case TerrainStepType.Test:
                        {
                            int i1 = steps [k].inputIndex0;
                            if (steps [i1].value >= steps [k].min && steps [i1].value <= steps [k].max)
                            {
                                value = 1f;
                            }
                            else
                            {
                                value = 0f;
                            }
                        }
                        break;
                        }
                    }
                    steps [k].value = value;
                }
                altitude = value;
            }
            else
            {
                altitude = -9999;                 // no terrain so make altitude very low so every chunk be considered above terrain for GI purposes
            }

            // Moisture
            moisture = NoiseTools.GetNoiseValueBilinear(moistureValues, noiseMoistureTextureSize, x * moistureScale, z * moistureScale);


            // Remove any potential beach
            if (altitude < beachLevelAlignedWithInt && altitude >= seaLevelAlignedWithInt)
            {
                float depth = beachLevelAlignedWithInt - altitude;
                if (depth > beachWidth || !allowBeach)
                {
                    altitude = seaLevelAlignedWithInt - 0.0001f;
                }
            }

            // Adjusts sea depth
            if (altitude < seaLevelAlignedWithInt)
            {
                float depth = seaLevelAlignedWithInt - altitude;
                altitude = seaLevelAlignedWithInt - 0.0001f - depth * seaDepthMultiplier;
            }
        }