Make simple gravity acceleration framerate independent.

Now it doesn't matter if you get 22 fps or 72, you jump the same height,
which actually happens to be slightly higher than the previous 72fps jump.
Effectively, you jump the height you would if you got infinite fps ;)
This commit is contained in:
Bill Currie 2012-04-28 14:53:15 +09:00
parent a43bd755ca
commit f9a384ffd4
9 changed files with 72 additions and 10 deletions

View file

@ -60,6 +60,7 @@ typedef struct {
float waterjumptime;
qboolean dead;
qboolean flying;
qboolean add_grav;
int spectator;
// world state

View file

@ -273,6 +273,7 @@ int SV_FlyMove (edict_t *ent, float time, struct trace_s *steptrace);
void SV_CheckVelocity (edict_t *ent);
qboolean SV_RunThink (edict_t *ent);
void SV_AddGravity (edict_t *ent);
void SV_FinishGravity (edict_t *ent, vec3_t move);
void SV_Physics_Toss (edict_t *ent);
void SV_Physics_Client (edict_t *ent, int num);
void SV_Physics (void);

View file

@ -223,6 +223,7 @@ typedef struct sv_data_s {
entity_state_t state;
byte alpha;
qboolean sendinterval;
qboolean add_grav;
} sv_data_t;
#define SVdata(e) ((sv_data_t *) ((e)->edata))

View file

@ -220,7 +220,7 @@ SV_TryUnstick (edict_t *ent, vec3_t oldvel)
/*
SV_WalkMove
Used by only players
Used only by players
*/
static void
SV_WalkMove (edict_t *ent)
@ -319,6 +319,8 @@ SV_Physics_Client (edict_t *ent, int num)
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, ent);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.PlayerPreThink);
SVdata (ent)->add_grav = false;
// do a move
SV_CheckVelocity (ent);

View file

@ -252,6 +252,10 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
VectorMultAdd (SVvector (ent, origin), time_left,
SVvector (ent, velocity), end);
if (SVdata (ent)->add_grav) {
SVdata (ent)->add_grav = false;
SV_FinishGravity (ent, end);
}
trace = SV_Move (SVvector (ent, origin), SVvector (ent, mins),
SVvector (ent, maxs), end, false, ent);
@ -342,13 +346,27 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
void
SV_AddGravity (edict_t *ent)
{
float ent_gravity;
float ent_grav;
if (sv_fields.gravity != -1 && SVfloat (ent, gravity))
ent_gravity = SVfloat (ent, gravity);
ent_grav = SVfloat (ent, gravity);
else
ent_gravity = 1.0;
SVvector (ent, velocity)[2] -= ent_gravity * sv_gravity->value * sv_frametime;
ent_grav = 1.0;
SVvector (ent, velocity)[2] -= ent_grav * sv_gravity->value * sv_frametime;
SVdata (ent)->add_grav = true;
}
void
SV_FinishGravity (edict_t *ent, vec3_t move)
{
float ent_grav;
if (sv_fields.gravity != -1 && SVfloat (ent, gravity))
ent_grav = SVfloat (ent, gravity);
else
ent_grav = 1.0;
ent_grav *= sv_gravity->value;
move[2] += ent_grav * sv_frametime * sv_frametime / 2;
}
/* PUSHMOVE */
@ -551,6 +569,7 @@ SV_PushMove (edict_t *pusher, float movetime)
}
VectorScale (SVvector (pusher, velocity), movetime, move);
//FIXME finish gravity
VectorScale (SVvector (pusher, avelocity), movetime, amove);
if (SV_Push (pusher, move, amove))
@ -697,6 +716,10 @@ SV_Physics_Toss (edict_t *ent)
// move origin
VectorScale (SVvector (ent, velocity), sv_frametime, move);
if (SVdata (ent)->add_grav) {
SVdata (ent)->add_grav = false;
SV_FinishGravity (ent, move);
}
trace = SV_PushEntity (ent, move);
if (trace.fraction == 1)
return;
@ -784,6 +807,7 @@ SV_RunEntity (edict_t *ent)
return;
SVfloat (ent, lastruntime) = (float) sv.time;
}
SVdata (ent)->add_grav = false;
switch ((int) SVfloat (ent, movetype)) {
case MOVETYPE_PUSH:

View file

@ -530,6 +530,7 @@ void SV_ProgStartFrame (void);
void SV_Physics (void);
void SV_CheckVelocity (struct edict_s *ent);
void SV_AddGravity (struct edict_s *ent);
void SV_FinishGravity (struct edict_s *ent, vec3_t move);
qboolean SV_RunThink (struct edict_s *ent);
void SV_Physics_Toss (struct edict_s *ent);
void SV_RunNewmis (void);

View file

@ -206,6 +206,7 @@ typedef struct sv_data_s {
link_t area; ///< linked to a division node or leaf
edict_leaf_t *leafs;
entity_state_t state;
qboolean add_grav;
} sv_data_t;
#define SVdata(e) ((sv_data_t *) ((e)->edata))

View file

@ -131,7 +131,11 @@ PM_FlyMove (void)
break;
VectorMultAdd (pmove.origin, time_left, pmove.velocity, end);
if (pmove.add_grav) {
pmove.add_grav = false;
end[2] += movevars.entgravity * movevars.gravity *
frametime * frametime / 2;
}
trace = PM_PlayerMove (pmove.origin, end);
if (trace.startsolid || trace.allsolid) { // entity is trapped in
@ -508,12 +512,14 @@ PM_AirMove (void)
VectorScale (wishvel, movevars.maxspeed / wishspeed, wishvel);
wishspeed = movevars.maxspeed;
}
pmove.add_grav = false;
if (onground != -1) {
pmove.velocity[2] = 0;
PM_Accelerate (wishdir, wishspeed, movevars.accelerate);
pmove.velocity[2] -= movevars.entgravity * movevars.gravity *
frametime;
pmove.add_grav = true;
PM_GroundMove ();
} else if (pmove.flying) {
PM_AirAccelerate (wishdir, wishspeed, movevars.accelerate);
@ -525,6 +531,7 @@ PM_AirMove (void)
// add gravity
pmove.velocity[2] -= movevars.entgravity * movevars.gravity *
frametime;
pmove.add_grav = true;
if (!PM_FlyMove ()) {
// the move didn't get blocked

View file

@ -252,6 +252,10 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
VectorMultAdd (SVvector (ent, origin), time_left,
SVvector (ent, velocity), end);
if (SVdata (ent)->add_grav) {
SVdata (ent)->add_grav = false;
SV_FinishGravity (ent, end);
}
trace = SV_Move (SVvector (ent, origin), SVvector (ent, mins),
SVvector (ent, maxs), end, false, ent);
@ -342,13 +346,27 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
void
SV_AddGravity (edict_t *ent)
{
float ent_gravity;
float ent_grav;
if (sv_fields.gravity != -1 && SVfloat (ent, gravity))
ent_gravity = SVfloat (ent, gravity);
ent_grav = SVfloat (ent, gravity);
else
ent_gravity = 1.0;
SVvector (ent, velocity)[2] -= ent_gravity * sv_gravity->value * sv_frametime;
ent_grav = 1.0;
SVvector (ent, velocity)[2] -= ent_grav * sv_gravity->value * sv_frametime;
SVdata (ent)->add_grav = true;
}
void
SV_FinishGravity (edict_t *ent, vec3_t move)
{
float ent_grav;
if (sv_fields.gravity != -1 && SVfloat (ent, gravity))
ent_grav = SVfloat (ent, gravity);
else
ent_grav = 1.0;
ent_grav *= sv_gravity->value;
move[2] += ent_grav * sv_frametime * sv_frametime / 2;
}
/* PUSHMOVE */
@ -551,6 +569,7 @@ SV_PushMove (edict_t *pusher, float movetime)
}
VectorScale (SVvector (pusher, velocity), movetime, move);
//FIXME finish gravity
VectorScale (SVvector (pusher, avelocity), movetime, amove);
if (SV_Push (pusher, move, amove))
@ -697,6 +716,10 @@ SV_Physics_Toss (edict_t *ent)
// move origin
VectorScale (SVvector (ent, velocity), sv_frametime, move);
if (SVdata (ent)->add_grav) {
SVdata (ent)->add_grav = false;
SV_FinishGravity (ent, move);
}
trace = SV_PushEntity (ent, move);
if (trace.fraction == 1)
return;
@ -784,6 +807,7 @@ SV_RunEntity (edict_t *ent)
return;
SVfloat (ent, lastruntime) = (float) sv.time;
}
SVdata (ent)->add_grav = false;
switch ((int) SVfloat (ent, movetype)) {
case MOVETYPE_PUSH: