Animation playback improvements

This commit is contained in:
dexy 2019-11-08 02:00:16 +11:00
parent 465b21d7ac
commit ef497b1f6d
2 changed files with 60 additions and 30 deletions

View File

@ -1368,9 +1368,9 @@ namespace CodeWalker.GameFiles
// structure data // structure data
public ulong AnimationPointer { get; set; } public ulong AnimationPointer { get; set; }
public float Unknown_58h { get; set; } public float StartTime { get; set; } //start time
public float Unknown_5Ch { get; set; } public float EndTime { get; set; } //end time
public float Unknown_60h { get; set; } public float Rate { get; set; } //1.0 rate..?
public uint Unknown_64h { get; set; } // 0x00000000 public uint Unknown_64h { get; set; } // 0x00000000
public uint Unknown_68h { get; set; } // 0x00000000 public uint Unknown_68h { get; set; } // 0x00000000
public uint Unknown_6Ch { get; set; } // 0x00000000 public uint Unknown_6Ch { get; set; } // 0x00000000
@ -1382,9 +1382,9 @@ namespace CodeWalker.GameFiles
{ {
base.Read(reader, parameters); base.Read(reader, parameters);
this.AnimationPointer = reader.ReadUInt64(); this.AnimationPointer = reader.ReadUInt64();
this.Unknown_58h = reader.ReadSingle(); this.StartTime = reader.ReadSingle();
this.Unknown_5Ch = reader.ReadSingle(); this.EndTime = reader.ReadSingle();
this.Unknown_60h = reader.ReadSingle(); this.Rate = reader.ReadSingle();
this.Unknown_64h = reader.ReadUInt32(); this.Unknown_64h = reader.ReadUInt32();
this.Unknown_68h = reader.ReadUInt32(); this.Unknown_68h = reader.ReadUInt32();
this.Unknown_6Ch = reader.ReadUInt32(); this.Unknown_6Ch = reader.ReadUInt32();
@ -1401,9 +1401,9 @@ namespace CodeWalker.GameFiles
this.AnimationPointer = (ulong)(this.Animation != null ? this.Animation.FilePosition : 0); this.AnimationPointer = (ulong)(this.Animation != null ? this.Animation.FilePosition : 0);
writer.Write(this.AnimationPointer); writer.Write(this.AnimationPointer);
writer.Write(this.Unknown_58h); writer.Write(this.StartTime);
writer.Write(this.Unknown_5Ch); writer.Write(this.EndTime);
writer.Write(this.Unknown_60h); writer.Write(this.Rate);
writer.Write(this.Unknown_64h); writer.Write(this.Unknown_64h);
writer.Write(this.Unknown_68h); writer.Write(this.Unknown_68h);
writer.Write(this.Unknown_6Ch); writer.Write(this.Unknown_6Ch);
@ -1416,6 +1416,14 @@ namespace CodeWalker.GameFiles
if (Animation != null) list.Add(Animation); if (Animation != null) list.Add(Animation);
return list.ToArray(); return list.ToArray();
} }
public float GetPlaybackTime(double currentTime)
{
double scaledTime = currentTime * Rate;
double duration = EndTime - StartTime;
double curpos = scaledTime % duration;
return StartTime + (float)curpos;
}
} }
[TypeConverter(typeof(ExpandableObjectConverter))] public class ClipAnimationList : ClipBase [TypeConverter(typeof(ExpandableObjectConverter))] public class ClipAnimationList : ClipBase
{ {
@ -1532,6 +1540,15 @@ namespace CodeWalker.GameFiles
if (Animation != null) list.Add(Animation); if (Animation != null) list.Add(Animation);
return list.ToArray(); return list.ToArray();
} }
public float GetPlaybackTime(double currentTime)
{
double scaledTime = currentTime * Rate;
double duration = EndTime - StartTime;
double curpos = scaledTime % duration;
return StartTime + (float)curpos;
}
} }

View File

@ -403,37 +403,33 @@ namespace CodeWalker.Rendering
} }
} }
} }
private void UpdateAnim(ClipMapEntry cme) private void UpdateAnim(ClipMapEntry cme)
{ {
if (cme.Next != null)
{
UpdateAnim(cme.Next);
}
var clipanim = cme.Clip as ClipAnimation; var clipanim = cme.Clip as ClipAnimation;
var anim = clipanim?.Animation; var anim = clipanim?.Animation;
if (anim != null) if (anim != null)
{ {
UpdateAnim(anim); UpdateAnim(anim, clipanim.GetPlaybackTime(CurrentAnimTime));
} }
var clipanimlist = cme.Clip as ClipAnimationList; var clipanimlist = cme.Clip as ClipAnimationList;
if (clipanimlist?.Animations != null) if (clipanimlist?.Animations != null)
{ {
if (clipanimlist.Animations.Count > 0) foreach (var canim in clipanimlist.Animations)
{ {
UpdateAnim(clipanimlist.Animations[0].Animation); if (canim?.Animation == null) continue;
UpdateAnim(canim.Animation, canim.GetPlaybackTime(CurrentAnimTime));
} }
////needs more work to synchronise these... seems to be multi layers, but timings are different
////sort of represents animations LODs, higher detail stuff like fingers and feet movements in the layers
//foreach (var canim in clipanimlist.Animations)
//{
// if (canim?.Animation == null) continue;
// UpdateAnim(canim.Animation);
// //break;
//}
} }
} }
private void UpdateAnim(Animation anim) private void UpdateAnim(Animation anim, float t)
{ {
if (anim == null) if (anim == null)
{ return; } { return; }
@ -449,7 +445,7 @@ namespace CodeWalker.Rendering
var frames = anim.Frames; var frames = anim.Frames;
var nframes = (ignoreLastFrame) ? (frames - 1) : frames; var nframes = (ignoreLastFrame) ? (frames - 1) : frames;
var curPos = ((CurrentAnimTime % duration) / duration) * nframes; var curPos = (t/duration) * nframes;
var frame0 = ((ushort)curPos) % frames; var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1) % frames; var frame1 = (frame0 + 1) % frames;
var falpha = (float)(curPos - Math.Floor(curPos)); var falpha = (float)(curPos - Math.Floor(curPos));
@ -543,13 +539,30 @@ namespace CodeWalker.Rendering
} }
private void UpdateAnimUV(ClipMapEntry cme, RenderableGeometry rgeom = null) private void UpdateAnimUV(ClipMapEntry cme, RenderableGeometry rgeom = null)
{ {
if (cme.Next != null) //is this a "chain" of clips to play..? if (cme.Next != null)
{ {
//cme = cme.Next; UpdateAnimUV(cme.Next, rgeom);
} }
var clipanim = cme.Clip as ClipAnimation;//maybe ClipAnimationList? var clipanim = cme.Clip as ClipAnimation;
var anim = clipanim?.Animation; if (clipanim?.Animation != null)
{
UpdateAnimUV(clipanim.Animation, clipanim.GetPlaybackTime(CurrentAnimTime), rgeom);
}
var clipanimlist = cme.Clip as ClipAnimationList;
if (clipanimlist?.Animations != null)
{
foreach (var canim in clipanimlist.Animations)
{
if (canim?.Animation == null) continue;
UpdateAnimUV(canim.Animation, canim.GetPlaybackTime(CurrentAnimTime), rgeom);
}
}
}
private void UpdateAnimUV(Animation anim, float t, RenderableGeometry rgeom = null)
{
if (anim == null) if (anim == null)
{ return; } { return; }
if (anim.BoneIds?.data_items == null) if (anim.BoneIds?.data_items == null)
@ -564,7 +577,7 @@ namespace CodeWalker.Rendering
var frames = anim.Frames; var frames = anim.Frames;
var nframes = (ignoreLastFrame) ? (frames - 1) : frames; var nframes = (ignoreLastFrame) ? (frames - 1) : frames;
var curPos = ((CurrentAnimTime % duration) / duration) * nframes; var curPos = (t / duration) * nframes;
var frame0 = ((ushort)curPos) % frames; var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1) % frames; var frame1 = (frame0 + 1) % frames;
var falpha = (float)(curPos - Math.Floor(curPos)); var falpha = (float)(curPos - Math.Floor(curPos));