@@ -25,6 +25,7 @@ import io.github.sceneview.model.lightEntities
25
25
import io.github.sceneview.model.model
26
26
import io.github.sceneview.model.renderableEntities
27
27
import io.github.sceneview.utils.intervalSeconds
28
+ import kotlin.math.abs
28
29
29
30
/* *
30
31
* Create the ModelNode from a loaded model instance.
@@ -110,7 +111,11 @@ open class ModelNode(
110
111
override var name = super <ChildNode >.name
111
112
}
112
113
113
- data class PlayingAnimation (val startTime : Long = System .nanoTime(), val loop : Boolean = true )
114
+ data class PlayingAnimation (
115
+ val startTime : Long = System .nanoTime(),
116
+ var speed : Float = 1f ,
117
+ val loop : Boolean = true
118
+ )
114
119
115
120
val renderableNodes = modelInstance.renderableEntities.map {
116
121
RenderableNode (modelInstance, it)
@@ -233,21 +238,46 @@ open class ModelNode(
233
238
* animation definition. Uses `TransformManager`.
234
239
*
235
240
* @param animationIndex Zero-based index for the `animation` of interest.
241
+ * @param speed The rate at which the `animation` plays. Reverses the `animation` if negative.
242
+ * Pauses the `animation` if zero.
243
+ * @param loop Specifies if the `animation` should repeat forever.
236
244
*
237
245
* @see Animator.getAnimationCount
238
246
*/
239
- fun playAnimation (animationIndex : Int , loop : Boolean = true) {
247
+ fun playAnimation (animationIndex : Int , speed : Float = 1f, loop : Boolean = true) {
240
248
if (animationIndex < animationCount) {
241
- playingAnimations[animationIndex] = PlayingAnimation (loop = loop)
249
+ playingAnimations[animationIndex] = PlayingAnimation (speed = speed, loop = loop)
242
250
}
243
251
}
244
252
245
253
/* *
246
254
* @see playAnimation
247
255
* @see Animator.getAnimationName
248
256
*/
249
- fun playAnimation (animationName : String , loop : Boolean = true) {
250
- animator.getAnimationIndex(animationName)?.let { playAnimation(it, loop) }
257
+ fun playAnimation (animationName : String , speed : Float = 1f, loop : Boolean = true) {
258
+ animator.getAnimationIndex(animationName)?.let { playAnimation(it, speed, loop) }
259
+ }
260
+
261
+ /* *
262
+ * Sets the rate at which the `animation` is played.
263
+ *
264
+ * @param animationIndex Zero-based index for the `animation` of interest.
265
+ * @param speed The rate at which the `animation` plays. Reverses the `animation` if negative.
266
+ * Pauses the `animation` if zero.
267
+ * @see playAnimation
268
+ */
269
+ fun setAnimationSpeed (animationIndex : Int , speed : Float ) {
270
+ if (animationIndex < animationCount) {
271
+ playingAnimations[animationIndex]?.speed = speed
272
+ }
273
+ }
274
+
275
+ /* *
276
+ * @see setAnimationSpeed
277
+ * @see Animator.getAnimationName
278
+ */
279
+ fun setAnimationSpeed (animationName : String , speed : Float ) {
280
+ animator.getAnimationIndex(animationName)?.let { setAnimationSpeed(it, speed) }
251
281
}
252
282
253
283
fun stopAnimation (animationIndex : Int ) {
@@ -383,18 +413,31 @@ open class ModelNode(
383
413
super .onFrame(frameTimeNanos)
384
414
385
415
model.popRenderable()
416
+ applyAnimations(frameTimeNanos)
417
+ animator.updateBoneMatrices()
418
+ }
386
419
420
+ private fun applyAnimations (frameTimeNanos : Long ) {
387
421
playingAnimations.forEach { (index, animation) ->
422
+ if (animation.speed == 0f ) return @forEach
423
+
388
424
animator.let { animator ->
389
425
val elapsedTimeSeconds = frameTimeNanos.intervalSeconds(animation.startTime)
390
- animator.applyAnimation(index, elapsedTimeSeconds.toFloat())
426
+ val adjustedTimeSeconds = elapsedTimeSeconds.toFloat() * abs(animation.speed)
427
+ val animationDuration = animator.getAnimationDuration(index)
428
+ val animationTime: Float = if (animation.speed > 0 ) {
429
+ adjustedTimeSeconds
430
+ } else {
431
+ animationDuration - adjustedTimeSeconds
432
+ }
391
433
392
- if (! animation.loop && elapsedTimeSeconds >= animator.getAnimationDuration(index)) {
434
+ animator.applyAnimation(index, animationTime)
435
+
436
+ if (! animation.loop && adjustedTimeSeconds >= animationDuration) {
393
437
playingAnimations.remove(index)
394
438
}
395
439
}
396
440
}
397
- animator.updateBoneMatrices()
398
441
}
399
442
}
400
443
0 commit comments