157 lines
4.8 KiB
C#
157 lines
4.8 KiB
C#
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;
|
||
}
|
||
}
|
||
} |