Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa543bdb authored by Mike Schneider's avatar Mike Schneider Committed by Android (Google) Code Review
Browse files

Merge "Fix wrong initial velocity while animating a discontinuity." into main

parents ed20edd6 4687fafa
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -359,14 +359,8 @@ private class ObservableComputations(
                // same time not already applying the `last*` state (as this would cause a
                // re-computation if the current state is being read before the next frame).
                if (isAnimatingUninterrupted) {
                    val currentDirectMapped = currentDirectMapped
                    val lastDirectMapped =
                        lastSegment.mapping.map(lastInput) - lastAnimation.targetValue

                    val frameDuration =
                        (currentAnimationTimeNanos - lastFrameTimeNanos) / 1_000_000_000.0
                    val staticDelta = (currentDirectMapped - lastDirectMapped)
                    directMappedVelocity = (staticDelta / frameDuration).toFloat()
                    directMappedVelocity =
                        computeDirectMappedVelocity(currentAnimationTimeNanos - lastFrameTimeNanos)
                } else {
                    directMappedVelocity = 0f
                }
+2 −5
Original line number Diff line number Diff line
@@ -76,10 +76,10 @@ internal constructor(
        get() = segment.key

    val output: Float
        get() = currentDirectMapped + (animation.targetValue + springState.displacement)
        get() = segment.mapping.map(input) + springState.displacement

    val outputTarget: Float
        get() = currentDirectMapped + animation.targetValue
        get() = segment.mapping.map(input)

    fun <T> semantic(semanticKey: SemanticKey<T>): T? {
        return segment.semantic(semanticKey)
@@ -87,7 +87,4 @@ internal constructor(

    val semantics: List<SemanticValue<*>>
        get() = with(segment) { spec.semantics(key) }

    private val currentDirectMapped: Float
        get() = segment.mapping.map(input) - animation.targetValue
}
+25 −27
Original line number Diff line number Diff line
@@ -125,41 +125,24 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static

    val isSameSegmentAndAtRest: Boolean
        get() =
            lastAnimation.isAtRest &&
            lastSpringState == SpringState.AtRest &&
                lastSegment.spec == spec &&
                lastSegment.isValidForInput(currentInput, currentDirection)

    val currentDirectMapped: Float
        get() =
            if (isSameSegmentAndAtRest) {
                lastSegment.mapping.map(currentInput)
            } else {
                val values = currentComputedValues
                values.segment.mapping.map(currentInput) - values.animation.targetValue
            }

    private val currentAnimatedDelta: Float
        get() =
            if (isSameSegmentAndAtRest) {
                0f
            } else {
                currentComputedValues.animation.targetValue + currentSpringState.displacement
            }

    val output: Float
        get() =
            if (isSameSegmentAndAtRest) {
                lastSegment.mapping.map(currentInput)
            } else {
                currentDirectMapped + currentAnimatedDelta
                outputTarget + currentSpringState.displacement
            }

    val outputTarget: Float
        get() =
            if (isSameSegmentAndAtRest) {
                lastAnimation.targetValue
                lastSegment.mapping.map(currentInput)
            } else {
                currentDirectMapped + currentComputedValues.animation.targetValue
                currentComputedValues.segment.mapping.map(currentInput)
            }

    val isStable: Boolean
@@ -176,6 +159,24 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
        }
    }

    fun computeDirectMappedVelocity(frameDurationNanos: Long): Float {
        val directMappedDelta =
            if (
                lastSegment.spec == spec &&
                    lastSegment.isValidForInput(currentInput, currentDirection)
            ) {
                lastSegment.mapping.map(currentInput) - lastSegment.mapping.map(lastInput)
            } else {
                val springChange = currentSpringState.displacement - lastSpringState.displacement

                currentComputedValues.segment.mapping.map(currentInput) -
                    lastSegment.mapping.map(lastInput) + springChange
            }

        val frameDuration = frameDurationNanos / 1_000_000_000.0
        return (directMappedDelta / frameDuration).toFloat()
    }

    /**
     * The current segment, which defines the [Mapping] function used to transform the input to the
     * output.
@@ -357,9 +358,9 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
    ): DiscontinuityAnimation {
        return when (segmentChange) {
            SegmentChangeType.Same -> {
                if (lastAnimation.isAtRest) {
                if (lastSpringState == SpringState.AtRest) {
                    // Nothing to update if no animation is ongoing
                    lastAnimation
                    DiscontinuityAnimation.None
                } else if (lastGuaranteeState == guarantee) {
                    // Nothing to update if the spring must not be tightened.
                    lastAnimation
@@ -409,7 +410,6 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static

                    val newTarget = delta - lastSpringState.displacement
                    DiscontinuityAnimation(
                        newTarget,
                        SpringState(-newTarget, lastSpringState.velocity + directMappedVelocity),
                        springParameters,
                        lastFrameTimeNanos,
@@ -434,7 +434,6 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                    var lastAnimationTime = lastFrameTimeNanos
                    var guaranteeState = lastGuaranteeState
                    var springState = lastSpringState
                    var springTarget = lastAnimation.targetValue
                    var springParameters = lastAnimation.springParameters

                    var segmentIndex = sourceIndex
@@ -507,7 +506,6 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                        }

                        if (deltaIsFinite) {
                            springTarget += delta
                            springState = springState.nudge(displacementDelta = -delta)
                        }
                        segmentIndex += directionOffset
@@ -536,7 +534,7 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static

                    val tightened = guarantee.updatedSpringParameters(segment.entryBreakpoint)

                    DiscontinuityAnimation(springTarget, springState, tightened, lastAnimationTime)
                    DiscontinuityAnimation(springState, tightened, lastAnimationTime)
                }
            }
        }
+0 −2
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import com.android.mechanics.spring.SpringState
 * output values for the same input.
 */
internal data class DiscontinuityAnimation(
    val targetValue: Float,
    val springStartState: SpringState,
    val springParameters: SpringParameters,
    val springStartTimeNanos: Long,
@@ -37,7 +36,6 @@ internal data class DiscontinuityAnimation(
    companion object {
        val None =
            DiscontinuityAnimation(
                targetValue = 0f,
                springStartState = SpringState.AtRest,
                springParameters = SpringParameters.Snap,
                springStartTimeNanos = 0L,
+2 −6
Original line number Diff line number Diff line
@@ -290,12 +290,8 @@ private class ImperativeComputations(

        // Prepare last* state
        if (isAnimatingUninterrupted) {
            val currentDirectMapped = currentDirectMapped
            val lastDirectMapped = lastSegment.mapping.map(lastInput) - lastAnimation.targetValue

            val frameDuration = (currentAnimationTimeNanos - lastFrameTimeNanos) / 1_000_000_000.0
            val staticDelta = (currentDirectMapped - lastDirectMapped)
            directMappedVelocity = (staticDelta / frameDuration).toFloat()
            directMappedVelocity =
                computeDirectMappedVelocity(currentAnimationTimeNanos - lastFrameTimeNanos)
        } else {
            directMappedVelocity = 0f
        }
Loading