public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, byte type, int RegionSizeX, int RegionSizeY) { LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}}; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize}; // Should be enough to fit even the most poorly packed data byte[] data = new byte[patches.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); foreach (TerrainPatch t in patches) CreatePatch(bitpack, t.Data, t.X, t.Y, RegionSizeX, RegionSizeY); 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; }
public static LayerDataPacket CreateLandPacket(float[] patchData, int x, int y) { LayerDataPacket layer = new LayerDataPacket(); layer.LayerID.Type = (byte)TerrainPatch.LayerType.Land; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); header.Stride = STRIDE; header.PatchSize = 16; header.Type = TerrainPatch.LayerType.Land; byte[] data = new byte[1536]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); CreatePatch(bitpack, patchData, x, y); 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; }
public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, byte type, int RegionSizeX, int RegionSizeY) { LayerDataPacket layer = new LayerDataPacket(); layer.LayerID.Type = type; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); header.Stride = STRIDE; header.PatchSize = Constants.TerrainPatchSize; // Should be enough to fit even the most poorly packed data byte[] data = new byte[patches.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 < patches.Length; i++) { CreatePatch(bitpack, patches[i].Data, patches[i].X, patches[i].Y, RegionSizeX, RegionSizeY); } 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); }
private void SendTerrainPacket(QueuedInterestListEvent[] eventDatas, IScenePresence presence) { const int PATCHES_PER_PACKET = 3; if (!(presence is LLAgent) || presence.InterestList == null) { return; } LLAgent agent = (LLAgent)presence; List <int> patches = new List <int>(PATCHES_PER_PACKET); for (int i = 0; i < eventDatas.Length; i++) { int[] state = (int[])eventDatas[i].Event.State; int x = state[0]; int y = state[1]; patches.Add(y * 16 + x); if (patches.Count == PATCHES_PER_PACKET || i == eventDatas.Length - 1) { LayerDataPacket packet = TerrainCompressor.CreateLandPacket(m_terrain.GetHeightmap(), patches.ToArray()); m_udp.SendPacket(agent, packet, ThrottleCategory.Land, false); patches = new List <int>(PATCHES_PER_PACKET); } } }
/// <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="heightmap">A 256 * 256 array of floating point values /// specifying the height at each meter in the simulator</param> /// <param name="patches">Array of indexes in the 16x16 grid of patches /// for this simulator. For example if 1 and 17 are specified, patches /// x=1,y=0 and x=1,y=1 are sent</param> /// <returns></returns> public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches) { LayerDataPacket layer = new LayerDataPacket(); layer.LayerID.Type = (byte)TerrainPatch.LayerType.Land; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); header.Stride = STRIDE; header.PatchSize = 16; header.Type = TerrainPatch.LayerType.Land; byte[] data = new byte[1536]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); for (int i = 0; i < patches.Length; i++) { CreatePatchFromHeightmap(bitpack, heightmap, patches[i] % 16, (patches[i] - (patches[i] % 16)) / 16); } 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); }
/// <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="heightmap"> /// A 256 * 256 array of floating point values /// specifying the height at each meter in the simulator /// </param> /// <param name="x"> /// Array of indexes in the 16x16 grid of patches /// for this simulator. For example if 1 and 17 are specified, patches /// x=1,y=0 and x=1,y=1 are sent /// </param> /// <param name="y"> /// Array of indexes in the 16x16 grid of patches /// for this simulator. For example if 1 and 17 are specified, patches /// x=1,y=0 and x=1,y=1 are sent /// </param> /// <param name="type"></param> /// <param name="RegionSizeX"></param> /// <param name="RegionSizeY"></param> /// <returns></returns> public static LayerDataPacket CreateLandPacket(short[] heightmap, int[] x, int[] y, byte type, int RegionSizeX, int RegionSizeY) { 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, heightmap, x[i], y[i], RegionSizeX, RegionSizeY); } 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); }
public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, TerrainPatch.LayerType type) { LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = (byte)type } }; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = 16, Type = type }; // Should be enough to fit even the most poorly packed data byte[] data = new byte[patches.Length * 16 * 16 * 2]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); foreach (TerrainPatch t in patches) { CreatePatch(bitpack, t.Data, t.X, t.Y); } 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); }
/// <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="heightmap">A 256 * 256 array of floating point values /// specifying the height at each meter in the simulator</param> /// <param name="patches">Array of indexes in the 16x16 grid of patches /// for this simulator. For example if 1 and 17 are specified, patches /// x=1,y=0 and x=1,y=1 are sent</param> /// <returns></returns> public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches) { LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = (byte)TerrainPatch.LayerType.Land } }; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = 16, Type = TerrainPatch.LayerType.Land }; byte[] data = new byte[1536]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); foreach (int t in patches) { CreatePatchFromHeightmap(bitpack, heightmap, t % 16, (t - (t % 16)) / 16); } 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); }
/// <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="heightmap">A 256 * 256 array of floating point values /// specifying the height at each meter in the simulator</param> /// <param name="patches">Array of indexes in the 16x16 grid of patches /// for this simulator. For example if 1 and 17 are specified, patches /// x=1,y=0 and x=1,y=1 are sent</param> /// <returns></returns> public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches) { LayerDataPacket layer = new LayerDataPacket(); layer.LayerID.Type = (byte)TerrainPatch.LayerType.Land; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); header.Stride = STRIDE; header.PatchSize = 16; header.Type = TerrainPatch.LayerType.Land; byte[] data = new byte[1536]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); for (int i = 0; i < patches.Length; i++) { CreatePatch(bitpack, heightmap, patches[i] % 16, (patches[i] - (patches[i] % 16)) / 16); } 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; }
public static LayerDataPacket CreateLandPacket(float[,] patchData, int x, int y) { LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = (byte)TerrainPatch.LayerType.Land } }; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = 16, Type = TerrainPatch.LayerType.Land }; byte[] data = new byte[1536]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); CreatePatch(bitpack, patchData, x, y); 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); }
/// <summary> /// /// </summary> /// <param name="userInfo"></param> /// <param name="layer"></param> /// <param name="name"></param> private void SendLayerData(NetworkInfo userInfo, LayerDataPacket layer, string fileName) { FileInfo fInfo = new FileInfo(fileName); long numBytes = fInfo.Length; FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fStream); byte [] data1 = br.ReadBytes((int)numBytes); br.Close(); fStream.Close(); layer.LayerData.Data = data1; _server.SendPacket(layer, true, userInfo); }
/// <summary> /// /// </summary> /// <param name="userInfo"></param> public void SendTerrainData(NetworkInfo userInfo) { lock (this._sendTerrainSync) { string data_path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"layer_data"); //send layerdata LayerDataPacket layerpack = new LayerDataPacket(); layerpack.LayerID.Type = 76; this.SendLayerData(userInfo, layerpack, Path.Combine(data_path, "layerdata0.dat")); Console.WriteLine("Sent terrain data"); //test this.SendAvatarData(userInfo); } }
void SendLayerData(Agent agent) { lock (heightmap) { for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { int[] patches = new int[1]; patches[0] = (y * 16) + x; LayerDataPacket layer = TerrainCompressor.CreateLandPacket(heightmap, patches); server.UDP.SendPacket(agent.AgentID, layer, PacketCategory.Terrain); } } } }
private void LayerDataHandler(object sender, PacketReceivedEventArgs e) { LayerDataPacket layer = (LayerDataPacket)e.Packet; BitPack bitpack = new BitPack(layer.LayerData.Data, 0); TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); TerrainPatch.LayerType type = (TerrainPatch.LayerType)layer.LayerID.Type; // Stride header.Stride = bitpack.UnpackBits(16); // Patch size header.PatchSize = bitpack.UnpackBits(8); // Layer type header.Type = (TerrainPatch.LayerType)bitpack.UnpackBits(8); switch (type) { case TerrainPatch.LayerType.Land: if (m_LandPatchReceivedEvent != null || Client.Settings.STORE_LAND_PATCHES) { DecompressLand(e.Simulator, bitpack, header); } break; case TerrainPatch.LayerType.Water: Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client); break; case TerrainPatch.LayerType.Wind: DecompressWind(e.Simulator, bitpack, header); break; case TerrainPatch.LayerType.Cloud: DecompressCloud(e.Simulator, bitpack, header); break; default: Logger.Log("Unrecognized LayerData type " + type.ToString(), Helpers.LogLevel.Warning, Client); break; } }
private void LayerDataHandler(Packet packet, Simulator simulator) { LayerDataPacket layer = (LayerDataPacket)packet; BitPack bitpack = new BitPack(layer.LayerData.Data, 0); GroupHeader header = new GroupHeader(); LayerType type = (LayerType)layer.LayerID.Type; // Stride header.Stride = bitpack.UnpackBits(16); // Patch size header.PatchSize = bitpack.UnpackBits(8); // Layer type header.Type = (LayerType)bitpack.UnpackBits(8); switch (type) { case LayerType.Land: if (OnLandPatch != null || Client.Settings.STORE_LAND_PATCHES) { DecompressLand(simulator, bitpack, header); } break; case LayerType.Water: Client.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error); break; case LayerType.Wind: DecompressWind(simulator, bitpack, header); break; case LayerType.Cloud: DecompressCloud(simulator, bitpack, header); break; default: Client.Log("Unrecognized LayerData type " + type.ToString(), Helpers.LogLevel.Warning); break; } }
/// <summary> /// /// </summary> /// <param name="userInfo"></param> public void SendTerrainData(NetworkInfo userInfo) { lock(this._sendTerrainSync) { string data_path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory ,@"layer_data" ); //send layerdata LayerDataPacket layerpack = new LayerDataPacket(); layerpack.LayerID.Type = 76; this.SendLayerData(userInfo, layerpack, Path.Combine(data_path,"layerdata0.dat")); Console.WriteLine("Sent terrain data"); //test this.SendAvatarData(userInfo); } }
/// <summary> /// /// </summary> /// <param name="userInfo"></param> /// <param name="layer"></param> /// <param name="name"></param> private void SendLayerData(NetworkInfo userInfo, LayerDataPacket layer, string fileName) { FileInfo fInfo = new FileInfo(fileName); long numBytes = fInfo.Length; FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fStream); byte [] data1 = br.ReadBytes((int)numBytes); br.Close(); fStream.Close(); layer.LayerData.Data = data1; _server.SendPacket(layer, true, userInfo); }
// 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; }
/// <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; }
/// <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="heightmap">A 256 * 256 array of floating point values /// specifying the height at each meter in the simulator</param> /// <param name="patches">Array of indexes in the 16x16 grid of patches /// for this simulator. For example if 1 and 17 are specified, patches /// x=1,y=0 and x=1,y=1 are sent</param> /// <returns></returns> public static LayerDataPacket CreateLandPacket(short[] heightmap, int[] x, int[] y, byte type, int RegionSizeX, int RegionSizeY) { LayerDataPacket layer = new LayerDataPacket(); layer.LayerID.Type = type; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); header.Stride = STRIDE; header.PatchSize = Constants.TerrainPatchSize; byte[] data = new byte[2112]; 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, heightmap, x[i], y[i], RegionSizeX, RegionSizeY); 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; }
public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, TerrainPatch.LayerType type) { LayerDataPacket layer = new LayerDataPacket(); layer.LayerID.Type = (byte)type; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader(); header.Stride = STRIDE; header.PatchSize = 16; header.Type = type; // Should be enough to fit even the most poorly packed data byte[] data = new byte[patches.Length * 16 * 16 * 2]; BitPack bitpack = new BitPack(data, 0); bitpack.PackBits(header.Stride, 16); bitpack.PackBits(header.PatchSize, 8); bitpack.PackBits((int)header.Type, 8); for (int i = 0; i < patches.Length; i++) CreatePatch(bitpack, patches[i].Data, patches[i].X, patches[i].Y); 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; }
public static LayerDataPacket CreateLandPacket(List <PatchInfo> ps, byte type) { LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = type } }; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = Constants.TerrainPatchSize }; byte[] outdata = new byte[1500]; byte[] indata = BitConverter.GetBytes((ushort)header.Stride); if (!BitConverter.IsLittleEndian) { Array.Reverse(indata); } outdata[0] = indata[0]; outdata[1] = indata[1]; outdata[2] = (byte)header.PatchSize; outdata[3] = type; int outBitPos = 32; PatchInfo eop = new PatchInfo(); eop.PackedData = new byte[] { END_OF_PATCHES }; eop.BitLength = 8; ps.Add(eop); foreach (PatchInfo pi in ps) { int count = 0; int curBytePos = 0; int bitCount = pi.BitLength; /* this bit pack method has a slight variance allowing it to directly accept BitPacked data */ while (bitCount > 0) { count = bitCount; if (count > 8) { count = 8; } byte srcBits = pi.PackedData[curBytePos]; while (count-- > 0) { byte curBitMask = (byte)(0x80 >> (outBitPos % 8)); if ((srcBits & 0x80) != 0) { outdata[outBitPos / 8] |= curBitMask; } else { outdata[outBitPos / 8] &= (byte)~curBitMask; } ++outBitPos; srcBits <<= 1; } ++curBytePos; if (bitCount > 8) { bitCount -= 8; } else { bitCount = 0; } } } layer.LayerData.Data = new byte[(outBitPos + 7) / 8]; Buffer.BlockCopy(outdata, 0, layer.LayerData.Data, 0, (outBitPos + 7) / 8); return(layer); }
public static LayerDataPacket CreateLandPacket(List<PatchInfo> ps, byte type) { LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = type } }; TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = Constants.TerrainPatchSize }; byte[] outdata = new byte[1500]; byte[] indata = BitConverter.GetBytes((ushort)header.Stride); if(!BitConverter.IsLittleEndian) { Array.Reverse(indata); } outdata[0] = indata[0]; outdata[1] = indata[1]; outdata[2] = (byte)header.PatchSize; outdata[3] = type; int outBitPos = 32; PatchInfo eop = new PatchInfo(); eop.PackedData = new byte[] { END_OF_PATCHES }; eop.BitLength = 8; ps.Add(eop); foreach(PatchInfo pi in ps) { int count = 0; int curBytePos = 0; int bitCount = pi.BitLength; /* this bit pack method has a slight variance allowing it to directly accept BitPacked data */ while (bitCount > 0) { count = bitCount; if (count > 8) { count = 8; } byte srcBits = pi.PackedData[curBytePos]; while (count-- > 0) { byte curBitMask = (byte)(0x80 >> (outBitPos % 8)); if ((srcBits & 0x80) != 0) { outdata[outBitPos / 8] |= curBitMask; } else { outdata[outBitPos / 8] &= (byte)~curBitMask; } ++outBitPos; srcBits <<= 1; } ++curBytePos; if (bitCount > 8) { bitCount -= 8; } else { bitCount = 0; } } } layer.LayerData.Data = new byte[(outBitPos + 7) / 8]; Buffer.BlockCopy(outdata, 0, layer.LayerData.Data, 0, (outBitPos + 7) / 8); return layer; }