Ejemplo n.º 1
0
 // Create terrain of specified size and initialize with specified terrain.
 // TODO: join this with the terrain initializers.
 public TerrainChannel(String type, int pX, int pY, int pZ)
 {
     m_terrainData = new HeightmapTerrainData(pX, pY, pZ);
     if (type.Equals("flat"))
         FlatLand();
     else
         PinHeadIsland();
 }
Ejemplo n.º 2
0
        /// <summary>
        ///     Add a patch of terrain to a BitPacker
        /// </summary>
        /// <param name="output">BitPacker to write the patch to</param>
        /// <param name="heightmap">
        ///     Heightmap of the simulator. Presumed to be an sizeX*sizeY array.
        /// </param>
        /// <param name="patchX">
        ///     X offset of the patch to create.
        /// </param>
        /// <param name="patchY">
        ///     Y offset of the patch to create.
        /// </param>
        /// <param name="pRegionSizeX"></param>
        /// <param name="pRegionSizeY"></param>
        public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY)
        {
            TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY);
            header.QuantWBits = 136;

            // If larger than legacy region size, pack patch X and Y info differently.
            if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
            {
                header.PatchIDs = (patchY & 0xFFFF);
                header.PatchIDs += (patchX << 16);
            }
            else
            {
                header.PatchIDs = (patchY & 0x1F);
                header.PatchIDs += (patchX << 5);
            }

            // m_log.DebugFormat("{0} CreatePatchFromHeightmap. patchX={1}, patchY={2}, DCOffset={3}, range={4}",
            //                         LogHeader, patchX, patchY, header.DCOffset, header.Range);

            // NOTE: No idea what prequant and postquant should be or what they do
            int wbits;
            int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
            wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits);
            EncodePatch(output, patch, 0, wbits);
        }
Ejemplo n.º 3
0
        public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] xPieces, int[] yPieces)
        {
            byte landPacketType = (byte)TerrainPatch.LayerType.Land;
            if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
            {
                landPacketType = (byte)TerrainPatch.LayerType.LandExtended;
            }

            return CreateLandPacket(terrData, xPieces, yPieces, landPacketType);
        }
        public void StoreTerrain(TerrainData terrData, UUID regionID)
        {
            lock (m_dbLock)
            {
                using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
                {
                    dbcon.Open();

                    using (MySqlCommand cmd = dbcon.CreateCommand())
                    {
                        cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
                        cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());

                        ExecuteNonQuery(cmd);

                        int terrainDBRevision;
                        Array terrainDBblob;
                        terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);

                        m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}",
                                    LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision);

                        cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
                        +   "values (?RegionUUID, ?Revision, ?Heightfield)";

                        cmd.Parameters.AddWithValue("Revision", terrainDBRevision);
                        cmd.Parameters.AddWithValue("Heightfield", terrainDBblob);

                        ExecuteNonQuery(cmd);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        // Create channel passed a heightmap and expected dimensions of the region.
        // The heightmap might not fit the passed size so accomodations must be made.
        public TerrainChannel(double[,] pM, int pSizeX, int pSizeY, int pAltitude)
        {
            int hmSizeX = pM.GetLength(0);
            int hmSizeY = pM.GetLength(1);

            m_terrainData = new HeightmapTerrainData(pSizeX, pSizeY, pAltitude);

            for (int xx = 0; xx < pSizeX; xx++)
                for (int yy = 0; yy < pSizeY; yy++)
                    if (xx > hmSizeX || yy > hmSizeY)
                        m_terrainData[xx, yy] = TerrainData.DefaultTerrainHeight;
                    else
                        m_terrainData[xx, yy] = (float)pM[xx, yy];
        }
Ejemplo n.º 6
0
 // Create terrain of given size
 public TerrainChannel(int pX, int pY)
 {
     m_terrainData = new HeightmapTerrainData(pX, pY, (int)Constants.RegionHeight);
 }
Ejemplo n.º 7
0
 // New terrain serialization format that includes the width and length.
 private void FromXml2(XmlReader xmlReader)
 {
     XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
     TerrainChannelXMLPackage package = (TerrainChannelXMLPackage)serializer.Deserialize(xmlReader);
     m_terrainData = new HeightmapTerrainData(package.Map, package.CompressionFactor, package.SizeX, package.SizeY, package.SizeZ);
 }
Ejemplo n.º 8
0
 public TerrainChannel(TerrainData pTerrData)
 {
     m_terrainData = pTerrData;
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Checks to see height deltas in the tainted terrain patch at xStart ,yStart
        /// are all within the current estate limits
        /// <returns>true if changes were limited, false otherwise</returns>
        /// </summary>
        private bool LimitChannelChanges(TerrainData terrData, int xStart, int yStart)
        {
            bool changesLimited = false;
            float minDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainLowerLimit;
            float maxDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit;

            // loop through the height map for this patch and compare it against
            // the revert map
            for (int x = xStart; x < xStart + Constants.TerrainPatchSize; x++)
            {
                for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++)
                {
                    float requestedHeight = terrData[x, y];
                    float bakedHeight = (float)m_revert[x, y];
                    float requestedDelta = requestedHeight - bakedHeight;

                    if (requestedDelta > maxDelta)
                    {
                        terrData[x, y] = bakedHeight + maxDelta;
                        changesLimited = true;
                    }
                    else if (requestedDelta < minDelta)
                    {
                        terrData[x, y] = bakedHeight + minDelta; //as lower is a -ve delta
                        changesLimited = true;
                    }
                }
            }

            return changesLimited;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Store a terrain revision in region storage
        /// </summary>
        /// <param name="ter">terrain heightfield</param>
        /// <param name="regionID">region UUID</param>
        public void StoreTerrain(TerrainData terrData, UUID regionID)
        {
            lock (ds)
            {
                using (
                    SqliteCommand cmd = new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID", m_conn))
                {
                    cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
                    cmd.ExecuteNonQuery();
                }

                // the following is an work around for .NET.  The perf
                // issues associated with it aren't as bad as you think.
                String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
                             " values(:RegionUUID, :Revision, :Heightfield)";

                int terrainDBRevision;
                Array terrainDBblob;
                terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);

                m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision);

                using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
                {
                    cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
                    cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision));
                    cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob));
                    cmd.ExecuteNonQuery();
                }
            }
        }
Ejemplo n.º 11
0
 public void StoreTerrain(TerrainData ter, UUID regionID)
 {
     if (m_terrains.ContainsKey(regionID))
         m_terrains.Remove(regionID);
     m_terrains.Add(regionID, ter);
 }
Ejemplo n.º 12
0
        private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
                                                               int prequant, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            int[] iout = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize];

            float oozrange = 1.0f / header.Range;
            float invprequat = (1 << prequant);
            float premult = oozrange * invprequat;

            float sub = 0.5f * header.Range + header.DCOffset;

            int wordsize = (prequant - 2) & 0x0f;
            header.QuantWBits = wordsize;
            header.QuantWBits |= wordsize << 4;

            int k = 0;
            int startX = patchX * Constants.TerrainPatchSize;
            int startY = patchY * Constants.TerrainPatchSize;
            for (int y = startY; y < startY + Constants.TerrainPatchSize; y++)
            {
                for (int x = startX; x < startX + Constants.TerrainPatchSize; x++)
                {
                    block[k++] = (terrData[x, y] - sub) * premult;
                }
            }
 
            wbits = (prequant >> 1);

            dct16x16(block, iout, ref wbits);

            return iout;
        }
Ejemplo n.º 13
0
        // Scan the height info we're returning and return a patch packet header for this patch.
        private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY, out float frange)
        {
            TerrainPatch.Header header = new TerrainPatch.Header();
            float zmax = float.MinValue;
            float zmin = float.MaxValue;

            int startx = patchX * Constants.TerrainPatchSize;
            int starty = patchY * Constants.TerrainPatchSize;

            for (int j = starty; j < starty + Constants.TerrainPatchSize; j++)
            {
                for (int i = startx; i < startx + Constants.TerrainPatchSize; i++)
                {
                    float val = terrData[i, j];
                    if (val > zmax) zmax = val;
                    if (val < zmin) zmin = val;
                }
            }

            header.DCOffset = zmin;
            frange = ((zmax - zmin) + 1.0f);
            header.Range = (int)frange;

            return header;
        }
Ejemplo n.º 14
0
        public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY)
        {
            float frange;
            TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY, out frange);
            header.QuantWBits = 130;

            bool largeRegion = false;
            // If larger than legacy region size, pack patch X and Y info differently.
            if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
            {
                header.PatchIDs = (patchY & 0xFFFF);
                header.PatchIDs += (patchX << 16);
                largeRegion = true;
            }
            else
            {
                header.PatchIDs = (patchY & 0x1F);
                header.PatchIDs += (patchX << 5);
            }

            if (Math.Round((double)frange, 2) == 1.0)
            {
                // flat terrain speed up things

                header.DCOffset -= 0.5f;

                header.QuantWBits = 0x00;
                output.PackBits(header.QuantWBits, 8);
                output.PackFloat(header.DCOffset);
                output.PackBits(1, 16);
                if (largeRegion)
                    output.PackBits(header.PatchIDs, 32);
                else
                    output.PackBits(header.PatchIDs, 10);

                // and thats all
                output.PackBits(ZERO_EOB, 2);
                return;
            }

            int wbits;
            int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
            EncodePatchHeader(output, header, patch, largeRegion, ref wbits);
            EncodePatch(output, patch, 0, wbits);
        }
Ejemplo n.º 15
0
        // new using terrain data and patchs indexes
        public static List<LayerDataPacket> CreateLayerDataPackets(TerrainData terrData, int[] x, int[] y, byte landPacketType)
        {
            List<LayerDataPacket> ret = new List<LayerDataPacket>();

            //create packet and global header
            LayerDataPacket layer = new LayerDataPacket();

            layer.LayerID.Type = landPacketType;

            byte[] data = new byte[x.Length * Constants.TerrainPatchSize * Constants.TerrainPatchSize * 2];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(STRIDE, 16);
            bitpack.PackBits(Constants.TerrainPatchSize, 8);
            bitpack.PackBits(landPacketType, 8);

            for (int i = 0; i < x.Length; i++)
            {
                CreatePatchFromTerrainData(bitpack, terrData, x[i], y[i]);
                if (bitpack.BytePos > 980 && i != x.Length - 1)
                {
                    //finish this packet
                    bitpack.PackBits(END_OF_PATCHES, 8);

                    layer.LayerData.Data = new byte[bitpack.BytePos + 1];
                    Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);
                    ret.Add(layer);

                    // start another
                    layer = new LayerDataPacket();
                    layer.LayerID.Type = landPacketType;

                    bitpack = new BitPack(data, 0);
                    bitpack.PackBits(STRIDE, 16);
                    bitpack.PackBits(Constants.TerrainPatchSize, 8);
                    bitpack.PackBits(landPacketType, 8);
                }
            }

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);
            ret.Add(layer);

            return ret;
        }
Ejemplo n.º 16
0
        // Scan the height info we're returning and return a patch packet header for this patch.
        private static TerrainPatch.Header PrescanPatch(TerrainData terrData, int patchX, int patchY)
        {
            TerrainPatch.Header header = new TerrainPatch.Header();
            float zmax = -99999999.0f;
            float zmin = 99999999.0f;

            for (int j = patchY*Constants.TerrainPatchSize; j < (patchY + 1)*Constants.TerrainPatchSize; j++)
            {
                for (int i = patchX*Constants.TerrainPatchSize; i < (patchX + 1)*Constants.TerrainPatchSize; i++)
                {
                    float val = terrData[i, j];
                    if (val > zmax) zmax = val;
                    if (val < zmin) zmin = val;
                }
            }

            header.DCOffset = zmin;
            header.Range = (int)((zmax - zmin) + 1.0f);

            return header;
        }
Ejemplo n.º 17
0
        private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
                                                               int prequant, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
            int wordsize = prequant;
            float oozrange = 1.0f/header.Range;
            float range = (1 << prequant);
            float premult = oozrange*range;
            float sub = (1 << (prequant - 1)) + header.DCOffset*premult;

            header.QuantWBits = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;

            int yPatchLimit = patchY >= (terrData.SizeY / Constants.TerrainPatchSize) ?
                            (terrData.SizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY;
            yPatchLimit = (yPatchLimit + 1) * Constants.TerrainPatchSize;

            int xPatchLimit = patchX >= (terrData.SizeX / Constants.TerrainPatchSize) ?
                            (terrData.SizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX;
            xPatchLimit = (xPatchLimit + 1) * Constants.TerrainPatchSize;

            for (int yy = patchY * Constants.TerrainPatchSize; yy < yPatchLimit; yy++)
            {
                for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++)
                {
                    block[k++] = terrData[xx, yy] * premult - sub;
                }
            }

            float[] ftemp = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
            int[] itemp = new int[Constants.TerrainPatchSize*Constants.TerrainPatchSize];

            int maxWbits = prequant + 5;
            wbits = (prequant >> 1);

            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);

            return itemp;
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Sends a copy of the current terrain to the scenes clients
 /// </summary>
 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
 /// <param name="x">The patch corner to send</param>
 /// <param name="y">The patch corner to send</param>
 private void SendToClients(TerrainData terrData, int x, int y)
 {
     // We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI.
     //float[] heightMap = terrData.GetFloatsSerialized();
     float[] heightMap = new float[10];
     m_scene.ForEachClient(
         delegate(IClientAPI controller)
             {
                 controller.SendLayerData( x / Constants.TerrainPatchSize,
                                         y / Constants.TerrainPatchSize,
                                         heightMap);
             }
     );
 }
Ejemplo n.º 19
0
        // Read legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array.
        private void FromXml(XmlReader xmlReader)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(byte[]));
            byte[] dataArray = (byte[])serializer.Deserialize(xmlReader);
            int index = 0;

            m_terrainData = new HeightmapTerrainData(Height, Width, (int)Constants.RegionHeight);
            
            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    float value;
                    value = BitConverter.ToSingle(dataArray, index);
                    index += 4;
                    this[x, y] = (double)value;
                }
            }
        }
Ejemplo n.º 20
0
 public void StoreTerrain(TerrainData ter, UUID regionID)
 {
     m_terrains[regionID] = ter;
 }
Ejemplo n.º 21
0
        public int Altitude { get { return m_terrainData.SizeZ; } } // Y dimension


        // Default, not-often-used builder
        public TerrainChannel()
        {
            m_terrainData = new HeightmapTerrainData((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
            FlatLand();
            // PinHeadIsland();
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Stores the terrain map to DB.
        /// </summary>
        /// <param name="terrain">terrain map data.</param>
        /// <param name="regionID">regionID.</param>
        public void StoreTerrain(TerrainData terrData, UUID regionID)
        {
            //Delete old terrain map
            string sql = "delete from terrain where RegionUUID=@RegionUUID";
            using (SqlConnection conn = new SqlConnection(m_connectionString))
            using (SqlCommand cmd = new SqlCommand(sql, conn))
            {
                cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
                conn.Open();
                cmd.ExecuteNonQuery();
            }

            sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";

            int terrainDBRevision;
            Array terrainDBblob;
            terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);

            using (SqlConnection conn = new SqlConnection(m_connectionString))
            {
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
                    cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
                    cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }
            }

            _Log.InfoFormat("{0} Stored terrain revision r={1}", LogHeader, terrainDBRevision);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Stores the terrain map to DB.
        /// </summary>
        /// <param name="terrain">terrain map data.</param>
        /// <param name="regionID">regionID.</param>
        public void StoreTerrain(TerrainData terrData, UUID regionID)
        {
            //Delete old terrain map
            string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID";
            using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
            {
                using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
                {
                    cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
                    conn.Open();
                    cmd.ExecuteNonQuery();

                    _Log.InfoFormat("{0} Deleted terrain revision id = {1}", LogHeader, regionID);
                }
            }

            int terrainDBRevision;
            Array terrainDBblob;
            terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);

            sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)";

            using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
            {
                using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
                {
                    cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
                    cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision));
                    cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob));
                    conn.Open();
                    cmd.ExecuteNonQuery();

                    _Log.InfoFormat("{0} Stored terrain id = {1}, terrainSize = <{2},{3}>",
                                    LogHeader, regionID, terrData.SizeX, terrData.SizeY);
                }
            }

        }
Ejemplo n.º 24
0
        // Create a land packet for a single patch.
        public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY)
        {
            int[] xPieces = new int[1];
            int[] yPieces = new int[1];
            xPieces[0] = patchX;  // patch X dimension
            yPieces[0] = patchY;

            byte landPacketType = (byte)TerrainPatch.LayerType.Land;
            if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
            {
                landPacketType = (byte)TerrainPatch.LayerType.LandExtended;
            }

            return CreateLandPacket(terrData, xPieces, yPieces, landPacketType);
        }
 public void StoreTerrain(TerrainData terrain, UUID regionID)
 {
     m_database.StoreTerrain(terrain, regionID);
 }
Ejemplo n.º 26
0
        /// <summary>
        ///     Creates a LayerData packet for compressed land data given a full
        ///     simulator heightmap and an array of indices of patches to compress
        /// </summary>
        /// <param name="terrData">
        ///     Terrain data that can result in a meter square heightmap.
        /// </param>
        /// <param name="x">
        ///     Array of indexes in the grid of patches
        ///     for this simulator.
        ///     If creating a packet for multiple patches, there will be entries in
        ///     both the X and Y arrays for each of the patches.
        ///     For example if patches 1 and 17 are to be sent,
        ///     x[] = {1,1} and y[] = {0,1} which specifies the patches at
        ///     indexes <1,0> and <1,1> (presuming the terrain size is 16x16 patches).
        /// </param>
        /// <param name="y">
        ///     Array of indexes in the grid of patches.
        /// </param>
        /// <param name="type"></param>
        /// <param name="pRegionSizeX"></param>
        /// <param name="pRegionSizeY"></param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] x, int[] y, byte type)
        {
            LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}};

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
                                                  {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize};

            byte[] data = new byte[x.Length * Constants.TerrainPatchSize * Constants.TerrainPatchSize * 2];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits(type, 8);

            for (int i = 0; i < x.Length; i++)
                CreatePatchFromHeightmap(bitpack, terrData, x[i], y[i]);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
Ejemplo n.º 27
0
        // Create a land packet for a single patch.
        public static LayerDataPacket CreateLandPacket(TerrainData terrData, int patchX, int patchY)
        {
            int[] xPieces = new int[1];
            int[] yPieces = new int[1];
            xPieces[0] = patchX;  // patch X dimension
            yPieces[0] = patchY;

            return CreateLandPacket(terrData, xPieces, yPieces);
        }