Browse Source

Reimplemented uploading of alias model data, which now includes all vertex, triangle index and UV data

console
Nico de Poel 5 years ago
parent
commit
0f02005c58
  1. 20
      Assets/Scripts/Data/QModel.cs
  2. 46
      Assets/Scripts/Modules/RenderModule.cs
  3. 2
      engine/code/gl_mesh.c
  4. 6
      engine/code/gl_model.c
  5. 2
      engine/code/gl_model.h
  6. 11
      engine/projects/uniquake/mod_uniquake.c

20
Assets/Scripts/Data/QModel.cs

@ -172,3 +172,23 @@ public struct QTriVertex
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] v;
public byte lightNormalIndex;
}
/// <summary>
/// Managed equivalent of mtriangle_t
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct QTriangle
{
public int facesFront;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public int[] vertIndex;
}
/// <summary>
/// Managed equivalent of stvert_t
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct QSTVert
{
public int onSeam;
public int s, t;
}

46
Assets/Scripts/Modules/RenderModule.cs

@ -7,6 +7,8 @@ using UnityEngine;
public class RenderModule : CallbackHandler<RenderModule>
{
private const int MaxAliasFrames = 256; // Should match MAXALIASFRAMES
private readonly UniQuake uq;
public RenderModule(UniQuake uniQuake)
@ -17,42 +19,54 @@ public class RenderModule : CallbackHandler<RenderModule>
{
target = SelfPtr,
ModUploadModel = CreateCallback<ModUploadModelCallback>(Callback_ModUploadModel),
UploadAliasModel = CreateCallback<UploadAliasModelCallback>(Callback_UploadAliasModel),
};
RegisterCallbacks(callbacks);
}
/// <summary>
/// This matches struct unity_syscalls_s from uniquake.h in native code.
/// This matches unity_modcalls_t from mod_uniquake.c in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
public IntPtr ModUploadModel;
public IntPtr UploadAliasModel;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void ModUploadModelCallback(IntPtr target, QModel model, QAliasHeader header, IntPtr frames);
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate int UploadAliasModelCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string name,
QAliasHeader header, IntPtr frames, [MarshalAs(UnmanagedType.LPArray, SizeConst = MaxAliasFrames)]
IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts);
[MonoPInvokeCallback(typeof(ModUploadModelCallback))]
private static void Callback_ModUploadModel(IntPtr target, QModel model, QAliasHeader header, IntPtr frames)
[MonoPInvokeCallback(typeof(UploadAliasModelCallback))]
private static int Callback_UploadAliasModel(IntPtr target, string name, QAliasHeader header, IntPtr frames, IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts)
{
if (header == null)
{
if (header != null)
Debug.LogWarning($"Uploading invalid alias model, name = {name}");
return 0;
}
if (frames != IntPtr.Zero)
header.frames = frames.ToStructArray<QAliasFrameDesc>(header.numFrames);
GetSelf(target).UploadModel(model, header);
var poseVertices = new QTriVertex[header.numFrames][];
for (int i = 0; i < header.numFrames && i < MaxAliasFrames; ++i)
{
poseVertices[i] = poseVerts[i].ToStructArray<QTriVertex>(header.numVerts);
}
private void UploadModel(QModel model, QAliasHeader header)
{
Debug.Log($"Model '{model?.name}' of type {model?.type}, num frames = {header?.numFrames}");
if (header?.frames != null)
{
string str = string.Join(", ", header.frames.Select(f => f.name));
Debug.Log($"Frame list: {str}");
return GetSelf(target).UploadAliasModel(name, header, poseVertices,
triangles.ToStructArray<QTriangle>(header.numTriangles),
stVerts.ToStructArray<QSTVert>(header.numVerts));
}
private int UploadAliasModel(string name, QAliasHeader header, QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices)
{
Debug.Log($"Alias model '{name}' with {header.numVerts} vertices, {header.numTriangles} triangles, {header.numFrames} frame(s)");
return 1;
}
}

2
engine/code/gl_mesh.c

@ -358,7 +358,5 @@ void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
for (i=0 ; i<paliashdr->numposes ; i++)
for (j=0 ; j<numorder ; j++)
*verts++ = poseverts[i][vertexorder[j]];
Mod_UploadModel(m, paliashdr);
}

6
engine/code/gl_model.c

@ -1507,7 +1507,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
}
}
Mod_UploadModel(mod, NULL);
// TODO: upload brush model to UniQuake
}
/*
@ -2015,6 +2015,10 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
//
GL_MakeAliasModelDisplayLists (mod, pheader);
// TODO: upload model to UniQuake, receive & store identifier as a result
// Vertices = poseverts, UVs = stverts, indices = triangles
UQ_GL_UploadAliasModel(mod->name, pheader, poseverts, triangles, stverts);
//
// move the complete, relocatable alias model to the cache
//

2
engine/code/gl_model.h

@ -451,6 +451,6 @@ void Mod_TouchModel (char *name);
mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
void Mod_UploadModel(model_t *model, aliashdr_t *aliashdr);
int UQ_GL_UploadAliasModel(char *name, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts);
#endif // __MODEL__

11
engine/projects/uniquake/mod_uniquake.c

@ -7,17 +7,14 @@ typedef struct unity_modcalls_s
{
void *target;
void(*ModUploadModel)(void *target, model_t *mdl, aliashdr_t *aliashdr, maliasframedesc_t *frames);
int(*UploadAliasModel)(void *target, char *name, aliashdr_t *aliashdr, maliasframedesc_t *frames, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts);
} unity_modcalls_t;
const unity_modcalls_t *unity_modcalls;
void Mod_UploadModel(model_t *mdl, aliashdr_t *aliashdr)
int UQ_GL_UploadAliasModel(char *name, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts)
{
// C# doesn't really understand this idea of a variable-length embedded array of structs,
// so we pass along the pointer to the first element which allows us to manually marshal the entire array.
if (aliashdr)
unity_modcalls->ModUploadModel(unity_modcalls->target, mdl, aliashdr, &aliashdr->frames[0]);
else
unity_modcalls->ModUploadModel(unity_modcalls->target, mdl, aliashdr, NULL);
// so we pass along the pointer to the first frame struct which allows us to manually marshal the entire array.
return unity_modcalls->UploadAliasModel(unity_modcalls->target, name, aliashdr, &aliashdr->frames[0], poseVerts, triangles, stVerts);
}
Loading…
Cancel
Save