brender-1997/math/vector.c

545 lines
13 KiB
C
Raw Normal View History

2022-05-03 16:30:35 -05:00
/*
* Copyright (c) 1992,1993-1995 Argonaut Technologies Limited. All rights reserved.
*
* $Id: vector.c 2.5 1996/12/04 18:30:44 OWAIN Exp $
* $Locker: $
*
* Vector op. - some of these are redefined as macros in vecfns.h
* for speed. (but the real functions still exist for debugging purposes)
*
*/
#undef _NO_VECTOR_MACROS
#define _NO_VECTOR_MACROS 1
#include "brender.h"
#include "shortcut.h"
#include "brassert.h"
BR_RCS_ID("$Id: vector.c 2.5 1996/12/04 18:30:44 OWAIN Exp $")
/**
** 2D Vectors
**/
void BR_PUBLIC_ENTRY BrVector2Copy(br_vector2 *v1,br_vector2 * v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=v2->v[0];
v1->v[1]=v2->v[1];
}
/*
* v1=(s1,s2)
*/
void BR_PUBLIC_ENTRY BrVector2Set(br_vector2 *v1, br_scalar s1, br_scalar s2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
v1->v[0]=s1;
v1->v[1]=s2;
}
void BR_PUBLIC_ENTRY BrVector2SetInt(br_vector2 *v1, int i1, int i2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
v1->v[0]=BrIntToScalar(i1);
v1->v[1]=BrIntToScalar(i2);
}
void BR_PUBLIC_ENTRY BrVector2SetFloat(br_vector2 *v1, float f1, float f2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
v1->v[0]=BrFloatToScalar(f1);
v1->v[1]=BrFloatToScalar(f2);
}
/*
* v1=-v2
*/
void BR_PUBLIC_ENTRY BrVector2Negate(br_vector2 *v1, br_vector2 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=-v2->v[0];
v1->v[1]=-v2->v[1];
}
/*
* v1=v2+v3
*/
void BR_PUBLIC_ENTRY BrVector2Add(br_vector2 *v1, br_vector2 *v2, br_vector2 *v3)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Left Hand Source Vector is NULL", v2 != NULL);
UASSERT_MESSAGE("Right Hand Source Vector is NULL", v3 != NULL);
v1->v[0]=v2->v[0]+v3->v[0];
v1->v[1]=v2->v[1]+v3->v[1];
}
/*
* v1+=v2
*/
void BR_PUBLIC_ENTRY BrVector2Accumulate(br_vector2 *v1, br_vector2 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]+=v2->v[0];
v1->v[1]+=v2->v[1];
}
/*
* v1=v2-v3
*/
void BR_PUBLIC_ENTRY BrVector2Sub(br_vector2 *v1, br_vector2 *v2, br_vector2 *v3)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Left Hand Source Vector is NULL", v2 != NULL);
UASSERT_MESSAGE("Right Hand Source Vector is NULL", v3 != NULL);
v1->v[0]=v2->v[0]-v3->v[0];
v1->v[1]=v2->v[1]-v3->v[1];
}
/*
* v1=v2*scalar
*/
void BR_PUBLIC_ENTRY BrVector2Scale(br_vector2 *v1, br_vector2 *v2, br_scalar s)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=BR_MUL(v2->v[0],(s));
v1->v[1]=BR_MUL(v2->v[1],(s));
}
/*
* v1=v2/scalar
*/
void BR_PUBLIC_ENTRY BrVector2InvScale(br_vector2 *v1, br_vector2 *v2, br_scalar s)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=BR_DIV(v2->v[0],(s));
v1->v[1]=BR_DIV(v2->v[1],(s));
}
/*
* = v1.v2
*/
br_scalar BR_PUBLIC_ENTRY BrVector2Dot(br_vector2 *v1, br_vector2 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
return BR_MAC2(v1->v[0],v2->v[0],v1->v[1],v2->v[1]);
}
/*
* = |v1|
*/
br_scalar BR_PUBLIC_ENTRY BrVector2Length(br_vector2 *v1)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
return BR_LENGTH2(v1->v[0],v1->v[1]);
}
/*
* = |v1| * |v1|
*/
br_scalar BR_PUBLIC_ENTRY BrVector2LengthSquared(br_vector2 *v1)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
return BR_SQR2(v1->v[0],v1->v[1]);
}
/**
** 3D VECTORS
**/
/*
* v1=v2
*/
void BR_PUBLIC_ENTRY BrVector3Copy(br_vector3 *v1, br_vector3 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=v2->v[0];
v1->v[1]=v2->v[1];
v1->v[2]=v2->v[2];
}
/*
* v1=(s1,s2,s3)
*/
void BR_PUBLIC_ENTRY BrVector3Set(br_vector3 *v1, br_scalar s1, br_scalar s2, br_scalar s3)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
v1->v[0]=s1;
v1->v[1]=s2;
v1->v[2]=s3;
}
void BR_PUBLIC_ENTRY BrVector3SetInt(br_vector3 *v1, int i1, int i2, int i3)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
v1->v[0]=BrIntToScalar(i1);
v1->v[1]=BrIntToScalar(i2);
v1->v[2]=BrIntToScalar(i3);
}
void BR_PUBLIC_ENTRY BrVector3SetFloat(br_vector3 *v1, float f1, float f2, float f3)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
v1->v[0]=BrFloatToScalar(f1);
v1->v[1]=BrFloatToScalar(f2);
v1->v[2]=BrFloatToScalar(f3);
}
/*
* v1=-v2
*/
void BR_PUBLIC_ENTRY BrVector3Negate(br_vector3 *v1,br_vector3 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v1 != NULL);
v1->v[0]=-v2->v[0];
v1->v[1]=-v2->v[1];
v1->v[2]=-v2->v[2];
}
/*
* v1=v2+v3
*/
void BR_PUBLIC_ENTRY BrVector3Add(br_vector3 *v1, br_vector3 *v2, br_vector3 *v3)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Left hand Source Vector is NULL", v2 != NULL);
UASSERT_MESSAGE("Right Hand Source Vector is NULL", v3 != NULL);
v1->v[0]=v2->v[0]+v3->v[0];
v1->v[1]=v2->v[1]+v3->v[1];
v1->v[2]=v2->v[2]+v3->v[2];
}
/*
* v1+=v2
*/
void BR_PUBLIC_ENTRY BrVector3Accumulate(br_vector3 *v1, br_vector3 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]+=v2->v[0];
v1->v[1]+=v2->v[1];
v1->v[2]+=v2->v[2];
}
/*
* v1=v2-v3
*/
void BR_PUBLIC_ENTRY BrVector3Sub(br_vector3 *v1, br_vector3 *v2, br_vector3 *v3)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Left hand Source Vector is NULL", v2 != NULL);
UASSERT_MESSAGE("Right hand Source Vector is NULL", v3 != NULL);
v1->v[0]=v2->v[0]-v3->v[0];
v1->v[1]=v2->v[1]-v3->v[1];
v1->v[2]=v2->v[2]-v3->v[2];
}
/*
* v1=v2*scalar
*/
void BR_PUBLIC_ENTRY BrVector3Scale(br_vector3 *v1, br_vector3 *v2, br_scalar s)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=BR_MUL(v2->v[0],(s));
v1->v[1]=BR_MUL(v2->v[1],(s));
v1->v[2]=BR_MUL(v2->v[2],(s));
}
/*
* v1=v2/scalar
*/
void BR_PUBLIC_ENTRY BrVector3InvScale(br_vector3 *v1, br_vector3 *v2, br_scalar s)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=BR_DIV(v2->v[0],(s));
v1->v[1]=BR_DIV(v2->v[1],(s));
v1->v[2]=BR_DIV(v2->v[2],(s));
}
/*
* = v1.v2
*/
br_scalar BR_PUBLIC_ENTRY BrVector3Dot(br_vector3 *v1, br_vector3 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
return BR_MAC3(v1->v[0],v2->v[0],v1->v[1],v2->v[1],v1->v[2],v2->v[2]);
}
/*
* v1 = v2 x v3
*/
void BR_PUBLIC_ENTRY BrVector3Cross(br_vector3 *v1,br_vector3 *v2,br_vector3 *v3)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Left hand Source Vector is NULL", v2 != NULL);
UASSERT_MESSAGE("Right hand Source Vector is NULL", v3 != NULL);
UASSERT_MESSAGE("Destination vector may not be source", v1 != v2);
UASSERT_MESSAGE("Destination vector may not be source", v1 != v3);
v1->v[0]=BR_MUL(v2->v[1],v3->v[2])-BR_MUL(v2->v[2],v3->v[1]);
v1->v[1]=BR_MUL(v2->v[2],v3->v[0])-BR_MUL(v2->v[0],v3->v[2]);
v1->v[2]=BR_MUL(v2->v[0],v3->v[1])-BR_MUL(v2->v[1],v3->v[0]);
}
/*
* = |v1|
*/
br_scalar BR_PUBLIC_ENTRY BrVector3Length(br_vector3 *v1)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
return BR_LENGTH3(v1->v[0],v1->v[1],v1->v[2]);
}
/*
* = |v1| * |v1|
*/
br_scalar BR_PUBLIC_ENTRY BrVector3LengthSquared(br_vector3 *v1)
{
UASSERT_MESSAGE("Subject Vector is NULL", v1 != NULL);
return BR_SQR3(v1->v[0],v1->v[1],v1->v[2]);
}
/*
* v1 = v2/|v2|
*/
void BR_PUBLIC_ENTRY BrVector3Normalise(br_vector3 *v1, br_vector3 *v2)
{
br_scalar scale;
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
scale = BR_LENGTH3(v2->v[0],v2->v[1],v2->v[2]);
if(scale > BR_SCALAR_EPSILON*2) {
scale=BR_DIV(BR_SCALAR(1.0),scale);
v1->v[0]=BR_MUL(v2->v[0],scale);
v1->v[1]=BR_MUL(v2->v[1],scale);
v1->v[2]=BR_MUL(v2->v[2],scale);
} else {
v1->v[0] = BR_SCALAR(1.0);
v1->v[1] = BR_SCALAR(0.0);
v1->v[2] = BR_SCALAR(0.0);
}
}
/*
* v1 = v2/|v2| (low precision)
*/
void BR_PUBLIC_ENTRY BrVector3NormaliseLP(br_vector3 *v1, br_vector3 *v2)
{
br_scalar scale;
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
scale = BR_RLENGTH3(v2->v[0],v2->v[1],v2->v[2]);
if(scale != BR_SCALAR(0.0)) {
v1->v[0]=BR_MUL(v2->v[0],scale);
v1->v[1]=BR_MUL(v2->v[1],scale);
v1->v[2]=BR_MUL(v2->v[2],scale);
}
}
/**
** 4D Vectors
**/
/*
* = v1.v2
*/
br_scalar BR_PUBLIC_ENTRY BrVector4Dot(br_vector4 *v1, br_vector4 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
return BR_MAC4(
v1->v[0],v2->v[0],
v1->v[1],v2->v[1],
v1->v[2],v2->v[2],
v1->v[3],v2->v[3]);
}
/*
* v1=v2
*/
void BR_PUBLIC_ENTRY BrVector4Copy(br_vector4 *v1, br_vector4 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=v2->v[0];
v1->v[1]=v2->v[1];
v1->v[2]=v2->v[2];
v1->v[3]=v2->v[3];
}
/**
** Private ops for fractional vectors
**/
/*
* = v1.v2 (v1 is a unit vector (word components))
*/
br_scalar BrFVector2Dot(br_fvector2 *v1, br_vector2 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
return BR_FMAC2(v1->v[0],v2->v[0],v1->v[1],v2->v[1]);
}
/*
* v1=v2
*/
void BrFVector3Copy(br_fvector3 *v1, br_vector3 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=BrScalarToFraction(v2->v[0]);
v1->v[1]=BrScalarToFraction(v2->v[1]);
v1->v[2]=BrScalarToFraction(v2->v[2]);
}
/*
* v1=v2*scalar
*/
void BrVector3ScaleF(br_vector3 *v1, br_fvector3 *v2, br_scalar s)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=BR_MUL(BrFractionToScalar(v2->v[0]),s);
v1->v[1]=BR_MUL(BrFractionToScalar(v2->v[1]),s);
v1->v[2]=BR_MUL(BrFractionToScalar(v2->v[2]),s);
}
/*
* = v1.v2 (v1 is a unit vector (word components))
*/
br_scalar BrFVector3Dot(br_fvector3 *v1, br_vector3 *v2)
{
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
return BR_FMAC3(v1->v[0],v2->v[0],v1->v[1],v2->v[1],v1->v[2],v2->v[2]);
}
/*
* v1 = v2/|v2|
*/
void BrFVector3Normalise(br_fvector3 *v1,br_vector3 *v2)
{
br_scalar scale;
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
scale=BR_LENGTH3(v2->v[0],v2->v[1],v2->v[2]);
if(scale != BR_SCALAR(0.0)) {
scale=BR_DIV(BR_FRACTION(1.0),scale);
v1->v[0]=(br_fraction)BR_MUL(v2->v[0],scale);
v1->v[1]=(br_fraction)BR_MUL(v2->v[1],scale);
v1->v[2]=(br_fraction)BR_MUL(v2->v[2],scale);
} else {
v1->v[0] = BR_FRACTION(1.0);
v1->v[1] = BR_FRACTION(0.0);
v1->v[2] = BR_FRACTION(0.0);
}
}
/*
* v1 = v2/|v2| (low precision)
*/
void BrFVector3NormaliseLP(br_fvector3 *v1, br_vector3 *v2)
{
br_scalar scale = BrScalarToFraction(BR_RLENGTH3(v1->v[0],v1->v[1],v1->v[2]));
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
v1->v[0]=(br_fraction)BR_MUL(v2->v[0],scale);
v1->v[1]=(br_fraction)BR_MUL(v2->v[1],scale);
v1->v[2]=(br_fraction)BR_MUL(v2->v[2],scale);
}
/*
* v1 = v2/|v2|
*/
void BR_PUBLIC_ENTRY BrVector2Normalise(br_vector2 *v1, br_vector2 *v2)
{
br_scalar scale;
scale = BR_LENGTH2(v2->v[0],v2->v[1]);
UASSERT_MESSAGE("Destination Vector is NULL", v1 != NULL);
UASSERT_MESSAGE("Source Vector is NULL", v2 != NULL);
if(scale > BR_SCALAR_EPSILON*2) {
scale=BR_DIV(BR_SCALAR(1.0),scale);
v1->v[0]=BR_MUL(v2->v[0],scale);
v1->v[1]=BR_MUL(v2->v[1],scale);
} else {
v1->v[0] = BR_SCALAR(1.0);
v1->v[1] = BR_SCALAR(0.0);
}
}