Files
test/Assets/PerfectWorld/Scripts/Move/AutoPFImp/AutoMove/CBitImage.cs
T
2026-01-10 12:11:05 +07:00

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;
}
}
}
}