From 15e3faa75384e740093883ba62520220fe527958 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Mon, 10 May 2021 20:52:07 +0200 Subject: [PATCH] Added callback function to allow Quake to send the view parameters to Unity, and apply them to the main camera. This makes actual movement through the map in Unity possible. --- Assets/Scripts/Data/QExtensions.cs | 5 +++++ Assets/Scripts/Data/QModel.cs | 15 +++++++++++++++ Assets/Scripts/Modules/RenderModule.Interop.cs | 11 +++++++++++ Assets/Scripts/Modules/RenderModule.cs | 10 ++++++++++ engine/Quake/gl_rmain.c | 2 ++ engine/Quake/render.h | 4 +++- engine/UniQuake/gl_uniquake.c | 6 ++++++ 7 files changed, 52 insertions(+), 1 deletion(-) diff --git a/Assets/Scripts/Data/QExtensions.cs b/Assets/Scripts/Data/QExtensions.cs index c31e8e9..584a6c9 100644 --- a/Assets/Scripts/Data/QExtensions.cs +++ b/Assets/Scripts/Data/QExtensions.cs @@ -50,4 +50,9 @@ public static class QExtensions { return new Vector3(vec.x, vec.z, vec.y); } + + public static Quaternion ToUnityRotation(this QVec3 angles) + { + return Quaternion.Euler(angles.x, 90 - angles.y, -angles.z); + } } diff --git a/Assets/Scripts/Data/QModel.cs b/Assets/Scripts/Data/QModel.cs index cd9feb8..7c84afa 100644 --- a/Assets/Scripts/Data/QModel.cs +++ b/Assets/Scripts/Data/QModel.cs @@ -269,6 +269,21 @@ public struct QNode }; } +/// +/// Managed equivalent of mleaf_t +/// +[StructLayout(LayoutKind.Sequential, Pack = 0)] +public struct QLeaf +{ + // Common with node + public int contents; // 0 for nodes, negative for leafs + public int visFrame; + public QVec3 mins, maxs; + public IntPtr parent; // Pointer to mnode_t + + // Leaf-specific data is unused +} + /// /// Managed equivalent of msurface_t /// diff --git a/Assets/Scripts/Modules/RenderModule.Interop.cs b/Assets/Scripts/Modules/RenderModule.Interop.cs index b155fb3..c7de286 100644 --- a/Assets/Scripts/Modules/RenderModule.Interop.cs +++ b/Assets/Scripts/Modules/RenderModule.Interop.cs @@ -16,6 +16,7 @@ public partial class RenderModule: CallbackHandler UploadAliasModel = CreateCallback(Callback_UploadAliasModel), UploadBrushModel = CreateCallback(Callback_UploadBrushModel), UploadTexture = CreateCallback(Callback_UploadTexture), + SetupView = CreateCallback(Callback_SetupView), }; RegisterCallbacks(callbacks); @@ -32,6 +33,7 @@ public partial class RenderModule: CallbackHandler public IntPtr UploadAliasModel; public IntPtr UploadBrushModel; public IntPtr UploadTexture; + public IntPtr SetupView; } [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] @@ -105,4 +107,13 @@ public partial class RenderModule: CallbackHandler Marshal.Copy(data, dataBytes, 0, dataBytes.Length); return GetSelf(target).UploadTexture(texture, dataBytes, ref texNum); } + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void SetupViewCallback(IntPtr target, QVec3 origin, QVec3 angles, QLeaf viewLeaf); + + [MonoPInvokeCallback(typeof(SetupViewCallback))] + private static void Callback_SetupView(IntPtr target, QVec3 origin, QVec3 angles, QLeaf viewLeaf) + { + GetSelf(target).SetupView(origin, angles, viewLeaf); + } } diff --git a/Assets/Scripts/Modules/RenderModule.cs b/Assets/Scripts/Modules/RenderModule.cs index 7f8d493..73d6640 100644 --- a/Assets/Scripts/Modules/RenderModule.cs +++ b/Assets/Scripts/Modules/RenderModule.cs @@ -155,4 +155,14 @@ public partial class RenderModule textures[texNum] = tex; return true; } + + private void SetupView(QVec3 origin, QVec3 angles, QLeaf viewLeaf) + { + var cam = Camera.main; + if (cam == null) + return; + + cam.transform.position = origin.ToVector3().ToUnity(); + cam.transform.rotation = angles.ToUnityRotation(); + } } diff --git a/engine/Quake/gl_rmain.c b/engine/Quake/gl_rmain.c index 2c75489..466cbd7 100644 --- a/engine/Quake/gl_rmain.c +++ b/engine/Quake/gl_rmain.c @@ -565,6 +565,8 @@ void R_SetupView (void) r_oldviewleaf = r_viewleaf; r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); + UQ_GL_SetupView(r_refdef.vieworg, r_refdef.viewangles, r_viewleaf); + V_SetContentsColor (r_viewleaf->contents); V_CalcBlend (); diff --git a/engine/Quake/render.h b/engine/Quake/render.h index 4ecb973..55aded4 100644 --- a/engine/Quake/render.h +++ b/engine/Quake/render.h @@ -174,5 +174,7 @@ void D_DeleteSurfaceCache (void); void D_InitCaches (void *buffer, int size); void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj); -#endif /* _QUAKE_RENDER_H */ +typedef struct mleaf_s mleaf_t; +void UQ_GL_SetupView(vec3_t origin, vec3_t angles, mleaf_t *viewLeaf); +#endif /* _QUAKE_RENDER_H */ diff --git a/engine/UniQuake/gl_uniquake.c b/engine/UniQuake/gl_uniquake.c index 2e45500..f535095 100644 --- a/engine/UniQuake/gl_uniquake.c +++ b/engine/UniQuake/gl_uniquake.c @@ -10,6 +10,7 @@ typedef struct unity_glcalls_s int(*UploadAliasModel)(void *target, const char *name, aliashdr_t *aliashdr, aliasframetype_t frametype, maliasframedesc_t *frames, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); int(*UploadBrushModel)(void *target, qmodel_t *model); qboolean(*UploadTexture)(void *target, gltexture_t *texture, unsigned *data, GLuint *texnum); + void(*SetupView)(void *target, vec3_t origin, vec3_t angles, mleaf_t *viewLeaf); } unity_glcalls_t; const unity_glcalls_t *unity_glcalls; @@ -31,3 +32,8 @@ qboolean UQ_GL_UploadTexture(gltexture_t *texture, unsigned *data) // Allow UniQuake to either sync up its internal texture reference number, or assign a new one. return unity_glcalls->UploadTexture(unity_glcalls->target, texture, data, &texture->texnum); } + +void UQ_GL_SetupView(vec3_t origin, vec3_t angles, mleaf_t *viewLeaf) +{ + unity_glcalls->SetupView(unity_glcalls->target, origin, angles, viewLeaf); +}