示例#1
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);

            int x;

            for (x = 0; x < map.Width; x++)
            {
                int y;
                for (y = 0; y < map.Height; y++)
                {
                    if (!mask[x, y])
                    {
                        continue;
                    }

                    // Calculate a sphere and add it to the heighmap
                    double z = strength;
                    z *= z;
                    z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));

                    double noise = TerrainUtil.PerlinNoise2D(x / (double)Constants.RegionSize, y / (double)Constants.RegionSize, 8, 1.0);

                    if (z > 0.0)
                    {
                        map[x, y] += noise * z * duration;
                    }
                }
            }
        }
示例#2
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
                                float size, float strength, int startX, int endX, int startY, int endY)
        {
            int   x, y;
            float distancefactor;
            float dx2;

            size *= size;

            for (x = startX; x <= endX; x++)
            {
                dx2 = (x - rx) * (x - rx);
                for (y = startY; y <= endY; y++)
                {
                    if (!mask[x, y])
                    {
                        continue;
                    }

                    // Calculate a sphere and add it to the heighmap
                    distancefactor = (dx2 + (y - ry) * (y - ry)) / size;
                    if (distancefactor > 1.0f)
                    {
                        continue;
                    }

                    distancefactor = strength * (1.0f - distancefactor);
                    float noise = (float)TerrainUtil.PerlinNoise2D(x / (double)map.Width, y / (double)map.Height, 8, 1.0);
                    map[x, y] += noise * distancefactor;
                }
            }
        }
示例#3
0
        public void ModifyMap(int X1, int X2, int Y1, int Y2, float[,] Q, int Shape, int Tool, bool IsPrimary, int Radius, float Flow, string MapName)
        {
            object Map = GetMap(MapName);

            int[,] IntArray     = new int[, ] {
            };
            byte[,] ByteArray   = new byte[, ] {
            };
            float[,] FloatArray = new float[, ] {
            };

            if (Map.GetType() == IntArray.GetType())
            {
                int[,] Array = (int[, ])Map;
                TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
            }
            else if (Map.GetType() == ByteArray.GetType())
            {
                byte[,] Array = (byte[, ])Map;
                TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
            }
            else if (Map.GetType() == FloatArray.GetType())
            {
                float[,] Array = (float[, ])Map;
                TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
            }
            HasTerrainUpdate = true;
        }
示例#4
0
        /*
         * public void UpdateTerrainSize(int NX, int NY, float NS)
         * {
         *  SX = NX;
         *  SY = NY;
         *  TerrainScale = NS;
         *
         *  HeightMap = VoxelUtil.MergeFields(new int[SX + 1, SY + 1],  HeightMap);
         *  VoxelUtil.ReplaceValue(HeightMap, 0, (int)Math.Round(TerrainDepth / HeightScale));
         *
         *  MaterialMap = VoxelUtil.MergeFields(new byte[SX * MaterialDensity, SY * MaterialDensity], MaterialMap);
         *  SecondaryMaterialMap = VoxelUtil.MergeFields(new byte[SX * MaterialDensity, SY * MaterialDensity], SecondaryMaterialMap);
         *  BlendAlphaMap = VoxelUtil.MergeFields(new byte[SX * MaterialDensity, SY * MaterialDensity], BlendAlphaMap);
         *  DecalMaterialMap = VoxelUtil.MergeFields(new byte[SX * MaterialDensity, SY * MaterialDensity], DecalMaterialMap);
         *  DecalAlphaMap = VoxelUtil.MergeFields(new byte[SX * MaterialDensity, SY * MaterialDensity], DecalAlphaMap);
         *
         *  WaterHeightMap = VoxelUtil.MergeFields(new int[SX + 1, SY + 1], WaterHeightMap);
         *
         *  FlowXMap = VoxelUtil.MergeFields( VoxelUtil.ReturnReplaceValue(new byte[SX, SY], 0, 128), FlowXMap);
         *  FlowYMap = VoxelUtil.MergeFields( VoxelUtil.ReturnReplaceValue(new byte[SX, SY], 0, 128), FlowYMap);
         *  FlowBackTimeMap = VoxelUtil.MergeFields( new byte[SX, SY], FlowBackTimeMap);
         *  FlowPulseSpeedMap = VoxelUtil.MergeFields(new byte[SX, SY], FlowPulseSpeedMap);
         *
         *  WaterMap = VoxelUtil.MergeFields( new byte[SX, SY], WaterMap);
         *  WaveLengthMap = VoxelUtil.MergeFields(new byte[SX + 1, SY + 1], WaveLengthMap);
         *  WaveHeightMap = VoxelUtil.MergeFields(new byte[SX + 1, SY + 1], WaveHeightMap);
         *
         *  WaterAlphaMap = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterAlphaMap);
         *  WaterFresnelMap = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterFresnelMap);
         *  FoamRampMap0 = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], FoamRampMap0);
         *  WaterColorFalloffMap = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterColorFalloffMap);
         *
         *  WaterColorR = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterColorR);
         *  WaterColorG = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterColorG);
         *  WaterColorB = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterColorB);
         *  WaterColorA = VoxelUtil.MergeFields(new byte[SX * WaterColorDensity + 1, SY * WaterColorDensity + 1], WaterColorA);
         *
         *  //VoxelUtil.ReturnReplaceValue(new byte[SX, SY], 0, 128);
         *  //VoxelUtil.ReturnReplaceValue(new byte[SX, SY], 0, 128);
         *
         *  //VoxelUtil.ReplaceValue(FoamPulseSpeedMap, 0, 128);
         *  //VoxelUtil.ReplaceValue(FoamPulseOffsetMap, 0, 128);
         *
         *  HasTerrainUpdate = true;
         * }
         */

        public void MergeEdges(WorldFile OtherFile, bool IsVertical, string MapName, int MergeMode)
        {
            int[,] IntArray     = new int[0, 0];
            byte[,] ByteArray   = new byte[0, 0];
            float[,] FloatArray = new float[0, 0];

            object Map      = GetMap(MapName);
            object OtherMap = OtherFile.GetMap(MapName);

            if (Map != null && OtherMap != null)
            {
                if (Map.GetType() == IntArray.GetType())
                {
                    TerrainUtil.MergeEdges((int[, ])Map, (int[, ])OtherMap, IsVertical, MergeMode);
                }
                else if (Map.GetType() == ByteArray.GetType())
                {
                    TerrainUtil.MergeEdges((byte[, ])Map, (byte[, ])OtherMap, IsVertical, MergeMode);
                }
                else if (Map.GetType() == FloatArray.GetType())
                {
                    TerrainUtil.MergeEdges((float[, ])Map, (float[, ])OtherMap, IsVertical, MergeMode);
                }
            }
        }
示例#5
0
        public void FloodEffect(ITerrainChannel map, UUID userID, float north,
                                float west, float south, float east, float strength)
        {
            float area = strength;
            float step = strength / 4;

            for (int x = (int)west; x < (int)east; x++)
            {
                for (int y = (int)south; y < (int)north; y++)
                {
                    if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0)))
                    {
                        continue;
                    }

                    float average  = 0;
                    int   avgsteps = 0;

                    float n;
                    for (n = 0 - area; n < area; n += step)
                    {
                        float l;
                        for (l = 0 - area; l < area; l += step)
                        {
                            avgsteps++;
                            average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
                        }
                    }

                    map[x, y] = average / avgsteps;
                }
            }
        }
示例#6
0
        public override float operate(float[,] map, TerrainModifierData data, int x, int y)
        {
            float factor = this.computeBevel(data, x, y);
            float noise  = (float)TerrainUtil.PerlinNoise2D((double)x / map.GetLength(0), (double)y / map.GetLength(1), 8, 1.0);

            return(map[x, y] + (data.elevation - (data.elevation - data.bevelevation) * factor) * (noise - .5f));
        }
示例#7
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
                                double strength, double duration, int startX, int endX, int startY, int endY)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);

            int x, y;

            for (x = startX; x <= endX; x++)
            {
                for (y = startY; y <= endY; y++)
                {
                    if (!mask[x, y])
                    {
                        continue;
                    }

                    // Calculate a sphere and add it to the heighmap
                    double z = strength;
                    z *= z;
                    z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));

                    double noise = TerrainUtil.PerlinNoise2D(x / (double)map.Width, y / (double)map.Height, 8, 1.0);

                    if (z > 0.0)
                    {
                        map[x, y] += noise * z * duration;
                    }
                }
            }
        }
示例#8
0
    void Start()
    {
        perlinIsland = new PerlinIsland(frequency, octaves, maxHeight);
        this.terrain = GetComponent <Terrain>();
        TerrainUtil terrainUtil = new TerrainUtil(terrain, texture2D, perlinIsland, height, width, depth);

        terrainUtil.Draw();
    }
    void Start()
    {
        fractalIsland = new FractalIsland(minValue, altitude, addAltitude);
        this.terrain  = GetComponent <Terrain>();
        TerrainUtil terrainUtil = new TerrainUtil(terrain, texture2D, fractalIsland, height, width, depth, 2);

        terrainUtil.Draw();
    }
    void Start()
    {
        diamondSquareAverageCornerIsland = new DiamondSquareAverageCornerIsland(minValue, altitude, addAltitude);
        this.terrain = GetComponent <Terrain>();
        TerrainUtil terrainUtil =
            new TerrainUtil(terrain, texture2D, diamondSquareAverageCornerIsland, height + 1, width + 1, depth);

        terrainUtil.Draw();
    }
示例#11
0
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        InputGeometryCompiler compiler = context.geomCompiler;
        List <Component>      items    = context.components;
        List <byte>           areas    = context.areas;

        for (int i = 0; i < items.Count; i++)
        {
            Component item = items[i];

            if (item is Terrain)
            {
                Terrain terrain = (Terrain)item;

                if (terrain.terrainData != terrainData)
                {
                    continue;
                }

                TriangleMesh mesh   = TerrainUtil.TriangulateSurface(terrain, mResolution);
                byte[]       lareas = NMGen.CreateAreaBuffer(mesh.triCount, areas[i]);

                if (compiler.AddTriangles(mesh, lareas))
                {
                    string msg = string.Format("Compiled the {0} terrain surface. Triangles: {1}"
                                               , terrain.name, mesh.triCount);

                    context.Log(msg, this);
                }
                else
                {
                    string msg =
                        string.Format("Compiler rejected mesh for the {0} terrain.", terrain.name);

                    context.LogError(msg, this);

                    return;
                }

                if (includeTrees)
                {
                    int before = compiler.TriCount;

                    TerrainUtil.TriangluateTrees(terrain, areas[i], compiler);

                    string msg = string.Format("Compiled the {0} terrain trees. Triangles: {1}"
                                               , terrain.name, compiler.TriCount - before);

                    context.Log(msg, this);
                }

                break;
            }
        }
    }
    private void Start()
    {
        perlinSolitaryIsland =
            new PerlinSolitaryIsland(truncatedProportion, mountainProportion, frequency, octaves, maxHeight);
        this.terrain = GetComponent <Terrain>();
        TerrainUtil terrainUtil = new TerrainUtil(terrain, texture2D, perlinSolitaryIsland, height, width, depth, 1);

        terrainUtil.Draw();
    }
示例#13
0
        public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength,
                                float duration, float BrushSize, List <IScene> scene)
        {
            if (m_module == null)
            {
                return;
            }
            strength = TerrainUtil.MetersToSphericalStrength(BrushSize);
            duration = 0.03f; //MCP Should be read from ini file

            if (duration > 1.0)
            {
                duration = 1;
            }
            if (duration < 0)
            {
                return;
            }

            int n  = (int)(BrushSize + 0.5f);
            int zx = (int)(rx + 0.5);
            int zy = (int)(ry + 0.5);

            int dx;

            for (dx = -n; dx <= n; dx++)
            {
                int dy;
                for (dy = -n; dy <= n; dy++)
                {
                    int x = zx + dx;
                    int y = zy + dy;
                    if (x >= 0 && y >= 0 && x < map.Width && y < map.Height)
                    {
                        if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0)))
                        {
                            continue;
                        }

                        // Calculate a sphere and add it to the heighmap
                        float z = 0;
                        if (duration < 4.0)
                        {
                            z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25f;
                        }

                        if (z > 0.0)
                        {
                            float s = strength * 0.025f;
                            map[x, y] = (map[x, y] * (1 - s)) + (m_module.TerrainRevertMap[x, y] * s);
                        }
                    }
                }
            }
        }
示例#14
0
        //Modifies With HeightAdjustMent
        public void ModifyMap(int X1, int X2, int Y1, int Y2, float[,] Q, int Shape, int Tool, bool IsPrimary, int Radius, float Flow, string MapName, string AdjustMapName, bool AdjustHeight)
        {
            object Map           = GetMap(MapName);
            object AdjustmentMap = GetMap(AdjustMapName);

            int[,] IntArray      = new int[, ] {
            };
            byte[,] ByteArray    = new byte[, ] {
            };
            float[,] FloatArrray = new float[, ] {
            };

            if (Map.GetType() == IntArray.GetType() && AdjustmentMap.GetType() == IntArray.GetType())
            {
                if (AdjustHeight)
                {
                    int[,] Array           = (int[, ])Map;
                    int[,] AdjustmentArray = (int[, ])AdjustmentMap;

                    TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, AdjustmentArray, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
                }
                else
                {
                    int[,] Array           = (int[, ])Map;
                    int[,] AdjustmentArray = (int[, ])AdjustmentMap;

                    int[,] OldArray = (int[, ])Array.Clone();

                    //apply difference
                    TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, AdjustmentArray, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
                    TerrainUtil.AdjustWaterHeight(OldArray, Array, AdjustmentArray);
                }
            }
            else if (Map.GetType() == FloatArrray.GetType() && AdjustmentMap.GetType() == FloatArrray.GetType())
            {
                if (AdjustHeight)
                {
                    float[,] Array           = (float[, ])Map;
                    float[,] AdjustmentArray = (float[, ])AdjustmentMap;
                    TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, AdjustmentArray, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
                }
                else
                {
                    float[,] Array           = (float[, ])Map;
                    float[,] AdjustmentArray = (float[, ])AdjustmentMap;
                    float[,] OldArray        = (float[, ])Array.Clone();
                    //apply difference
                    TerrainUtil.ApplySquareBrush(X1, X2, Y1, Y2, Q, Array, AdjustmentArray, Shape, Tool, Radius, IsPrimary ? 1 : -1, Flow);
                    TerrainUtil.AdjustWaterHeight(OldArray, Array, AdjustmentArray);
                }
            }
            HasTerrainUpdate = true;
        }
示例#15
0
    // Use this for initialization
    void Start()
    {
        Terrain terrain = GameObject.Find("Terrain").GetComponent <Terrain>();

        //TerrainUtil.Sink(terrain, new Vector3(0, 4f, 0), 1, -10);
        int[] indexs = new int[10];
        for (int i = 0; i < 9; i++)
        {
            indexs[i] = 1;
        }
        TerrainUtil.Rise(terrain, indexs, 1f, 1);
        //TerrainUtil.Flatten(terrain, 0);
    }
示例#16
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
                                double strength, double duration, int startX, int endX, int startY, int endY)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);

            int x, y;

            // blend in map
            for (x = startX; x <= endX; x++)
            {
                for (y = startY; y <= endY; y++)
                {
                    if (!mask[x, y])
                    {
                        continue;
                    }

                    double z;
                    if (duration < 4.0)
                    {
                        z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25;
                    }
                    else
                    {
                        z = 1.0;
                    }

                    double delta = rz - map[x, y];
                    if (Math.Abs(delta) > 0.1)
                    {
                        if (z > 1.0)
                        {
                            z = 1.0;
                        }
                        else if (z < 0.0)
                        {
                            z = 0.0;
                        }
                        delta *= z;
                    }

                    if (delta != 0) // add in non-zero amount
                    {
                        map[x, y] += delta;
                    }
                }
            }
        }
示例#17
0
        public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
                                int startX, int endX, int startY, int endY)
        {
            int x, y;

            for (x = startX; x <= endX; x++)
            {
                for (y = startY; y <= endY; y++)
                {
                    if (fillArea[x, y])
                    {
                        double noise = TerrainUtil.PerlinNoise2D((double)x / map.Width, (double)y / map.Height, 8, 1.0);
                        map[x, y] += noise * strength;
                    }
                }
            }
        }
示例#18
0
        public void FloodEffect(ITerrainChannel map, UUID userID, float north,
                                float west, float south, float east, float strength)
        {
            for (int x = (int)west; x < (int)east; x++)
            {
                for (int y = (int)south; y < (int)north; y++)
                {
                    if (!((Scene)map.Scene).Permissions.CanTerraformLand(userID, new Vector3(x, y, 0)))
                    {
                        continue;
                    }
                    float noise = TerrainUtil.PerlinNoise2D(x / map.Scene.RegionInfo.RegionSizeX, y / map.Scene.RegionInfo.RegionSizeY, 8, 1);

                    map[x, y] += noise * strength;
                }
            }
        }
示例#19
0
        public void RunEffect(ITerrainChannel map)
        {
            int x, y;

            for (x = 0; x < map.Width; x++)
            {
                for (y = 0; y < map.Height; y++)
                {
                    map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
                    double spherFac = TerrainUtil.SphericalFactor(x, y, map.Width / 2, map.Height / 2, 50) * 0.01;
                    if (map[x, y] < spherFac)
                    {
                        map[x, y] = spherFac;
                    }
                }
            }
        }
        public void RunEffect(ITerrainChannel map)
        {
            int x, y;

            for (x = 0; x < map.Width; x++)
            {
                for (y = 0; y < map.Height; y++)
                {
                    map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25f) * 10;
                    float spherFac = TerrainUtil.SphericalFactor(x, y, map.Scene.RegionInfo.RegionSizeX / 2, map.Scene.RegionInfo.RegionSizeY / 2, 50) * 0.01f;
                    if (map[x, y] < spherFac)
                    {
                        map[x, y] = spherFac;
                    }
                }
            }
        }
示例#21
0
        public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
        {
            int x;

            for (x = 0; x < map.Width; x++)
            {
                int y;
                for (y = 0; y < map.Height; y++)
                {
                    if (fillArea[x, y])
                    {
                        double noise = TerrainUtil.PerlinNoise2D((double)x / map.Width, (double)y / map.Height, 8, 1.0);

                        map[x, y] += noise * strength;
                    }
                }
            }
        }
 void DebuffRiverBankTerrain(ref byte volume, ref byte type, float bottomHeight, float noise2D, float fTerType, IntVector2 worldxz, int vy)
 {
     if (vy > Mathf.CeilToInt(bottomHeight))
     {
         volume = 0;
         type   = BLOCK_AIR;
     }
     else if (vy == Mathf.CeilToInt(bottomHeight))
     {
         float height = bottomHeight % 1;
         if (height == 0)
         {
             height = 1;
         }
         volume = TerrainUtil.HeightToVolume(height);
     }
     else if (vy == Mathf.CeilToInt(bottomHeight) - 1)
     {
         volume = 255;
     }
 }
示例#23
0
        public void RunEffect(ITerrainChannel map)
        {
            int   x, y;
            int   cx = map.Width / 2;
            int   cy = map.Height / 2;
            float h;
            float b;

            for (x = 0; x < map.Width; x++)
            {
                for (y = 0; y < map.Height; y++)
                {
                    h = 25 * TerrainUtil.SphericalFactor(x - cx, y - cy, 50);
                    b = 10 * TerrainUtil.SphericalFactor(x - cx, y - cy, 100);
                    if (h < b)
                    {
                        h = b;
                    }
                    map[x, y] = h;
                }
            }
        }
示例#24
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);
            duration = 0.03; //MCP Should be read from ini file

            if (duration > 1.0)
            {
                duration = 1.0;
            }
            if (duration < 0)
            {
                return;
            }

            int x;

            for (x = 0; x < map.Width; x++)
            {
                int y;
                for (y = 0; y < map.Height; y++)
                {
                    if (!mask[x, y])
                    {
                        continue;
                    }

                    // Calculate a sphere and add it to the heighmap
                    double z = strength;
                    z *= z;
                    z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));

                    if (z > 0.0)
                    {
                        z        *= duration;
                        map[x, y] = (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z);
                    }
                }
            }
        }
示例#25
0
        public void TerrainToBitmap(Bitmap mapbmp)
        {
            int tc = Environment.TickCount;

            m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain");

            // These textures should be in the AssetCache anyway, as every client conneting to this
            // region needs them. Except on start, when the map is recreated (before anyone connected),
            // and on change of the estate settings (textures and terrain values), when the map should
            // be recreated.
            RegionSettings settings = m_scene.RegionInfo.RegionSettings;

            // the four terrain colors as HSVs for interpolation
            HSV hsv1 = new HSV(computeAverageColor(settings.TerrainTexture1, defaultColor1));
            HSV hsv2 = new HSV(computeAverageColor(settings.TerrainTexture2, defaultColor2));
            HSV hsv3 = new HSV(computeAverageColor(settings.TerrainTexture3, defaultColor3));
            HSV hsv4 = new HSV(computeAverageColor(settings.TerrainTexture4, defaultColor4));

            float levelNElow  = (float)settings.Elevation1NE;
            float levelNEhigh = (float)settings.Elevation2NE;

            float levelNWlow  = (float)settings.Elevation1NW;
            float levelNWhigh = (float)settings.Elevation2NW;

            float levelSElow  = (float)settings.Elevation1SE;
            float levelSEhigh = (float)settings.Elevation2SE;

            float levelSWlow  = (float)settings.Elevation1SW;
            float levelSWhigh = (float)settings.Elevation2SW;

            float waterHeight = (float)settings.WaterHeight;

            double[,] hm = m_scene.Heightmap.GetDoubles();

            for (int x = 0; x < (int)Constants.RegionSize; x++)
            {
                float columnRatio = x / ((float)Constants.RegionSize - 1); // 0 - 1, for interpolation
                for (int y = 0; y < (int)Constants.RegionSize; y++)
                {
                    float rowRatio = y / ((float)Constants.RegionSize - 1); // 0 - 1, for interpolation

                    // Y flip the cordinates for the bitmap: hf origin is lower left, bm origin is upper left
                    int yr = ((int)Constants.RegionSize - 1) - y;

                    float heightvalue = getHeight(hm, x, y);
                    if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
                    {
                        heightvalue = 0;
                    }

                    if (heightvalue > waterHeight)
                    {
                        // add a bit noise for breaking up those flat colors:
                        // - a large-scale noise, for the "patches" (using an doubled s-curve for sharper contrast)
                        // - a small-scale noise, for bringing in some small scale variation
                        //float bigNoise = (float)TerrainUtil.InterpolatedNoise(x / 8.0, y / 8.0) * .5f + .5f; // map to 0.0 - 1.0
                        //float smallNoise = (float)TerrainUtil.InterpolatedNoise(x + 33, y + 43) * .5f + .5f;
                        //float hmod = heightvalue + smallNoise * 3f + S(S(bigNoise)) * 10f;
                        float hmod =
                            heightvalue +
                            (float)TerrainUtil.InterpolatedNoise(x + 33, y + 43) * 1.5f + 1.5f +            // 0 - 3
                            S(S((float)TerrainUtil.InterpolatedNoise(x / 8.0, y / 8.0) * .5f + .5f)) * 10f; // 0 - 10

                        // find the low/high values for this point (interpolated bilinearily)
                        // (and remember, x=0,y=0 is SW)
                        float low = levelSWlow * (1f - rowRatio) * (1f - columnRatio) +
                                    levelSElow * (1f - rowRatio) * columnRatio +
                                    levelNWlow * rowRatio * (1f - columnRatio) +
                                    levelNElow * rowRatio * columnRatio;
                        float high = levelSWhigh * (1f - rowRatio) * (1f - columnRatio) +
                                     levelSEhigh * (1f - rowRatio) * columnRatio +
                                     levelNWhigh * rowRatio * (1f - columnRatio) +
                                     levelNEhigh * rowRatio * columnRatio;
                        if (high < low)
                        {
                            // someone tried to fool us. High value should be higher than low every time
                            float tmp = high;
                            high = low;
                            low  = tmp;
                        }

                        HSV hsv;
                        if (hmod <= low)
                        {
                            hsv = hsv1;              // too low
                        }
                        else if (hmod >= high)
                        {
                            hsv = hsv4;                    // too high
                        }
                        else
                        {
                            // HSV-interpolate along the colors
                            // first, rescale h to 0.0 - 1.0
                            hmod = (hmod - low) / (high - low);
                            // now we have to split: 0.00 => color1, 0.33 => color2, 0.67 => color3, 1.00 => color4
                            if (hmod < 1f / 3f)
                            {
                                hsv = interpolateHSV(ref hsv1, ref hsv2, hmod * 3f);
                            }
                            else if (hmod < 2f / 3f)
                            {
                                hsv = interpolateHSV(ref hsv2, ref hsv3, (hmod * 3f) - 1f);
                            }
                            else
                            {
                                hsv = interpolateHSV(ref hsv3, ref hsv4, (hmod * 3f) - 2f);
                            }
                        }

                        // Shade the terrain for shadows
                        if (x < ((int)Constants.RegionSize - 1) && y < ((int)Constants.RegionSize - 1))
                        {
                            float hfvaluecompare = getHeight(hm, x + 1, y + 1); // light from north-east => look at land height there
                            if (Single.IsInfinity(hfvaluecompare) || Single.IsNaN(hfvaluecompare))
                            {
                                hfvaluecompare = 0f;
                            }

                            float hfdiff = heightvalue - hfvaluecompare; // => positive if NE is lower, negative if here is lower
                            hfdiff *= 0.06f;                             // some random factor so "it looks good"
                            if (hfdiff > 0.02f)
                            {
                                float highlightfactor = 0.18f;
                                // NE is lower than here
                                // We have to desaturate and lighten the land at the same time
                                hsv.s = (hsv.s - (hfdiff * highlightfactor) > 0f) ? hsv.s - (hfdiff * highlightfactor) : 0f;
                                hsv.v = (hsv.v + (hfdiff * highlightfactor) < 1f) ? hsv.v + (hfdiff * highlightfactor) : 1f;
                            }
                            else if (hfdiff < -0.02f)
                            {
                                // here is lower than NE:
                                // We have to desaturate and blacken the land at the same time
                                hsv.s = (hsv.s + hfdiff > 0f) ? hsv.s + hfdiff : 0f;
                                hsv.v = (hsv.v + hfdiff > 0f) ? hsv.v + hfdiff : 0f;
                            }
                        }
                        mapbmp.SetPixel(x, yr, hsv.toColor());
                    }
                    else
                    {
                        // We're under the water level with the terrain, so paint water instead of land

                        heightvalue = waterHeight - heightvalue;
                        if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
                        {
                            heightvalue = 0f;
                        }
                        else if (heightvalue > 19f)
                        {
                            heightvalue = 19f;
                        }
                        else if (heightvalue < 0f)
                        {
                            heightvalue = 0f;
                        }

                        heightvalue = 100f - (heightvalue * 100f) / 19f;  // 0 - 19 => 100 - 0

                        mapbmp.SetPixel(x, yr, WATER_COLOR);
                    }
                }
            }
            m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms");
        }
示例#26
0
        public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength,
                                float duration, float BrushSize, Scene scene)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);

            int x;

            for (x = 0; x < map.Width; x++)
            {
                int y;
                for (y = 0; y < map.Height; y++)
                {
                    if (!scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0)))
                    {
                        continue;
                    }

                    double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);

                    if (z > 0) // add in non-zero amount
                    {
                        const int NEIGHBOUR_ME  = 4;
                        const int NEIGHBOUR_MAX = 9;

                        for (int j = 0; j < NEIGHBOUR_MAX; j++)
                        {
                            if (j != NEIGHBOUR_ME)
                            {
                                int[] coords = Neighbours(type, j);

                                coords[0] += x;
                                coords[1] += y;

                                if (coords[0] > map.Width - 1)
                                {
                                    continue;
                                }
                                if (coords[1] > map.Height - 1)
                                {
                                    continue;
                                }
                                if (coords[0] < 0)
                                {
                                    continue;
                                }
                                if (coords[1] < 0)
                                {
                                    continue;
                                }

                                double heightF = map[x, y];
                                double target  = map[coords[0], coords[1]];

                                if (target > heightF + talus)
                                {
                                    double calc = duration * ((target - heightF) - talus) * z;
                                    heightF += calc;
                                    target  -= calc;
                                }

                                map[x, y] = heightF;
                                map[coords[0], coords[1]] = target;
                            }
                        }
                    }
                }
            }
        }
示例#27
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);

            int x;

            for (x = 0; x < map.Width; x++)
            {
                int y;
                for (y = 0; y < map.Height; y++)
                {
                    if (!mask[x, y])
                    {
                        continue;
                    }

                    double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);

                    if (z > 0) // add in non-zero amount
                    {
                        const int NEIGHBOUR_ME  = 4;
                        const int NEIGHBOUR_MAX = 9;

                        double max = Double.MinValue;
                        int    loc = 0;


                        for (int j = 0; j < NEIGHBOUR_MAX; j++)
                        {
                            if (j != NEIGHBOUR_ME)
                            {
                                int[] coords = Neighbours(type, j);

                                coords[0] += x;
                                coords[1] += y;

                                if (coords[0] > map.Width - 1)
                                {
                                    continue;
                                }
                                if (coords[1] > map.Height - 1)
                                {
                                    continue;
                                }
                                if (coords[0] < 0)
                                {
                                    continue;
                                }
                                if (coords[1] < 0)
                                {
                                    continue;
                                }

                                double cellmax = map[x, y] - map[coords[0], coords[1]];
                                if (cellmax > max)
                                {
                                    max = cellmax;
                                    loc = j;
                                }
                            }
                        }

                        double T = nConst / ((map.Width + map.Height) / 2.0);
                        // Apply results
                        if (0 < max && max <= T)
                        {
                            int[]  maxCoords   = Neighbours(type, loc);
                            double heightDelta = 0.5 * max * z * duration;
                            map[x, y] -= heightDelta;
                            map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
                        }
                    }
                }
            }
        }
示例#28
0
        public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration)
        {
            strength = TerrainUtil.MetersToSphericalStrength(strength);

            int x, y;
            // Using one 'rain' round for this, so skipping a useless loop
            // Will need to adapt back in for the Flood brush

            ITerrainChannel water    = new TerrainChannel(map.Width, map.Height);
            ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);

            // Fill with rain
            for (x = 0; x < water.Width; x++)
            {
                for (y = 0; y < water.Height; y++)
                {
                    water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
                }
            }

            for (int i = 0; i < rounds; i++)
            {
                // Erode underlying terrain
                for (x = 0; x < water.Width; x++)
                {
                    for (y = 0; y < water.Height; y++)
                    {
                        if (mask[x, y])
                        {
                            const double solConst = (1.0 / rounds);
                            double       sedDelta = water[x, y] * solConst;
                            map[x, y]      -= sedDelta;
                            sediment[x, y] += sedDelta;
                        }
                    }
                }

                // Move water
                for (x = 0; x < water.Width; x++)
                {
                    for (y = 0; y < water.Height; y++)
                    {
                        if (water[x, y] <= 0)
                        {
                            continue;
                        }

                        // Step 1. Calculate average of neighbours

                        int    neighbours    = 0;
                        double altitudeTotal = 0.0;
                        double altitudeMe    = map[x, y] + water[x, y];

                        const int NEIGHBOUR_ME  = 4;
                        const int NEIGHBOUR_MAX = 9;

                        for (int j = 0; j < NEIGHBOUR_MAX; j++)
                        {
                            if (j != NEIGHBOUR_ME)
                            {
                                int[] coords = Neighbours(type, j);

                                coords[0] += x;
                                coords[1] += y;

                                if (coords[0] > map.Width - 1)
                                {
                                    continue;
                                }
                                if (coords[1] > map.Height - 1)
                                {
                                    continue;
                                }
                                if (coords[0] < 0)
                                {
                                    continue;
                                }
                                if (coords[1] < 0)
                                {
                                    continue;
                                }

                                // Calculate total height of this neighbour
                                double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];

                                // If it's greater than me...
                                if (altitudeNeighbour - altitudeMe < 0)
                                {
                                    // Add it to our calculations
                                    neighbours++;
                                    altitudeTotal += altitudeNeighbour;
                                }
                            }
                        }

                        if (neighbours == 0)
                        {
                            continue;
                        }

                        double altitudeAvg = altitudeTotal / neighbours;

                        // Step 2. Allocate water to neighbours.
                        for (int j = 0; j < NEIGHBOUR_MAX; j++)
                        {
                            if (j != NEIGHBOUR_ME)
                            {
                                int[] coords = Neighbours(type, j);

                                coords[0] += x;
                                coords[1] += y;

                                if (coords[0] > map.Width - 1)
                                {
                                    continue;
                                }
                                if (coords[1] > map.Height - 1)
                                {
                                    continue;
                                }
                                if (coords[0] < 0)
                                {
                                    continue;
                                }
                                if (coords[1] < 0)
                                {
                                    continue;
                                }

                                // Skip if we dont have water to begin with.
                                if (water[x, y] < 0)
                                {
                                    continue;
                                }

                                // Calculate our delta average
                                double altitudeDelta = altitudeMe - altitudeAvg;

                                if (altitudeDelta < 0)
                                {
                                    continue;
                                }

                                // Calculate how much water we can move
                                double waterMin   = Math.Min(water[x, y], altitudeDelta);
                                double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
                                                                / altitudeTotal);

                                double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);

                                if (sedimentDelta > 0)
                                {
                                    sediment[x, y] -= sedimentDelta;
                                    sediment[coords[0], coords[1]] += sedimentDelta;
                                }
                            }
                        }
                    }
                }

                // Evaporate

                for (x = 0; x < water.Width; x++)
                {
                    for (y = 0; y < water.Height; y++)
                    {
                        water[x, y] *= 1.0 - (rainHeight / rounds);

                        double waterCapacity = waterSaturation * water[x, y];

                        double sedimentDeposit = sediment[x, y] - waterCapacity;
                        if (sedimentDeposit > 0)
                        {
                            if (mask[x, y])
                            {
                                sediment[x, y] -= sedimentDeposit;
                                map[x, y]      += sedimentDeposit;
                            }
                        }
                    }
                }
            }

            // Deposit any remainder (should be minimal)
            for (x = 0; x < water.Width; x++)
            {
                for (y = 0; y < water.Height; y++)
                {
                    if (mask[x, y] && sediment[x, y] > 0)
                    {
                        map[x, y] += sediment[x, y];
                    }
                }
            }
        }
示例#29
0
        public void PaintEffect(ITerrainChannel map, UUID userID, float rx, float ry, float rz, float strength,
                                float duration, float BrushSize)
        {
            strength = TerrainUtil.MetersToSphericalStrength(BrushSize);

            int x, y;

            int xFrom = (int)(rx - BrushSize + 0.5);
            int xTo   = (int)(rx + BrushSize + 0.5) + 1;
            int yFrom = (int)(ry - BrushSize + 0.5);
            int yTo   = (int)(ry + BrushSize + 0.5) + 1;

            if (xFrom < 0)
            {
                xFrom = 0;
            }

            if (yFrom < 0)
            {
                yFrom = 0;
            }

            if (xTo > map.Width)
            {
                xTo = map.Width;
            }

            if (yTo > map.Height)
            {
                yTo = map.Height;
            }

            // blend in map
            for (x = xFrom; x < xTo; x++)
            {
                for (y = yFrom; y < yTo; y++)
                {
                    if (!map.Scene.Permissions.CanTerraformLand(userID, new Vector3(x, y, 0)))
                    {
                        continue;
                    }

                    float z;
                    if (duration < 4.0)
                    {
                        z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25f;
                    }
                    else
                    {
                        z = 1;
                    }

                    float delta = rz - map[x, y];
                    if (Math.Abs(delta) > 0.1)
                    {
                        if (z > 1)
                        {
                            z = 1;
                        }
                        else if (z < 0)
                        {
                            z = 0;
                        }
                        delta *= z;
                    }

                    if (delta != 0) // add in non-zero amount
                    {
                        map[x, y] += delta;
                    }
                }
            }
        }
示例#30
0
        public void RunEffect(ITerrainChannel map)
        {
            ITerrainPaintableEffect eroder = new WeatherSphere();

            bool[,] cliffMask   = new bool[map.Width, map.Height];
            bool[,] channelMask = new bool[map.Width, map.Height];
            bool[,] smoothMask  = new bool[map.Width, map.Height];
            bool[,] allowMask   = new bool[map.Width, map.Height];

            m_log.Info("S1");

            // Step one, generate rough mask
            int x, y;

            for (x = 0; x < map.Width; x++)
            {
                for (y = 0; y < map.Height; y++)
                {
                    m_log.Info(".");
                    smoothMask[x, y] = true;
                    allowMask[x, y]  = true;

                    // Start underwater
                    map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
                    // Add a little height. (terrain should now be above water, mostly.)
                    map[x, y] += 20;

                    const int channelsX     = 4;
                    int       channelWidth  = (map.Width / channelsX / 4);
                    const int channelsY     = 4;
                    int       channelHeight = (map.Height / channelsY / 4);

                    SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
                    SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
                }
            }

            m_log.Info("S2");
            //smooth.FloodEffect(map, smoothMask, 4.0);

            m_log.Info("S3");
            for (x = 0; x < map.Width; x++)
            {
                for (y = 0; y < map.Height; y++)
                {
                    if (cliffMask[x, y])
                    {
                        eroder.PaintEffect(map, allowMask, x, y, -1, 4, 0.1);
                    }
                }
            }

            for (x = 0; x < map.Width; x += 2)
            {
                for (y = 0; y < map.Height; y += 2)
                {
                    if (map[x, y] < 0.1)
                    {
                        map[x, y] = 0.1;
                    }
                    if (map[x, y] > 256)
                    {
                        map[x, y] = 256;
                    }
                }
            }
            //smooth.FloodEffect(map, smoothMask, 4.0);
        }