diff --git a/Assets/Scripts/Data/QModel.cs b/Assets/Scripts/Data/QModel.cs index e5724f5..1d571fe 100644 --- a/Assets/Scripts/Data/QModel.cs +++ b/Assets/Scripts/Data/QModel.cs @@ -145,6 +145,24 @@ public enum QSyncType Rand } +/// +/// Managed equivalent of aliasframetype_t +/// +public enum QAliasFrameType +{ + Single = 0, + Group, +} + +/// +/// Managed equivalent of aliasskintype_t +/// +public enum QAliasSkinType +{ + Single = 0, + Group, +} + /// /// Managed equivalent of hull_t /// diff --git a/Assets/Scripts/Modules/AliasModel.cs b/Assets/Scripts/Modules/AliasModel.cs index 0e16c6b..1a7b9d3 100644 --- a/Assets/Scripts/Modules/AliasModel.cs +++ b/Assets/Scripts/Modules/AliasModel.cs @@ -8,11 +8,13 @@ public class AliasModel private static readonly Regex AnimationRegex = new Regex(@"^[a-zA-Z]+"); private readonly string name; + private readonly QAliasFrameType frameType; private readonly List<(int, Mesh)> animationMeshes = new List<(int, Mesh)>(); - public AliasModel(string name) + public AliasModel(string name, QAliasFrameType frameType) { this.name = name; + this.frameType = frameType; } public int GetAnimationFrameCount(float frameNum) @@ -139,7 +141,7 @@ public class AliasModel return; Array.Resize(ref stVerts, header.numVerts + seamVertices.Count); - for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx) + for (int frameIdx = 0; frameIdx < header.numPoses; ++frameIdx) { Array.Resize(ref poseVertices[frameIdx], header.numVerts + seamVertices.Count); } @@ -172,7 +174,7 @@ public class AliasModel stVerts[newVertIndex] = stVertCopy; // Clone the vertex position data for all frames - for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx) + for (int frameIdx = 0; frameIdx < header.numPoses; ++frameIdx) { QTriVertex triVertCopy = poseVertices[frameIdx][vertIndex]; poseVertices[frameIdx][newVertIndex] = triVertCopy; diff --git a/Assets/Scripts/Modules/RenderModule.Interop.cs b/Assets/Scripts/Modules/RenderModule.Interop.cs index 146190d..8112b44 100644 --- a/Assets/Scripts/Modules/RenderModule.Interop.cs +++ b/Assets/Scripts/Modules/RenderModule.Interop.cs @@ -34,12 +34,12 @@ public partial class RenderModule: CallbackHandler [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); + QAliasHeader header, QAliasFrameType frameType, IntPtr frames, + [MarshalAs(UnmanagedType.LPArray, SizeConst = MaxAliasFrames)] IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts); [MonoPInvokeCallback(typeof(UploadAliasModelCallback))] private static int Callback_UploadAliasModel(IntPtr target, - string name, QAliasHeader header, IntPtr frames, + string name, QAliasHeader header, QAliasFrameType frameType, IntPtr frames, IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts) { if (header == null) @@ -54,14 +54,20 @@ public partial class RenderModule: CallbackHandler if (frames != IntPtr.Zero) header.frames = frames.ToStructArray(header.numFrames); - var poseVertices = new QTriVertex[header.numFrames][]; + header.numPoses = 0; for (int i = 0; i < header.numFrames; ++i) + { + header.numPoses += header.frames[i].numPoses; + } + + var poseVertices = new QTriVertex[header.numPoses][]; + for (int i = 0; i < header.numPoses; ++i) { poseVertices[i] = poseVerts[i].ToStructArray(header.numVerts); } return GetSelf(target).UploadAliasModel( - name, header, poseVertices, + name, header, frameType, poseVertices, triangles.ToStructArray(header.numTriangles), stVerts.ToStructArray(header.numVerts)); } diff --git a/Assets/Scripts/Modules/RenderModule.cs b/Assets/Scripts/Modules/RenderModule.cs index bbab168..aff010c 100644 --- a/Assets/Scripts/Modules/RenderModule.cs +++ b/Assets/Scripts/Modules/RenderModule.cs @@ -27,13 +27,19 @@ public partial class RenderModule private float xPos = -8f; - private int UploadAliasModel(string name, QAliasHeader header, + private int UploadAliasModel(string name, QAliasHeader header, QAliasFrameType frameType, QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices) { - Debug.Log($"Alias model '{name}' with {header.numVerts} vertices, {header.numTriangles} triangles, {header.numFrames} frame(s)"); + var sb = new System.Text.StringBuilder(); + foreach (var frame in header.frames) + { + sb.AppendLine($"- {frame.name} ({frame.numPoses} poses)"); + } + + Debug.Log($"Alias model '{name}' (frame type {frameType}) with {header.numVerts} vertices, {header.numTriangles} triangles, {header.numFrames} frame(s), {header.numPoses} pose(s):\n{sb}"); string modelName = System.IO.Path.GetFileNameWithoutExtension(name); - AliasModel aliasModel = new AliasModel(modelName); + AliasModel aliasModel = new AliasModel(modelName, frameType); aliasModel.ImportMeshData(header, poseVertices, triangles, stVertices); aliasModels.Add(aliasModel); diff --git a/engine/Quake/gl_model.c b/engine/Quake/gl_model.c index 7144fb9..053c141 100644 --- a/engine/Quake/gl_model.c +++ b/engine/Quake/gl_model.c @@ -2634,10 +2634,11 @@ void Mod_LoadAliasModel (qmodel_t *mod, void *buffer) posenum = 0; pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; + aliasframetype_t frametype; + frametype = (aliasframetype_t)LittleLong(pframetype->type); + for (i=0 ; itype); if (frametype == ALIAS_SINGLE) pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); else @@ -2657,7 +2658,7 @@ void Mod_LoadAliasModel (qmodel_t *mod, void *buffer) // GL_MakeAliasModelDisplayLists (mod, pheader); - UQ_GL_UploadAliasModel(mod, pheader, poseverts, triangles, stverts); + UQ_GL_UploadAliasModel(mod, pheader, frametype, poseverts, triangles, stverts); // // move the complete, relocatable alias model to the cache diff --git a/engine/Quake/gl_model.h b/engine/Quake/gl_model.h index c648bfb..bcc76d9 100644 --- a/engine/Quake/gl_model.h +++ b/engine/Quake/gl_model.h @@ -516,7 +516,7 @@ byte *Mod_NoVisPVS (qmodel_t *model); void Mod_SetExtraFlags (qmodel_t *mod); -int UQ_GL_UploadAliasModel(qmodel_t *model, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); +int UQ_GL_UploadAliasModel(qmodel_t *model, aliashdr_t *aliashdr, aliasframetype_t frametype, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); int UQ_GL_UploadBrushModel(qmodel_t *model); #endif // __MODEL__ diff --git a/engine/UniQuake/gl_uniquake.c b/engine/UniQuake/gl_uniquake.c index 9862bbc..c311e1f 100644 --- a/engine/UniQuake/gl_uniquake.c +++ b/engine/UniQuake/gl_uniquake.c @@ -7,17 +7,17 @@ typedef struct unity_glcalls_s { void *target; - int(*UploadAliasModel)(void *target, const char *name, aliashdr_t *aliashdr, maliasframedesc_t *frames, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); + 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); } unity_glcalls_t; const unity_glcalls_t *unity_glcalls; -int UQ_GL_UploadAliasModel(qmodel_t *model, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts) +int UQ_GL_UploadAliasModel(qmodel_t *model, aliashdr_t *aliashdr, aliasframetype_t frametype, 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 frame struct which allows us to manually marshal the entire array. - return unity_glcalls->UploadAliasModel(unity_glcalls->target, model->name, aliashdr, &aliashdr->frames[0], poseVerts, triangles, stVerts); + return unity_glcalls->UploadAliasModel(unity_glcalls->target, model->name, aliashdr, frametype, &aliashdr->frames[0], poseVerts, triangles, stVerts); } int UQ_GL_UploadBrushModel(qmodel_t *model)