2017-09-15 08:22:51 -07:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2018-01-31 21:09:08 -06:00
|
|
|
using System.IO;
|
2018-11-22 01:33:17 -05:00
|
|
|
using System.Text;
|
2018-01-31 21:09:08 -06:00
|
|
|
|
|
|
|
|
using ACE.Entity.Enum;
|
2017-09-15 08:22:51 -07:00
|
|
|
|
|
|
|
|
namespace ACE.DatLoader.Entity
|
|
|
|
|
{
|
2018-01-31 21:09:08 -06:00
|
|
|
public class BSPNode : IUnpackable
|
2017-09-15 08:22:51 -07:00
|
|
|
{
|
|
|
|
|
// These constants are actually strings in the dat file
|
|
|
|
|
private const uint PORT = 1347375700; // 0x504F5254
|
|
|
|
|
private const uint LEAF = 1279607110; // 0x4C454146
|
|
|
|
|
private const uint BPnn = 1112567406; // 0x42506E6E
|
|
|
|
|
private const uint BPIn = 1112557934; // 0x4250496E
|
|
|
|
|
private const uint BpIN = 1114655054; // 0x4270494E
|
|
|
|
|
private const uint BpnN = 1114664526; // 0x42706E4E
|
|
|
|
|
private const uint BPIN = 1112557902; // 0x4250494E
|
|
|
|
|
private const uint BPnN = 1112567374; // 0x42506E4E
|
|
|
|
|
|
2018-11-22 01:33:17 -05:00
|
|
|
public string Type { get; protected set; }
|
2018-01-31 21:09:08 -06:00
|
|
|
|
|
|
|
|
public Plane SplittingPlane { get; protected set; }
|
|
|
|
|
|
|
|
|
|
public BSPNode PosNode { get; protected set; }
|
|
|
|
|
public BSPNode NegNode { get; protected set; }
|
|
|
|
|
|
|
|
|
|
public Sphere Sphere { get; protected set; }
|
|
|
|
|
|
|
|
|
|
public List<ushort> InPolys { get; protected set; } // List of PolygonIds
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// You must use the Unpack(BinaryReader reader, BSPType treeType) method.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <exception cref="NotSupportedException">You must use the Unpack(BinaryReader reader, BSPType treeType) method.</exception>
|
|
|
|
|
public virtual void Unpack(BinaryReader reader)
|
2017-09-15 08:22:51 -07:00
|
|
|
{
|
2018-01-31 21:09:08 -06:00
|
|
|
throw new NotSupportedException();
|
|
|
|
|
}
|
2017-09-15 08:22:51 -07:00
|
|
|
|
2018-01-31 21:09:08 -06:00
|
|
|
public virtual void Unpack(BinaryReader reader, BSPType treeType)
|
|
|
|
|
{
|
2018-11-22 01:33:17 -05:00
|
|
|
Type = Encoding.ASCII.GetString(reader.ReadBytes(4)).Reverse();
|
2017-09-15 08:22:51 -07:00
|
|
|
|
2018-01-31 21:09:08 -06:00
|
|
|
switch (Type)
|
2017-09-15 08:22:51 -07:00
|
|
|
{
|
2018-01-31 21:09:08 -06:00
|
|
|
// These types will unpack the data completely, in their own classes
|
2018-11-22 01:33:17 -05:00
|
|
|
case "PORT":
|
|
|
|
|
case "LEAF":
|
2018-01-31 21:09:08 -06:00
|
|
|
throw new Exception();
|
2017-09-15 08:22:51 -07:00
|
|
|
}
|
|
|
|
|
|
2018-01-31 21:09:08 -06:00
|
|
|
SplittingPlane = new Plane();
|
|
|
|
|
SplittingPlane.Unpack(reader);
|
2017-09-15 08:22:51 -07:00
|
|
|
|
2018-01-31 21:09:08 -06:00
|
|
|
switch (Type)
|
2017-09-15 08:22:51 -07:00
|
|
|
{
|
2018-11-22 01:33:17 -05:00
|
|
|
case "BPnn":
|
|
|
|
|
case "BPIn":
|
2018-01-31 21:09:08 -06:00
|
|
|
PosNode = BSPNode.ReadNode(reader, treeType);
|
2017-09-15 08:22:51 -07:00
|
|
|
break;
|
2018-11-22 01:33:17 -05:00
|
|
|
case "BpIN":
|
|
|
|
|
case "BpnN":
|
2018-01-31 21:09:08 -06:00
|
|
|
NegNode = BSPNode.ReadNode(reader, treeType);
|
2017-09-15 08:22:51 -07:00
|
|
|
break;
|
2018-11-22 01:33:17 -05:00
|
|
|
case "BPIN":
|
|
|
|
|
case "BPnN":
|
2018-01-31 21:09:08 -06:00
|
|
|
PosNode = BSPNode.ReadNode(reader, treeType);
|
|
|
|
|
NegNode = BSPNode.ReadNode(reader, treeType);
|
2017-09-15 08:22:51 -07:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (treeType == BSPType.Cell)
|
2018-01-31 21:09:08 -06:00
|
|
|
return;
|
2017-09-15 08:22:51 -07:00
|
|
|
|
2018-01-31 21:09:08 -06:00
|
|
|
Sphere = new Sphere();
|
|
|
|
|
Sphere.Unpack(reader);
|
2017-09-15 08:22:51 -07:00
|
|
|
|
|
|
|
|
if (treeType == BSPType.Physics)
|
2018-01-31 21:09:08 -06:00
|
|
|
return;
|
2017-09-15 08:22:51 -07:00
|
|
|
|
2018-01-31 21:09:08 -06:00
|
|
|
InPolys = new List<ushort>();
|
|
|
|
|
uint numPolys = reader.ReadUInt32();
|
2017-09-15 08:22:51 -07:00
|
|
|
for (uint i = 0; i < numPolys; i++)
|
2018-01-31 21:09:08 -06:00
|
|
|
InPolys.Add(reader.ReadUInt16());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BSPNode ReadNode(BinaryReader reader, BSPType treeType)
|
|
|
|
|
{
|
|
|
|
|
// We peek forward to get the type, then revert our position.
|
2018-11-22 01:33:17 -05:00
|
|
|
var type = Encoding.ASCII.GetString(reader.ReadBytes(4)).Reverse();
|
2018-01-31 21:09:08 -06:00
|
|
|
reader.BaseStream.Position -= 4;
|
|
|
|
|
|
|
|
|
|
BSPNode node;
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
2018-11-22 01:33:17 -05:00
|
|
|
case "PORT":
|
2018-01-31 21:09:08 -06:00
|
|
|
node = new BSPPortal();
|
|
|
|
|
break;
|
|
|
|
|
|
2018-11-22 01:33:17 -05:00
|
|
|
case "LEAF":
|
2018-01-31 21:09:08 -06:00
|
|
|
node = new BSPLeaf();
|
|
|
|
|
break;
|
|
|
|
|
|
2018-11-22 01:33:17 -05:00
|
|
|
case "BPnn":
|
|
|
|
|
case "BPIn":
|
|
|
|
|
case "BpIN":
|
|
|
|
|
case "BpnN":
|
|
|
|
|
case "BPIN":
|
|
|
|
|
case "BPnN":
|
2018-01-31 21:09:08 -06:00
|
|
|
default:
|
|
|
|
|
node = new BSPNode();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node.Unpack(reader, treeType);
|
|
|
|
|
|
|
|
|
|
return node;
|
2017-09-15 08:22:51 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|