Ramp Jumping

Locked
themuffinman
Posts: 384
Joined: Fri Mar 05, 2010 5:29 pm

Ramp Jumping

Post 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)?

:dork:
UglyFoot
Posts: 139
Joined: Fri Jul 22, 2011 12:35 pm

Re: Ramp Jumping

Post 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.
User avatar
Eraser
Posts: 19177
Joined: Fri Dec 01, 2000 8:00 am

Re: Ramp Jumping

Post 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.
UglyFoot
Posts: 139
Joined: Fri Jul 22, 2011 12:35 pm

Re: Ramp Jumping

Post 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;
themuffinman
Posts: 384
Joined: Fri Mar 05, 2010 5:29 pm

Re: Ramp Jumping

Post 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. :confused:

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.
eot
Posts: 2
Joined: Tue May 07, 2013 8:31 am

Re: Ramp Jumping

Post 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.
themuffinman
Posts: 384
Joined: Fri Mar 05, 2010 5:29 pm

Re: Ramp Jumping

Post 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.
eot
Posts: 2
Joined: Tue May 07, 2013 8:31 am

Re: Ramp Jumping

Post by eot »

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