Page 1 of 1
Ramp Jumping
Posted: Mon Dec 26, 2011 9:44 am
by themuffinman
I've been altering the physics for a Q3 mod I've been working on and so far I've got double jumping, air accel, air-stop accel, air control, ladder physics etc., but I've got no idea how to implement ramp jumping. Does anyone know:
1. the exact details on how ramp jumping works (I assume it checks your z-coordinate before and after a jump and if the latter is higher then it adds an extra boost should you jump again right after landing), or...
2. have a link to any useful ramp jump code (I've looked through Q2's pmove.c and can't find anything yet)?

Re: Ramp Jumping
Posted: Mon Jan 02, 2012 10:54 pm
by UglyFoot
You could read about what happens when a ball bounces in a ramp. I've read a bit and I would say that you should remove the normal component of the velocity (because players don't bounce) but keep the parallel unchanged. That's in case the gravity is perpendicular to the plane, in the ramp case there's also an acceleration but I'm not sure about how to calculate it.
Re: Ramp Jumping
Posted: Tue Jan 03, 2012 8:11 am
by Eraser
themuffinman wrote:2. have a link to any useful ramp jump code (I've looked through Q2's pmove.c and can't find anything yet)?
I doubt you'll find any specific implementation of ramp jumping in the Quake 2 code. As far as I know, the introduction of odd movement features like these were anomalies of the physics code and weren't put in there intentionally.
Re: Ramp Jumping
Posted: Fri Jan 06, 2012 6:52 pm
by UglyFoot
I've wrote a bit of code that works, though it's not perfect. You have to paste it in PM_CheckJump (bg_pmove.c), after
Code: Select all
pml.groundPlane = qfalse; // jumping away
pml.walking = qfalse;
pm->ps->pm_flags |= PMF_JUMP_HELD;
pm->ps->groundEntityNum = ENTITYNUM_NONE;
pm->ps->velocity[2] = JUMP_VELOCITY;
Code: Select all
// Calc sinus of the angle between plane XY and the ramp plane
CrossProduct(axisDefault[2], pml.groundTrace.plane.normal, cross_vec);
sin_angle = VectorLength(cross_vec);
Com_Printf("sin: %f\n", sin_angle);
// Get the accel vector
VectorCopy(pm->ps->velocity, accel_vec);
accel_vec[2]=0;
VectorNormalize(accel_vec);
accel = DEFAULT_GRAVITY * sin_angle;
Com_Printf("accel: %f\n", accel);
VectorScale(accel_vec, accel, accel_vec);
// Multiply it and add to the velocity
Com_Printf("accel * 1: %f\n", accel * 1);
VectorMA(pm->ps->velocity, 1, accel_vec, pm->ps->velocity);
These are the variables:
Code: Select all
vec3_t accel_vec, cross_vec;
float accel, sin_angle;
Re: Ramp Jumping
Posted: Sat Jan 07, 2012 7:19 am
by themuffinman
@UglyFoot: You lost me in the first post lol. Nice effort with the code there though. It does seem to only work on ramps and seems to propel you forward instead of up but it'll give me a few ideas on what to do. This video illustrates what you can do with ramp jumping:
http://www.youtube.com/watch?v=OWXSAjlHX4w (you can skip the first 55 seconds or so past the credits and other mumble jumble)
It's not just about adding velocity when jumping on ramps, there's more to it. Most of the time it is adding to double jumps. Still nobody I've asked seems to be able to give a precise description of what goes on behind ramp jumps.
Someone on tastyspleen.net's forums pointed out a section in Q2's pmove.c:PM_CatagorizePosition. That function basically serves the same purpose as Q3's PM_GroundTrace and PM_SetWaterLevel...
Code: Select all
/*
=============
PM_CatagorizePosition
=============
*/
void PM_CatagorizePosition (void)
{
vec3_t point;
int cont;
trace_t trace;
int sample1;
int sample2;
// if the player hull point one unit down is solid, the player
// is on ground
// see if standing on something solid
point[0] = pml.origin[0];
point[1] = pml.origin[1];
point[2] = pml.origin[2] - 0.25;
if (pml.velocity[2] > 180) //!!ZOID changed from 100 to 180 (ramp accel)
{
pm->s.pm_flags &= ~PMF_ON_GROUND;
pm->groundentity = NULL;
}
else
{
trace = pm->trace (pml.origin, pm->mins, pm->maxs, point);
pml.groundplane = trace.plane;
pml.groundsurface = trace.surface;
pml.groundcontents = trace.contents;
if (!trace.ent || (trace.plane.normal[2] < 0.7 && !trace.startsolid) )
{
pm->groundentity = NULL;
pm->s.pm_flags &= ~PMF_ON_GROUND;
}
else
{
pm->groundentity = trace.ent;
// hitting solid ground will end a waterjump
if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
{
pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
pm->s.pm_time = 0;
}
if (! (pm->s.pm_flags & PMF_ON_GROUND) )
{ // just hit the ground
pm->s.pm_flags |= PMF_ON_GROUND;
// don't do landing time if we were just going down a slope
if (pml.velocity[2] < -200)
{
pm->s.pm_flags |= PMF_TIME_LAND;
// don't allow another jump for a little while
if (pml.velocity[2] < -400)
pm->s.pm_time = 25;
else
pm->s.pm_time = 18;
}
}
}
#if 0
if (trace.fraction < 1.0 && trace.ent && pml.velocity[2] < 0)
pml.velocity[2] = 0;
#endif
if (pm->numtouch < MAXTOUCH && trace.ent)
{
pm->touchents[pm->numtouch] = trace.ent;
pm->numtouch++;
}
}
//
// get waterlevel, accounting for ducking
//
pm->waterlevel = 0;
pm->watertype = 0;
sample2 = pm->viewheight - pm->mins[2];
sample1 = sample2 / 2;
point[2] = pml.origin[2] + pm->mins[2] + 1;
cont = pm->pointcontents (point);
if (cont & MASK_WATER)
{
pm->watertype = cont;
pm->waterlevel = 1;
point[2] = pml.origin[2] + pm->mins[2] + sample1;
cont = pm->pointcontents (point);
if (cont & MASK_WATER)
{
pm->waterlevel = 2;
point[2] = pml.origin[2] + pm->mins[2] + sample2;
cont = pm->pointcontents (point);
if (cont & MASK_WATER)
pm->waterlevel = 3;
}
}
}
That (pml.velocity[2] > 180) part isn't in Q3. Although it doesn't look like anything significant I added and rewrote it anyway, but it doesn't change anything.
@Eraser: You're probably thinking of Q1. Q2 didn't originally come with double+ramp jumping. It was real bad and even more boring than what vQ3 physics would be, hence why popular demand made Id Software enhance the physics in a patch.
Re: Ramp Jumping
Posted: Tue May 07, 2013 2:13 pm
by eot
UglyFoot wrote:You could read about what happens when a ball bounces in a ramp. I've read a bit and I would say that you should remove the normal component of the velocity (because players don't bounce) but keep the parallel unchanged. That's in case the gravity is perpendicular to the plane, in the ramp case there's also an acceleration but I'm not sure about how to calculate it.
I was curious about this so I did some testing and it is indeed what happens, the normal component of the velocity (normal to the ramp) is set to zero. It's just regular collision detection in Q3, when you hit the ramp your velocity is projected on the tangent plane of the ramp and the rest is discarded, so some of your horizontal velocity is converted to vertical. Some of your vertical speed is also converted to horizontal, or another way to think about it is that the more vertical speed you have the less of your horizontal is converted to vertical because you're not impacting the ramp at as high an angle.
Anyway, the reason you get so much height from it is because it kind of works like a triple jump. When you hit the ramp still going upwards from your first jump you get to keep all that upward momentum that you have from jumping, you even get some extra from the ramp, but because you're on the ground you can jump again and because it's CPMA you can even do a double jump and add 370 UPS to your vertical speed. So the first jump, the double jump and the ramp pushing you upwards all contribute to giving you more vertical speed.
The difference between VQ3 and CPM is that in VQ3 the speed of your jump is always set to 270, but in CPM the jump seems to be addative, so if you start with some vertical velocity the jump just adds to it. I'm not sure why that is because according to this:
http://games.linuxdude.com/tamaps/archi ... /step2.txt it shouldn't work that way. That isn't the source though so who knows. For regular double jumps your speed is set to 0 when you step up the ledge, so in that situation the first jump doesn't contribute.
edit: I should say as well that falling down a ramp works the same in both VQ3 and CPM. It's just the same thing basically, the velocity vector is again projected on the tangent plane. When you jump off the ramp the jump just cancels your vertical velocity and you jump normally. I guess that's a little strange since the jump in CPM was addative in the last case.
Re: Ramp Jumping
Posted: Tue May 07, 2013 7:13 pm
by themuffinman
I did actually find a solution quite a while back while porting Q2 physics over to Q3. Ramp jumping is just additive jump velocity, changing this:
Code: Select all
pm->ps->velocity[2] = JUMP_VELOCITY;
...to this:
Code: Select all
pm->ps->velocity[2] += JUMP_VELOCITY;
I'm not sure where the glitch comes in to give jump velocity boosts while moving up a slope, I guess it happens somewhere where changes in origin are converted to velocity.
It's hilarious that all you need is to insert one character to get it to work perfectly yet QL's ramp jumping is so incredibly crap... no idea how they coded it but it's a mess.
Re: Ramp Jumping
Posted: Tue May 07, 2013 8:51 pm
by eot
Nice

Does it work for when you fall onto a ramp as well (negative z-vel)?