예제 #1
0
        public TerrainController(SceneInterface scene)
        {
            uint x;
            uint y;

            uint xPatches = scene.SizeX / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES;
            uint yPatches = scene.SizeY / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES;

            LowerLimit = (float)scene.RegionSettings.TerrainLowerLimit;
            RaiseLimit = (float)scene.RegionSettings.TerrainRaiseLimit;

            m_Scene          = scene;
            m_TerrainPatches = new LayerPatch[yPatches, xPatches];

            for (y = 0; y < yPatches; ++y)
            {
                for (x = 0; x < xPatches; ++x)
                {
                    m_TerrainPatches[y, x] = new LayerPatch(22)
                    {
                        X = x,
                        Y = y
                    };
                }
            }
            Patch = new PatchesAccessor(m_TerrainPatches, xPatches, yPatches);
        }
예제 #2
0
 bool ISimulationDataTerrainStorageInterface.TryGetDefault(UUID regionID, List <LayerPatch> list)
 {
     using (var connection = new MySqlConnection(m_ConnectionString))
     {
         connection.Open();
         using (var cmd = new MySqlCommand("SELECT PatchID, TerrainData FROM defaultterrains WHERE RegionID = @regionid", connection))
         {
             cmd.Parameters.AddParameter("@regionid", regionID);
             cmd.CommandTimeout = 3600;
             using (MySqlDataReader dbReader = cmd.ExecuteReader())
             {
                 while (dbReader.Read())
                 {
                     var patch = new LayerPatch
                     {
                         ExtendedPatchID = dbReader.GetUInt32("PatchID"),
                         Serialization   = dbReader.GetBytes("TerrainData")
                     };
                     list.Add(patch);
                 }
             }
         }
     }
     return(list.Count != 0);
 }
예제 #3
0
        public double this[uint x, uint y]
        {
            get
            {
                if (x >= m_Scene.SizeX || y >= m_Scene.SizeY)
                {
                    throw new KeyNotFoundException();
                }
                return(m_TerrainPatches[x / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, y / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES].Data[y % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, x % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES]);
            }
            set
            {
                LayerPatch lp = null;
                if (x >= m_Scene.SizeX || y >= m_Scene.SizeY)
                {
                    throw new KeyNotFoundException();
                }

                m_TerrainRwLock.AcquireWriterLock(() =>
                {
                    lp = m_TerrainPatches[x / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, y / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];
                    lp.Data[y % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, x % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES] = (float)value;
                    lp.IncrementSerial();
                });
                if (lp != null)
                {
                    lp.Dirty = true;
                }
            }
        }
예제 #4
0
        public static void NoiseArea(UGUI agentOwner, SceneInterface scene, ModifyLand modify, ModifyLand.Data data)
        {
            var changed = new List <LayerPatch>();

            for (int x = (int)data.West; x < (int)data.East; x++)
            {
                for (int y = (int)data.South; y < (int)data.North; y++)
                {
                    if (!scene.CanTerraform(agentOwner, new Vector3(x, y, 0)))
                    {
                        continue;
                    }

                    double noise = PerlinNoise2D((double)x / scene.SizeX,
                                                 (double)y / scene.SizeY, 8, 1);

                    LayerPatch lp = scene.Terrain.AdjustTerrain((uint)x, (uint)y, noise * modify.Size);
                    if (lp != null && !changed.Contains(lp))
                    {
                        changed.Add(lp);
                    }
                }
            }

            if (changed.Count != 0)
            {
                foreach (LayerPatch lp in changed)
                {
                    lp.IncrementSerial();
                    scene.Terrain.UpdateTerrainListeners(lp);
                }
                scene.Terrain.UpdateTerrainDataToClients();
            }
        }
예제 #5
0
        public static List <LayerPatch> ToPatchesFromGrayscale(this Bitmap bitmap)
        {
            var patches = new List <LayerPatch>();

            if ((bitmap.Width % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES) != 0 ||
                (bitmap.Height % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES) != 0)
            {
                throw new ArgumentException("bitmap wxh is not dividable by LAYER_PATCH_NUM_XY_ENTRIES");
            }

            for (uint y = 0; y < bitmap.Height / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++y)
            {
                for (uint x = 0; x < bitmap.Width / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++x)
                {
                    var patch = new LayerPatch
                    {
                        X = x,
                        Y = (uint)bitmap.Height / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES - 1 - y
                    };
                    for (uint py = 0; py < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++py)
                    {
                        for (uint px = 0; px < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++px)
                        {
                            long lx = x * LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES + px;
                            long ly = bitmap.Height - (long)y * LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES - py - 1;
                            patch[px, py] = bitmap.GetPixel((int)lx, (int)ly).GetBrightness() * 128f;
                        }
                    }
                    patches.Add(patch);
                }
            }

            return(patches);
        }
예제 #6
0
 List <LayerPatch> ISimulationDataTerrainStorageInterface.this[UUID regionID]
 {
     get
     {
         var patches = new List <LayerPatch>();
         using (var connection = new NpgsqlConnection(m_ConnectionString))
         {
             connection.Open();
             using (var cmd = new NpgsqlCommand("SELECT \"PatchID\", \"TerrainData\" FROM terrains WHERE \"RegionID\" = @regionid", connection))
             {
                 cmd.Parameters.AddParameter("@regionid", regionID);
                 cmd.CommandTimeout = 3600;
                 using (NpgsqlDataReader dbReader = cmd.ExecuteReader())
                 {
                     while (dbReader.Read())
                     {
                         var patch = new LayerPatch
                         {
                             ExtendedPatchID = (uint)(int)dbReader["PatchID"],
                             Serialization   = dbReader.GetBytes("TerrainData")
                         };
                         patches.Add(patch);
                     }
                 }
             }
         }
         return(patches);
     }
 }
예제 #7
0
 public void UpdateTerrainListeners(LayerPatch layerpatch)
 {
     layerpatch = new LayerPatch(layerpatch);
     foreach (ITerrainListener listener in TerrainListeners)
     {
         listener.TerrainUpdate(layerpatch);
     }
 }
예제 #8
0
 public void UpdateWithSerial(LayerPatch p)
 {
     if (p.X >= m_NumXPatches || p.Y >= m_NumYPatches)
     {
         throw new KeyNotFoundException();
     }
     m_TerrainPatches[p.Y, p.X].UpdateWithSerial(p);
 }
예제 #9
0
 public void TerrainUpdate(LayerPatch layerpatch)
 {
     if (layerpatch == null)
     {
         throw new ArgumentNullException(nameof(layerpatch));
     }
     m_StorageTerrainRequestQueue.Enqueue(layerpatch);
 }
        private List <LayerData> CompileWindData(Vector3 basepos)
        {
            var mlist       = new List <LayerData>();
            var patchesList = new List <LayerPatch>();
            var patchX      = new LayerPatch();
            var patchY      = new LayerPatch();

            /* round to nearest low pos */
            bool rX = basepos.X % 256 >= 128;
            bool rY = basepos.Y % 256 >= 128;

            basepos.X = Math.Floor(basepos.X / 256) * 256;
            basepos.Y = Math.Floor(basepos.Y / 256) * 256;

            for (int y = 0; y < 16; ++y)
            {
                for (int x = 0; x < 16; ++x)
                {
                    Vector3 actpos = basepos;
                    actpos.X += x * 4;
                    actpos.Y += y * 4;
                    if (rX && x < 8)
                    {
                        actpos.X += 128;
                    }
                    if (rY && y < 8)
                    {
                        actpos.Y += 128;
                    }
                    Vector3 w = Wind[actpos];
                    patchX[x, y] = (float)w.X;
                    patchY[x, y] = (float)w.Y;
                }
            }

            patchesList.Add(patchX);
            patchesList.Add(patchY);

            var layerType = LayerData.LayerDataType.Wind;

            if (BASE_REGION_SIZE < m_Scene.SizeX || BASE_REGION_SIZE < m_Scene.SizeY)
            {
                layerType = LayerData.LayerDataType.WindExtended;
            }
            int offset = 0;

            while (offset < patchesList.Count)
            {
                int remaining = Math.Min(patchesList.Count - offset, LayerCompressor.MESSAGES_PER_WIND_LAYER_PACKET);
                int actualused;
                mlist.Add(LayerCompressor.ToLayerMessage(patchesList, layerType, offset, remaining, out actualused));
                offset += actualused;
            }
            return(mlist);
        }
예제 #11
0
        public static void FlattenArea(UGUI agentOwner, SceneInterface scene, ModifyLand modify, ModifyLand.Data data)
        {
            var changed = new List <LayerPatch>();

            double sum   = 0;
            double steps = 0;

            for (var x = (int)data.West; x < (int)data.East; x++)
            {
                for (var y = (int)data.South; y < (int)data.North; y++)
                {
                    if (!scene.CanTerraform(agentOwner, new Vector3(x, y, 0)))
                    {
                        continue;
                    }
                    sum += scene.Terrain[(uint)x, (uint)y];
                    steps++;
                }
            }

            double avg = sum / steps;

            double str = 0.1f * modify.Size; // == 0.2 in the default client

            for (var x = (int)data.West; x < (int)data.East; x++)
            {
                for (var y = (int)data.South; y < (int)data.North; y++)
                {
                    if (scene.CanTerraform(agentOwner, new Vector3(x, y, 0)))
                    {
                        LayerPatch lp = scene.Terrain.BlendTerrain((uint)x, (uint)y, avg, str);
                        if (lp != null && !changed.Contains(lp))
                        {
                            changed.Add(lp);
                        }
                    }
                }
            }

            if (changed.Count != 0)
            {
                foreach (LayerPatch lp in changed)
                {
                    lp.IncrementSerial();
                    scene.Terrain.UpdateTerrainListeners(lp);
                }
                scene.Terrain.UpdateTerrainDataToClients();
            }
        }
예제 #12
0
        public static void SmoothArea(UGUI agentOwner, SceneInterface scene, ModifyLand modify, ModifyLand.Data data)
        {
            var changed = new List <LayerPatch>();

            double area = modify.Size;
            double step = area / 4;

            for (int x = (int)data.West; x < (int)data.East; x++)
            {
                for (int y = (int)data.South; y < (int)data.North; y++)
                {
                    if (!scene.CanTerraform(agentOwner, new Vector3(x, y, 0)))
                    {
                        continue;
                    }

                    double average  = 0;
                    int    avgsteps = 0;

                    for (double n = 0 - area; n < area; n += step)
                    {
                        for (double l = 0 - area; l < area; l += step)
                        {
                            avgsteps++;
                            average += GetBilinearInterpolate(x + n, y + l, scene);
                        }
                    }

                    LayerPatch lp = scene.Terrain.BlendTerrain((uint)x, (uint)y, average / avgsteps, 1);
                    if (lp != null && !changed.Contains(lp))
                    {
                        changed.Add(lp);
                    }
                }
            }

            if (changed.Count != 0)
            {
                foreach (LayerPatch lp in changed)
                {
                    lp.IncrementSerial();
                    scene.Terrain.UpdateTerrainListeners(lp);
                }
                scene.Terrain.UpdateTerrainDataToClients();
            }
        }
예제 #13
0
        /*
         * public IList<TerrainPatch> GetTerrainDistanceSorted(Vector3 v)
         * {
         *  SortedList<int, TerrainPatch> sorted = new SortedList<int, TerrainPatch>();
         *  uint x;
         *  uint y;
         *
         *  if(v.X < 0)
         *  {
         *      x = 0;
         *  }
         *  else if(v.X >= SizeX)
         *  {
         *      x = SizeX - 1;
         *  }
         *  else
         *  {
         *      x = (uint)v.X / TERRAIN_PATCH_SIZE;
         *  }
         *
         *  if (v.Y < 0)
         *  {
         *      y = 0;
         *  }
         *  else if(v.Y >= SizeY)
         *  {
         *      y = SizeY - 1;
         *  }
         *  else
         *  {
         *      y = (uint)v.Y / TERRAIN_PATCH_SIZE;
         *  }
         *
         *  int distance;
         *
         *  for(uint py = 0; py < SizeY / TERRAIN_PATCH_SIZE; ++py)
         *  {
         *      for(uint px = 0; px < SizeX / TERRAIN_PATCH_SIZE; ++px)
         *      {
         *          distance = ((int)px - (int)x) * ((int)px - (int)x) + ((int)py - (int)y) * ((int)py - (int)y);
         *          sorted.Add(distance, new TerrainPatch(px, py, m_Map[py * m_PatchCountX + px]));
         *      }
         *  }
         *
         *  return sorted.Values;
         * }
         */
        private List <LayerData> CompileTerrainData(IAgent agent) => m_TerrainRwLock.AcquireReaderLock(() =>
        {
            int y;
            int x;
            var mlist        = new List <LayerData>();
            var dirtyPatches = new List <LayerPatch>();
            RwLockedDictionary <uint, uint> agentSceneSerials = agent.TransmittedTerrainSerials[m_Scene.ID];

            for (y = 0; y < m_Scene.SizeY / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++y)
            {
                for (x = 0; x < m_Scene.SizeX / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++x)
                {
                    LayerPatch patch = m_TerrainPatches[y, x];
                    uint serial;
                    if (agentSceneSerials.TryGetValue(patch.ExtendedPatchID, out serial))
                    {
                        if (serial != patch.Serial)
                        {
                            agentSceneSerials[patch.ExtendedPatchID] = serial;
                            dirtyPatches.Add(m_TerrainPatches[y, x]);
                        }
                    }
                    else
                    {
                        dirtyPatches.Add(m_TerrainPatches[y, x]);
                    }
                }
            }
            var layerType = LayerData.LayerDataType.Land;

            if (BASE_REGION_SIZE < m_Scene.SizeX || BASE_REGION_SIZE < m_Scene.SizeY)
            {
                layerType = LayerData.LayerDataType.LandExtended;
            }
            int offset = 0;
            while (offset < dirtyPatches.Count)
            {
                int remaining  = dirtyPatches.Count - offset;
                int actualused = 0;
                mlist.Add(LayerCompressor.ToLayerMessage(dirtyPatches, layerType, offset, remaining, out actualused));
                offset += actualused;
            }
            return(mlist);
        });
        public bool TryGetDefault(UUID regionID, List <LayerPatch> list)
        {
            RwLockedDictionary <uint, byte[]> patchesData;

            if (m_DefaultTerrainData.TryGetValue(regionID, out patchesData))
            {
                foreach (var kvp in patchesData)
                {
                    var patch = new LayerPatch
                    {
                        ExtendedPatchID = kvp.Key,
                        Serialization   = kvp.Value
                    };
                    list.Add(patch);
                }
                return(true);
            }
            return(false);
        }
 List <LayerPatch> ISimulationDataTerrainStorageInterface.this[UUID regionID]
 {
     get
     {
         RwLockedDictionary <uint, byte[]> patchesData;
         var patches = new List <LayerPatch>();
         if (m_TerrainData.TryGetValue(regionID, out patchesData))
         {
             foreach (var kvp in patchesData)
             {
                 var patch = new LayerPatch
                 {
                     ExtendedPatchID = kvp.Key,
                     Serialization   = kvp.Value
                 };
                 patches.Add(patch);
             }
         }
         return(patches);
     }
 }
            public static List <LayerPatch> LoadStream(Stream input, int suggested_width, int suggested_height)
            {
                var patches = new List <LayerPatch>();
                var vals    = new float[LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, suggested_width];

                using (var bs = new BinaryReader(input))
                {
                    for (uint patchy = 0; patchy < suggested_height / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++patchy)
                    {
                        /* we have to load 16 lines at a time */
                        for (uint liney = 0; liney < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++liney)
                        {
                            for (uint x = 0; x < suggested_width; ++x)
                            {
                                vals[liney, x] = bs.ReadSingle();
                            }
                        }

                        /* now build patches from those 16 lines */
                        for (uint patchx = 0; patchx < suggested_width / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++patchx)
                        {
                            var patch = new LayerPatch
                            {
                                X = patchx,
                                Y = patchy
                            };
                            for (uint y = 0; y < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++y)
                            {
                                for (uint x = 0; x < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++x)
                                {
                                    patch[x, y] = vals[y, x + patchx * LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];
                                }
                            }
                            patches.Add(patch);
                        }
                    }
                }

                return(patches);
            }
예제 #17
0
        public LayerPatch AdjustTerrain(uint x, uint y, double change)
        {
            if (x >= m_Scene.SizeX || y >= m_Scene.SizeY)
            {
                throw new KeyNotFoundException();
            }

            return(m_TerrainRwLock.AcquireWriterLock(() =>
            {
                LayerPatch lp = m_TerrainPatches[x / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, y / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];
                float val = lp.Data[y % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, x % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES] + (float)change;
                if (val < LowerLimit)
                {
                    val = LowerLimit;
                }
                else if (val > RaiseLimit)
                {
                    val = RaiseLimit;
                }
                lp.Data[y % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, x % LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES] = val;
                return lp;
            }));
        }
예제 #18
0
        public void Flush()
        {
            var updatedPatches = new List <LayerPatch>();

            m_TerrainRwLock.AcquireReaderLock(-1);
            try
            {
                int x;
                int y;

                for (y = 0; y < m_Scene.SizeY / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++y)
                {
                    for (x = 0; x < m_Scene.SizeX / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++x)
                    {
                        LayerPatch patch = m_TerrainPatches[y, x];
                        if (patch.Dirty)
                        {
                            updatedPatches.Add(patch);
                            patch.Dirty = false;
                        }
                    }
                }
            }
            finally
            {
                m_TerrainRwLock.ReleaseReaderLock();
            }
            UpdateTerrainDataToClients();
            foreach (LayerPatch lp in updatedPatches)
            {
                foreach (ITerrainListener listener in TerrainListeners)
                {
                    listener.TerrainUpdate(new LayerPatch(lp));
                }
            }
        }
예제 #19
0
        public List <LayerPatch> LoadStream(System.IO.Stream input, int suggested_width, int suggested_height)
        {
            Encoding ascii   = Encoding.ASCII;
            var      patches = new List <LayerPatch>();

            using (var bs = new BinaryReader(input))
            {
                if (ascii.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
                {
                    for (; ;)
                    {
                        switch (ascii.GetString(bs.ReadBytes(4)))
                        {
                        case "SIZE":
                            suggested_width  = bs.ReadInt16() + 1;
                            suggested_height = suggested_width;
                            bs.ReadInt16();
                            break;

                        case "XPTS":
                            suggested_width = bs.ReadInt16();
                            bs.ReadInt16();
                            break;

                        case "YPTS":
                            suggested_height = bs.ReadInt16();
                            bs.ReadInt16();
                            break;

                        case "ALTW":
                            float heightScale = (float)bs.ReadInt16() / 65536f;
                            var   baseHeight  = (float)bs.ReadInt16();
                            var   vals        = new float[LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES, suggested_width / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];

                            for (uint patchy = 0; patchy < suggested_height / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++patchy)
                            {
                                /* we have to load 16 lines at a time */
                                for (uint liney = 0; liney < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++liney)
                                {
                                    for (uint x = 0; x < suggested_width; ++x)
                                    {
                                        vals[liney, x] = baseHeight + bs.ReadInt16() * heightScale;
                                    }
                                }

                                /* now build patches from those 16 lines */
                                for (uint patchx = 0; patchx < suggested_width / LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++patchx)
                                {
                                    var patch = new LayerPatch
                                    {
                                        X = patchx,
                                        Y = patchy
                                    };
                                    for (uint y = 0; y < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++y)
                                    {
                                        for (uint x = 0; x < LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES; ++x)
                                        {
                                            patch[x, y] = vals[y, x + patchx * LayerCompressor.LAYER_PATCH_NUM_XY_ENTRIES];
                                        }
                                    }
                                    patches.Add(patch);
                                }
                            }
                            return(patches);

                        default:
                            bs.ReadInt32();
                            break;
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("Invalid file format");
                }
            }
        }
예제 #20
0
 public static uint XYToYNormal(this LayerPatch p, uint lineWidth, uint minY) =>
 (p.Y - minY) * lineWidth + p.X;
예제 #21
0
        public static void FlattenSphere(UGUI agentOwner, SceneInterface scene, ModifyLand modify, ModifyLand.Data data)
        {
            var changed = new List <LayerPatch>();

            double strength = MetersToSphericalStrength(data.BrushSize);

            int xFrom = (int)(data.West - data.BrushSize + 0.5);
            int xTo   = (int)(data.West + data.BrushSize + 0.5);
            int yFrom = (int)(data.South - data.BrushSize + 0.5);
            int yTo   = (int)(data.South + data.BrushSize + 0.5);

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

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

            if (xTo >= scene.SizeX)
            {
                xTo = (int)scene.SizeX - 1;
            }

            if (yTo > scene.SizeY)
            {
                yTo = (int)scene.SizeY - 1;
            }

            for (int x = xFrom; x <= xTo; x++)
            {
                for (int y = yFrom; y <= yTo; y++)
                {
                    var pos = new Vector3(x, y, 0);
                    if (!scene.CanTerraform(agentOwner, pos))
                    {
                        continue;
                    }

                    double z = (modify.Seconds < 4.0) ?
                               SphericalFactor(x, y, data.West, data.South, strength) * modify.Seconds * 0.25f :
                               1;

                    double delta = modify.Height - scene.Terrain[(uint)x, (uint)y];
                    if (Math.Abs(delta) > 0.1)
                    {
                        if (z > 1)
                        {
                            z = 1;
                        }
                        else if (z < 0)
                        {
                            z = 0;
                        }
                        delta *= z;
                    }

                    if (Math.Abs(delta) >= Double.Epsilon) // add in non-zero amount
                    {
                        LayerPatch lp = scene.Terrain.AdjustTerrain((uint)x, (uint)y, delta);
                        if (lp != null && !changed.Contains(lp))
                        {
                            changed.Add(lp);
                        }
                    }
                }
            }

            if (changed.Count != 0)
            {
                foreach (LayerPatch lp in changed)
                {
                    lp.IncrementSerial();
                }
                scene.Terrain.UpdateTerrainDataToClients();
            }
        }
예제 #22
0
 public static uint XYToYInverted(this LayerPatch p, uint lineWidth, uint maxY) => (maxY - p.Y) * lineWidth + p.X;
예제 #23
0
        public static void LowerSphere(UGUI agentOwner, SceneInterface scene, ModifyLand modify, ModifyLand.Data data)
        {
            var changed = new List <LayerPatch>();

            int xFrom = (int)(data.West - data.BrushSize + 0.5);
            int xTo   = (int)(data.West + data.BrushSize + 0.5);
            int yFrom = (int)(data.South - data.BrushSize + 0.5);
            int yTo   = (int)(data.South + data.BrushSize + 0.5);

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

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

            if (xTo >= scene.SizeX)
            {
                xTo = (int)scene.SizeX - 1;
            }

            if (yTo >= scene.SizeY)
            {
                yTo = (int)scene.SizeY - 1;
            }

            for (int x = xFrom; x <= xTo; x++)
            {
                for (int y = yFrom; y <= yTo; y++)
                {
                    Vector3 pos = new Vector3(x, y, 0);
                    if (!scene.CanTerraform(agentOwner, pos))
                    {
                        continue;
                    }

                    // Calculate a cos-sphere and add it to the heightmap
                    double r = Math.Sqrt((x - data.West) * (x - data.West) + ((y - data.South) * (y - data.South)));
                    double z = Math.Cos(r * Math.PI / (data.BrushSize * 2));
                    if (z > 0.0)
                    {
                        LayerPatch lp = scene.Terrain.AdjustTerrain((uint)x, (uint)y, -z * modify.Seconds);
                        if (lp != null && !changed.Contains(lp))
                        {
                            changed.Add(lp);
                        }
                    }
                }
            }

            if (changed.Count != 0)
            {
                foreach (LayerPatch lp in changed)
                {
                    lp.IncrementSerial();
                    scene.Terrain.UpdateTerrainListeners(lp);
                }
                scene.Terrain.UpdateTerrainDataToClients();
            }
        }
예제 #24
0
        public static void NoiseSphere(UGUI agentOwner, SceneInterface scene, ModifyLand modify, ModifyLand.Data data)
        {
            var changed = new List <LayerPatch>();

            int n = (int)(data.BrushSize + 0.5f);

            if (data.BrushSize > 6)
            {
                data.BrushSize = 6;
            }

            double strength = MetersToSphericalStrength(data.BrushSize);

            double area     = data.BrushSize;
            double step     = data.BrushSize / 4;
            double duration = modify.Seconds * 0.01f;

            int zx = (int)(data.West + 0.5);
            int zy = (int)(data.South + 0.5);

            double average  = 0;
            int    avgsteps = 0;

            for (double nn = 0 - area; nn < area; nn += step)
            {
                for (double l = 0 - area; l < area; l += step)
                {
                    avgsteps++;
                    average += GetBilinearInterpolate(data.West + nn, data.South + l, scene);
                }
            }

            for (int dx = -n; dx <= n; dx++)
            {
                for (int dy = -n; dy <= n; dy++)
                {
                    int x = zx + dx;
                    int y = zy + dy;
                    if (x >= 0 && y >= 0 && x < scene.SizeX && y < scene.SizeY)
                    {
                        Vector3 pos = new Vector3(x, y, 0);
                        if (!scene.CanTerraform(agentOwner, pos))
                        {
                            continue;
                        }

                        double z = SphericalFactor(x, y, data.West, data.South, strength) / (strength);
                        if (z > 0) // add in non-zero amount
                        {
                            double a = scene.Terrain[(uint)x, (uint)y] - (average / avgsteps);

                            LayerPatch lp = scene.Terrain.AdjustTerrain((uint)x, (uint)y, a * duration);
                            if (lp != null && !changed.Contains(lp))
                            {
                                changed.Add(lp);
                            }
                        }
                    }
                }
            }

            if (changed.Count != 0)
            {
                foreach (LayerPatch lp in changed)
                {
                    lp.IncrementSerial();
                    scene.Terrain.UpdateTerrainListeners(lp);
                }
                scene.Terrain.UpdateTerrainDataToClients();
            }
        }