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
public ulong AnimationPointer { get; set; }
public float Unknown_58h { get; set; }
public float Unknown_5Ch { get; set; }
public float Unknown_60h { get; set; }
public float StartTime { get; set; } //start time
public float EndTime { get; set; } //end time
public float Rate { get; set; } //1.0 rate..?
public uint Unknown_64h { get; set; } // 0x00000000
public uint Unknown_68h { get; set; } // 0x00000000
public uint Unknown_6Ch { get; set; } // 0x00000000
@ -1382,9 +1382,9 @@ namespace CodeWalker.GameFiles
{
base.Read(reader, parameters);
this.AnimationPointer = reader.ReadUInt64();
this.Unknown_58h = reader.ReadSingle();
this.Unknown_5Ch = reader.ReadSingle();
this.Unknown_60h = reader.ReadSingle();
this.StartTime = reader.ReadSingle();
this.EndTime = reader.ReadSingle();
this.Rate = reader.ReadSingle();
this.Unknown_64h = reader.ReadUInt32();
this.Unknown_68h = reader.ReadUInt32();
this.Unknown_6Ch = reader.ReadUInt32();
@ -1401,9 +1401,9 @@ namespace CodeWalker.GameFiles
this.AnimationPointer = (ulong)(this.Animation != null ? this.Animation.FilePosition : 0);
writer.Write(this.AnimationPointer);
writer.Write(this.Unknown_58h);
writer.Write(this.Unknown_5Ch);
writer.Write(this.Unknown_60h);
writer.Write(this.StartTime);
writer.Write(this.EndTime);
writer.Write(this.Rate);
writer.Write(this.Unknown_64h);
writer.Write(this.Unknown_68h);
writer.Write(this.Unknown_6Ch);
@ -1416,6 +1416,14 @@ namespace CodeWalker.GameFiles
if (Animation != null) list.Add(Animation);
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
{
@ -1532,6 +1540,15 @@ namespace CodeWalker.GameFiles
if (Animation != null) list.Add(Animation);
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)
{
if (cme.Next != null)
{
UpdateAnim(cme.Next);
}
var clipanim = cme.Clip as ClipAnimation;
var anim = clipanim?.Animation;
if (anim != null)
{
UpdateAnim(anim);
UpdateAnim(anim, clipanim.GetPlaybackTime(CurrentAnimTime));
}
var clipanimlist = cme.Clip as ClipAnimationList;
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)
{ return; }
@ -449,7 +445,7 @@ namespace CodeWalker.Rendering
var frames = anim.Frames;
var nframes = (ignoreLastFrame) ? (frames - 1) : frames;
var curPos = ((CurrentAnimTime % duration) / duration) * nframes;
var curPos = (t/duration) * nframes;
var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1) % frames;
var falpha = (float)(curPos - Math.Floor(curPos));
@ -543,13 +539,30 @@ namespace CodeWalker.Rendering
}
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 anim = clipanim?.Animation;
var clipanim = cme.Clip as ClipAnimation;
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)
{ return; }
if (anim.BoneIds?.data_items == null)
@ -564,7 +577,7 @@ namespace CodeWalker.Rendering
var frames = anim.Frames;
var nframes = (ignoreLastFrame) ? (frames - 1) : frames;
var curPos = ((CurrentAnimTime % duration) / duration) * nframes;
var curPos = (t / duration) * nframes;
var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1) % frames;
var falpha = (float)(curPos - Math.Floor(curPos));