/*============================================================================= VECTOR.C: VECTOR functions Created June 1997 by Gary Shaw =============================================================================*/ #include #include #include "types.h" #include "vector.h" #include "debug.h" #include "fastmath.h" #include "globals.h" /*============================================================================= Functions: =============================================================================*/ /*----------------------------------------------------------------------------- Name : vecNormalize Description : normalizes a vector (makes it a unit vector) Inputs : vector Outputs : vector is normalized Return : ----------------------------------------------------------------------------*/ void vecNormalize(vector *a) { real32 mag = fsqrt(vecMagnitudeSquared(*a)); real32 oneOverMag; #ifdef OPTIMIZE_VERBOSE // vecNormalizeCounter++; #endif if (mag == 0.0f) { return; } oneOverMag = 1.0f / mag; a->x *= oneOverMag; a->y *= oneOverMag; a->z *= oneOverMag; } /*----------------------------------------------------------------------------- Name : vecHomogenize Description : homogenizes an hvector (to the w == 1 plane) Inputs : dst - destination vector src - source hvector Outputs : dst is homogenized from src Return : ----------------------------------------------------------------------------*/ void vecHomogenize(vector* dst, hvector* src) { real32 oneOverW; vecGrabVecFromHVec(*dst, *src); if (src->w == 0.0f || src->w == 1.0f) { return; } oneOverW = 1.0f / src->w; dst->x *= oneOverW; dst->y *= oneOverW; dst->z *= oneOverW; } /*----------------------------------------------------------------------------- Name : vecCopyAndNormalize Description : copies a source vector to destination vector, and then normalizes the destination vector Inputs : src, dst Outputs : Return : ----------------------------------------------------------------------------*/ void vecCopyAndNormalize(vector *src,vector *dst) { real32 mag = fsqrt(vecMagnitudeSquared(*src)); real32 oneOverMag = 1.0f / mag; dst->x = src->x * oneOverMag; dst->y = src->y * oneOverMag; dst->z = src->z * oneOverMag; } /*----------------------------------------------------------------------------- Name : vecNormalizeToLength Description : Normalizes vector to given length. Inputs : vector, length Outputs : vector will now have length length. Return : ----------------------------------------------------------------------------*/ void vecNormalizeToLength(vector *a,real32 length) { real32 mag = fsqrt(vecMagnitudeSquared(*a)); real32 ratio = length / mag; a->x *= ratio; a->y *= ratio; a->z *= ratio; } /*----------------------------------------------------------------------------- Name : vecCapVectorSloppy Description : limits a vector's magnitude from growing beyond a maximum magnitude by chopping x,y,z separately. Inputs : vectorToCap, maxMagnitude Outputs : Return : ----------------------------------------------------------------------------*/ void vecCapVectorSloppy(vector *vectorToCap,real32 maxMagnitude) { real32 negMaxMagnitude = -maxMagnitude; if (vectorToCap->x > maxMagnitude) { vectorToCap->x = maxMagnitude; } else if (vectorToCap->x < negMaxMagnitude) { vectorToCap->x = negMaxMagnitude; } if (vectorToCap->y > maxMagnitude) { vectorToCap->y = maxMagnitude; } else if (vectorToCap->y < negMaxMagnitude) { vectorToCap->y = negMaxMagnitude; } if (vectorToCap->z > maxMagnitude) { vectorToCap->z = maxMagnitude; } else if (vectorToCap->z < negMaxMagnitude) { vectorToCap->z = negMaxMagnitude; } } /*----------------------------------------------------------------------------- Name : vecCapVector Description : limits a vector's magnitude from growing beyond a maximum magnitude Inputs : vectorToCap, maxMagnitude Outputs : Return : ----------------------------------------------------------------------------*/ void vecCapVector(vector *vectorToCap,real32 maxMagnitude) { real32 actualMag = fsqrt(vecMagnitudeSquared(*vectorToCap)); real32 ratio; if (actualMag > maxMagnitude) { ratio = maxMagnitude / actualMag; vectorToCap->x *= ratio; vectorToCap->y *= ratio; vectorToCap->z *= ratio; } } /*----------------------------------------------------------------------------- Name : vecCapVectorWithMag Description : limits a vector's magnitude from growing beyond a maximum magnitude Inputs : vectorToCap, maxMagnitude, actualMag Outputs : Return : ----------------------------------------------------------------------------*/ void vecCapVectorWithMag(vector *vectorToCap,real32 maxMagnitude,real32 actualMag) { real32 ratio; if (actualMag > maxMagnitude) { ratio = maxMagnitude / actualMag; vectorToCap->x *= ratio; vectorToCap->y *= ratio; vectorToCap->z *= ratio; } } /*----------------------------------------------------------------------------- Name : vecCapMinVector Description : limits a vector's minimum magnitude from growing below a maximum magnitude Inputs : vectorToCap, minMagnitude Outputs : Return : ----------------------------------------------------------------------------*/ void vecCapMinVector(vector *vectorToCap,real32 minMagnitude) { real32 actualMag = fsqrt(vecMagnitudeSquared(*vectorToCap)); real32 ratio; if (actualMag < minMagnitude) { ratio = minMagnitude / actualMag; vectorToCap->x *= ratio; vectorToCap->y *= ratio; vectorToCap->z *= ratio; } } /*----------------------------------------------------------------------------- Name : vecCapMinMaxVector Description : limits both the vector's minimum and maximum magnitude Inputs : vectorToCap, minMagnitude, maxMagnitude Outputs : Return : ----------------------------------------------------------------------------*/ void vecCapMinMaxVector(vector *vectorToCap,real32 minMagnitude,real32 maxMagnitude) { real32 actualMag = fsqrt(vecMagnitudeSquared(*vectorToCap)); real32 ratio; if (actualMag < minMagnitude) { ratio = minMagnitude / actualMag; vectorToCap->x *= ratio; vectorToCap->y *= ratio; vectorToCap->z *= ratio; } if (actualMag > maxMagnitude) { ratio = maxMagnitude / actualMag; vectorToCap->x *= ratio; vectorToCap->y *= ratio; vectorToCap->z *= ratio; } } /*----------------------------------------------------------------------------- Name : getVectDistSloppy Description : given a distance vector, gives a sloppy approximation of the distance Inputs : diff Outputs : Return : sloppy approximation of the distance ----------------------------------------------------------------------------*/ real32 getVectDistSloppy(vector diff) { diff.x = abs(diff.x); diff.y = abs(diff.y); diff.z = abs(diff.z); if (diff.x > diff.y) { if (diff.x > diff.z) { return diff.x; } else { return diff.z; } } else { if (diff.y > diff.z) { return diff.y; } else { return diff.z; } } } /*----------------------------------------------------------------------------- Name : vecLineIntersectWithXYPlane Description : finds the point of intersection between a line and the XY plane at z=zp. The line is defined with the two points linepoint1 and linepoint2. Inputs : linepoint1, linepoint2, zp Outputs : result, point of intersection Return : ----------------------------------------------------------------------------*/ void vecLineIntersectWithXYPlane(vector *result,vector *linepoint1,vector *linepoint2,real32 zp) { real32 k; k = (zp - linepoint1->z) / (linepoint2->z - linepoint1->z); result->x = (linepoint2->x - linepoint1->x)*k + linepoint1->x; result->y = (linepoint2->y - linepoint1->y)*k + linepoint1->y; result->z = zp; } /*----------------------------------------------------------------------------- Name : vecLineIntersectWithYZPlane Description : finds the point of intersection between a line and the YZ plane at x=xp. The line is defined with the two points linepoint1 and linepoint2. Inputs : linepoint1, linepoint2, xp Outputs : result, point of intersection Return : ----------------------------------------------------------------------------*/ void vecLineIntersectWithYZPlane(vector *result,vector *linepoint1,vector *linepoint2,real32 xp) { real32 k; k = (xp - linepoint1->x) / (linepoint2->x - linepoint1->x); result->y = (linepoint2->y - linepoint1->y)*k + linepoint1->y; result->z = (linepoint2->z - linepoint1->z)*k + linepoint1->z; result->x = xp; } /*----------------------------------------------------------------------------- Name : vecLineIntersectWithXZPlane Description : finds the point of intersection between a line and the XZ plane at y=yp. The line is defined with the two points linepoint1 and linepoint2. Inputs : linepoint1, linepoint2, yp Outputs : result, point of intersection Return : ----------------------------------------------------------------------------*/ void vecLineIntersectWithXZPlane(vector *result,vector *linepoint1,vector *linepoint2,real32 yp) { real32 k; k = (yp - linepoint1->y) / (linepoint2->y - linepoint1->y); result->x = (linepoint2->x - linepoint1->x)*k + linepoint1->x; result->z = (linepoint2->z - linepoint1->z)*k + linepoint1->z; result->y = yp; } /*----------------------------------------------------------------------------- Name : vecLineIntersectWithPlane Description : Compute the intersection of an arbitrary plane and an arbitrary ray. Inputs : Vplane - point on plane Vnormal - normal to plane Vline - point on line Vdirection - direction of line Outputs : dest - intersection point Return : will generate error if there is no intersection (line is paralell to plane) ----------------------------------------------------------------------------*/ void vecLineIntersectWithPlane(vector *dest, vector *Vplane, vector *Vnormal, vector *Vline, vector *Vdirection) { real32 tScalar, value; vector temp; value = vecDotProduct(*Vdirection, *Vnormal); dbgAssert(value != 0.0f); vecSub(temp, *Vline, *Vplane); //t = _-(Rl-Rp).N_ // V.N tScalar = -vecDotProduct(temp, *Vnormal) / value; //R = Rl + tV dest->x = Vline->x + tScalar * Vdirection->x; dest->y = Vline->y + tScalar * Vdirection->y; dest->z = Vline->z + tScalar * Vdirection->z; } /*----------------------------------------------------------------------------- Name : vecVectorsBlend Description : Linearly blend between two vectors. Inputs : start, end - endpoints of the interpolation factor - amount of end to use Outputs : result - where the interpolated result is stored. Return : ----------------------------------------------------------------------------*/ void vecVectorsBlend(vector *result, vector *start, vector *end, real32 factor) { real32 oneMinusFactor = 1.0f - factor; result->x = start->x * oneMinusFactor + end->x * factor; result->y = start->y * oneMinusFactor + end->y * factor; result->z = start->z * oneMinusFactor + end->z * factor; }