Coriolis Wise Guy
Posts: 4159 Registered: Dec 1999 |
posted 08-21-2001 10:55 PM
WARNING: EXTREMELY long post with only 1
smiley -- but it's worth it, as I answer pretty much every physics /
FPS question in quake 3.
Earlier this evening, Ctrl told me that he
was dissatisfied with my previous explanation of why your fps
affects jumping. So, I did some more research. Specifically, I wrote
a mod to measure your jumping.
Here are the key points that I
discovered: (1) The final velocity vectors are clamped to
integers every time the player movement code is called. This gets
called once per frame for fast clients, but never less than 20 times
per second. (2) This conversion is done by the equation (int)x,
where "x" is a floating point value. (3) The integer conversion
done by the Q3 vm *IS NOT ANSI COMPLIENT*. ANSI C specifies that
integer conversion is done by ignoring the fraction. The Q3 vm does
it by rounding to the nearest integer.
This third point explains exactly why DLL's
have slower speeds and jump heights than QVM's. In a QVM, the
rounding is to nearest integer, so errors will tend to cancel out.
In a DLL, rounding is always towards 0, so errors always reduce your
speed and will always accumulate. The rounding error in a DLL always
acts as extra friction. I expect you can get around this problem in
DLL's by rewriting the "SnapVector" macro to emulate the QVM's
rounding method.
Now, back to the jumps. In theory, the
rounding errors should cancel out over the number of frames in a
typical jump. This assumes that the fraction can be any value with
equal probability. However, in practice, this is not the case. Each
frame tends to be the same time as the previous one. The change in
velocity is the acceleration times the frame time. Acceleration is
due to gravity, and is therefore constant. Frame time is also nearly
constant, so the change in velocity is also nearly constant in each
frame. Since velocity always starts as an integer, and the change is
always nearly the same, under a constant fps rounding has nearly the
same error each frame. With a constant frame rate, Q3's rounding
errors will tend to accumulate. For some frame rates, this will
always round down; for others, it will always round up.
Based on this, the ideal frame rate for
jumping distance is the highest one your computer can maintain that
gets a fraction remainder near 0.5, but always greater than 0.5.
Q3's gravity is 800, so you want the fractional part of 800/fps to
be greater than 0.5. To protect against frame rate fluctuations,
you'd also want nearby frame rates to have fractions greater than
0.5. Lastly, you want there to be as many frames as possible, so
that the most possible positive error gets accumulated.
This chart gives (1) fps, (2) remainder of
800 / fps, (3) number of frames in 0.675 seconds, (4) maximum
positive accumulated error in 0.675 seconds. The table was generated
for all frame rates from 20 to 200 fps.
code:
23 0.78 15 3.26
26 0.77 17 3.92
27 0.63 18 6.67
28 0.57 18 7.71
29 0.59 19 7.86
30 0.67 20 6.67
31 0.81 20 3.87
34 0.53 22 10.35
35 0.86 23 3.29
37 0.62 24 9.08
39 0.51 26 12.67
41 0.51 27 13.17
43 0.60 29 11.47
45 0.78 30 6.67
48 0.67 32 10.67
51 0.69 34 10.67
54 0.81 36 6.67
55 0.55 37 16.82
58 0.79 39 8.07
59 0.56 39 17.19
62 0.90 41 3.97
63 0.70 42 12.67
67 0.94 45 2.69
68 0.76 45 10.59
69 0.59 46 18.67
73 0.96 49 2.01
74 0.81 49 9.27
75 0.67 50 16.67
76 0.53 51 24.16
81 0.88 54 6.67
82 0.76 55 13.41
83 0.64 56 20.24
84 0.52 56 26.67
89 0.99 60 0.67
90 0.89 60 6.67
91 0.79 61 12.74
92 0.70 62 18.87
93 0.60 62 24.67
94 0.51 63 30.83
101 0.92 68 5.39
102 0.84 68 10.67
103 0.77 69 16.08
104 0.69 70 21.54
105 0.62 70 26.67
106 0.55 71 32.15
115 0.96 77 3.35
116 0.90 78 8.07
117 0.84 78 12.67
118 0.78 79 17.41
119 0.72 80 22.18
120 0.67 81 27.00
121 0.61 81 31.46
122 0.56 82 36.30
123 0.50 83 41.16
134 0.97 90 2.69
135 0.93 91 6.74
136 0.88 91 10.71
137 0.84 92 14.77
138 0.80 93 18.87
139 0.76 93 22.75
140 0.71 94 26.86
141 0.67 95 30.99
142 0.63 95 34.79
143 0.59 96 38.94
144 0.56 97 43.11
145 0.52 97 46.83
161 0.97 108 3.35
162 0.94 109 6.73
163 0.91 110 10.12
164 0.88 110 13.41
165 0.85 111 16.82
166 0.82 112 20.24
167 0.79 112 23.47
168 0.76 113 26.90
169 0.73 114 30.36
170 0.71 114 33.53
171 0.68 115 36.99
172 0.65 116 40.47
173 0.62 116 43.58
174 0.60 117 47.07
175 0.57 118 50.57
176 0.55 118 53.64
177 0.52 119 57.15
The C++ code to generate the above table
is
code:
#include <stdio.H>
int main(int argc, char*
argv[]) { for( int i=20; i<300; i++ ) { double f =
800.0 / i; int ipart = (int)f; double fpart = f -
ipart;
if( fpart > 0.5f ) { printf( "%3d
%.2f %3d %6.2f\n", i, fpart, (int)(i * .675), (1.0-fpart) *
(int)(i*.675) ); } }
return 0; }
Matching our conditions with the table, we
predict that the best frame rates would be about 29, 41, 83, 92,
120, 140, and 170. Notice that these numbers are very near the
values that people have found experimentally. This match between
theory and experience lends credence to the model used.
..........
|
Coriolis Wise Guy
Posts: 4159 Registered: Dec 1999 |
posted 08-25-2001 11:04 PM
I've done some more thinking :O
Q3 measures frame time in an integer number
of milliseconds. This means that there are only certain frame rates
that it can hit... specifically, frame rates of 1000 / N, where N is
an integer number of milliseconds. Given this, you can find viable
frame rates by varying N. So, the possible frame rates are:
200 166-167 142-143 125 111-112 100 90-91 83-84 76-77 71-72 66-67 62-63 58-59 55-56 52-53 50 47-48 45-46 43-44 41-42 40 38-39 37-38 35-36 34-35 33-34 32-33 31-32 30-31 29-30 28-29 27-28 26-27 25-26 25 24-25 23-24 22-23 21-22 20-21 20
The lines with multiple numbers are ones that
do not evenly divide 1000, so for example you cannot exactly hit 142
or 143 fps but must toggle between them.
So, when testing values for com_maxfps, these
are the only numbers it really makes sense to try:
200 166 142 125 111 100 90 83 76 71 66 62 58 55 52 50 47 45 43 40-41 37-38 20-35
|