diff --git a/LibBSP/src/Attributes/CountAttribute.cs b/LibBSP/src/Attributes/CountAttribute.cs
new file mode 100644
index 0000000..97669e3
--- /dev/null
+++ b/LibBSP/src/Attributes/CountAttribute.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace LibBSP {
+ ///
+ /// Custom Attribute class to mark a member of a struct as an count for another lump. The
+ /// member this Attribute is applied to should always be paired with a member with an Index
+ /// Attribute applied to it. The two attributes can the be used to grab a range of objects
+ /// from the specified lump through the BSP.GetReferencedObjects<T> method.
+ ///
+ public class CountAttribute : Attribute {
+
+ public string lumpName;
+
+ ///
+ /// Constructs a new instance of an CountAttribute object. The member this Attribute
+ /// is applied to will be used as a count of objects in the lump referenced by .
+ ///
+ /// The lump the member is an count for. Corresponds to the public properties in the BSP class.
+ public CountAttribute(string lumpName) {
+ this.lumpName = lumpName;
+ }
+ }
+}
diff --git a/LibBSP/src/Attributes/IndexAttribute.cs b/LibBSP/src/Attributes/IndexAttribute.cs
new file mode 100644
index 0000000..3631401
--- /dev/null
+++ b/LibBSP/src/Attributes/IndexAttribute.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace LibBSP {
+ ///
+ /// Custom Attribute class to mark a member of a struct as an index into another lump. The
+ /// member this Attribute is applied to should always be paired with a member with a Count
+ /// Attribute applied to it. The two attributes can the be used to grab a range of objects
+ /// from the specified lump through the BSP.GetReferencedObjects<T> method.
+ ///
+ public class IndexAttribute : Attribute {
+
+ public string lumpName;
+
+ ///
+ /// Constructs a new instance of an IndexAttribute object. The member this Attribute
+ /// is applied to will be used as an index into the lump referenced by .
+ ///
+ /// The lump the member is an index into. Corresponds to the public properties in the BSP class.
+ public IndexAttribute(string lumpName) {
+ this.lumpName = lumpName;
+ }
+ }
+}
diff --git a/LibBSP/src/Extensions/CustomAttributeExtensions.cs b/LibBSP/src/Extensions/CustomAttributeExtensions.cs
new file mode 100644
index 0000000..7fef756
--- /dev/null
+++ b/LibBSP/src/Extensions/CustomAttributeExtensions.cs
@@ -0,0 +1,16 @@
+#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)
+
+using System;
+using System.Reflection;
+
+namespace LibBSP {
+ public static class CustomAttributeExtensions {
+
+ public static T GetCustomAttribute(this MemberInfo element) where T : Attribute {
+ return Attribute.GetCustomAttribute(element, typeof(T)) as T;
+ }
+
+ }
+}
+
+#endif
diff --git a/LibBSP/src/Structs/BSP/BSP.cs b/LibBSP/src/Structs/BSP/BSP.cs
index b226b3e..a9f07be 100644
--- a/LibBSP/src/Structs/BSP/BSP.cs
+++ b/LibBSP/src/Structs/BSP/BSP.cs
@@ -5,6 +5,7 @@
using System;
using System.IO;
using System.Collections.Generic;
+using System.Reflection;
#if UNITY
using UnityEngine;
#endif
@@ -435,5 +436,66 @@ namespace LibBSP {
reader = new BSPReader(file);
this.filePath = file.FullName;
}
+
+ ///
+ /// Gets all objects of type referenced through passed object
+ /// contained in the lump stored in this BSP class. This is done by
+ /// reflecting the Type of and looping through its public properties to find
+ /// a member with an IndexAttribute attribute and a member with CountAttribute attribute
+ /// both corresponding to . The index and count are obtained and used to construct
+ /// a new List<> object containing the corresponding objects.
+ ///
+ /// The type of object stored in the lump .
+ /// The object which contains and index and count corresponding to .
+ /// The name of the property in this BSP object to get a List of objects from.
+ /// The List<> of objects in the lump from the index and length specified in .
+ /// The BSP class contains no property corresponding to .
+ /// The object referenced by is missing one or both members with IndexAttribute or CountAttribute attributes corresponding to .
+ public List GetReferencedObjects(object o, string lumpName)
+ {
+ // First, find the property in this class corresponding to lumpName, and grab its "get" method
+ PropertyInfo targetLump = typeof(BSP).GetProperty(lumpName, BindingFlags.Public | BindingFlags.Instance);
+ if (targetLump == null) {
+ throw new ArgumentException("The lump " + lumpName + " does not exist in the BSP class");
+ }
+
+ // Next, find the properties in the passed object corresponding to lumpName, through the Index and Length custom attributes
+ Type objectType = o.GetType();
+ PropertyInfo[] objectProperties = objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+ PropertyInfo indexProperty = null;
+ PropertyInfo countProperty = null;
+ foreach (PropertyInfo info in objectProperties) {
+ IndexAttribute indexAttribute = info.GetCustomAttribute();
+ if (indexAttribute != null) {
+ if (indexAttribute.lumpName == lumpName) {
+ indexProperty = info;
+ if (indexProperty != null && countProperty != null) {
+ break;
+ }
+ }
+ }
+ CountAttribute lengthAttribute = info.GetCustomAttribute();
+ if (lengthAttribute != null) {
+ if (lengthAttribute.lumpName == lumpName) {
+ countProperty = info;
+ if (indexProperty != null && countProperty != null) {
+ break;
+ }
+ }
+ }
+ }
+ if (indexProperty == null || countProperty == null) {
+ throw new ArgumentException("An object of type " + objectType.Name + " does not implement both an Index and Count for lump " + lumpName);
+ }
+
+ // Get the index and length from the object
+ int index = (int)indexProperty.GetGetMethod().Invoke(o, null);
+ int count = (int)countProperty.GetGetMethod().Invoke(o, null);
+
+ // Get the lump from this class
+ List theLump = targetLump.GetGetMethod().Invoke(this, null) as List;
+
+ return theLump.GetRange(index, count);
+ }
}
}
diff --git a/LibBSP/src/Structs/BSP/Brush.cs b/LibBSP/src/Structs/BSP/Brush.cs
index 40d33a5..5af44dc 100644
--- a/LibBSP/src/Structs/BSP/Brush.cs
+++ b/LibBSP/src/Structs/BSP/Brush.cs
@@ -7,8 +7,8 @@ namespace LibBSP {
///
public struct Brush {
- public int firstSide { get; private set; }
- public int numSides { get; private set; }
+ [Index("brushSides")] public int firstSide { get; private set; }
+ [Count("brushSides")] public int numSides { get; private set; }
public int texture { get; private set; }
public int contents { get; private set; }
diff --git a/LibBSP/src/Structs/BSP/Face.cs b/LibBSP/src/Structs/BSP/Face.cs
index 72016cc..a37d84a 100644
--- a/LibBSP/src/Structs/BSP/Face.cs
+++ b/LibBSP/src/Structs/BSP/Face.cs
@@ -26,18 +26,18 @@ namespace LibBSP {
public int plane { get; private set; }
public int side { get; private set; }
- public int firstEdge { get; private set; }
- public int numEdges { get; private set; }
+ [Index("edges")] public int firstEdge { get; private set; }
+ [Count("edges")] public int numEdges { get; private set; }
public int texture { get; private set; }
- public int firstVertex { get; private set; }
- public int numVertices { get; private set; }
+ [Index("vertices")] public int firstVertex { get; private set; }
+ [Count("vertices")] public int numVertices { get; private set; }
public int material { get; private set; }
public int textureScale { get; private set; }
public int displacement { get; private set; }
public int original { get; private set; }
public int flags { get; private set; }
- public int firstIndex { get; private set; }
- public int numIndices { get; private set; }
+ [Index("indices")] public int firstIndex { get; private set; }
+ [Count("indices")] public int numIndices { get; private set; }
public int unknown { get; private set; }
public int lightStyles { get; private set; }
public int lightMaps { get; private set; }
diff --git a/LibBSP/src/Structs/BSP/Leaf.cs b/LibBSP/src/Structs/BSP/Leaf.cs
index d49a241..98d8504 100644
--- a/LibBSP/src/Structs/BSP/Leaf.cs
+++ b/LibBSP/src/Structs/BSP/Leaf.cs
@@ -8,10 +8,10 @@ namespace LibBSP {
public struct Leaf {
public int contents { get; private set; }
- public int firstMarkBrush { get; private set; }
- public int numMarkBrushes { get; private set; }
- public int firstMarkFace { get; private set; }
- public int numMarkFaces { get; private set; }
+ [Index("markBrushes")] public int firstMarkBrush { get; private set; }
+ [Count("markBrushes")] public int numMarkBrushes { get; private set; }
+ [Index("markSurfaces")] public int firstMarkFace { get; private set; }
+ [Count("markSurfaces")] public int numMarkFaces { get; private set; }
public int pvs { get; private set; }
///
diff --git a/LibBSP/src/Structs/BSP/Lumps/SourceDispVertices.cs b/LibBSP/src/Structs/BSP/Lumps/SourceDispVertices.cs
index 90cd467..f136e4a 100644
--- a/LibBSP/src/Structs/BSP/Lumps/SourceDispVertices.cs
+++ b/LibBSP/src/Structs/BSP/Lumps/SourceDispVertices.cs
@@ -31,7 +31,7 @@ namespace LibBSP {
/// The first vertex to get
/// The power of the displacement
/// Array of SourceDispVertex objects containing all the vertices in this displacement
- public virtual SourceDispVertex[] GetVertsInDisp(int first, int power) {
+ public virtual SourceDispVertex[] GetVerticesInDisplacement(int first, int power) {
int numVerts = 0;
switch (power) {
case 2: {
diff --git a/LibBSP/src/Structs/BSP/Model.cs b/LibBSP/src/Structs/BSP/Model.cs
index c57687f..26a6f10 100644
--- a/LibBSP/src/Structs/BSP/Model.cs
+++ b/LibBSP/src/Structs/BSP/Model.cs
@@ -17,12 +17,12 @@ namespace LibBSP {
public struct Model {
public int headNode { get; private set; } // Quake, Half-life, Quake 2, SiN
- public int firstLeaf { get; private set; } // 007 nightfire
- public int numLeaves { get; private set; }
- public int firstBrush { get; private set; } // Quake 3 and derivatives
- public int numBrushes { get; private set; }
- public int firstFace { get; private set; } // Quake/GoldSrc
- public int numFaces { get; private set; }
+ [Index("leaves")] public int firstLeaf { get; private set; } // 007 nightfire
+ [Count("leaves")] public int numLeaves { get; private set; }
+ [Index("brushes")] public int firstBrush { get; private set; } // Quake 3 and derivatives
+ [Count("brushes")] public int numBrushes { get; private set; }
+ [Index("faces")] public int firstFace { get; private set; } // Quake/GoldSrc
+ [Count("faces")] public int numFaces { get; private set; }
///
/// Creates a new Model object from a byte array.