private FileWrapper CreateBMPFile(string filePath, int countX, int countZ)
        {
            FileWrapper bmpFile = new FileWrapper(filePath);

            bmpFile.Clear();  // don't want excess bytes remaining in the new file


            bmpFile.WriteShort(0x4d42);     // 'B' 'M'

            int headerByteSize = 14 + 0x28; // 14 bytes for file header + 0x28 bytes for the data header

            int bytesPerPixel = 3;          // rgba = 4 bytes per cell, rgb = 3 bytes per cell
            int bytesPerRow   = countX * bytesPerPixel;
            int paddedBytes   = GetBMPBytePadding(countX);

            bytesPerRow += paddedBytes;

            int pixelByteSize = bytesPerRow * countZ;

            int totalByteSize = headerByteSize + pixelByteSize;

            bmpFile.WriteInt(totalByteSize);  // total size of the file in bytes

            bmpFile.WriteInt(0);              // ignored (usage depends on the program creating the file, which is irrelevant for our purposes)
            bmpFile.WriteInt(headerByteSize); // offset to start of the pixel data


            // data header

            bmpFile.WriteInt(0x28);                // length of data header
            bmpFile.WriteInt(countX);              // image width
            bmpFile.WriteInt(countZ);              // image height
            bmpFile.WriteShort(1);                 // "number of color planes, must be 1"
            bmpFile.WriteShort(bytesPerPixel * 8); // bits per pixel (24 bytes = rgb, 32 bits = rgba)
            bmpFile.WriteInt(0);                   // compression method, 0 = none
            bmpFile.WriteInt(pixelByteSize);       // total byte size of pixel data

            bmpFile.WriteInt(0);                   // rest of the header has meaning but is ignoreable
            bmpFile.WriteInt(0);
            bmpFile.WriteInt(0);
            bmpFile.WriteInt(0);


            // pixel data goes next (handled elsewhere)

            return(bmpFile);
        }
        private void WriteLSGNGRIDFile()
        {
            string baseFileName = this.ngridFile.GetFolderPath() + this.ngridFile.GetName();

            string outputFileName = baseFileName;

            if (this.overlayFile != null)
            {
                outputFileName += "." + this.overlayFile.GetName();
            }
            FileWrapper outputLSGNGRID = new FileWrapper(outputFileName + ".LSGNGRID");

            outputLSGNGRID.Clear();  // don't want excess bytes remaining in the new file


            string magic = "LSGNGRID";

            outputLSGNGRID.WriteChars(magic.ToCharArray());

            outputLSGNGRID.WriteInt(2);  // version number

            outputLSGNGRID.WriteVector3(minBounds);
            outputLSGNGRID.WriteVector3(maxBounds);

            outputLSGNGRID.WriteFloat(cellSize);
            outputLSGNGRID.WriteInt(cellCountX);
            outputLSGNGRID.WriteInt(cellCountZ);

            outputLSGNGRID.WriteInt(heightSampleCountX);
            outputLSGNGRID.WriteInt(heightSampleCountZ);
            outputLSGNGRID.WriteFloat(heightSampleOffsetX);
            outputLSGNGRID.WriteFloat(heightSampleOffsetZ);


            // height sample data is written first because cells need to use it for calculating their own height values

            for (int i = 0; i < heightSamples.Count; i++)
            {
                float sample = heightSamples[i];

                outputLSGNGRID.WriteFloat(sample);
            }


            for (int i = 0; i < cells.Count; i++)
            {
                NavGridCell cell = cells[i];


                outputLSGNGRID.WriteShort((int)cell.visionPathingFlags);
                outputLSGNGRID.WriteByte((int)cell.riverRegionFlags);

                int jungleQuadrantAndMainRegionFlags = ((int)cell.jungleQuadrantFlags) | ((int)cell.mainRegionFlags << 4);
                outputLSGNGRID.WriteByte(jungleQuadrantAndMainRegionFlags);

                int nearestLaneAndPOIFlags = ((int)cell.nearestLaneFlags) | ((int)cell.poiFlags << 4);
                outputLSGNGRID.WriteByte(nearestLaneAndPOIFlags);

                int ringAndSRXFlags = ((int)cell.ringFlags) | ((int)cell.srxFlags << 4);
                outputLSGNGRID.WriteByte(ringAndSRXFlags);
            }


            outputLSGNGRID.Close();
        }