mirror of
https://github.com/celisej567/LibBSP.git
synced 2026-09-11 20:09:36 +03:00
Add custom attributes for Index and Count members of some lumps to indicate which lump they refer to. These can be used with BSP.GetReferencedObjects to get all objects of one lump referred to by an object from another.
This commit is contained in:
24
LibBSP/src/Attributes/CountAttribute.cs
Normal file
24
LibBSP/src/Attributes/CountAttribute.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LibBSP {
|
||||
/// <summary>
|
||||
/// 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 <c>BSP.GetReferencedObjects<T></c> method.
|
||||
/// </summary>
|
||||
public class CountAttribute : Attribute {
|
||||
|
||||
public string lumpName;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of an <c>CountAttribute</c> object. The member this Attribute
|
||||
/// is applied to will be used as a count of objects in the lump referenced by <paramref name="lumpName"/>.
|
||||
/// </summary>
|
||||
/// <param name="lumpName">The lump the member is an count for. Corresponds to the public properties in the <c>BSP</c> class.</param>
|
||||
public CountAttribute(string lumpName) {
|
||||
this.lumpName = lumpName;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
LibBSP/src/Attributes/IndexAttribute.cs
Normal file
24
LibBSP/src/Attributes/IndexAttribute.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LibBSP {
|
||||
/// <summary>
|
||||
/// 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 <c>BSP.GetReferencedObjects<T></c> method.
|
||||
/// </summary>
|
||||
public class IndexAttribute : Attribute {
|
||||
|
||||
public string lumpName;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of an <c>IndexAttribute</c> object. The member this Attribute
|
||||
/// is applied to will be used as an index into the lump referenced by <paramref name="lumpName"/>.
|
||||
/// </summary>
|
||||
/// <param name="lumpName">The lump the member is an index into. Corresponds to the public properties in the <c>BSP</c> class.</param>
|
||||
public IndexAttribute(string lumpName) {
|
||||
this.lumpName = lumpName;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
LibBSP/src/Extensions/CustomAttributeExtensions.cs
Normal file
16
LibBSP/src/Extensions/CustomAttributeExtensions.cs
Normal file
@@ -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<T>(this MemberInfo element) where T : Attribute {
|
||||
return Attribute.GetCustomAttribute(element, typeof(T)) as T;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all objects of type <typeparamref name="T"/> referenced through passed object <paramref name="o"/>
|
||||
/// contained in the lump <paramref name="lumpName"/> stored in this <c>BSP</c> class. This is done by
|
||||
/// reflecting the <c>Type</c> of <paramref name="o"/> and looping through its public properties to find
|
||||
/// a member with an <c>IndexAttribute</c> attribute and a member with <c>CountAttribute</c> attribute
|
||||
/// both corresponding to <paramref name="lumpName"/>. The index and count are obtained and used to construct
|
||||
/// a new <c>List<<typeparamref name="T"/>></c> object containing the corresponding objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of <c>object</c> stored in the lump <paramref name="lumpName"/>.</typeparam>
|
||||
/// <param name="o">The <c>object</c> which contains and index and count corresponding to <paramref name="lumpName"/>.</param>
|
||||
/// <param name="lumpName">The name of the property in this <c>BSP</c> object to get a <c>List</c> of objects from.</param>
|
||||
/// <returns>The <c>List<<typeparamref name="T"/>></c> of objects in the lump from the index and length specified in <paramref name="o"/>.</returns>
|
||||
/// <exception cref="ArgumentException">The <c>BSP</c> class contains no property corresponding to <paramref name="lumpName"/>.</exception>
|
||||
/// <exception cref="ArgumentException">The <c>object</c> referenced by <paramref name="o"/> is missing one or both members with <c>IndexAttribute</c> or <c>CountAttribute</c> attributes corresponding to <paramref name="lumpName"/>.</exception>
|
||||
public List<T> GetReferencedObjects<T>(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<IndexAttribute>();
|
||||
if (indexAttribute != null) {
|
||||
if (indexAttribute.lumpName == lumpName) {
|
||||
indexProperty = info;
|
||||
if (indexProperty != null && countProperty != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CountAttribute lengthAttribute = info.GetCustomAttribute<CountAttribute>();
|
||||
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<T> theLump = targetLump.GetGetMethod().Invoke(this, null) as List<T>;
|
||||
|
||||
return theLump.GetRange(index, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace LibBSP {
|
||||
/// </summary>
|
||||
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; }
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace LibBSP {
|
||||
/// <param name="first">The first vertex to get</param>
|
||||
/// <param name="power">The power of the displacement</param>
|
||||
/// <returns>Array of <c>SourceDispVertex</c> objects containing all the vertices in this displacement</returns>
|
||||
public virtual SourceDispVertex[] GetVertsInDisp(int first, int power) {
|
||||
public virtual SourceDispVertex[] GetVerticesInDisplacement(int first, int power) {
|
||||
int numVerts = 0;
|
||||
switch (power) {
|
||||
case 2: {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <c>Model</c> object from a <c>byte</c> array.
|
||||
|
||||
Reference in New Issue
Block a user