Object movement calcuations showing pixel shifting on hardware

Occasionally, you might see an object being shifted by one pixel during a movement animation, especially when comparing the appearance within Altia Design vs. when viewing the animation on hardware after generating code using DeepScreen. This is an issue because of fixed point math. The Altia Design editor always uses floating point math, but many DeepScreen targets use fixed point math.

When you interpolate something, you calculate a percentage to move/scale something. The percentage is essentially
calculated by:

```
FLOAT percent = (FLOAT)((value - lowVal) / (highVal - lowVal));
```

*value = current event/state value
lowVal = lowest defined event/state value in the interpolation
highVal = highest defined event/state value in the interpolation*

Ultimately this percentage is multiplied by the delta in which an object translates.

---

With:

value = [0-100]
lowVal = 0;
highVal = 100;

We see the following using the standard Altia fixed point 1-17-14 format (1 sign bit, 17 bits before the decimal
point and 14 bits after the decimal point).

```
-------------------------
val : fixed (float)
-------------------------
0 : 0.000000 (0.000000)
1 : 0.009949 (0.010000)
2 : 0.019958 (0.020000)
3 : 0.029968 (0.030000)
4 : 0.039978 (0.040000)
5 : 0.049988 (0.050000)
6 : 0.059998 (0.060000)
7 : 0.069946 (0.070000)
8 : 0.079956 (0.080000)
9 : 0.089966 (0.090000)
10 : 0.099976 (0.100000)
11 : 0.109985 (0.110000)
12 : 0.119995 (0.120000)
13 : 0.129944 (0.130000)
14 : 0.139954 (0.140000)
15 : 0.149963 (0.150000)
16 : 0.159973 (0.160000)
17 : 0.169983 (0.170000)
18 : 0.179993 (0.180000)
19 : 0.189941 (0.190000)
20 : 0.199951 (0.200000)
21 : 0.209961 (0.210000)
22 : 0.219971 (0.220000)
23 : 0.229980 (0.230000)
24 : 0.239990 (0.240000)
25 : 0.250000 (0.250000)
26 : 0.259949 (0.260000)
27 : 0.269958 (0.270000)
28 : 0.279968 (0.280000)
29 : 0.289978 (0.290000)
30 : 0.299988 (0.300000)
31 : 0.309998 (0.310000)
32 : 0.319946 (0.320000)
33 : 0.329956 (0.330000)
34 : 0.339966 (0.340000)
35 : 0.349976 (0.350000)
36 : 0.359985 (0.360000)
37 : 0.369995 (0.370000)
38 : 0.379944 (0.380000)
39 : 0.389954 (0.390000)
40 : 0.399963 (0.400000)
41 : 0.409973 (0.410000)
42 : 0.419983 (0.420000)
43 : 0.429993 (0.430000)
44 : 0.439941 (0.440000)
45 : 0.449951 (0.450000)
46 : 0.459961 (0.460000)
47 : 0.469971 (0.470000)
48 : 0.479980 (0.480000)
49 : 0.489990 (0.490000)
50 : 0.500000 (0.500000)
51 : 0.509949 (0.510000)
52 : 0.519958 (0.520000)
53 : 0.529968 (0.530000)
54 : 0.539978 (0.540000)
55 : 0.549988 (0.550000)
56 : 0.559998 (0.560000)
57 : 0.569946 (0.570000)
58 : 0.579956 (0.580000)
59 : 0.589966 (0.590000)
60 : 0.599976 (0.600000)
61 : 0.609985 (0.610000)
62 : 0.619995 (0.620000)
63 : 0.629944 (0.630000)
64 : 0.639954 (0.640000)
65 : 0.649963 (0.650000)
66 : 0.659973 (0.660000)
67 : 0.669983 (0.670000)
68 : 0.679993 (0.680000)
69 : 0.689941 (0.690000)
70 : 0.699951 (0.700000)
71 : 0.709961 (0.710000)
72 : 0.719971 (0.720000)
73 : 0.729980 (0.730000)
74 : 0.739990 (0.740000)
75 : 0.750000 (0.750000)
76 : 0.759949 (0.760000)
77 : 0.769958 (0.770000)
78 : 0.779968 (0.780000)
79 : 0.789978 (0.790000)
80 : 0.799988 (0.800000)
81 : 0.809998 (0.810000)
82 : 0.819946 (0.820000)
83 : 0.829956 (0.830000)
84 : 0.839966 (0.840000)
85 : 0.849976 (0.850000)
86 : 0.859985 (0.860000)
87 : 0.869995 (0.870000)
88 : 0.879944 (0.880000)
89 : 0.889954 (0.890000)
90 : 0.899963 (0.900000)
91 : 0.909973 (0.910000)
92 : 0.919983 (0.920000)
93 : 0.929993 (0.930000)
94 : 0.939941 (0.940000)
95 : 0.949951 (0.950000)
96 : 0.959961 (0.960000)
97 : 0.969971 (0.970000)
98 : 0.979980 (0.980000)
99 : 0.989990 (0.990000)
100 : 1.000000 (1.000000)
```

Notice that the fixed point calculation doesn't exactly match the floating point calculation. It's impossible to match the floating point calculation unless you reserve 21 bits after the decimal point. This isn't practical because it only leaves 11 bits for the sign/value before the decimal point.

---

To get a closer match we are adding 16 to the fixed point percentage value (0.0009765625) in miniGL.

```
-------------------------
val : fixed (float)
-------------------------
0 : 0.000977 (0.000000)
1 : 0.010925 (0.010000)
2 : 0.020935 (0.020000)
3 : 0.030945 (0.030000)
4 : 0.040955 (0.040000)
5 : 0.050964 (0.050000)
6 : 0.060974 (0.060000)
7 : 0.070923 (0.070000)
8 : 0.080933 (0.080000)
9 : 0.090942 (0.090000)
10 : 0.100952 (0.100000)
11 : 0.110962 (0.110000)
12 : 0.120972 (0.120000)
13 : 0.130920 (0.130000)
14 : 0.140930 (0.140000)
15 : 0.150940 (0.150000)
16 : 0.160950 (0.160000)
17 : 0.170959 (0.170000)
18 : 0.180969 (0.180000)
19 : 0.190918 (0.190000)
20 : 0.200928 (0.200000)
21 : 0.210938 (0.210000)
22 : 0.220947 (0.220000)
23 : 0.230957 (0.230000)
24 : 0.240967 (0.240000)
25 : 0.250977 (0.250000)
26 : 0.260925 (0.260000)
27 : 0.270935 (0.270000)
28 : 0.280945 (0.280000)
29 : 0.290955 (0.290000)
30 : 0.300964 (0.300000)
31 : 0.310974 (0.310000)
32 : 0.320923 (0.320000)
33 : 0.330933 (0.330000)
34 : 0.340942 (0.340000)
35 : 0.350952 (0.350000)
36 : 0.360962 (0.360000)
37 : 0.370972 (0.370000)
38 : 0.380920 (0.380000)
39 : 0.390930 (0.390000)
40 : 0.400940 (0.400000)
41 : 0.410950 (0.410000)
42 : 0.420959 (0.420000)
43 : 0.430969 (0.430000)
44 : 0.440918 (0.440000)
45 : 0.450928 (0.450000)
46 : 0.460938 (0.460000)
47 : 0.470947 (0.470000)
48 : 0.480957 (0.480000)
49 : 0.490967 (0.490000)
50 : 0.500977 (0.500000)
51 : 0.510925 (0.510000)
52 : 0.520935 (0.520000)
53 : 0.530945 (0.530000)
54 : 0.540955 (0.540000)
55 : 0.550964 (0.550000)
56 : 0.560974 (0.560000)
57 : 0.570923 (0.570000)
58 : 0.580933 (0.580000)
59 : 0.590942 (0.590000)
60 : 0.600952 (0.600000)
61 : 0.610962 (0.610000)
62 : 0.620972 (0.620000)
63 : 0.630920 (0.630000)
64 : 0.640930 (0.640000)
65 : 0.650940 (0.650000)
66 : 0.660950 (0.660000)
67 : 0.670959 (0.670000)
68 : 0.680969 (0.680000)
69 : 0.690918 (0.690000)
70 : 0.700928 (0.700000)
71 : 0.710938 (0.710000)
72 : 0.720947 (0.720000)
73 : 0.730957 (0.730000)
74 : 0.740967 (0.740000)
75 : 0.750977 (0.750000)
76 : 0.760925 (0.760000)
77 : 0.770935 (0.770000)
78 : 0.780945 (0.780000)
79 : 0.790955 (0.790000)
80 : 0.800964 (0.800000)
81 : 0.810974 (0.810000)
82 : 0.820923 (0.820000)
83 : 0.830933 (0.830000)
84 : 0.840942 (0.840000)
85 : 0.850952 (0.850000)
86 : 0.860962 (0.860000)
87 : 0.870972 (0.870000)
88 : 0.880920 (0.880000)
89 : 0.890930 (0.890000)
90 : 0.900940 (0.900000)
91 : 0.910950 (0.910000)
92 : 0.920959 (0.920000)
93 : 0.930969 (0.930000)
94 : 0.940918 (0.940000)
95 : 0.950928 (0.950000)
96 : 0.960938 (0.960000)
97 : 0.970947 (0.970000)
98 : 0.980957 (0.980000)
99 : 0.990967 (0.990000)
100 : 1.000977 (1.000000)
```

With this, we are a bit closer but still not exact. Naturally, it will never be exact. This method does, however, make our test designs match Altia Design exactly.

While the method above worked in this case, we cannot guarantee that other designs will match exactly when calculating the position of an interpolated value. If an exact match is needed, then the animation states will need to be defined explicitly.

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.