Convert 16.16 fixed point curve export to fractional x/128 export
parent
9e1014bbd9
commit
18f1e20aa1
|
@ -1,6 +1,4 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use fixed::FixedI32;
|
|
||||||
use fixed::types::extra::U16;
|
|
||||||
use flo_curves::*;
|
use flo_curves::*;
|
||||||
use flo_curves::{bezier, Coord2};
|
use flo_curves::{bezier, Coord2};
|
||||||
|
|
||||||
|
@ -14,20 +12,19 @@ easing function is cubic bezier going from 0.0 to 1.0
|
||||||
|
|
||||||
140-120=20 increments
|
140-120=20 increments
|
||||||
0.0 is +0 and 1.0 is +20
|
0.0 is +0 and 1.0 is +20
|
||||||
so e.g. if you read a 0.5 at the given increment it's 0.5 * 20 = +10
|
|
||||||
|
|
||||||
curves are exported from reskit sampled at 1/60 increments
|
console has no floating point and fixed point will overflow 16-bit
|
||||||
reskit accepts arguments for control points and exports 16.16 fixed point binary files
|
each curve tailored for use case. for camera motion:
|
||||||
so a 1 second animation is 60 increments, 2 seconds is 120, etc.
|
- generate the cubic bezier easing curve in my custom branch of reskit, converting 0.0-1.0 floating point spans to x/128 fractions equivalent to x/100 fractions.
|
||||||
|
literal grade school shit i realised i wasted a weekend re-deriving from first principles. these fparts even export as single bytes, so that's 3 less bytes per point
|
||||||
each iteration be like:
|
on the curve than if i were sticking with 16.16 fix. for a 1 second animation, 60 points are taken on the 0.0-1.0 curve, for a 2 second animation, 120 points are taken, etc.
|
||||||
1. take cubic bezier sample and post increment
|
equivalent PAL framerate curves can be export in the same curve file.
|
||||||
2. the value at this iteration is (final - beginning) * sample
|
- the camera animates moves by setting a new destination point and performing interpolation of intermediate positions along the curve - just like css easing functions, or
|
||||||
a. so example (140-120)*0.5 for a linear curve sampled right in the middle
|
unity/unreal bezier curves. you restrict camera new position to +/- powers of two in any axis to eliminate mul[s/u].w. e.g. camera moves +2, +4, +8.... in the x direction.
|
||||||
3. round the value to the nearest whole integer
|
- for each axis, new position - current position = span of movement. so if you're starting at x = 30 and moving to x = 46, you're going +16 in the x direction
|
||||||
4. do not go back to 1 if we exhausted the curve
|
- while the camera is animating, interpolate positions by reading the fractional on the curve for the current frame and doing fractional * span / 128. since new camera positions
|
||||||
|
in any axis are kept power of two this can all be done using asl/asr. take the remainder with the and 2^127 trick and bump the resulting value up 1 if the modulo is >= 64
|
||||||
need fixed point arithmetic multiplication
|
- ✨ cubic bezier animated camera motion
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,15 +45,20 @@ pub fn get_cubic_bezier( p0: (f64, f64), c0: (f64, f64), c1: (f64, f64), p1: (f6
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut current_jiffy = 0.0;
|
let mut current_jiffy = 0.0;
|
||||||
// (jiffies) of 16.16 fixed point integers: Each point in the curve at the given frame
|
// For each point in curve: 1 byte fractional point in the curve at the given frame
|
||||||
for i in 0..jiffies {
|
for i in 0..jiffies {
|
||||||
let point = curve.point_at_pos( current_jiffy );
|
let point = curve.point_at_pos( current_jiffy );
|
||||||
let x = point.1;
|
let x = point.1;
|
||||||
print_info( &format!( "at iteration {}, curve is {:?}, 16.16 format will be {}", i, point, x ) );
|
|
||||||
|
// Round and convert x to n/100 fraction, then equivalent n/128 fraction
|
||||||
|
let x = ( ( x * 100.0 ).round() / 100.0 ) * 100.0; // only get last two decimal places, then convert to whole number
|
||||||
|
let x = x * 128.0 / 100.0; // x / 100 = y / 128
|
||||||
|
let x = x.round() as u8;
|
||||||
|
|
||||||
|
print_info( &format!( "at iteration {}, curve is {:?}, fractional format will be {}", i, point, x ) );
|
||||||
current_jiffy += 1.0 / jiffies as f64;
|
current_jiffy += 1.0 / jiffies as f64;
|
||||||
|
|
||||||
let as_fixed = FixedI32::<U16>::from_num( x );
|
result.push( x );
|
||||||
result.extend( as_fixed.to_be_bytes() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok( result )
|
Ok( result )
|
||||||
|
|
Loading…
Reference in New Issue