diff --git a/Assets/Scripts/Data/QConstants.cs b/Assets/Scripts/Data/QConstants.cs index b66a1c2..942cc5c 100644 --- a/Assets/Scripts/Data/QConstants.cs +++ b/Assets/Scripts/Data/QConstants.cs @@ -3,4 +3,6 @@ public const int MaxQPath = 64; // Should correspond to MAX_QPATH public const int MaxMapHulls = 4; // Should correspond to MAX_MAP_HULLS public const int MaxSkins = 32; // Should correspond to MAX_SKINS + public const int MaxDLights = 64; // Should correspond to MAX_DLIGHTS + public const int MaxLightmaps = 4; // Should correspond to MAXLIGHTMAPS } diff --git a/Assets/Scripts/Data/QExtensions.cs b/Assets/Scripts/Data/QExtensions.cs index fa68609..9853558 100644 --- a/Assets/Scripts/Data/QExtensions.cs +++ b/Assets/Scripts/Data/QExtensions.cs @@ -20,6 +20,16 @@ public static class QExtensions return result; } + public static int[] ToIntArray(this IntPtr ptr, int count) + { + if (ptr == IntPtr.Zero) + return null; + + int[] result = new int[count]; + Marshal.Copy(ptr, result, 0, count); + return result; + } + public static Vector3 ToVector3(this QVec3 vec) { return new Vector3(vec.x, vec.y, vec.z); diff --git a/Assets/Scripts/Data/QMath.cs b/Assets/Scripts/Data/QMath.cs index 4d75335..c0eacf1 100644 --- a/Assets/Scripts/Data/QMath.cs +++ b/Assets/Scripts/Data/QMath.cs @@ -19,4 +19,18 @@ public struct QVec4i public int y; public int z; public int w; -} \ No newline at end of file +} + +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QVec2s +{ + public short x; + public short y; +} + +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QVec2i +{ + public int x; + public int y; +} diff --git a/Assets/Scripts/Data/QModel.cs b/Assets/Scripts/Data/QModel.cs index 7c5f667..919d0fe 100644 --- a/Assets/Scripts/Data/QModel.cs +++ b/Assets/Scripts/Data/QModel.cs @@ -39,7 +39,7 @@ public class QModel public IntPtr leafs; // Array of mleaf_t public int numVertices; - public IntPtr vertices; // Array of mvertex_t + public IntPtr vertices; // Array of mvertex_t (which is just a single vec3_t) public int numEdges; public IntPtr edges; // Array of medge_t @@ -220,3 +220,77 @@ public struct QSTVert public int onSeam; public int s, t; } + +/// +/// Managed equivalent of dmodel_t +/// +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QDModel +{ + public QVec3 mins, maxs; + public QVec3 origin; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxMapHulls)] public int[] headNode; + public int visLeafs; + public int firstFace, numFaces; +} + +/// +/// Managed equivalent of mplane_t +/// +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QPlane +{ + public QVec3 normal; + public float dist; + public byte type; + public byte signBits; + public byte pad0, pad1; +} + +/// +/// Managed equivalent of medge_t +/// +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QEdge +{ + public uint v0, v1; + public uint cachedEdgeOffset; +} + +/// +/// Managed equivalent of msurface_t +/// +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QSurface +{ + public int visFrame; + public bool culled; + public QVec3 mins, maxs; + + public IntPtr plane; // Pointer to mplane_t + public int flags; + + public int firstEdge; + public int numEdges; + + public QVec2s textureMins; + public QVec2s extents; + + public QVec2i lightST; + + public IntPtr polys; // Pointer to glpoly_t + public IntPtr textureChain; // Pointer to msurface_t + + public IntPtr texInfo; // Pointer to mtexinfo_t + + public int vboFirstVert; // QuakeSpasm VBO stuff + + public int dLightFrame; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (QConstants.MaxDLights + 31) >> 5)] public uint[] dLightBits; + + public int lightmapTextureNum; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxLightmaps)] public byte[] styles; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxLightmaps)] public int[] cachedLight; + public bool cachedDLight; + public IntPtr samples; // Pointer to byte +} diff --git a/Assets/Scripts/Modules/RenderModule.Interop.cs b/Assets/Scripts/Modules/RenderModule.Interop.cs index 5300e88..054f022 100644 --- a/Assets/Scripts/Modules/RenderModule.Interop.cs +++ b/Assets/Scripts/Modules/RenderModule.Interop.cs @@ -89,7 +89,15 @@ public partial class RenderModule: CallbackHandler [MonoPInvokeCallback(typeof(UploadBrushModelCallback))] private static int Callback_UploadBrushModel(IntPtr target, QModel model) { - return GetSelf(target).UploadBrushModel(model); + if (model == null || model.type != QModelType.Brush) + return -1; + + var vertices = model.vertices.ToStructArray(model.numVertices); + var edges = model.edges.ToStructArray(model.numEdges); + var surfaces = model.surfaces.ToStructArray(model.numSurfaces); + var surfaceEdges = model.surfEdges.ToIntArray(model.numSurfEdges); + + return GetSelf(target).UploadBrushModel(model, vertices, edges, surfaces, surfaceEdges); } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] diff --git a/Assets/Scripts/Modules/RenderModule.cs b/Assets/Scripts/Modules/RenderModule.cs index e751797..0e8d4da 100644 --- a/Assets/Scripts/Modules/RenderModule.cs +++ b/Assets/Scripts/Modules/RenderModule.cs @@ -119,12 +119,13 @@ public partial class RenderModule return 1; } - private int UploadBrushModel(QModel model) + private int UploadBrushModel(QModel model, QVec3[] vertices, QEdge[] edges, QSurface[] surfaces, int[] surfaceEdges) { - if (model.type != QModelType.Brush) - return -1; + Debug.Log($"Brush model '{model.name}' with {model.numVertices} vertices, {model.numEdges} edges, {model.numSurfaces} surfaces"); + + var brushModel = new BrushModel(model.name); + brushModel.ImportMeshData(model, vertices, edges, surfaces, surfaceEdges); - Debug.Log($"Brush model '{model.name}' with {model.numLeafs} leafs, {model.numVertices} vertices, {model.numSurfaces} surfaces"); return 1; }