brender-v1.3.2/core/math/plane.c
2022-05-03 13:10:51 -07:00

89 lines
2.1 KiB
C

/*
* Copyright (c) 1992,1993-1995 Argonaut Technologies Limited. All rights reserved.
*
* $Id: plane.c 1.3 1998/08/03 16:48:18 jon Exp $
* $Locker: $
*/
#include "brender.h"
#include "shortcut.h"
#include "brmath.h"
#include "brassert.h"
BR_RCS_ID("$Id: plane.c 1.3 1998/08/03 16:48:18 jon Exp $")
/*
* Work out the plane equation of the plane defined by three points
*
* Use float for intermdiates for accuracy
*
* Returns != 0 if points were co-linear
*/
br_int_32 BR_PUBLIC_ENTRY BrPlaneEquation(br_vector4 *eqn, br_vector3 *v0, br_vector3 *v1, br_vector3 *v2)
{
br_vector3 a,b;
float ax,ay,az;
float bx,by,bz;
float nx,ny,nz,d;
float l;
UASSERT_MESSAGE("Plane Equation is NULL", eqn != NULL);
UASSERT_MESSAGE("BrPlaneEquation: Vector 0 is NULL", v0 != NULL);
UASSERT_MESSAGE("BrPlaneEquation: Vector 1 is NULL", v1 != NULL);
UASSERT_MESSAGE("BrPlaneEquation: Vector 2 is NULL", v2 != NULL);
BrVector3Sub(&a,v1,v0);
BrVector3Sub(&b,v2,v0);
ax = BrScalarToFloat(a.v[0]);
ay = BrScalarToFloat(a.v[1]);
az = BrScalarToFloat(a.v[2]);
bx = BrScalarToFloat(b.v[0]);
by = BrScalarToFloat(b.v[1]);
bz = BrScalarToFloat(b.v[2]);
nx = ay*bz-az*by;
ny = az*bx-ax*bz;
nz = ax*by-ay*bx;
l = BrFloatSqrt(nx * nx + ny * ny + nz * nz);
if(l != 0) {
l = 1.0F/l;
nx *= l;
ny *= l;
nz *= l;
} else {
nx = 0.0F;
ny = 0.0F;
nz = 1.0F;
}
d = nx * BrScalarToFloat(v0->v[0]) +
ny * BrScalarToFloat(v0->v[1]) +
nz * BrScalarToFloat(v0->v[2]);
eqn->v[0] = BrFloatToScalar(nx);
eqn->v[1] = BrFloatToScalar(ny);
eqn->v[2] = BrFloatToScalar(nz);
eqn->v[3] = BrFloatToScalar(d);
return l == 0;
}
/*
* Apply a matrix34 transformation to a plane equation
*/
void BR_PUBLIC_ENTRY BrMatrix34ApplyPlaneEquation(br_vector4 *A, br_vector4 *B, br_matrix34 *C)
{
br_scalar length;
BrMatrix34ApplyV((br_vector3 *)A, (br_vector3 *)B, C);
length = BrVector3Length((br_vector3 *)A);
BrVector3Scale((br_vector3 *)A, (br_vector3 *)A, BR_RCP(length));
A->v[3] = BR_MUL(length, B->v[3]) + BrVector3Dot((br_vector3 *)A, (br_vector3 *)&C->m[3]);
}