Quake3World.com Forums
     Technology & Troubleshooting
        The DEFINITIVE fps physics post cloned


Post new topicReply to topic
Login | Profile | | FAQ | Search | IRC




Print view Previous topic | Next topic 
Topic Starter Topic: The DEFINITIVE fps physics post cloned

XXXG-00W0
XXXG-00W0
Joined: 27 Dec 2002
Posts: 2891
PostPosted: 03-15-2005 11:17 AM           Profile Send private message  E-mail  Edit post Reply with quote


Coriolis wrote:
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:
--------------------------------------------------------------------------------
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.

Now, on to the mod I wrote. Here are some in-game screenshots at various frame rates:













When you jump, you are given 270 units / second of upward velocity, with a gravity of 800 units / second squared. Basic physics tells us that you should reach a maximum height of 45.5625 units after 0.3375 seconds. The height value shows the actual height of your jump. Frames is the number of frames the server used in reaching that height. Extra Vel is the approximate additional velocity you gained from rounding errors. Extra Hgt is the approximate additional height you gained from rounding errors.

Lastly, here is the mod I used to get the above results. You can use it to optimize your frame rate for maximum jumping height / distance.

Any questions?

EDIT: forgot to properly close the UBB italics tag


[This message has been edited by Coriolis (edited 08-21-2000).]


Did this to make it searchable again.

Edit: fixed, screenshots and mod are not present but it will still be clear i hope.




Last edited by Survivor on 03-15-2005 11:40 AM, edited 2 times in total.

Top
                 

XXXG-00W0
XXXG-00W0
Joined: 27 Dec 2002
Posts: 2891
PostPosted: 03-15-2005 11:38 AM           Profile Send private message  E-mail  Edit post Reply with quote


Poxy wrote:
77, 78, 79, 80
what happened to them?

oh and: missing Dist. for 83 frames.


Coriolis wrote:
The distance only shows up when you land. If it's missing, that's because you weren't going down fast enough for Q3 to consider it a landing.

I only showed frame rates where the fraction was > 0. The complete chart would show all frame rates, but it would be about twice as big. Almost as good as lots of fractions above but near 0.5 is fractions above 0.5 or near 0.0, so the ommission may be a problem. But, the source code is right there; remove the "if", and you can see the rounding error for all frame rates. But be warned; the fourth column assumes you round up a fraction, but Q3 actually rounds down fractions less than 0.5.




Top
                 

piecemaker
piecemaker
Joined: 25 Jan 2005
Posts: 886
PostPosted: 03-15-2005 01:23 PM           Profile Send private message  E-mail  Edit post Reply with quote


Oh my god I remember that one!

Nice catch! ;)




Top
                 

It felt good...
It felt good...
Joined: 28 Mar 2001
Posts: 9558
PostPosted: 03-15-2005 06:52 PM           Profile   Send private message  E-mail  Edit post Reply with quote


It'd be nice to try 333 in OSP but the bastids hard locked it seeing as it feels like having 700 grav. ;)




Top
                 

Timed Out
Timed Out
Joined: 02 Aug 2000
Posts: 38063
PostPosted: 03-16-2005 01:11 PM           Profile   Send private message  E-mail  Edit post Reply with quote


Did they? I've used it in the past and it felt fine =/



_________________
"Maybe you have some bird ideas. Maybe that’s the best you can do."
― Terry A. Davis


Top
                 

Quake Addict
Quake Addict
Joined: 13 May 2000
Posts: 1794
PostPosted: 03-19-2005 09:47 AM           Profile Send private message  E-mail  Edit post Reply with quote


Funny i tried /com_maxfps 170 and i cant do the jump to mega healt on dm13, but with com_maxfps 125 its ok... and my jump seem higher with com_maxfps 333...why is that?

Also is there a value that help with longer jump ?



_________________
Fast and furious_That's what it's all about...Image


Top
                 
Quake3World.com | Forum Index | Technology & Troubleshooting


Post new topic Reply to topic


cron
Quake3World.com
© ZeniMax. Zenimax, QUAKE III ARENA, Id Software and associated trademarks are trademarks of the ZeniMax group of companies. All rights reserved.
This is an unofficial fan website without any affiliation with or endorsement by ZeniMax.
All views and opinions expressed are those of the author.