44using CUE4Parse_Conversion . Animations . PSA ;
55using CUE4Parse . UE4 . Assets . Exports . Animation ;
66using CUE4Parse . UE4 . Objects . Core . Math ;
7+ using CUE4Parse . Utils ;
78using FModel . Views . Snooper . Buffers ;
89using OpenTK . Graphics . OpenGL4 ;
910using Serilog ;
@@ -74,7 +75,6 @@ public void Animate(CAnimSet anim, bool rotationOnly)
7475 var skeletonBoneIndex = bone . SkeletonIndex ;
7576 if ( sequence . OriginalSequence . FindTrackForBoneIndex ( skeletonBoneIndex ) < 0 )
7677 {
77- bone . IsAnimated |= false ;
7878 for ( int frame = 0 ; frame < _animatedBonesTransform [ s ] [ bone . Index ] . Length ; frame ++ )
7979 {
8080 _animatedBonesTransform [ s ] [ bone . Index ] [ frame ] = new Transform
@@ -86,7 +86,7 @@ public void Animate(CAnimSet anim, bool rotationOnly)
8686 }
8787 else
8888 {
89- bone . IsAnimated |= true ;
89+ bone . AnimatedBySequences . Add ( s ) ;
9090 for ( int frame = 0 ; frame < _animatedBonesTransform [ s ] [ bone . Index ] . Length ; frame ++ )
9191 {
9292 var boneOrientation = bone . Rest . Rotation ;
@@ -173,7 +173,6 @@ private void MapSkeleton(CAnimSet anim)
173173 continue ;
174174
175175 bone . SkeletonIndex = boneIndex ;
176- bone . IsAnimated = false ;
177176 }
178177
179178#if DEBUG
@@ -192,7 +191,7 @@ public void ResetAnimatedData(bool full = false)
192191 foreach ( var bone in BonesByLoweredName . Values )
193192 {
194193 bone . SkeletonIndex = - 1 ;
195- bone . IsAnimated = false ;
194+ bone . AnimatedBySequences . Clear ( ) ;
196195 }
197196
198197 if ( ! full ) return ;
@@ -208,22 +207,59 @@ public void Setup()
208207 _ssbo . UpdateRange ( BoneCount , Matrix4x4 . Identity ) ;
209208 }
210209
211- public void UpdateAnimationMatrices ( int currentSequence , int frameInSequence , int nextFrameInSequence , float lerp )
210+ public void UpdateAnimationMatrices ( Animation animation )
212211 {
213212 if ( ! IsAnimated ) return ;
214213
215214 _ssbo . Bind ( ) ;
216- for ( int boneIndex = 0 ; boneIndex < BoneCount ; boneIndex ++ )
215+
216+ foreach ( var bone in BonesByLoweredName . Values )
217217 {
218+ var ( s , f ) = GetBoneFrameData ( bone , animation ) ;
219+ var frameInSequence = Math . Min ( f . FloorToInt ( ) , animation . Sequences [ s ] . EndFrame ) ;
220+ var nextFrameInSequence = Math . Min ( frameInSequence + 1 , animation . Sequences [ s ] . EndFrame ) ;
221+ var lerpAmount = Math . Clamp ( f - frameInSequence , 0 , 1 ) ;
222+
223+ var boneIndex = bone . Index ;
218224 var matrix = Matrix4x4 . Lerp (
219- _animatedBonesTransform [ currentSequence ] [ boneIndex ] [ frameInSequence ] . Matrix ,
220- _animatedBonesTransform [ currentSequence ] [ boneIndex ] [ nextFrameInSequence ] . Matrix ,
221- lerp ) ;
225+ _animatedBonesTransform [ s ] [ boneIndex ] [ frameInSequence ] . Matrix ,
226+ _animatedBonesTransform [ s ] [ boneIndex ] [ nextFrameInSequence ] . Matrix ,
227+ lerpAmount ) ;
222228 _ssbo . Update ( boneIndex , _invertedBonesMatrix [ boneIndex ] * matrix ) ;
223229 }
230+
224231 _ssbo . Unbind ( ) ;
225232 }
226233
234+ private ( int , float ) GetBoneFrameData ( Bone bone , Animation animation )
235+ {
236+ int s = - 1 ;
237+ float f = 0.0f ;
238+
239+ void Get ( Bone b )
240+ {
241+ foreach ( var i in b . AnimatedBySequences )
242+ {
243+ s = i ;
244+ if ( animation . Framing . TryGetValue ( s , out f ) )
245+ break ;
246+ }
247+ }
248+
249+ Get ( bone ) ;
250+ if ( s == - 1 )
251+ {
252+ var parent = BonesByLoweredName [ bone . LoweredParentName ] ;
253+ while ( ! parent . IsAnimated )
254+ {
255+ parent = BonesByLoweredName [ parent . LoweredParentName ] ;
256+ }
257+ Get ( parent ) ;
258+ }
259+
260+ return ( s , f ) ;
261+ }
262+
227263 public Matrix4x4 GetBoneMatrix ( Bone bone ) => IsAnimated ? bone . Rest . Matrix * _ssbo . Get ( bone . Index ) : bone . Rest . Matrix ;
228264
229265 public void Render ( )
0 commit comments