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);
+}