From 10e54f10cae537cf3b2f3be2371e230886741f40 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Thu, 22 Apr 2021 10:33:02 +0200 Subject: [PATCH] Added a separate code path for converting frame group animations, and renamed some variables to use the correct frame/pose terminology --- Assets/Scripts/Modules/AliasModel.cs | 43 +++++++++++++++++++------- Assets/Scripts/Modules/RenderModule.cs | 2 +- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Assets/Scripts/Modules/AliasModel.cs b/Assets/Scripts/Modules/AliasModel.cs index 1a7b9d3..8c72ef2 100644 --- a/Assets/Scripts/Modules/AliasModel.cs +++ b/Assets/Scripts/Modules/AliasModel.cs @@ -81,11 +81,20 @@ public class AliasModel ConvertUVs(stVertices, header.skinWidth, header.skinHeight, out var uvs); // Identify animation sequences and turn each one into a separate Mesh with a single blend shape animation + if (frameType == QAliasFrameType.Single) + ImportSingleFrameAnimations(header, poseVertices, indices, uvs); + else + ImportGroupFrameAnimations(header, poseVertices, indices, uvs); + } + + private void ImportSingleFrameAnimations(QAliasHeader header, QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs) + { Mesh mesh; string animName = null; int startFrame = 0; for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx) { + // Individual sequences are identified by their prefix string frameName = AnimationRegex.Match(header.frames[frameIdx].name).Value; if (animName == null) { @@ -108,6 +117,18 @@ public class AliasModel mesh = CreateAnimatedMesh(header, poseVertices, indices, uvs, $"{name}_{animName}", startFrame, header.numFrames); animationMeshes.Add((startFrame, mesh)); } + + private void ImportGroupFrameAnimations(QAliasHeader header, QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs) + { + for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx) + { + var frame = header.frames[frameIdx]; + Mesh mesh = CreateAnimatedMesh(header, poseVertices, indices, uvs, $"{name}_{frameIdx}", + frame.firstPose, frame.firstPose + frame.numPoses); + + animationMeshes.Add((frame.firstPose, mesh)); + } + } /// /// Quake has a bit of a weird outdated mesh setup where skin textures are split into a front side and a back side. @@ -233,17 +254,17 @@ public class AliasModel private static Mesh CreateAnimatedMesh( QAliasHeader header, QTriVertex[][] poseVertices, ushort[] indices, Vector2[] uvs, - string animationName, int startFrame, int endFrame) + string animationName, int startPose, int endPose) { - ConvertVertices(header, poseVertices[startFrame], out var baseVertices, out var baseNormals); + ConvertVertices(header, poseVertices[startPose], out var baseVertices, out var baseNormals); var mesh = new Mesh { name = animationName }; mesh.SetVertices(baseVertices); mesh.SetNormals(baseNormals); - if (endFrame - startFrame > 1) + if (endPose - startPose > 1) { - CreateBlendShapes(mesh, animationName, baseVertices, baseNormals, header, poseVertices, startFrame, endFrame); + CreateBlendShapes(mesh, animationName, baseVertices, baseNormals, header, poseVertices, startPose, endPose); } mesh.SetIndices(indices, MeshTopology.Triangles, 0, false); @@ -256,7 +277,7 @@ public class AliasModel private static void CreateBlendShapes( Mesh mesh, string animName, Vector3[] baseVertices, Vector3[] baseNormals, - QAliasHeader header, QTriVertex[][] poseVertices, int startFrame, int endFrame) + QAliasHeader header, QTriVertex[][] poseVertices, int startPose, int endPose) { var deltaVertices = new Vector3[header.numVerts]; var deltaNormals = new Vector3[header.numVerts]; @@ -264,13 +285,13 @@ public class AliasModel Vector3 scale = header.scale.ToVector3(); Vector3 origin = header.scaleOrigin.ToVector3(); - int numFrames = endFrame - startFrame; + int numPoses = endPose - startPose; - // Repeat the first frame at the end, so we can smoothly animate the entire cycle and loop the animation without any breaks. - for (int index = 1; index <= numFrames; ++index) + // Repeat the first pose at the end, so we can smoothly animate the entire cycle and loop the animation without any breaks. + for (int index = 1; index <= numPoses; ++index) { - int frameIdx = startFrame + index % numFrames; - var poseVerts = poseVertices[frameIdx]; + int poseIdx = startPose + index % numPoses; + var poseVerts = poseVertices[poseIdx]; for (int vertIdx = 0; vertIdx < header.numVerts; ++vertIdx) { @@ -279,7 +300,7 @@ public class AliasModel deltaNormals[vertIdx] = QLightNormals.Get(poseVerts[vertIdx].lightNormalIndex) - baseNormals[vertIdx]; } - mesh.AddBlendShapeFrame(animName, (float)index / numFrames, deltaVertices, deltaNormals, null); + mesh.AddBlendShapeFrame(animName, (float)index / numPoses, deltaVertices, deltaNormals, null); } } } diff --git a/Assets/Scripts/Modules/RenderModule.cs b/Assets/Scripts/Modules/RenderModule.cs index aff010c..6d33350 100644 --- a/Assets/Scripts/Modules/RenderModule.cs +++ b/Assets/Scripts/Modules/RenderModule.cs @@ -48,7 +48,7 @@ public partial class RenderModule aliasModel.Animate(0, out Mesh mesh, out float blendWeight); - if (header.numFrames > 1) + if (header.numPoses > 1) { var mr = go.AddComponent(); mr.material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));