KopMap/Assets/MindPowerSdk/Map/SceneObjFile.cs
2025-04-03 02:30:16 +08:00

157 lines
4.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using MindPowerSdk;
using UnityEngine;
namespace MindPowerSdk
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct SceneObjInfo
{
public ushort TypeId; // 高2位是type(0: 场景物件, 1: 特效物件), 其余是ID
public int X; // 相对坐标
public int Y;
public short HeightOff;
public short YawAngle;
public short Scale; // 保留未使用
public short GetTypeId()
{
return (short)(TypeId >> 14);
}
public short GetID()
{
return (short)(TypeId & 0x3FFF);
}
public override string ToString()
{
return $"type={GetTypeId()},id={GetID()},x={X},y={Y},height_off={HeightOff},yaw_angle={YawAngle},scale={Scale}";
}
}
public class SceneObjFile
{
/// <summary>
/// 文件头
/// </summary>
public struct Header
{
public string Title; // "HF Object File!" char[16]
public int Version;
public int FileSize;
public int SectionCntX; // 地图的横向区域数
public int SectionCntY; // 地图的纵向区域数
public int SectionWidth; // 区域的宽度单位Tile
public int SectionHeight; // 区域的高度单位Tile
public int SectionObjNum; // 区域允许的最大物件数
}
/// <summary>
/// 用来索引文件中对象的数据
/// </summary>
public struct SSectionIndex
{
public int ObjInfoPos;
public int ObjNum;
}
public Header FileHeader { get; private set; }
SSectionIndex[,] sectionIndex;
public List<SceneObjInfo>[,] objInfos;
public unsafe int Load(string obj_file)
{
FileStream fs = File.OpenRead(obj_file);
BinaryReader r = new BinaryReader(fs);
long size = r.BaseStream.Length;
Header s = new Header();
s.Title = Encoding.ASCII.GetString(r.ReadBytes(16));
s.Version = r.ReadInt32();
s.FileSize = r.ReadInt32(); // 实际是32位
s.SectionCntX = r.ReadInt32();
s.SectionCntY = r.ReadInt32();
s.SectionWidth = r.ReadInt32();
s.SectionHeight = r.ReadInt32();
s.SectionObjNum = r.ReadInt32();
FileHeader = s;
Debug.Log(JsonUtility.ToJson(s));
if (s.FileSize != size)
{
Debug.LogWarning($"{obj_file} 文件szie不匹配: {s.FileSize} != {size}");
return -1;
}
if (s.Version != 600)
{
Debug.LogWarning($"{obj_file} 版本只支持600: 当前是={s.Version}");
return -1;
}
// 读取索引信息
sectionIndex = new SSectionIndex[s.SectionCntX, s.SectionCntY];
for (int y = 0; y < s.SectionCntY; y++)
{
for (int x = 0; x < s.SectionCntX; x++)
{
SSectionIndex data = new SSectionIndex();
data.ObjInfoPos = r.ReadInt32();
data.ObjNum = r.ReadInt32();
sectionIndex[x, y] = data;
if (data.ObjNum != 0)
Debug.Log(JsonUtility.ToJson(data));
}
}
// 读取场景物体
objInfos = new List<SceneObjInfo>[s.SectionCntX, s.SectionCntY];
for (int y = 0; y < s.SectionCntY; y++)
{
for (int x = 0; x < s.SectionCntX; x++)
{
SSectionIndex idx = sectionIndex[x, y];
if (idx.ObjNum == 0)
continue;
var list = objInfos[x, y] ??= new List<SceneObjInfo>();
r.BaseStream.Seek(idx.ObjInfoPos, SeekOrigin.Begin);
for (int i = 0; i < idx.ObjNum; i++)
{
byte[] tmpBytes = r.ReadBytes(sizeof(SceneObjInfo));
SceneObjInfo sceneObjInfo = StructReader.ReadStructFromArray<SceneObjInfo>(tmpBytes);
// 转成绝对坐标
int sectionX = x * s.SectionWidth * 100;
int sectionY = y * s.SectionHeight * 100;
sceneObjInfo.X += sectionX;
sceneObjInfo.Y += sectionY;
list.Add(sceneObjInfo);
Debug.Log(sceneObjInfo.ToString());
}
}
}
return 0;
}
}
}