mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-12-11 04:51:21 +04:00
186 lines
8.0 KiB
C#
186 lines
8.0 KiB
C#
using System.Buffers.Binary;
|
|
using Common;
|
|
using NResLib;
|
|
|
|
namespace ParkanPlayground;
|
|
|
|
public static class Msh02
|
|
{
|
|
public static Msh02Component ReadComponent(FileStream mshFs, NResArchive archive)
|
|
{
|
|
var fileEntry = archive.Files.FirstOrDefault(x => x.FileType == "02 00 00 00");
|
|
|
|
if (fileEntry is null)
|
|
{
|
|
throw new Exception("Archive doesn't contain 02 component");
|
|
}
|
|
|
|
var data = new byte[fileEntry.FileLength];
|
|
mshFs.Seek(fileEntry.OffsetInFile, SeekOrigin.Begin);
|
|
mshFs.ReadExactly(data, 0, data.Length);
|
|
|
|
var header = data.AsSpan(0, 0x8c); // 140 bytes header
|
|
|
|
var center = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(0x60)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(0x64)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(0x68))
|
|
);
|
|
var centerW = BinaryPrimitives.ReadSingleLittleEndian(header.Slice(0x6c));
|
|
|
|
var bb = new BoundingBox();
|
|
bb.Vec1 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(0)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(4)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(8))
|
|
);
|
|
bb.Vec2 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(12)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(16)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(20))
|
|
);
|
|
bb.Vec3 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(24)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(28)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(32))
|
|
);
|
|
bb.Vec4 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(36)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(40)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(44))
|
|
);
|
|
bb.Vec5 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(48)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(52)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(56))
|
|
);
|
|
bb.Vec6 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(60)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(64)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(68))
|
|
);
|
|
bb.Vec7 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(72)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(76)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(80))
|
|
);
|
|
bb.Vec8 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(84)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(88)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(92))
|
|
);
|
|
|
|
var bottom = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(112)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(116)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(120))
|
|
);
|
|
|
|
var top = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(124)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(128)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(header.Slice(132))
|
|
);
|
|
|
|
var xyRadius = BinaryPrimitives.ReadSingleLittleEndian(header.Slice(136));
|
|
|
|
|
|
List<Msh02Element> elements = new List<Msh02Element>();
|
|
var skippedHeader = data.AsSpan(0x8c); // skip header
|
|
for (var i = 0; i < fileEntry.ElementCount; i++)
|
|
{
|
|
var element = new Msh02Element();
|
|
element.StartIndexIn07 =
|
|
BinaryPrimitives.ReadUInt16LittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 0));
|
|
element.CountIn07 =
|
|
BinaryPrimitives.ReadUInt16LittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 2));
|
|
element.StartOffsetIn0d =
|
|
BinaryPrimitives.ReadUInt16LittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 4));
|
|
element.ByteLengthIn0D =
|
|
BinaryPrimitives.ReadUInt16LittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 6));
|
|
element.LocalMinimum = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 8)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 12)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 16))
|
|
);
|
|
element.LocalMaximum = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 20)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 24)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 28))
|
|
);
|
|
element.Center = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 32)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 36)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 40))
|
|
);
|
|
element.Vector4 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 44)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 48)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 52))
|
|
);
|
|
element.Vector5 = new Vector3(
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 56)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 60)),
|
|
BinaryPrimitives.ReadSingleLittleEndian(skippedHeader.Slice(fileEntry.ElementSize * i + 64))
|
|
);
|
|
elements.Add(element);
|
|
|
|
_ = 5;
|
|
}
|
|
|
|
return new Msh02Component()
|
|
{
|
|
Header = new Msh02Header()
|
|
{
|
|
BoundingBox = bb,
|
|
Center = center,
|
|
CenterW = centerW,
|
|
Bottom = bottom,
|
|
Top = top,
|
|
XYRadius = xyRadius
|
|
},
|
|
Elements = elements
|
|
};
|
|
}
|
|
|
|
public class Msh02Component
|
|
{
|
|
public Msh02Header Header { get; set; }
|
|
public List<Msh02Element> Elements { get; set; }
|
|
}
|
|
|
|
public class Msh02Header
|
|
{
|
|
public BoundingBox BoundingBox { get; set; }
|
|
public Vector3 Center { get; set; }
|
|
public float CenterW { get; set; }
|
|
public Vector3 Bottom { get; set; }
|
|
public Vector3 Top { get; set; }
|
|
public float XYRadius { get; set; }
|
|
}
|
|
|
|
public class Msh02Element
|
|
{
|
|
public ushort StartIndexIn07 { get; set; }
|
|
public ushort CountIn07 { get; set; }
|
|
public ushort StartOffsetIn0d { get; set; }
|
|
public ushort ByteLengthIn0D { get; set; }
|
|
public Vector3 LocalMinimum { get; set; }
|
|
public Vector3 LocalMaximum { get; set; }
|
|
public Vector3 Center { get; set; }
|
|
public Vector3 Vector4 { get; set; }
|
|
public Vector3 Vector5 { get; set; }
|
|
}
|
|
|
|
public class BoundingBox
|
|
{
|
|
public Vector3 Vec1 { get; set; }
|
|
public Vector3 Vec2 { get; set; }
|
|
public Vector3 Vec3 { get; set; }
|
|
public Vector3 Vec4 { get; set; }
|
|
public Vector3 Vec5 { get; set; }
|
|
public Vector3 Vec6 { get; set; }
|
|
public Vector3 Vec7 { get; set; }
|
|
public Vector3 Vec8 { get; set; }
|
|
}
|
|
} |