Provides a noise module that outputs a three-dimensional perlin noise. [GENERATOR]
Inheritance: ModuleBase
Beispiel #1
0
    //通过世界坐标获取他方块的类型
    public static byte GetTerrainBlock(Vector3i worldPosition)
    {
        //libNooise噪音对象
        Perlin noise = new LibNoise.Generator.Perlin(1f, 1f, 1f, 8, GameManager.randomSeed, QualityMode.High);

        //为随机数指定种子,每次随机都为同样值
        Random.InitState(GameManager.randomSeed);
        //因为柏林噪音在(0,0)点是上下左右对称的,所以我们设置一个很远很远的地方作为新的(0,0)点
        Vector3 offset = new Vector3(Random.value * 100000, Random.value * 100000, Random.value * 100000);


        float  noiseX     = Mathf.Abs((worldPosition.x + offset.x) / 20); //改变地形的平缓程度,值越大越平缓
        float  noiseY     = Mathf.Abs((worldPosition.y + offset.y) / 20); //不要小于20
        float  noiseZ     = Mathf.Abs((worldPosition.z + offset.z) / 20);
        double noiseValue = noise.GetValue(noiseX, noiseY, noiseZ);

        //没有此两行就为洞窟地貌
        noiseValue += (20 - worldPosition.y) / 15f;//30改变修正山高度,也可以为将整体噪音图像向上平移
        noiseValue /= worldPosition.y / 5f;

        if (noiseValue > 0.5f)
        {
            return(1);
        }

        return(0);
    }
Beispiel #2
0
    //通过方块的世界坐标获取它的方块类型
    public static byte GetTerrainBlock(Vector3i worldPosition)
    {
        //LibNoise噪音对象
        Perlin noise = new LibNoise.Generator.Perlin(1f, 1f, 1f, 8, SeedManager.randomSeed, QualityMode.High);

        //为随机数指定种子,这样每次随机的都是同样的值
        Random.InitState(SeedManager.randomSeed);
        //因为柏林噪音在(0,0)点是上下左右对称的,所以我们设置一个很远很远的地方作为新的(0,0)点
        Vector3 offset = new Vector3(Random.value * 100000, Random.value * 100000, Random.value * 100000);

        float  noiseX     = Mathf.Abs((worldPosition.x + offset.x) / 20);
        float  noiseY     = Mathf.Abs((worldPosition.y + offset.y) / 20);
        float  noiseZ     = Mathf.Abs((worldPosition.z + offset.z) / 20);
        double noiseValue = noise.GetValue(noiseX, noiseY, noiseZ);

        noiseValue += (20 - worldPosition.y) / 15f;
        noiseValue /= worldPosition.y / 5f;

        if (noiseValue > 0.5f)
        {
            return(1);
        }

        return(0);
    }
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 public Turbulence()
     : base(1)
 {
     this.m_xDistort = new Perlin();
     this.m_yDistort = new Perlin();
     this.m_zDistort = new Perlin();
 }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 public Turbulence()
     : base(1)
 {
     _xDistort = new Generator.Perlin();
     _yDistort = new Generator.Perlin();
     _zDistort = new Generator.Perlin();
 }
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 public Turbulence()
     : base(1)
 {
     Power = 1.0;
     _xDistort = new Perlin();
     _yDistort = new Perlin();
     _zDistort = new Perlin();
 }
Beispiel #6
0
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 /// <param name="input">The input module.</param>
 public Turbulence(ModuleBase input)
     : base(1)
 {
     _xDistort = new Generator.Perlin();
     _yDistort = new Generator.Perlin();
     _zDistort = new Generator.Perlin();
     Modules[0] = input;
 }
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 /// <param name="input">The input module.</param>
 public Turbulence(ModuleBase input)
     : base(1)
 {
     Power = 1.0;
     _xDistort = new Perlin();
     _yDistort = new Perlin();
     _zDistort = new Perlin();
     Modules[0] = input;
 }
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 /// <param name="x">The perlin noise to apply on the x-axis.</param>
 /// <param name="y">The perlin noise to apply on the y-axis.</param>
 /// <param name="z">The perlin noise to apply on the z-axis.</param>
 /// <param name="power">The power of the turbulence.</param>
 /// <param name="input">The input module.</param>
 public Turbulence(Perlin x, Perlin y, Perlin z, float power, ModuleBase input)
     : base(1)
 {
     this.m_xDistort = x;
     this.m_yDistort = y;
     this.m_zDistort = z;
     this.m_modules[0] = input;
     this.Power = power;
 }
Beispiel #9
0
 /// <summary>
 /// Initializes a new instance of Turbulence.
 /// </summary>
 /// <param name="x">The perlin noise to apply on the x-axis.</param>
 /// <param name="y">The perlin noise to apply on the y-axis.</param>
 /// <param name="z">The perlin noise to apply on the z-axis.</param>
 /// <param name="power">The power of the turbulence.</param>
 /// <param name="input">The input module.</param>
 public Turbulence( Generator.Perlin x, Generator.Perlin y, Generator.Perlin z, double power, ModuleBase input)
     : base(1)
 {
     _xDistort = x;
     _yDistort = y;
     _zDistort = z;
     Modules[0] = input;
     Power = power;
 }
 public void Perlin()
 {
     LibNoise.Generator.Perlin _noise = new LibNoise.Generator.Perlin();
     _noise.Seed        = Seed;
     _noise.OctaveCount = OctaveCount;
     _noise.Persistence = Persistence;
     _noise.Frequency   = Frequency;
     _noise.Lacunarity  = Lacunarity;
     Heights(terr, _noise);
 }
Beispiel #11
0
    /***
     * This function generates and return a Planet object.
     *
     * @param "subdivide" this is how many time we subdivide the original shape.
     * @param "type" decided the original shape we are subdividing, default is 0. (0 = cube, 1, = icosohedron)
     */
    static public GameObject GeneratePlanet(int seed, int type = 0)
    {
        #region Generate Random/Noise Based on Seed
        LibNoise.Generator.Perlin perlin = new LibNoise.Generator.Perlin();
        Random.InitState(seed);
        perlin.Seed = seed;
        #endregion

        // TODO I want this to be able to generate a subdivide 6 planet, but it can't.
        #region Generate Subdivide
        float subdivide_seed = Random.value;
        int   subdivide      = 5;
        if (subdivide <= 0.3)
        {
            subdivide = 4;
        }
        else if (subdivide <= 0.8)
        {
            subdivide = 5;
        }
        Debug.Log("subdivide: " + subdivide);
        #endregion

        #region Initialize Primitive
        Primitive primitive = null;
        if (type == 0)
        {
            primitive = InitAsCube();
            primitive = SubdivideCube(primitive, subdivide);
        }
        else if (type == 1)
        {
            primitive = InitAsIcosohedron();
            primitive = SubdivideIcosohedron(primitive, subdivide);
        }
        else
        {
            return(null);
        }
        #endregion

        #region Create GameObject
        GameObject planet = CreateGameObject(primitive, perlin);
        #endregion

        #region Generate Axis Tilt
        int sign = (Random.value >= 0.5) ? 1 : -1;
        planet.GetComponent <Planet>().SetAxis(sign * Random.value * 10);
        #endregion

        return(planet);
    }
Beispiel #12
0
    void RandomizeTerrainHeights()
    {
        int noiseSeed   = Random.Range(0, int.MaxValue);
        var noiseMap    = new LibNoise.Noise2D(m_TerrainData.heightmapWidth, m_TerrainData.heightmapHeight);
        var noiseModule = new LibNoise.Generator.Perlin();

        // Configure the noise parameters
        noiseModule.OctaveCount = 20;
        noiseModule.Persistence = 0.45f;
        noiseModule.Seed        = noiseSeed;
        noiseMap.Generator      = noiseModule;

        // Generate the noise map
        noiseMap.GeneratePlanar(-1.5f, 1.5, -1.5, 1.5f, true);

        // Get a two-dimensional array of heights from the noise map
        float borderHeight = m_TerrainBorderHeight / m_TerrainData.size.y;

        float[,] heights = noiseMap.GetData();

        // Loop through every "pixel" and set the height to a random value
        for (int x = 0; x < m_TerrainData.heightmapWidth; x++)
        {
            for (int y = 0; y < m_TerrainData.heightmapHeight; y++)
            {
                // Divide the height by 2 so it doesn't flow over the top of the arena
                heights[x, y] /= 2f;

                // Fill in flat areas with random noise
                if (heights[x, y] <= borderHeight &&
                    heights[x, y] >= borderHeight / 2)
                {
                    float newHeight = Random.Range(0f, borderHeight / 2);
                    heights[x, y] = Mathf.Lerp(heights[x, y], newHeight, 0.5f);
                }

                // Update the maxHeight variable if the current height point breaks the previous record
                if (heights[x, y] > m_MaxHeight)
                {
                    m_MaxHeight = heights[x, y];
                }
            }
        }

        // Debug.Log("Max Height: " + m_MaxHeight);

        // Store the result back into terrainData
        m_TerrainData.SetHeights(0, 0, heights);
    }
        public static LibNoise.ModuleBase GetRTSGenerator(double multiply)
        {
            // part 3
            Perlin perlinGen = new Perlin ();
            perlinGen.OctaveCount = 1;
            perlinGen.Frequency = 0.5f;

            /*Const constGen4 = new Const ();
            constGen4.Value = 2f;
            Add perlinMultGenerator = new Add (constGen4,perlinGen);
            */
            //Multiply perlinMultGenerator2 = new Multiply (constGen3,perlinGen);
            //Clamp perlinMultGenerator2Clamp = new Clamp (-1.0f,1.0f,perlinMultGenerator2);

            //Multiply pTest = new Multiply (constGen50,perlinGen);

            // part 3 perlin big
            Perlin perlinGen2 = new Perlin ();
            perlinGen2.OctaveCount = 10;
            perlinGen2.Frequency = 0.1f;
            Add perlinGenMult = new Add(new Const(0.5), new Multiply(perlinGen2,new Const(0.5) ));
            //Clamp perlinZeroToOne =  new Clamp(0.0,1.0,perlinGenMult);
            //part 4 perlin small
            Perlin perlinGen3 = new Perlin ();
            perlinGen3.OctaveCount = 2;
            perlinGen3.Frequency = 0.6f;
            Add perlinSmall =  new Add(new Const(0.5),new Multiply(new Const(0.5),perlinGen3));

            // part 1 voronoi
            Voronoi voronoiGenerator = new Voronoi (0.3,0.0,0,true);
            Add voronoiZeroToOne =  new Add(new Const(0.5),new Multiply(new Const(0.5),voronoiGenerator));

            LibNoise.ModuleBase combinedNoise = new Add(new Multiply(perlinSmall		,new Const(0.15))
                                                        ,new Multiply(voronoiZeroToOne	,new Const(0.85))
                                                        );
            // p4 voroni + p1 perlin small

            //LibNoise.ModuleBase noiseFinal = new Multiply(combinedNoise,new Const(1.0));
            //LibNoise.ModuleBase noiseFinal =          new Multiply(combinedNoise,new Power(new Multiply(perlinGenMult,new Const(1.5)),constGen3));
            LibNoise.ModuleBase noiseFinal = new Multiply( combinedNoise , new Power(perlinGenMult,new Const (3)) );

            // mult part 1 and part 2
            //Multiply rtsGenerator = new Multiply (perlinGen2,constGen50);

            return new Multiply (noiseFinal,new Const (multiply));

            //Blend rtsGenerator2 = new Blend (rtsGenerator,rtsGenerator3,perlinMultGenerator2Clamp);
        }
        public static LibNoise.ModuleBase PrettyWorldGenerator()
        {
            // mult perlin big
            Perlin perlinGenM = new Perlin (0.016,2.0,0.5,3,0,LibNoise.QualityMode.Medium);
            Add perlinGenMult = new Add(new Const(0.5), new Multiply(perlinGenM,new Const(0.5) ));

            // mult voronoi
            Voronoi voronoiGeneratorM = new Voronoi (0.032,0.0,0,true);
            Add voronoiZeroToOneM =  new Add(new Const(0.5),new Multiply(new Const(0.5),voronoiGeneratorM));

            Add mulTotal = new Add (new Multiply(perlinGenMult,new Const(0.5)),
                                    new Multiply(voronoiZeroToOneM,new Const(0.5))
                                    );

            //part 1 perlin
            Perlin perlinGen = new Perlin (0.3,2.0,0.5,2,0,LibNoise.QualityMode.Medium);
            Add perlinZeroToOne =  new Add(new Const(0.5),new Multiply(new Const(0.5),perlinGen));
            //part 2 perlin
            Perlin perlinGen2 = new Perlin (0.08,2.0,0.5,5,0,LibNoise.QualityMode.Medium);
            Add perlinZeroToOne2 =  new Add(new Const(0.5),new Multiply(new Const(0.5),perlinGen2));

            // part 1 voronoi
            Voronoi voronoiGenerator = new Voronoi (0.06,0.0,0,true);
            Add voronoiZeroToOne =  new Add(new Const(0.5),new Multiply(new Const(0.5),voronoiGenerator));

            // part 2 voronoi
            Voronoi voronoiGenerator2 = new Voronoi (0.09,0.0,0,true);
            Add voronoiZeroToOne2 =  new Add(new Const(0.5),new Multiply(new Const(0.5),voronoiGenerator2));
            // part 2 voronoi
            Voronoi voronoiGenerator3 = new Voronoi (0.2,0.0,0,true);
            Add voronoiZeroToOne3 =  new Add(new Const(0.5),new Multiply(new Const(0.5),voronoiGenerator3));
            // part 2 voronoi
            Voronoi voronoiGenerator4 = new Voronoi (0.4,0.0,0,true);
            Add voronoiZeroToOne4 =  new Add(new Const(0.5),new Multiply(new Const(0.5),voronoiGenerator4));

            LibNoise.ModuleBase combinedNoise = new Add(new Multiply(perlinZeroToOne		,new Const(0.03))
                                                        ,new Multiply(voronoiZeroToOne	,new Const(0.70))
                                                        );
            combinedNoise = new Add( combinedNoise , new Multiply(voronoiZeroToOne2,new Const(0.06)) );
            combinedNoise = new Add( combinedNoise , new Multiply(voronoiZeroToOne3,new Const(0.04)) );
            combinedNoise = new Add( combinedNoise , new Multiply(voronoiZeroToOne4,new Const(0.02)) );
            combinedNoise = new Add( combinedNoise , new Multiply(perlinZeroToOne2,new Const(0.15)) );

            LibNoise.ModuleBase noiseFinal = new Multiply( combinedNoise , new Power(mulTotal,new Const (2.8)) );

            return noiseFinal;
        }
Beispiel #15
0
    //Copied
    public Vector2 PerlinNoise3D(Transform tr, float radius, float scaler, int octaves = 2, float lucanarity = 2f, float gain = 0.1f, float warp = 0.1f, float testing = 10)
    {
        LibNoise.Generator.Perlin             planes    = GameObject.FindGameObjectWithTag("Setting").GetComponent <TestongThings>().planes;
        LibNoise.Generator.RidgedMultifractal mountains = GameObject.FindGameObjectWithTag("Setting").GetComponent <TestongThings>().mountains;
        float highest = 0;
        float lowest  = 0;

        for (var i = 0; i < vertices.Length; i++)
        {
            Vector3 point = tr.TransformPoint(vertices[i]);
            //Vector3 point = vertices[i];
            float sum = 0.0f, freq = 1.0f, amp = 1.0f;

            for (int j = 0; j < octaves; j++)
            {
                sum  += amp * (float)planes.GetValue(point);
                freq *= lucanarity;
                amp  *= gain;
            }

            sum *= (float)mountains.GetValue(point * freq) * octaves * testing;
            sum  = Mathf.Max(-1, sum / 2);


            vertices[i] = vertices[i].normalized * (radius * scaler + sum);


            if (sum > highest)
            {
                highest = sum;
            }
            if (sum < lowest && sum > 0)
            {
                lowest = sum;
            }
        }
        return(new Vector2(lowest, highest));
    }
Beispiel #16
0
    private static GameObject CreateGameObject(Primitive primitive, LibNoise.Generator.Perlin perlin)
    {
        #region Create Planet Object
        GameObject planet = new GameObject("Planet");
        planet.AddComponent <Planet>();
        planet.GetComponent <Planet>().m_Polygons = primitive.m_Polygons;
        planet.GetComponent <Planet>().Perlin     = perlin;

        MeshCollider meshCollider = planet.AddComponent <MeshCollider>();
        MeshFilter   meshFilter   = planet.AddComponent <MeshFilter>();
        MeshRenderer meshRenderer = planet.AddComponent <MeshRenderer>();
        meshRenderer.material = new Material(Shader.Find("Particles/Standard Surface"));
        #endregion

        #region Generate Terrain
        List <float>   p_TerrainHeight = new List <float>();
        List <Color32> p_TerrainType   = new List <Color32>();
        GenerateTerrain(p_TerrainHeight, p_TerrainType);
        planet.GetComponent <Planet>().p_TerrainHeight = p_TerrainHeight;
        planet.GetComponent <Planet>().p_TerrainType   = p_TerrainType;
        #endregion

        #region Local Variables
        int       vertexCount = (primitive.m_Polygons[0].type == 0) ? primitive.m_Polygons.Count * 6 : primitive.m_Polygons.Count * 3;
        int[]     indices     = new int[vertexCount];
        Vector3[] vertices    = new Vector3[vertexCount];
        Color32[] colors      = new Color32[vertexCount];
        #endregion

        #region Create Mesh Data
        for (int i = 0; i < primitive.m_Polygons.Count; i++)
        {
            #region Get/Set Polygon Data
            var poly = primitive.m_Polygons[i];

            int index = i;
            if (poly.type == 0)
            {
                index = index * 6;
                primitive.m_Polygons[i].indices.Add(index);
                primitive.m_Polygons[i].indices.Add(index + 3);

                primitive.m_Polygons[i].t_Vertices.Add(index + 0);
                primitive.m_Polygons[i].t_Vertices.Add(index + 2);
                primitive.m_Polygons[i].t_Vertices.Add(index + 1);
                primitive.m_Polygons[i].t_Vertices.Add(index + 4);
            }
            else
            {
                index = index * 3;
                primitive.m_Polygons[i].indices.Add(index);

                primitive.m_Polygons[i].t_Vertices.Add(index + 0);
                primitive.m_Polygons[i].t_Vertices.Add(index + 2);
                primitive.m_Polygons[i].t_Vertices.Add(index + 1);
            }
            #endregion

            #region Set Mesh Indices
            indices[index + 0] = index + 0;
            indices[index + 1] = index + 1;
            indices[index + 2] = index + 2;

            if (poly.type == 0)
            {
                indices[index + 3] = index + 3;
                indices[index + 4] = index + 4;
                indices[index + 5] = index + 5;
            }
            #endregion

            #region Set Mesh Vertices
            vertices[index + 0] = primitive.m_Vertices[poly.m_Vertices[0]];
            vertices[index + 1] = primitive.m_Vertices[poly.m_Vertices[2]];
            vertices[index + 2] = primitive.m_Vertices[poly.m_Vertices[1]];
            if (poly.type == 0)
            {
                vertices[index + 3] = primitive.m_Vertices[poly.m_Vertices[0]];
                vertices[index + 4] = primitive.m_Vertices[poly.m_Vertices[3]];
                vertices[index + 5] = primitive.m_Vertices[poly.m_Vertices[2]];
            }
            #endregion

            #region Get Polgon Color (Legacy)

            /*
             * double value0 = Mathf.Abs((float)perlin.GetValue(vertices[index].x, vertices[index].y, vertices[index].z));
             * double value1 = Mathf.Abs((float)perlin.GetValue(vertices[index + 1].x, vertices[index + 1].y, vertices[index + 1].z));
             * double value2 = Mathf.Abs((float)perlin.GetValue(vertices[index + 2].x, vertices[index + 2].y, vertices[index + 2].z));
             * double value3 = Mathf.Abs((float)perlin.GetValue(vertices[index + 3].x, vertices[index + 3].y, vertices[index + 3].z));
             * double value = (value1 + value2 + value3 + value0) / 4;
             * Color32 polyColor = p_TerrainType[p_TerrainType.Count - 1];
             * for (int range = 0; range < p_TerrainHeight.Count; range++)
             * {
             *  if (value <= p_TerrainHeight[range])
             *  {
             *      polyColor = p_TerrainType[range];
             *      break;
             *  }
             * }
             */
            #endregion

            #region Set Colors (Legacy)

            /*
             * colors[index] = polyColor;
             * colors[index + 1] = polyColor;
             * colors[index + 2] = polyColor;
             *
             * if (poly.type == 0)
             * {
             *  colors[index + 3] = polyColor;
             *  colors[index + 4] = polyColor;
             *  colors[index + 5] = polyColor;
             * }
             */
            #endregion

            #region Set Color
            int j_max = (primitive.m_Polygons[i].type == 0) ? 6 : 4;
            for (int j = 0; j < j_max; j++)
            {
                double value = Mathf.Abs((float)perlin.GetValue(vertices[index + j].x, vertices[index + j].y, vertices[index + j].z));
                colors[index + j] = p_TerrainType[p_TerrainType.Count - 1];
                for (int range = 0; range < p_TerrainHeight.Count; range++)
                {
                    if (value <= p_TerrainHeight[range])
                    {
                        colors[index + j] = p_TerrainType[range];
                        break;
                    }
                }
            }
            #endregion
        }
        #endregion

        #region Create Mesh
        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.SetTriangles(indices, 0);
        meshFilter.mesh = mesh;
        meshFilter.mesh.RecalculateNormals();
        meshCollider.sharedMesh = mesh;
        #endregion

        return(planet);
    }
Beispiel #17
0
 /// <summary>
 ///
 /// </summary>
 public XNoiseDefault()
 {
     perlinNoiseGenerator = new LibNoise.Generator.Perlin();
 }
 public NoiseProvider()
 {
     PerlinNoiseGenerator = new Perlin();
 }
        /// <summary>
        /// Returns the output value for the given input coordinates.
        /// </summary>
        /// <param name="x">The input coordinate on the x-axis.</param>
        /// <param name="y">The input coordinate on the y-axis.</param>
        /// <param name="z">The input coordinate on the z-axis.</param>
        /// <returns>The resulting output value.</returns>
        public override double GetValue(double x, double y, double z)
        {
						float signal;
                        float value;
                        int curOctave;

						ModuleBase tmpperl = new Perlin(Frequency,Lacunarity,0.5,OctaveCount,Seed,QualityMode.Medium);
			
                        x *= this.m_frequency;
			            y *= this.m_frequency;
			            z *= this.m_frequency;

                        // Initialize value : first unscaled octave of function; later octaves are scaled 
                        value = (float)m_offset + (float)tmpperl.GetValue(x, y, z);

                        x *= this.m_lacunarity;
                        y *= this.m_lacunarity;
                        z *= this.m_lacunarity;

                        // inner loop of spectral construction, where the fractal is built
                        for(curOctave = 1; curOctave < m_octaveCount; curOctave++) {
				
						
                        // obtain displaced noise value.
                        signal = (float)m_offset + (float)Utils.GradientCoherentNoise3D(x, y, z, m_seed, this.m_quality);;
                        
                        //scale amplitude appropriately for this frequency 
                        signal *= (float)m_weights[curOctave];

                        // scale increment by current altitude of function
                        signal *= value;

                                // Add the signal to the output value.
                                value += signal;

                                // Go to the next octave.
                                x *= m_lacunarity;
                                y *= m_lacunarity;
                                z *= m_lacunarity;

                        }//end for

                        //take care of remainder in _octaveCount
                        float remainder = m_octaveCount - (int)m_octaveCount;

                        if(remainder > 0.0f) {
                                signal = (float)m_offset + (float)tmpperl.GetValue(x, y, z);
                                signal *= (float)m_weights[curOctave];
                                signal *= value;
                                signal *= remainder;
                                value +=  signal;
                        }//end if

                        return value;

        }
Beispiel #20
0
 private static float getAxis(LibNoise.Generator.Perlin perlin)
 {
     return((float)perlin.GetValue(0, 0, 1) * 10);
 }
        /// <summary>
        /// Returns the output value for the given input coordinates.
        /// </summary>
        /// <param name="x">The input coordinate on the x-axis.</param>
        /// <param name="y">The input coordinate on the y-axis.</param>
        /// <param name="z">The input coordinate on the z-axis.</param>
        /// <returns>The resulting output value.</returns>
        public override double GetValue(double x, double y, double z)
        {
                        float signal;
                        float value;
                        int curOctave;

                        x *= Frequency;
                        y *= Frequency;
                        z *= Frequency;

                        // Initialize value, fBM starts with 0
                        value = 0;
			
						ModuleBase tmpperl = new Perlin(Frequency,Lacunarity,0.5,OctaveCount,Seed,QualityMode.Medium);
			
                        // Inner loop of spectral construction, where the fractal is built
                        for(curOctave = 0; curOctave < OctaveCount; curOctave++) {

                                // Get the coherent-noise value.
                                signal = (float)tmpperl.GetValue(x, y, z) * (float)m_weights[curOctave];

                                // Add the signal to the output value.
                                value += signal;

                                // Go to the next octave.
                                x *= Lacunarity;
                                y *= Lacunarity;
                                z *= Lacunarity;

                        }//end for

                        //take care of remainder in _octaveCount
                        float remainder = OctaveCount - (int)OctaveCount;
                        if(remainder > 0.0f) {
                                value += remainder * (float)tmpperl.GetValue(x, y, z) * (float)m_weights[curOctave];
                        }//end if

                        return value;
        }