131 lines
4.3 KiB
C#
131 lines
4.3 KiB
C#
using System;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
// Filename : CBitImage.cs
|
|
// Creator : ported from C++ (AutoPFImp/AutoMoveImp/bitimage.h)
|
|
// Date : 2026/01/09
|
|
|
|
namespace AutoMove
|
|
{
|
|
/// <summary>
|
|
/// Bit image used by AutoPF (passable map).
|
|
/// 自动寻路使用的位图(可通行图)。
|
|
/// </summary>
|
|
public class CBitImage
|
|
{
|
|
// Current Version // 当前版本
|
|
private const uint BITIMAGE_VER = 0x00000003;
|
|
// old version // 旧版本
|
|
private const uint BITIMAGE_OLD_VER = 0x00000001;
|
|
// magic // 魔数
|
|
// C++: (DWORD)(('b'<<24)| ('m'<<16)|('p'<<8)|('f')) => bytes: 'f''p''m''b' in LE.
|
|
private const uint BITIMAGE_MAGIC = 0x626D7066;
|
|
|
|
// width of the bit image (in chars) // 位图宽(按字节)
|
|
private int m_iWidth;
|
|
// length of the bit image (in chars) // 位图长(按字节)
|
|
private int m_iLength;
|
|
// pixel size // 像素尺寸
|
|
private float m_fPixelSize;
|
|
// width of the bit image ( in pixels) // 位图宽(像素)
|
|
private int m_iImageWidth;
|
|
// length of the bit image ( in pixels) // 位图长(像素)
|
|
private int m_iImageLength;
|
|
|
|
// raw bit image bytes // 位图原始字节
|
|
private byte[] m_BitImage;
|
|
|
|
public void Release()
|
|
{
|
|
m_BitImage = null;
|
|
m_iWidth = 0;
|
|
m_iLength = 0;
|
|
m_iImageWidth = 0;
|
|
m_iImageLength = 0;
|
|
m_fPixelSize = 1.0f;
|
|
}
|
|
|
|
public void GetImageSize(out int width, out int length)
|
|
{
|
|
width = m_iImageWidth;
|
|
length = m_iImageLength;
|
|
}
|
|
|
|
public float GetPixelSize() => m_fPixelSize;
|
|
|
|
public bool GetPixel(int u, int v)
|
|
{
|
|
if (m_BitImage == null) return false;
|
|
if (u < 0 || u >= m_iImageWidth || v < 0 || v >= m_iImageLength) return false;
|
|
|
|
int uInChar = u >> 3;
|
|
int shift = u & 0x7;
|
|
return (m_BitImage[v * m_iWidth + uInChar] & (1 << shift)) != 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load from file bytes (binary). Supports old and magic formats like original C++.
|
|
/// 从文件字节加载(二进制)。支持原版 C++ 的旧版和带 magic 版本。
|
|
/// </summary>
|
|
public bool Load(byte[] fileBytes)
|
|
{
|
|
try
|
|
{
|
|
if (fileBytes == null || fileBytes.Length < 8) return false;
|
|
using var ms = new MemoryStream(fileBytes, false);
|
|
using var br = new BinaryReader(ms);
|
|
|
|
uint flag = br.ReadUInt32();
|
|
if (flag == BITIMAGE_OLD_VER)
|
|
{
|
|
// old: proceed to BufSize
|
|
// 旧版:直接读取 BufSize
|
|
}
|
|
else if (flag == BITIMAGE_MAGIC)
|
|
{
|
|
// magic then version
|
|
// magic 后面跟版本号
|
|
uint ver = br.ReadUInt32();
|
|
if (ver > BITIMAGE_VER)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
uint bufSize = br.ReadUInt32();
|
|
if (bufSize == 0 || bufSize > fileBytes.Length) return false;
|
|
|
|
byte[] buf = br.ReadBytes((int)bufSize);
|
|
if (buf.Length != bufSize) return false;
|
|
|
|
int cur = 0;
|
|
m_iWidth = BitConverter.ToInt32(buf, cur); cur += 4;
|
|
m_iLength = BitConverter.ToInt32(buf, cur); cur += 4;
|
|
m_iImageWidth = BitConverter.ToInt32(buf, cur); cur += 4;
|
|
m_iImageLength = BitConverter.ToInt32(buf, cur); cur += 4;
|
|
m_fPixelSize = BitConverter.ToSingle(buf, cur); cur += 4;
|
|
|
|
int imgSize = m_iWidth * m_iLength;
|
|
if (imgSize <= 0) return false;
|
|
if (cur + imgSize > buf.Length) return false;
|
|
|
|
m_BitImage = new byte[imgSize];
|
|
Buffer.BlockCopy(buf, cur, m_BitImage, 0, imgSize);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[CBitImage] Load failed: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|