@@ -717,17 +717,33 @@ function UVOL2Reactor() {
717717 component . canPlay . set ( true )
718718 } , [ volumetric . paused ] )
719719
720- const getAttribute = ( name : string , target : string , index : number ) => {
721- const key = createKey ( target , index )
720+ const getFrame = ( currentTime : number , frameRate : number , integer = true ) => {
721+ const frame = currentTime * frameRate
722+ return integer ? Math . round ( frame ) : frame
723+ }
724+
725+ const getAttribute = ( name : 'keyframeA' | 'keyframeB' , currentTime : number ) => {
726+ const currentGeometryTarget = component . geometryTarget . value
727+ let index = getFrame ( currentTime , manifest . current . geometry . targets [ currentGeometryTarget ] . frameRate , false )
728+ if ( name === 'keyframeA' ) {
729+ index = Math . floor ( index )
730+ } else {
731+ index = Math . ceil ( index )
732+ }
733+ const key = createKey ( currentGeometryTarget , index )
722734 if ( ! geometryBuffer . has ( key ) ) {
723- const frameRate = manifest . current . geometry . targets [ target ] . frameRate
724735 const targets = Object . keys ( manifest . current . geometry . targets )
725736
726737 for ( let i = 0 ; i < targets . length ; i ++ ) {
727738 const _target = targets [ i ]
728739 const _targetData = manifest . current . geometry . targets [ _target ]
729- const _frameRate = _targetData . frameRate
730- const _index = Math . round ( ( index * _frameRate ) / frameRate )
740+ let _index = getFrame ( currentTime , _targetData . frameRate , false )
741+ if ( name === 'keyframeA' ) {
742+ _index = Math . floor ( _index )
743+ } else {
744+ _index = Math . ceil ( _index )
745+ }
746+
731747 if ( geometryBuffer . has ( createKey ( _target , _index ) ) ) {
732748 const attribute = geometryBuffer . get ( createKey ( _target , _index ) ) ! as InterleavedBufferAttribute
733749 return attribute
@@ -842,16 +858,15 @@ function UVOL2Reactor() {
842858 }
843859 }
844860
845- const setTexture = ( target : string , index : number ) => {
861+ const setTexture = ( target : string , index : number , currentTime : number ) => {
846862 const key = createKey ( target , index )
847863 if ( ! textureBuffer . has ( key ) ) {
848864 const targets = Object . keys ( manifest . current . texture . baseColor . targets )
849- const frameRate = manifest . current . texture . baseColor . targets [ target ] . frameRate
850865 for ( let i = 0 ; i < targets . length ; i ++ ) {
851866 const _frameRate = manifest . current . texture . baseColor . targets [ targets [ i ] ] . frameRate
852- const _index = Math . round ( ( index * _frameRate ) / frameRate )
867+ const _index = getFrame ( currentTime , _frameRate )
853868 if ( textureBuffer . has ( createKey ( targets [ i ] , _index ) ) ) {
854- setTexture ( targets [ i ] , _index )
869+ setTexture ( targets [ i ] , _index , currentTime )
855870 return
856871 }
857872 }
@@ -890,14 +905,8 @@ function UVOL2Reactor() {
890905 }
891906
892907 const updateUniformSolve = ( currentTime : number ) => {
893- const geometryTarget = component . geometryTarget . value
894- const geometryFrame = currentTime * manifest . current . geometry . targets [ geometryTarget ] . frameRate
895- const keyframeAIndex = Math . floor ( geometryFrame )
896- const keyframeBIndex = Math . ceil ( geometryFrame )
897- let mixRatio = geometryFrame - keyframeAIndex
898-
899- const keyframeA = getAttribute ( 'position' , geometryTarget , keyframeAIndex )
900- const keyframeB = getAttribute ( 'position' , geometryTarget , keyframeBIndex )
908+ const keyframeA = getAttribute ( 'keyframeA' , currentTime )
909+ const keyframeB = getAttribute ( 'keyframeB' , currentTime )
901910
902911 if ( ! keyframeA && ! keyframeB ) {
903912 return
@@ -910,14 +919,17 @@ function UVOL2Reactor() {
910919 ; ( mesh . material as ShaderMaterial ) . uniforms . mixRatio . value = 0
911920 return
912921 } else if ( keyframeA && keyframeB ) {
922+ const keyframeAIndex = parseInt ( keyframeA . name . slice ( - KEY_PADDING ) )
913923 const keyframeATarget = keyframeA . name . slice ( 0 , - KEY_PADDING )
924+ const keyframeATime = keyframeAIndex / manifest . current . geometry . targets [ keyframeATarget ] . frameRate
925+
926+ const keyframeBIndex = parseInt ( keyframeB . name . slice ( - KEY_PADDING ) )
914927 const keyframeBTarget = keyframeB . name . slice ( 0 , - KEY_PADDING )
915- if ( keyframeATarget === keyframeBTarget && keyframeATarget !== geometryTarget ) {
916- // If both keyframes are of different target, update the mixRatio
917- const _geometryFrame = currentTime * manifest . current . geometry . targets [ keyframeATarget ] . frameRate
918- const _keyframeAIndex = Math . floor ( _geometryFrame )
919- mixRatio = _geometryFrame - _keyframeAIndex
920- }
928+ const keyframeBTime = keyframeBIndex / manifest . current . geometry . targets [ keyframeBTarget ] . frameRate
929+
930+ const d1 = Math . abs ( currentTime - keyframeATime )
931+ const d2 = Math . abs ( currentTime - keyframeBTime )
932+ const mixRatio = d1 + d2 > 0 ? d1 / ( d1 + d2 ) : 0.5
921933 setAttribute ( 'keyframeA' , keyframeA )
922934 setAttribute ( 'keyframeB' , keyframeB )
923935 ; ( mesh . material as ShaderMaterial ) . uniforms . mixRatio . value = mixRatio
@@ -941,7 +953,7 @@ function UVOL2Reactor() {
941953 const updateTexture = ( currentTime : number ) => {
942954 const textureTarget = component . textureTarget . value
943955 const textureFrame = Math . round ( currentTime * manifest . current . texture . baseColor . targets [ textureTarget ] . frameRate )
944- setTexture ( textureTarget , textureFrame )
956+ setTexture ( textureTarget , textureFrame , currentTime )
945957 }
946958
947959 const update = ( ) => {
0 commit comments