diff --git a/LibBSP/LibBSP.csproj b/LibBSP/LibBSP.csproj index 8f0cc9a..d5c18a2 100644 --- a/LibBSP/LibBSP.csproj +++ b/LibBSP/LibBSP.csproj @@ -67,6 +67,7 @@ + diff --git a/LibBSP/Source/Structs/BSP/BSP.cs b/LibBSP/Source/Structs/BSP/BSP.cs index 78c87d7..329561f 100644 --- a/LibBSP/Source/Structs/BSP/BSP.cs +++ b/LibBSP/Source/Structs/BSP/BSP.cs @@ -90,6 +90,8 @@ namespace LibBSP { private List _brushes; private List _brushSides; private NumList _markBrushes; + // MoHAA + private List _staticModels; // Nightfire private Textures _materials; private NumList _indices; @@ -448,6 +450,21 @@ namespace LibBSP { } } + /// + /// A List of objects in the BSP file, if available. + /// + public List staticModels { + get { + if (_staticModels == null) { + int index = StaticModel.GetIndexForLump(version); + if (index >= 0) { + _staticModels = StaticModel.LumpFactory(reader.ReadLump(this[index]), version, this[index].version); + } + } + return _staticModels; + } + } + /// /// A object containing the Face Vertex Indices lump, if available. /// diff --git a/LibBSP/Source/Structs/BSP/StaticModel.cs b/LibBSP/Source/Structs/BSP/StaticModel.cs new file mode 100644 index 0000000..1e9fef4 --- /dev/null +++ b/LibBSP/Source/Structs/BSP/StaticModel.cs @@ -0,0 +1,109 @@ +#if UNITY_2_6 || UNITY_2_6_1 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_5_3_OR_NEWER +#define UNITY +#endif + +using System; +using System.Collections.Generic; +#if UNITY +using UnityEngine; +#endif + +namespace LibBSP { +#if !UNITY + using Vector3 = Vector3d; +#endif + /// + /// Handles the data needed for a static model object from MoHAA. + /// + public struct StaticModel { + + public string name { get; private set; } + public Vector3 origin { get; private set; } + public Vector3 angles { get; private set; } + public float scale { get; private set; } + [Index("vertices")] public int firstVertex { get; private set; } + [Count("vertices")] public short numVertices { get; private set; } + + /// + /// Creates a new object from a byte array. + /// + /// byte array to parse. + /// The map type. + /// The version of static prop lump this object is a member of. + /// was null. + /// This structure is not implemented for the given maptype. + public StaticModel(byte[] data, MapType type, int version = 0) : this() { + if (data == null) { + throw new ArgumentNullException(); + } + name = ""; + origin = Vector3.zero; + angles = Vector3.zero; + scale = 0; + switch (type) { + case MapType.MOHAA: { + byte[] nameBytes = new byte[128]; + Array.Copy(data, 0, nameBytes, 0, 128); + name = nameBytes.ToNullTerminatedString(); + origin = new Vector3(BitConverter.ToSingle(data, 128), BitConverter.ToSingle(data, 132), BitConverter.ToSingle(data, 136)); + angles = new Vector3(BitConverter.ToSingle(data, 140), BitConverter.ToSingle(data, 144), BitConverter.ToSingle(data, 148)); + scale = BitConverter.ToSingle(data, 152); + firstVertex = BitConverter.ToInt32(data, 156); + numVertices = BitConverter.ToInt16(data, 160); + break; + } + default: { + throw new ArgumentException("Map type " + type + " isn't supported by the StaticModel class."); + } + } + } + + /// + /// Factory method to parse a byte array into a List of objects. + /// + /// The data to parse. + /// The map type. + /// The version of this lump. + /// A List of objects. + /// was null. + /// This structure is not implemented for the given maptype. + public static List LumpFactory(byte[] data, MapType type, int version = 0) { + if (data == null) { + throw new ArgumentNullException(); + } + int structLength = 0; + switch (type) { + case MapType.MOHAA: { + structLength = 164; + break; + } + default: { + throw new ArgumentException("Map type " + type + " isn't supported by the StaticModel lump factory."); + } + } + List lump = new List(data.Length / structLength); + byte[] bytes = new byte[structLength]; + for (int i = 0; i < data.Length / structLength; ++i) { + Array.Copy(data, (i * structLength), bytes, 0, structLength); + lump.Add(new StaticModel(bytes, type, version)); + } + return lump; + } + + /// + /// Gets the index for this lump in the BSP file for a specific map format. + /// + /// The map type. + /// Index for this lump, or -1 if the format doesn't have this lump. + public static int GetIndexForLump(MapType type) { + switch (type) { + case MapType.MOHAA: { + return 25; + } + default: { + return -1; + } + } + } + } +}