Vector Math Functions - Wudan

A Vector is 3 floating point numbers (in Q3 based SDKs, it is type vec3_t), which generally represent either an Axis or a Coordinate. Both kinds have an X, Y and Z component.

Frequently, where there are vec3_t's, there are also Vector Mathematics involved, which can seem complicated, because they don't give you a clue what they're doing just by looking at them. Eventually, you'll be able to visualize what the Vector manipulation functions are doing just as easily as you'd visualize regular operators.

Here are some Vector Math Functions:

VectorAdd

void VectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out )

{

out[0] = veca[0] + vecb[0];

out[1] = veca[1] + vecb[1];

out[2] = veca[2] + vecb[2];

}

Adds the components of vec3_t veca and the corresponding components of vec3_t vecb, which results in vec3_t out, which is a brand new vector.
{

out[0] = veca[0] + vecb[0];

out[1] = veca[1] + vecb[1];

out[2] = veca[2] + vecb[2];

}

VectorSubtract

void VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out )

{

out[0] = veca[0] - vecb[0];

out[1] = veca[1] - vecb[1];

out[2] = veca[2] - vecb[2];

}

Subtracts the components of vec3_t veca by the corresponding components of vec3_t vecb, results in vec3_t out, which is a brand new vector.
{

out[0] = veca[0] - vecb[0];

out[1] = veca[1] - vecb[1];

out[2] = veca[2] - vecb[2];

}

VectorCopy

void VectorCopy( const vec3_t in, vec3_t out )

{

out[0] = in[0];

out[1] = in[1];

out[2] = in[2];

}

Sets the Values for vec3_t out equal to vec3_t in.
{

out[0] = in[0];

out[1] = in[1];

out[2] = in[2];

}

VectorScale

void VectorScale( const vec3_t in, vec_t scale, vec3_t out )

{

out[0] = in[0] * scale;

out[1] = in[1] * scale;

out[2] = in[2] * scale;

}

Takes vec3_t in, multplies each component by vec_t scale (which is float type), sets the results of each to the corresponding values of vec3_t out. A value of 2.0 in vec_t scale would double the values in vec3_t out, which is a new vector.
{

out[0] = in[0] * scale;

out[1] = in[1] * scale;

out[2] = in[2] * scale;

}

VectorSet

void VectorSet( vec3_t veca, float x, float y, float z)

{

veca[0] = x;

veca[1] = y;

veca[2] = z;

)

Sets the corresponding components of vec3_t veca to float values x, y, and z.
{

veca[0] = x;

veca[1] = y;

veca[2] = z;

)

VectorClear

void VectorClear( vec3_t veca )

{

veca[0] = veca[1] = veca[2] = 0.0;

}

This sets the value of each component of vec3_t veca to zero.
{

veca[0] = veca[1] = veca[2] = 0.0;

}

VectorNegate

void VectorNegate( const vec3_t veca, vec3_t vecb )

{

vecb[0] = -veca[0];

vecb[1] = -veca[1];

vecb[2] = -veca[2];

}

Sets each component of vec3_t vecb equal to negative (or flipped) values of vec3_t veca.
{

vecb[0] = -veca[0];

vecb[1] = -veca[1];

vecb[2] = -veca[2];

}

VectorMA

void VectorMA( const vec3_t veca, float scale,

const vec3_t vecb, vec3_t vecc)

{

vecc[0] = veca[0] + scale * vecb[0];

vecc[1] = veca[1] + scale * vecb[1];

vecc[2] = veca[2] + scale * vecb[2];

}

This is half VectorScale, half VectorAdd. It multiplies each component of vec3_t vecb by the value of float scale, then adds each the corresponding components of vec3_t veca, resulting in vec3_t vecc.
const vec3_t vecb, vec3_t vecc)

{

vecc[0] = veca[0] + scale * vecb[0];

vecc[1] = veca[1] + scale * vecb[1];

vecc[2] = veca[2] + scale * vecb[2];

}

It looks complicated, which understates the super-cool uses of this function. Let's say you wanted to put something at about half the distance between two coordinate vectors - we'll call them vec3_t here and vec3_t there. First, you'd subtract here from there, resulting in new vec3_t displacement. Next, you'd call VectorMA, using a scale value of 0.5 (ergo, halfway), which would set the value of vec3_t halfwaymark, which would be exactly halfway from here to there. It would look like this:

VectorSubtract( there, here, displacement );

VectorMA( here, 0.5, displacement, halfwaymark );

VectorMA( here, 0.5, displacement, halfwaymark );

DotProduct

vec_t DotProduct( const vec3_t v1, const vec3_t v2 )

{

return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];

}

Might not seem like much, just multiplication, but it's actually used often enough - it'll return a float (as listed above, a vec_t, which is of float type.)
{

return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];

}

One of it's most relevant uses is in bg_pmove.c, called in PM_Accelerate:

currentspeed = DotProduct (pm->ps->velocity, wishdir);

You see, the function of PM_Accelerate needs to know the players exact speed, to make it easier for itself, and the speed when it comes in to PM_Accelerate is a vector - hardly useful when you want to do regular math with it. So, it calls DotProduct on the velocity ( a vector ) and the wishdir ( direction the player is facing ) and it simplifies what could have been 2 or 3 extra mathematic functions, in to 1.