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