Difference between revisions of "QW physics air ru"
*>Sss |
*>Sss |
||
(13 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | + | Предыдущая часть [http://wiki.quakeworld.nu/QW_physics_user_commands_ru] | |
− | |||
− | + | Физика QW: движение в воздухе, распрыг. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Line 45: | Line 9: | ||
Вычисляется т.н. вектор желаемой скорости. | Вычисляется т.н. вектор желаемой скорости. | ||
В данном случае горизонтален и складывается только из 2-х компонент: | В данном случае горизонтален и складывается только из 2-х компонент: | ||
− | + | горизонтального вектора длины forwardmove, направленного вдоль направления взгляда по горизонтали, и вектора длины sidemove, направленного вбок. | |
− | и вектора длины sidemove, направленного вбок. | ||
upmove не учитывается. | upmove не учитывается. | ||
В вертикальном направлении играет роль только гравитация. Она учитывается отдельно. | В вертикальном направлении играет роль только гравитация. Она учитывается отдельно. | ||
− | Далее, если длина получившегося вектора превышает ограничение сервера, | + | Далее, если длина получившегося вектора превышает ограничение сервера V_max, |
то его уменьшают до соответствующей длины. | то его уменьшают до соответствующей длины. | ||
Это число равно 320 для обычного TDM и | Это число равно 320 для обычного TDM и | ||
Line 75: | Line 38: | ||
accelspeed = accel * wishspeed * pm_frametime = | accelspeed = accel * wishspeed * pm_frametime = | ||
10 *320 * 0.014 = 44.8. | 10 *320 * 0.014 = 44.8. | ||
− | + | wishspeed - это не wishspd, а то что было до применения ограничения 30, | |
+ | т.е. при нормальных настройках это V_max. | ||
+ | |||
После выбирается минимальная из addspeed и accelspeed | После выбирается минимальная из addspeed и accelspeed | ||
Line 100: | Line 65: | ||
зато важно, куда направлен его wishdir. | зато важно, куда направлен его wishdir. | ||
+ | |||
+ | Обозначим accel = a и pm_frametime = T. | ||
+ | |||
+ | T = 0.013, если работает 77fps физика | ||
+ | и T = 0.014, если работает 72fps физика (TF2003 standard, old TDM standard). | ||
Пусть угол между горизонтальной скоростью v и wishdir равен gamma. | Пусть угол между горизонтальной скоростью v и wishdir равен gamma. | ||
+ | |||
+ | [[Image:Wishdir.png]] | ||
wishspd = min(wishspd, 30) = 30 при заданных выше условиях. | wishspd = min(wishspd, 30) = 30 при заданных выше условиях. | ||
− | addspeed = | + | addspeed = min(30 - v * cos(gamma), a * T * V_max) |
− | |||
− | |||
− | + | График зависимости addspeed от cos(gamma): | |
− | addspeed | ||
− | |||
− | |||
− | |||
− | |||
− | + | [[Image:Addspeed air fixed.png]] | |
− | |||
− | |||
− | + | Точка перелома - cos(gamma_k). | |
+ | Здесь 30 - v * cos(gamma_k) == a * T * V_max, | ||
− | + | cos(gamma_k) = (30 - a * T * V_max) / v. | |
− | + | Не забываем, что диапазон значений косинуса [-1; 1]. | |
+ | Точка перелома выходит на границу допустимых значений при cos(gamma_k) = -1. | ||
+ | При этом скорость v = 14.8. В TF это значение также мало. | ||
+ | А как уже было выяснено скорость 30 достигается за один фрейм. | ||
+ | Поэтому точка перелома находится всегда в допустимом диапазоне. | ||
− | |||
− | |||
− | + | Рассмотрим, какой максимальный вклад в прирост скорости может дать | |
+ | горизонтальная часть графика. | ||
− | + | Из теоремы косинусов | |
+ | v_new^2 = v^2 + (a*T*V_max)^2 +2*v*(a*T*V_Max)*cos(gamma). | ||
− | + | Приращение тем больше, чем больше cos(gamma). | |
− | + | Следовательно, на горизонтальной части лучшая точка - точка перелома, | |
+ | которая лежит также на наклонной части. | ||
− | + | Рассмотрим вклад, который может дать наклонная часть. | |
− | + | v_new^2 = v^2 + (30 - v*cos(gamma))^2 + 2v*(30 - v*cos(gamma))*cos(gamma) | |
− | + | ||
+ | Отсюда v_new^2 = v^2 + 30^2 - (v*cos(gamma))^2 | ||
+ | |||
+ | Чем ближе к 0 cos(gamma), тем больше приращение скорости. | ||
+ | |||
+ | Точка перелома cos(gamma) < 0, если 30 < a * T * V_max, | ||
+ | т.е. V_max > 30 / (a * T) = 230.8 при 77 fps и 214 при 72 fps физике. | ||
+ | |||
+ | Таким образом при распрыге в qw наибольшее ускорение получается при cos(gamma_best) == 0, | ||
+ | кроме как у hwguy при 77fps (но не 72fps, как в TF2003!), | ||
+ | где наилучшей точкой является точка излома cos(gamma_best) = (30 - a * T * V_max) / v. | ||
+ | В этом исключительном случае 30 - a * T * V_max = 0.1, т.е при V > v_max=230 | ||
+ | 0 < cos(gamma_best_hwg_77) < 4.34e-4. | ||
+ | Поэтому этим исключительным случаем можно спокойно пренебречь. | ||
+ | |||
+ | При cos(gamma) = 0 v_new^2 = v^2 + 30^2 | ||
+ | |||
+ | d(v^2)/dt = 30^2/T. | ||
+ | |||
+ | Идеальный разбег с прыжка на месте: | ||
+ | v(t) = 30 * sqrt(t / T). | ||
+ | |||
+ | |||
+ | dv/dt = 30^2/(2*v*T). | ||
− | + | Ускорение при 77 fps больше, чем при 72fps на 7.7%. | |
− | |||
+ | За один фрейм угол поворота вектора скорости v delta_fi = arctg(30/v), | ||
+ | т.е. угловая скорость поворота вектора v равна omega = (1/T)*arctg(30/v). | ||
+ | При v>>30 omega = 30 / (vT). | ||
С ростом скорости надо всё медленнее поворачиваться. | С ростом скорости надо всё медленнее поворачиваться. | ||
+ | |||
+ | Подтверждено экспериментально, что переменная sv_maxvelocity (2000) не ограничивает | ||
+ | скорость игрока. | ||
+ | |||
+ | Теоретически её можно достичь распрыгом за приблизительно 58 секунд с 77fps физикой. | ||
+ | |||
+ | Игрок должен обеспечивать правильное направление wishdir. | ||
+ | Это обеспечивается поворотом и правильным нажатием клавиш. | ||
Комментарии и поправки приветствуются. | Комментарии и поправки приветствуются. | ||
+ | |||
+ | Движение на земле рассмотрено здесь: [http://wiki.quakeworld.nu/QW_physics_ground_ru] |
Latest revision as of 08:42, 28 February 2010
Предыдущая часть [1]
Физика QW: движение в воздухе, распрыг.
Рассмотрим движение игрока в воздухе. Вычисляется т.н. вектор желаемой скорости. В данном случае горизонтален и складывается только из 2-х компонент: горизонтального вектора длины forwardmove, направленного вдоль направления взгляда по горизонтали, и вектора длины sidemove, направленного вбок. upmove не учитывается.
В вертикальном направлении играет роль только гравитация. Она учитывается отдельно.
Далее, если длина получившегося вектора превышает ограничение сервера V_max, то его уменьшают до соответствующей длины. Это число равно 320 для обычного TDM и меняется от 230 до 450 в зависимости от класса игрока в TF.
Далее используются единичный вектор желаемого направления и значение желаемой скорости: мы попали в функцию PM_PlayerAccelerate().
Здесь значение желаемой скорости сразу ограничивается числом 30: wishspd = min(wishspd, 30);
Находим проекцию текущей скорости на желаемое направление: currentspeed = DotProduct (pmove.velocity, wishdir);
Вычисляем разницу между желаемой скоростью и проекцией теущей скорости. Если получается отрицательное число, то скорость не меняется. addspeed = wishspd - currentspeed; if (addspeed <= 0) return;
Далее вычисляется величина
accelspeed = accel * wishspeed * pm_frametime =
10 *320 * 0.014 = 44.8.
wishspeed - это не wishspd, а то что было до применения ограничения 30, т.е. при нормальных настройках это V_max.
После выбирается минимальная из addspeed и accelspeed
accelspeed = min(accelspeed, addspeed);
Добавляем к вектору скорости вектор с полученной длиной и направлением wishdir VectorMA(pmove.velocity, accelspeed, wishdir, pmove.velocity);
Простейшие частные случаи.
Если игрок в воздухе и не нажимает на кнопки,
то скорость (горизонтальная) сохраняется.
Если у игрока нулевая скорость, то выполнив +forward, он приобретёт сразу скорость 30, направленную горизонтально вперёд.
Теперь рассмотрим распрыг. Скорость сразу будем считать большей, чем ограничение сервера (320 в TDM), т.к. её можно достигнуть ещё на земле. Разумеется, считаем, что игрок не устанавливал значения cl_sidespeed, cl_forwardspeed, cl_backspeed слишком маленькими.
Замечательным фактом является то, что в сущности, не важно, куда смотрит игрок, зато важно, куда направлен его wishdir.
Обозначим accel = a и pm_frametime = T.
T = 0.013, если работает 77fps физика и T = 0.014, если работает 72fps физика (TF2003 standard, old TDM standard).
Пусть угол между горизонтальной скоростью v и wishdir равен gamma.
wishspd = min(wishspd, 30) = 30 при заданных выше условиях.
addspeed = min(30 - v * cos(gamma), a * T * V_max)
График зависимости addspeed от cos(gamma):
Точка перелома - cos(gamma_k). Здесь 30 - v * cos(gamma_k) == a * T * V_max,
cos(gamma_k) = (30 - a * T * V_max) / v.
Не забываем, что диапазон значений косинуса [-1; 1]. Точка перелома выходит на границу допустимых значений при cos(gamma_k) = -1. При этом скорость v = 14.8. В TF это значение также мало. А как уже было выяснено скорость 30 достигается за один фрейм. Поэтому точка перелома находится всегда в допустимом диапазоне.
Рассмотрим, какой максимальный вклад в прирост скорости может дать
горизонтальная часть графика.
Из теоремы косинусов v_new^2 = v^2 + (a*T*V_max)^2 +2*v*(a*T*V_Max)*cos(gamma).
Приращение тем больше, чем больше cos(gamma). Следовательно, на горизонтальной части лучшая точка - точка перелома, которая лежит также на наклонной части.
Рассмотрим вклад, который может дать наклонная часть.
v_new^2 = v^2 + (30 - v*cos(gamma))^2 + 2v*(30 - v*cos(gamma))*cos(gamma)
Отсюда v_new^2 = v^2 + 30^2 - (v*cos(gamma))^2
Чем ближе к 0 cos(gamma), тем больше приращение скорости.
Точка перелома cos(gamma) < 0, если 30 < a * T * V_max, т.е. V_max > 30 / (a * T) = 230.8 при 77 fps и 214 при 72 fps физике.
Таким образом при распрыге в qw наибольшее ускорение получается при cos(gamma_best) == 0, кроме как у hwguy при 77fps (но не 72fps, как в TF2003!), где наилучшей точкой является точка излома cos(gamma_best) = (30 - a * T * V_max) / v. В этом исключительном случае 30 - a * T * V_max = 0.1, т.е при V > v_max=230
0 < cos(gamma_best_hwg_77) < 4.34e-4.
Поэтому этим исключительным случаем можно спокойно пренебречь.
При cos(gamma) = 0 v_new^2 = v^2 + 30^2
d(v^2)/dt = 30^2/T.
Идеальный разбег с прыжка на месте: v(t) = 30 * sqrt(t / T).
dv/dt = 30^2/(2*v*T).
Ускорение при 77 fps больше, чем при 72fps на 7.7%.
За один фрейм угол поворота вектора скорости v delta_fi = arctg(30/v), т.е. угловая скорость поворота вектора v равна omega = (1/T)*arctg(30/v). При v>>30 omega = 30 / (vT). С ростом скорости надо всё медленнее поворачиваться.
Подтверждено экспериментально, что переменная sv_maxvelocity (2000) не ограничивает скорость игрока.
Теоретически её можно достичь распрыгом за приблизительно 58 секунд с 77fps физикой.
Игрок должен обеспечивать правильное направление wishdir. Это обеспечивается поворотом и правильным нажатием клавиш.
Комментарии и поправки приветствуются.
Движение на земле рассмотрено здесь: [2]