private Bitmap generateColorMapImage(RGB[,] map) { int width = map.GetUpperBound(0) + 1; int height = map.GetUpperBound(1) + 1; byte[] buffer = new byte[width * height * 3]; int i = 0; for (int y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { buffer[i++] = this.terrain.ColorMap[x, y].B; buffer[i++] = this.terrain.ColorMap[x, y].G; buffer[i++] = this.terrain.ColorMap[x, y].R; } } GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); Bitmap bmp = new Bitmap(width, height, width * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb, handle.AddrOfPinnedObject()); this.imageHandles.Add(handle); return bmp; }
/// <summary> /// Writes the terrain to the specified stream. /// </summary> /// <param name="stream">The destination stream.</param> public void Write(Stream stream) { BinaryWriter writer = new BinaryWriter(stream); if (Version > 0) { writer.Write(0x52524554u); // 'TERR' if (Version < 4) { writer.Write(0x00000003u); // version } else { writer.Write(Version); // version } writer.Write(GridMinX); writer.Write(GridMinZ); writer.Write(GridMaxX); writer.Write(GridMaxZ); } for (int y = 0; y < this.Height; y += CLUSTER_SIZE) { for (int x = 0; x < this.Width; x += CLUSTER_SIZE) { bool haveHeight = true; bool haveColor = true; bool haveAlpha1 = true; bool haveAlpha2 = true; bool haveAlpha3 = true; bool haveCell = true; if (Version >= 5) { haveHeight = false; haveColor = false; haveAlpha1 = false; haveAlpha2 = false; haveAlpha3 = false; haveCell = false; float height = this.HeightMapFloat[x, y]; RGB color = this.ColorMap[x, y]; byte alpha1 = this.AlphaMap1[x, y]; byte alpha2 = this.AlphaMap2[x, y]; byte alpha3 = this.AlphaMap3[x, y]; CellType cell = this.CellMap[x, y]; for (int cy = 0; cy < CLUSTER_SIZE; cy++) { if (!haveHeight) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { if (height != this.HeightMapFloat[x + cx, y + cy]) { haveHeight = true; break; } } } } for (int cy = 0; cy < CLUSTER_SIZE; cy++) { if (!haveColor) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { if (color.R != this.ColorMap[x + cx, y + cy].R || color.G != this.ColorMap[x + cx, y + cy].G || color.B != this.ColorMap[x + cx, y + cy].B) { haveColor = true; break; } } } } for (int cy = 0; cy < CLUSTER_SIZE; cy++) { if (!haveAlpha1) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { if (alpha1 != this.AlphaMap1[x + cx, y + cy]) { haveAlpha1 = true; break; } } } } for (int cy = 0; cy < CLUSTER_SIZE; cy++) { if (!haveAlpha2) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { if (alpha2 != this.AlphaMap2[x + cx, y + cy]) { haveAlpha2 = true; break; } } } } for (int cy = 0; cy < CLUSTER_SIZE; cy++) { if (!haveAlpha3) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { if (alpha3 != this.AlphaMap3[x + cx, y + cy]) { haveAlpha3 = true; break; } } } } for (int cy = 0; cy < CLUSTER_SIZE; cy++) { if (!haveCell) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { if (cell != this.CellMap[x + cx, y + cy]) { haveCell = true; break; } } } } byte Compression = 0; if (haveHeight) { Compression += 1; } if (haveColor) { Compression += (1 << 1); } if (haveAlpha1) { Compression += (1 << 2); } if (haveAlpha2) { Compression += (1 << 3); } if (haveAlpha3) { Compression += (1 << 4); } if (haveCell) { Compression += (1 << 5); } writer.Write(Compression); } if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write(this.HeightMap[x + _cx, y + _cy]); } } } else if (Version < 4) { // height map for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.HeightMap[x + cx, y + cy]); } } } else { // height map if (haveHeight) { for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.HeightMapFloat[x + cx, y + cy]); } } } else { writer.Write(this.HeightMapFloat[x, y]); } } if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write(this.NormalMap[x + _cx, y + _cy]); } } } else if (Version < 4) { // normal map for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.NormalMap[x + cx, y + cy]); } } } // color map if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write(this.ColorMap[x + _cx, y + _cy].R); writer.Write(this.ColorMap[x + _cx, y + _cy].G); writer.Write(this.ColorMap[x + _cx, y + _cy].B); } } } else //if (Version < 4) { if (haveColor) { for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.ColorMap[x + cx, y + cy].R); writer.Write(this.ColorMap[x + cx, y + cy].G); writer.Write(this.ColorMap[x + cx, y + cy].B); } } } else { writer.Write(this.ColorMap[x, y].R); writer.Write(this.ColorMap[x, y].G); writer.Write(this.ColorMap[x, y].B); } } // alpha map 1 if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write(this.AlphaMap1[x + _cx, y + _cy]); } } } else //if (Version < 4) { if (haveAlpha1) { for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.AlphaMap1[x + cx, y + cy]); } } } else { writer.Write(this.AlphaMap1[x, y]); } } // alpha map 2 if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write(this.AlphaMap2[x + _cx, y + _cy]); } } } else //if (Version < 4) { if (haveAlpha2) { for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.AlphaMap2[x + cx, y + cy]); } } } else { writer.Write(this.AlphaMap2[x, y]); } } // alpha map 3 if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write(this.AlphaMap3[x + _cx, y + _cy]); } } } else //if (Version < 4) { if (haveAlpha3) { for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write(this.AlphaMap3[x + cx, y + cy]); } } } else { writer.Write(this.AlphaMap3[x, y]); } } // cliff map if (Version < 3) { for (int cy = 0; cy < (CLUSTER_SIZE + 1); cy++) { for (int cx = 0; cx < (CLUSTER_SIZE + 1); cx++) { int _cx = cx; int _cy = cy; if ((x + cx) == this.Width) { _cx--; } if ((x + cy) == this.Width) { _cy--; } writer.Write((byte)this.CellMap[x + _cx, y + _cy]); } } } else //if (Version < 4) { if (haveCell) { for (int cy = 0; cy < CLUSTER_SIZE; cy++) { for (int cx = 0; cx < CLUSTER_SIZE; cx++) { writer.Write((byte)this.CellMap[x + cx, y + cy]); } } } else { writer.Write((byte)this.CellMap[x, y]); } } // info map writer.Write(this.InfoMap[x / CLUSTER_SIZE, y / CLUSTER_SIZE]); // ??? if (Version > 0) { if (Version < 3) { for (int i = 0; i < 25; i++) { writer.Write(0x00); } } if (Version == 2) { writer.Write(0x00); } } } } }