Odin icon indicating copy to clipboard operation
Odin copied to clipboard

Wrong progressing of flux tween when dt budget has been consumed by delay

Open gordonshamway23 opened this issue 3 months ago • 0 comments

The following line in math/ease/ease.odin

tween.progress += tween.rate * (dt + delay_remainder)

(https://github.com/odin-lang/Odin/blame/09d7f1337bd8ddccc6b058c3f5752f6365beb31b/core/math/ease/ease.odin#L482)

is wrong in my opinion.

If delay_remainder is negative, dt has been consumed by the delay already. Whats left is just -delay_remainder.

Correct would be:

if delay_remainder<0 do tween.progress += tween.rate * -delay_remainder
else do tween.progress += tween.rate * dt

Alternatively I would rewrite the flux_update procedure as follows:

// update all tweens, wait for their delay if one exists
// calls callbacks in all stages, when they're filled
// deletes tween from the map after completion
flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float(T) {
	clear(&flux.keys_to_be_deleted)

	for key, &tween in flux.values {

		// Update delay if necessary.
		if tween.delay > 0 {
			tween.delay -= dt

			if tween.delay < 0 {
				// We finished the delay, but in doing so consumed part of this frame's `dt` budget.
				// Correct dt to what's left.
				dt = -tween.delay // NEW
				// We're done with this delay.
				tween.delay = 0
			}
		}

		// We either had no delay, or the delay has been consumed.
		if tween.delay <= 0 {
			if !tween.inited {
				flux_tween_init(&tween, tween.duration)
				
				if tween.on_start != nil {
					tween.on_start(flux, tween.data)
				}
			} 

			// NEW
			tween.progress += tween.rate * dt
			x := tween.progress >= 1 ? 1 : ease(tween.type, tween.progress)
			
                        // .... remaining skipped
		}
	}
	
	// .... remaining skipped
}

Are there any opinions on that?

Have a nice day.

gordonshamway23 avatar Mar 24 '24 09:03 gordonshamway23