Add line, plane, ray and segments, split math unit test

Added some basic geometric primitives such as planes, rays, segments
and lines (plus some extra functions like xProject, xBarycentric, Lerpf),
as well as some intersection tests between them.

Additionally, I split massive math test into smaller ones and tweaked
unit test library (testing no longer stops after first failure).
This commit is contained in:
2025-02-24 09:37:22 +03:00
parent be16daaecf
commit 67e7582d63
24 changed files with 3755 additions and 915 deletions

View File

@@ -106,6 +106,19 @@ void BH_Vec4fNormal(const float *in,
float *out);
/**
* Computes normal vector from the \a in stores result into \a out and returns
* source length of the vector.
*
* \param in Input 4D vector
* \param out Output 4D vector
*
* \return Returns length prior to normalization
*/
float BH_Vec4fNormalEx(const float *in,
float *out);
/**
* Computes minimum vector from the \a a and \a b vectors and stores result
* into \a out.
@@ -147,6 +160,39 @@ void BH_Vec4fLerp(const float *a,
float *out);
/**
* Projects \a a vector onto \a b vector and stores result into \a out.
*
* \param a A 4D vector
* \param b B 4D vector
* \param out Output 4D vector
*/
void BH_Vec4fProject(const float *a,
const float *b,
float *out);
/**
* Computes point from barycentric coordiantes \a v, \a w and points \a a,
* \a b and \a c vectors.
*
* Output vector is calculated as A + v*(B-A) + w*(C-A).
*
* \param a A 4D vector
* \param b B 4D vector
* \param c C 4D vector
* \param v V barycentric coordinate
* \param w W barycentric coordinate
* \param out Output 4D vector
*/
void BH_Vec4fBarycentric(const float *a,
const float *b,
const float *c,
float v,
float w,
float *out);
/**
* Adds \a a and \a b floating point vectors and stores result into \a out.
*
@@ -262,6 +308,19 @@ void BH_Vec3fNormal(const float *in,
float *out);
/**
* Computes normal vector from the \a in stores result into \a out and returns
* source length of the vector.
*
* \param in Input 3D vector
* \param out Output 3D vector
*
* \return Returns length prior to normalization
*/
float BH_Vec3fNormalEx(const float *in,
float *out);
/**
* Computes minimum vector from the \a a and \a b vectors and stores result into
* \a out.
@@ -303,6 +362,39 @@ void BH_Vec3fLerp(const float *a,
float *out);
/**
* Projects \a a vector onto \a b vector and stores result into \a out.
*
* \param a A 3D vector
* \param b B 3D vector
* \param out Output 3D vector
*/
void BH_Vec3fProject(const float *a,
const float *b,
float *out);
/**
* Computes point from barycentric coordiantes \a v, \a w and points \a a,
* \a b and \a c vectors.
*
* Output vector is calculated as A + v*(B-A) + w*(C-A).
*
* \param a A 3D vector
* \param b B 3D vector
* \param c C 3D vector
* \param v V barycentric coordinate
* \param w W barycentric coordinate
* \param out Output 3D vector
*/
void BH_Vec3fBarycentric(const float *a,
const float *b,
const float *c,
float v,
float w,
float *out);
/**
* Adds \a a and \a b floating point vectors and stores result into \a out.
*
@@ -416,6 +508,19 @@ void BH_Vec2fNormal(const float *in,
float *out);
/**
* Computes normal vector from the \a in stores result into \a out and returns
* source length of the vector.
*
* \param in Input 2D vector
* \param out Output 2D vector
*
* \return Returns length prior to normalization
*/
float BH_Vec2fNormalEx(const float *in,
float *out);
/**
* Computes minimum vector from the \a a and \a b vectors and stores result into
* \a out.
@@ -457,6 +562,51 @@ void BH_Vec2fLerp(const float *a,
float *out);
/**
* Projects \a a vector onto \a b vector and stores result into \a out.
*
* \param a A 2D vector
* \param b B 2D vector
* \param out Output 2D vector
*/
void BH_Vec2fProject(const float *a,
const float *b,
float *out);
/**
* Computes point from barycentric coordiantes \a v, \a w and points \a a,
* \a b and \a c vectors.
*
* Output vector is calculated as A + v*(B-A) + w*(C-A).
*
* \param a A 2D vector
* \param b B 2D vector
* \param c C 2D vector
* \param v V barycentric coordinate
* \param w W barycentric coordinate
* \param out Output 2D vector
*/
void BH_Vec2fBarycentric(const float *a,
const float *b,
const float *c,
float u,
float v,
float *out);
/**
* Interpolates between \a a and \a b values by \a t amount and returns the
* result.
*
* \param a A 2D vector
* \param b B 2D vector
* \param t Amount
* \param out Output 2D vector
*/
float BH_Lerpf(float a, float b, float t);
/**
* Adds \a a and \a b integer vectors and stores result into \a out.
*
@@ -1205,12 +1355,12 @@ void BH_Mat4fFromFrustum(float fov,
/**
* Computes camera view matrix and stores result into \a out.
*
* \param pos Position vector
* \param position Position vector
* \param at Target vector
* \param up Up vector
* \param out Output 4x4 matrix
*/
void BH_Mat4fFromLookAt(const float *pos,
void BH_Mat4fFromLookAt(const float *position,
const float *at,
const float *up,
float *out);
@@ -1397,4 +1547,349 @@ void BH_Mat3fApplyVec2f(float *a,
float *out);
/**
* Computes plane from points \a a, \a b, \a c and stores result into \a out.
*
* X, Y, Z components of the \a out vector are plane normal, W component is a
* distance from the origin (0,0,0) to the plane.
*
* It is assumed, that points provided in clockwise order.
*
* If points form degenerate triangle, this function will return error.
*
* \param a A 3D vector
* \param b B 3D vector
* \param c C 3D vector
* \param out Output 4D vector
*
* \return On success, returns zero.
* \return On failure, returns error-code.
*/
int BH_PlaneFromPoints(const float *a,
const float *b,
const float *c,
float *out);
/**
* Computes distance from \a plane to the \a point and returns result.
*
* \param plane Plane 4D vector
* \param point Point 3D vector
*
* \return Returns distance from plane to point.
*/
float BH_PlaneDistance(const float *plane,
const float *point);
/**
* Computes closest point on the \a plane to the \a point and stores result
* into \a out.
*
* \param plane Plane 4D vector
* \param point Point 3D vector
* \param out Output 3D vector
*/
void BH_PlaneClosestPoint(const float *plane,
const float *point,
float *out);
/**
* Computes time of intersection \a t between ray (given \a start and
* \a direction) and \a plane and stores intersection point into \a out.
*
* The returned intersection time \a t is for the ray.
*
* \param start Start 3D vector
* \param direction Direction 3D vector
* \param plane Plane 4D vector
* \param t Time of intersection
* \param out Output 3D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Ray3fIntersectPlane(const float *start,
const float *direction,
const float *plane,
float *t,
float *out);
/**
* Computes time of intersection \a t between ray (given \a start and
* \a direction) and triangle formed by \a a, \a b, \a c points and intersection
* point into \a out.
*
* The returned intersection time \a t is for the ray.
*
* \param start Start 3D vector
* \param direction Direction 3D vector
* \param a A 3D vector
* \param b B 3D vector
* \param c C 3D vector
* \param t Time of intersection
* \param out Output 3D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Ray3fIntersectTriangle(const float *start,
const float *direction,
const float *a,
const float *b,
const float *c,
float *t,
float *out);
/**
* Computes time of intesection \a t between line segment (given \a a and \a b
* points) and \a plane and stores intersection point into \a out.
*
* The returned intersection time \a t is for the segment.
*
* \param a A 3D vector
* \param b B 3D vector
* \param plane Plane 4D vector
* \param t Time of intersection
* \param out Output 3D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Segment3fIntersectPlane(const float *start,
const float *end,
const float *plane,
float *t,
float *out);
/**
* Computes time of intersection \a t between segment (given \a start and
* \a end) and triangle formed by \a a, \a b, \a c points and intersection
* point into \a out.
*
* The returned intersection time \a t is for the segment.
*
* \param start Start 3D vector
* \param direction Direction 3D vector
* \param a A 3D vector
* \param b B 3D vector
* \param c C 3D vector
* \param t Time of intersection
* \param out Output 3D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Segment3fIntersectTriangle(const float *start,
const float *end,
const float *a,
const float *b,
const float *c,
float *t,
float *out);
/**
* Computes barycentric coordinates from \a point and triangle made of \a a,
* \a b, \a c points and stores result into \a out.
*
* \param a A 3D vector
* \param b B 3D vector
* \param c C 3D vector
* \param point Point 3D vector
* \param out Output 3D vector
*/
void BH_Triangle3fBarycentric(const float *a,
const float *b,
const float *c,
const float *point,
float *out);
/**
* Computes line from \a a and \a b points and stores result into \a out.
*
* \param a A 2D vector
* \param b B 2D vector
* \param out Output 3D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_LineFromPoints(const float *a,
const float *b,
float *out);
/**
* Computes distance from \a line to the \a point and returns result.
*
* \param line Line 3D vector
* \param point Point 2D vector
*
* \return Returns distance from plane to point.
*/
float BH_LineDistance(const float *line,
const float *point);
/**
* Computes closest point on the \a line to the \a point and stores result into
* \a out.
*
* \param line Line 3D vector
* \param point Point 2D vector
* \param out Output 2D vector
*/
void BH_LineClosestPoint(const float *line,
const float *point,
float *out);
/**
* Computes time of intersection \a t between ray (given \a start and
* \a direction) and \a line and stores intersection point into \a out.
*
* The returned intersection time \a t is for the ray.
*
* \param start Start 2D vector
* \param direction Direction 2D vector
* \param line Line 3D vector
* \param t Time of intersection
* \param out Output 2D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Ray2fIntersectLine(const float *start,
const float *direction,
const float *line,
float *t,
float *out);
/**
* Computes time of intersection \a time1 and \a time2 between one line (given
* \a startA and \a directionA) and other line (given \a startB and
* \a directionB).
*
* \param startA A Start 2D vector
* \param directionA A Direction 2D vector
* \param startB B Start 2D vector
* \param directionB B Direction 2D vector
* \param time1 Time of intersection of first line
* \param time2 Time of intersection of second line
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Ray2fIntersectTime(const float *startA,
const float *directionA,
const float *startB,
const float *directionB,
float *time1,
float *time2);
/**
* Computes time of intersection \a t between one ray (given \a startA and
* \a directionA) and other ray (given \a startB and \a directionB) and stores
* intersection point into \a out.
*
* The returned intersection time \a t is for the first ray.
*
* \param startA A Start 2D vector
* \param directionA A Direction 2D vector
* \param startB B Start 2D vector
* \param directionB B Direction 2D vector
* \param t Time of intersection
* \param out Output 2D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Ray2fIntersectRay(const float *startA,
const float *directionA,
const float *startB,
const float *directionB,
float *t,
float *out);
/**
* Computes time of intersection \a t between one ray (given \a startA and
* \a directionA) and segment (given \a startB and \a endB) and stores result
* into \a out.
*
* The returned intersection time \a t is for the ray.
*
* \param startA A Start 2D vector
* \param directionA A Direction 2D vector
* \param startB B Start 2D vector
* \param endB B End 2D vector
* \param t Time of intersection
* \param out Output 2D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Ray2fIntersectSegment(const float *startA,
const float *directionA,
const float *startB,
const float *endB,
float *t,
float *out);
/**
* Computes time of intersection \a t between segment (given \a start and
* \a end) and \a line and stores intersection point into \a out.
*
* The returned intersection time \a t is for the segment.
*
* \param start Start 2D vector
* \param end End 2D vector
* \param line Line 3D vector
* \param t Time of intersection
* \param out Output 2D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Segment2fIntersectLine(const float *start,
const float *end,
const float *line,
float *t,
float *out);
/**
* Computes time of intersection \a t between one segment (given \a startA and
* \a endA) and other sergment (given \a startB and \a endB) and stores
* intersection point into \a out.
*
* The returned intersection time \a t is for the first segment.
*
* \param startA A Start 2D vector
* \param endA A End 2D vector
* \param startB B Start 2D vector
* \param endB B End 2D vector
* \param t Time of intersection
* \param out Output 2D vector
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_Segment2fIntersectSegment(const float *startA,
const float *endA,
const float *startB,
const float *endB,
float *t,
float *out);
#endif /* BH_MATH_H */

View File

@@ -1,4 +1,5 @@
#include <BH/Math.h>
#include <math.h>
#include <string.h>
@@ -89,6 +90,17 @@ void BH_Vec4fNormal(const float *in,
}
float BH_Vec4fNormalEx(const float *in,
float *out)
{
float length;
length = BH_Vec4fLength(in);
BH_Vec4fScale(in, 1.0f / length, out);
return length;
}
void BH_Vec4fMin(const float *a,
const float *b,
float *out)
@@ -124,6 +136,34 @@ void BH_Vec4fLerp(const float *a,
}
void BH_Vec4fProject(const float *a,
const float *b,
float *out)
{
float amount;
amount = BH_Vec4fDot(a, b) / BH_Vec4fDot(b, b);
BH_Vec4fScale(b, amount, out);
}
void BH_Vec4fBarycentric(const float *a,
const float *b,
const float *c,
float v,
float w,
float *out)
{
float tmp1[4], tmp2[4];
float u;
u = 1.0f - v - w;
tmp1[0] = tmp1[1] = tmp1[2] = tmp1[3] = u; BH_Vec4fMul(a, tmp1, tmp2);
tmp1[0] = tmp1[1] = tmp1[2] = tmp1[3] = v; BH_Vec4fMulAdd(b, tmp1, tmp2, tmp2);
tmp1[0] = tmp1[1] = tmp1[2] = tmp1[3] = w; BH_Vec4fMulAdd(c, tmp1, tmp2, out);
}
void BH_Vec3fAdd(const float *a,
const float *b,
float *out)
@@ -217,6 +257,17 @@ void BH_Vec3fNormal(const float *in,
}
float BH_Vec3fNormalEx(const float *in,
float *out)
{
float length;
length = BH_Vec3fLength(in);
BH_Vec3fScale(in, 1.0f / length, out);
return length;
}
void BH_Vec3fMin(const float *a,
const float *b,
float *out)
@@ -250,6 +301,34 @@ void BH_Vec3fLerp(const float *a,
}
void BH_Vec3fProject(const float *a,
const float *b,
float *out)
{
float amount;
amount = BH_Vec3fDot(a, b) / BH_Vec3fDot(b, b);
BH_Vec3fScale(b, amount, out);
}
void BH_Vec3fBarycentric(const float *a,
const float *b,
const float *c,
float v,
float w,
float *out)
{
float tmp1[3], tmp2[3];
float u;
u = 1.0f - v - w;
tmp1[0] = tmp1[1] = tmp1[2] = u; BH_Vec3fMul(a, tmp1, tmp2);
tmp1[0] = tmp1[1] = tmp1[2] = v; BH_Vec3fMulAdd(b, tmp1, tmp2, tmp2);
tmp1[0] = tmp1[1] = tmp1[2] = w; BH_Vec3fMulAdd(c, tmp1, tmp2, out);
}
void BH_Vec2fAdd(const float *a,
const float *b,
float *out)
@@ -331,6 +410,17 @@ void BH_Vec2fNormal(const float *in,
}
float BH_Vec2fNormalEx(const float *in,
float *out)
{
float length;
length = BH_Vec2fLength(in);
BH_Vec2fScale(in, 1.0f / length, out);
return length;
}
void BH_Vec2fMin(const float *a,
const float *b,
float *out)
@@ -362,6 +452,40 @@ void BH_Vec2fLerp(const float *a,
}
void BH_Vec2fProject(const float *a,
const float *b,
float *out)
{
float amount;
amount = BH_Vec2fDot(a, b) / BH_Vec2fDot(b, b);
BH_Vec2fScale(b, amount, out);
}
void BH_Vec2fBarycentric(const float *a,
const float *b,
const float *c,
float v,
float w,
float *out)
{
float tmp1[2], tmp2[2];
float u;
u = 1.0f - v - w;
tmp1[0] = tmp1[1] = u; BH_Vec2fMul(a, tmp1, tmp2);
tmp1[0] = tmp1[1] = v; BH_Vec2fMulAdd(b, tmp1, tmp2, tmp2);
tmp1[0] = tmp1[1] = w; BH_Vec2fMulAdd(c, tmp1, tmp2, out);
}
float BH_Lerpf(float a, float b, float t)
{
return a + (b - a) * t;
}
void BH_Vec4iAdd(const int *a,
const int *b,
int *out)
@@ -1176,37 +1300,37 @@ void BH_Mat4fFromFrustum(float fov,
}
void BH_Mat4fFromLookAt(const float *pos,
void BH_Mat4fFromLookAt(const float *position,
const float *at,
const float *up,
float *out)
{
float cdir[3], cright[3], cup[3];
float cameraDir[3], cameraRight[3], cameraUp[3];
BH_Vec3fSub(pos, at, cdir);
BH_Vec3fNormal(cdir, cdir);
BH_Vec3fCross(up, cdir, cright);
BH_Vec3fNormal(cright, cright);
BH_Vec3fCross(cdir, cright, cup);
BH_Vec3fSub(position, at, cameraDir);
BH_Vec3fNormal(cameraDir, cameraDir);
BH_Vec3fCross(up, cameraDir, cameraRight);
BH_Vec3fNormal(cameraRight, cameraRight);
BH_Vec3fCross(cameraDir, cameraRight, cameraUp);
out[0] = cright[0];
out[1] = cup[0];
out[2] = cdir[0];
out[0] = cameraRight[0];
out[1] = cameraUp[0];
out[2] = cameraDir[0];
out[3] = 0.0f;
out[4] = cright[1];
out[5] = cup[1];
out[6] = cdir[1];
out[4] = cameraRight[1];
out[5] = cameraUp[1];
out[6] = cameraDir[1];
out[7] = 0.0f;
out[8] = cright[2];
out[9] = cup[2];
out[10] = cdir[2];
out[8] = cameraRight[2];
out[9] = cameraUp[2];
out[10] = cameraDir[2];
out[11] = 0.0f;
out[12] = -BH_Vec3fDot(cright, pos);
out[13] = -BH_Vec3fDot(cup, pos);
out[14] = -BH_Vec3fDot(cdir, pos);
out[12] = -BH_Vec3fDot(cameraRight, position);
out[13] = -BH_Vec3fDot(cameraUp, position);
out[14] = -BH_Vec3fDot(cameraDir, position);
out[15] = 1.0f;
}
@@ -1447,3 +1571,394 @@ void BH_Mat3fApplyVec2f(float *a,
memcpy(out, tmp, sizeof(float) * 2);
}
int BH_PlaneFromPoints(const float *a,
const float *b,
const float *c,
float *out)
{
float tmp1[3], tmp2[3];
BH_Vec3fSub(b, a, tmp1);
BH_Vec3fSub(c, a, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fNormalEx(tmp1, tmp1) == 0.0f)
return BH_ERROR;
out[3] = BH_Vec3fDot(a, tmp1);
memcpy(out, tmp1, sizeof(tmp1));
return BH_OK;
}
float BH_PlaneDistance(const float *plane,
const float *point)
{
return BH_Vec3fDot(plane, point) - plane[3];
}
void BH_PlaneClosestPoint(const float *plane,
const float *point,
float *out)
{
float tmp[3];
BH_Vec3fScale(plane, BH_PlaneDistance(plane, point), tmp);
BH_Vec3fSub(point, tmp, out);
}
int BH_Ray3fIntersectPlane(const float *start,
const float *direction,
const float *plane,
float *t,
float *out)
{
float tmp1[3];
float denom, time;
/* Calculate intersection time */
denom = BH_Vec3fDot(direction, plane);
time = (plane[3] - BH_Vec3fDot(plane, start)) / denom;
/* Check for ray/plane parallel to each other or point is behing the ray. */
if (denom == 0.0f || time < 0.0f)
return BH_ERROR;
/* Compute intersection point */
BH_Vec3fScale(direction, time, tmp1);
BH_Vec3fAdd(start, tmp1, out);
*t = time;
return BH_OK;
}
int BH_Ray3fIntersectTriangle(const float *start,
const float *direction,
const float *a,
const float *b,
const float *c,
float *t,
float *out)
{
float plane[4];
float tmp1[3], tmp2[3], tmp3[3];
float time;
/* Compute plane */
if (BH_PlaneFromPoints(a, b, c, plane))
return BH_ERROR;
/* Compute intersection point in ray against plane */
if (BH_Ray3fIntersectPlane(start, direction, plane, &time, tmp3))
return BH_ERROR;
/* Check if point inside rectangle */
BH_Vec3fSub(b, a, tmp1);
BH_Vec3fSub(tmp3, a, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fDot(tmp1, plane) < 0.0f)
return BH_ERROR;
BH_Vec3fSub(c, b, tmp1);
BH_Vec3fSub(tmp3, b, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fDot(tmp1, plane) < 0.0f)
return BH_ERROR;
BH_Vec3fSub(a, c, tmp1);
BH_Vec3fSub(tmp3, c, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fDot(tmp1, plane) < 0.0f)
return BH_ERROR;
/* Copy intersection point */
memcpy(out, tmp3, sizeof(tmp3));
*t = time;
return BH_OK;
}
int BH_Segment3fIntersectPlane(const float *start,
const float *end,
const float *plane,
float *t,
float *out)
{
float tmp[3];
float denom, time;
/* Calculate intersection time */
BH_Vec3fSub(end, start, tmp);
denom = BH_Vec3fDot(tmp, plane);
time = (plane[3] - BH_Vec3fDot(plane, start)) / denom;
/* Check for ray/plane parallel to each other or point is behing the ray. */
if (denom == 0.0f || time < 0.0f || time > 1.0f)
return BH_ERROR;
/* Compute intersection point */
BH_Vec3fScale(tmp, time, tmp);
BH_Vec3fAdd(start, tmp, out);
*t = time;
return BH_OK;
}
int BH_Segment3fIntersectTriangle(const float *start,
const float *end,
const float *a,
const float *b,
const float *c,
float *t,
float *out)
{
float plane[4];
float tmp1[3], tmp2[3], tmp3[3];
float time;
/* Compute plane */
if (BH_PlaneFromPoints(a, b, c, plane))
return BH_ERROR;
/* Compute intersection point in ray against plane */
if (BH_Segment3fIntersectPlane(start, end, plane, &time, tmp3))
return BH_ERROR;
/* Check if point inside rectangle */
BH_Vec3fSub(b, a, tmp1);
BH_Vec3fSub(tmp3, a, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fDot(tmp1, plane) < 0.0f)
return BH_ERROR;
BH_Vec3fSub(c, b, tmp1);
BH_Vec3fSub(tmp3, b, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fDot(tmp1, plane) < 0.0f)
return BH_ERROR;
BH_Vec3fSub(a, c, tmp1);
BH_Vec3fSub(tmp3, c, tmp2);
BH_Vec3fCross(tmp2, tmp1, tmp1);
if (BH_Vec3fDot(tmp1, plane) < 0.0f)
return BH_ERROR;
/* Copy intersection point */
memcpy(out, tmp3, sizeof(tmp3));
*t = time;
return BH_OK;
}
void BH_Triangle3fBarycentric(const float *a,
const float *b,
const float *c,
const float *point,
float *out)
{
float tmp1[3], tmp2[3], tmp3[3];
float t11, t12, t22, t31, t32, denom;
BH_Vec3fSub(b, a, tmp1);
BH_Vec3fSub(c, a, tmp2);
BH_Vec3fSub(point, a, tmp3);
t11 = BH_Vec3fDot(tmp1, tmp1);
t12 = BH_Vec3fDot(tmp1, tmp2);
t22 = BH_Vec3fDot(tmp2, tmp2);
t31 = BH_Vec3fDot(tmp3, tmp1);
t32 = BH_Vec3fDot(tmp3, tmp2);
denom = 1.0f / (t11 * t22 - t12 * t12);
out[1] = (t22 * t31 - t12 * t32) * denom;
out[2] = (t11 * t32 - t12 * t31) * denom;
out[0] = 1.0f - out[1] - out[2];
}
int BH_LineFromPoints(const float *a,
const float *b,
float *out)
{
float tmp[2];
tmp[0] = a[1] - b[1];
tmp[1] = b[0] - a[0];
if (BH_Vec2fNormalEx(tmp, tmp) == 0.0f)
return BH_ERROR;
out[2] = BH_Vec2fDot(tmp, a);
memcpy(out, tmp, sizeof(tmp));
return BH_OK;
}
float BH_LineDistance(const float *line,
const float *point)
{
return BH_Vec2fDot(line, point) - line[2];
}
void BH_LineClosestPoint(const float *line,
const float *point,
float *out)
{
float tmp[2];
BH_Vec2fScale(line, BH_LineDistance(line, point), tmp);
BH_Vec2fSub(point, tmp, out);
}
int BH_Ray2fIntersectLine(const float *start,
const float *direction,
const float *line,
float *t,
float *out)
{
float tmp1[2];
float denom, time;
/* Calculate intersection time */
denom = BH_Vec2fDot(direction, line);
time = (line[2] - BH_Vec2fDot(line, start)) / denom;
/* Check for ray/plane parallel to each other or point is behing the ray. */
if (denom == 0.0f || time < 0.0f)
return BH_ERROR;
/* Compute intersection point */
BH_Vec2fScale(direction, time, tmp1);
BH_Vec2fAdd(start, tmp1, out);
*t = time;
return BH_OK;
}
int BH_Ray2fIntersectTime(const float *startA,
const float *directionA,
const float *startB,
const float *directionB,
float *time1,
float *time2)
{
float tmp1[2], tmp2[2], tmp3[2];
float denom;
/* Rotate directions by 90 degrees and caluclate denom */
tmp1[0] = -directionA[1]; tmp1[1] = directionA[0];
tmp2[0] = -directionB[1]; tmp2[1] = directionB[0];
denom = BH_Vec2fDot(tmp1, directionB);
if (denom == 0.0f)
return BH_ERROR;
/* Calculate segments offset and intersection times */
BH_Vec2fSub(startA, startB, tmp3);
*time1 = BH_Vec2fDot(tmp3, tmp2) / denom;
*time2 = BH_Vec2fDot(tmp3, tmp1) / denom;
return BH_OK;
}
int BH_Ray2fIntersectRay(const float *startA,
const float *directionA,
const float *startB,
const float *directionB,
float *t,
float *out)
{
float tmp[2];
float time1, time2;
if (BH_Ray2fIntersectTime(startA, directionA, startB, directionB, &time1, &time2))
return BH_ERROR;
if (time1 < 0.0f || time2 < 0.0f)
return BH_ERROR;
BH_Vec2fScale(directionA, time1, tmp);
BH_Vec2fAdd(startA, tmp, out);
*t = time1;
return BH_OK;
}
int BH_Ray2fIntersectSegment(const float *startA,
const float *directionA,
const float *startB,
const float *endB,
float *t,
float *out)
{
float tmp[2];
float time1, time2;
BH_Vec2fSub(endB, startB, tmp);
if (BH_Ray2fIntersectTime(startA, directionA, startB, tmp, &time1, &time2))
return BH_ERROR;
if (time1 < 0.0f || time2 < 0.0f || time2 > 1.0f)
return BH_ERROR;
BH_Vec2fScale(directionA, time1, tmp);
BH_Vec2fAdd(startA, tmp, out);
*t = time1;
return BH_OK;
}
int BH_Segment2fIntersectLine(const float *start,
const float *end,
const float *line,
float *t,
float *out)
{
float tmp[2];
float denom, time;
/* Calculate intersection time */
BH_Vec2fSub(end, start, tmp);
denom = BH_Vec2fDot(tmp, line);
time = (line[2] - BH_Vec2fDot(line, start)) / denom;
/* Check for ray/plane parallel to each other or point is behing the ray. */
if (denom == 0.0f || time < 0.0f || time > 1.0f)
return BH_ERROR;
/* Compute intersection point */
BH_Vec2fScale(tmp, time, tmp);
BH_Vec2fAdd(start, tmp, out);
*t = time;
return BH_OK;
}
int BH_Segment2fIntersectSegment(const float *startA,
const float *endA,
const float *startB,
const float *endB,
float *t,
float *out)
{
float tmp1[2], tmp2[2];
float time1, time2;
BH_Vec2fSub(endA, startA, tmp1);
BH_Vec2fSub(endB, startB, tmp2);
if (BH_Ray2fIntersectTime(startA, tmp1, startB, tmp2, &time1, &time2))
return BH_ERROR;
if (time1 < 0.0f || time1 > 1.0f || time2 < 0.0f || time2 > 1.0f)
return BH_ERROR;
BH_Vec2fLerp(startA, endA, time1, out);
*t = time1;
return BH_OK;
}

Binary file not shown.

Binary file not shown.

BIN
test/reference/plane.wxmx Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

84
test/src/TestLine.c Normal file
View File

@@ -0,0 +1,84 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(FromPoints)
{
float a[2], b[2], r[3];
a[0] = -8.0f; a[1] = 1.0f;
b[0] = -2.0f; b[1] = 3.0f;
BH_VERIFY(BH_LineFromPoints(a, b, r) == BH_OK);
BH_VERIFY_DELTA(r[0],-0.3162f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.9487f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.4785f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Degenerate)
{
float a[2], b[2], r[3];
a[0] = -8.0f; a[1] = 1.0f;
b[0] = -8.0f; b[1] = 1.0f;
BH_VERIFY(BH_LineFromPoints(a, b, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(Distance)
{
float a[2], b[2], r[3];
a[0] = -8.0f; a[1] = 1.0f;
b[0] = -2.0f; b[1] = 3.0f;
BH_VERIFY(BH_LineFromPoints(a, b, r) == BH_OK);
BH_VERIFY_DELTA(BH_LineDistance(r, a), 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_LineDistance(r, b), 0.0000f, ACCEPTABLE_DELTA);
a[0] = -7.0f; a[1] = 4.0f;
BH_VERIFY_DELTA(BH_LineDistance(r, a), 2.5298f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(ClosestPoint)
{
float a[2], b[2], r[3];
a[0] = -8.0f; a[1] = 1.0f;
b[0] = -2.0f; b[1] = 3.0f;
BH_VERIFY(BH_LineFromPoints(a, b, r) == BH_OK);
a[0] = -7.0f; a[1] = 4.0f;
BH_LineClosestPoint(r, a, b);
BH_VERIFY_DELTA(b[0],-6.2000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 1.6000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(FromPoints);
BH_UNIT_ADD(Degenerate);
BH_UNIT_ADD(Distance);
BH_UNIT_ADD(ClosestPoint);
return BH_UnitRun();
}

316
test/src/TestMat3f.c Normal file
View File

@@ -0,0 +1,316 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(Identity)
{
float r[9];
BH_Mat3fIdentity(r);
BH_VERIFY(r[0] == 1.0f);
BH_VERIFY(r[1] == 0.0f);
BH_VERIFY(r[2] == 0.0f);
BH_VERIFY(r[3] == 0.0f);
BH_VERIFY(r[4] == 1.0f);
BH_VERIFY(r[5] == 0.0f);
BH_VERIFY(r[6] == 0.0f);
BH_VERIFY(r[7] == 0.0f);
BH_VERIFY(r[8] == 1.0f);
return 0;
}
BH_UNIT_TEST(Add)
{
float a[9], b[9], r[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[3] = 1.0f; b[6] = 2.0f;
b[1] = 3.0f; b[4] = 1.0f; b[7] = 0.0f;
b[2] = 4.0f; b[5] = 2.0f; b[8] = 4.0f;
BH_Mat3fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 8.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Sub)
{
float a[9], b[9], r[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[3] = 1.0f; b[6] = 2.0f;
b[1] = 3.0f; b[4] = 1.0f; b[7] = 0.0f;
b[2] = 4.0f; b[5] = 2.0f; b[8] = 4.0f;
BH_Mat3fSub(a, b, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Mul)
{
float a[9], b[9], r[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[3] = 1.0f; b[6] = 2.0f;
b[1] = 3.0f; b[4] = 1.0f; b[7] = 0.0f;
b[2] = 4.0f; b[5] = 2.0f; b[8] = 4.0f;
BH_Mat3fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 21.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 27.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 12.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 18.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 18.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scale)
{
float a[9], r[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
BH_Mat3fScale(a, 10, r);
BH_VERIFY_DELTA(r[0], 50.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 40.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Transpose)
{
float a[9], r[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
BH_Mat3fTranspose(a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Trace)
{
float a[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
BH_VERIFY_DELTA(BH_Mat3fTrace(a), 9.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Det)
{
float a[9], b[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[3] = 1.0f; b[6] = 2.0f;
b[1] = 3.0f; b[4] = 1.0f; b[7] = 0.0f;
b[2] = 4.0f; b[5] = 2.0f; b[8] = 4.0f;
BH_VERIFY_DELTA(BH_Mat3fDet(a), 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_Mat3fDet(b), 0.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Inverse)
{
float a[9], b[9], r[9];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[3] = 1.0f; b[6] = 2.0f;
b[1] = 3.0f; b[4] = 1.0f; b[7] = 0.0f;
b[2] = 4.0f; b[5] = 2.0f; b[8] = 4.0f;
BH_VERIFY(BH_Mat3fInverse(a, r) == BH_OK);
BH_VERIFY_DELTA(r[0], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 1.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.3333f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], -2.3333f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], -0.5000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Mat3fInverse(b, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(Translation)
{
float r[9];
BH_Mat3fFromTranslation(1.0f, 2.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scaling)
{
float r[9];
BH_Mat3fFromScale(1.0f, 2.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Apply)
{
float a[9];
float b[3];
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[1] = -1.0f; b[2] = 4.0f;
BH_Mat3fApplyVec3f(a, b, b);
BH_VERIFY_DELTA(b[0], 17.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[2], 15.0000f, ACCEPTABLE_DELTA);
b[0] = 2.0f; b[1] = -1.0f;
BH_Mat3fApplyVec2f(a, b, b);
BH_VERIFY_DELTA(b[0], 11.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 6.0000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Identity);
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(Transpose);
BH_UNIT_ADD(Trace);
BH_UNIT_ADD(Det);
BH_UNIT_ADD(Inverse);
BH_UNIT_ADD(Translation);
BH_UNIT_ADD(Scaling);
BH_UNIT_ADD(Apply);
return BH_UnitRun();
}

404
test/src/TestMat4f.c Normal file
View File

@@ -0,0 +1,404 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(Identity)
{
float r[16];
BH_Mat4fIdentity(r);
BH_VERIFY(r[0] == 1.0f);
BH_VERIFY(r[1] == 0.0f);
BH_VERIFY(r[2] == 0.0f);
BH_VERIFY(r[3] == 0.0f);
BH_VERIFY(r[4] == 0.0f);
BH_VERIFY(r[5] == 1.0f);
BH_VERIFY(r[6] == 0.0f);
BH_VERIFY(r[7] == 0.0f);
BH_VERIFY(r[8] == 0.0f);
BH_VERIFY(r[9] == 0.0f);
BH_VERIFY(r[10] == 1.0f);
BH_VERIFY(r[11] == 0.0f);
BH_VERIFY(r[12] == 0.0f);
BH_VERIFY(r[13] == 0.0f);
BH_VERIFY(r[14] == 0.0f);
BH_VERIFY(r[15] == 1.0f);
return 0;
}
BH_UNIT_TEST(Add)
{
float a[16], b[16], r[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 5.0f; b[4] = 1.0f; b[8] = 2.0f; b[12] = 7.0f;
b[1] = 3.0f; b[5] = 1.0f; b[9] = 0.0f; b[13] = 2.0f;
b[2] = 4.0f; b[6] = 2.0f; b[10] = 4.0f; b[14] = 5.0f;
b[3] = 6.0f; b[7] = 2.0f; b[11] = 0.0f; b[15] = 4.0f;
BH_Mat4fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 10.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 14.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 7.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Sub)
{
float a[16], b[16], r[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 5.0f; b[4] = 1.0f; b[8] = 2.0f; b[12] = 7.0f;
b[1] = 3.0f; b[5] = 1.0f; b[9] = 0.0f; b[13] = 2.0f;
b[2] = 4.0f; b[6] = 2.0f; b[10] = 4.0f; b[14] = 5.0f;
b[3] = 6.0f; b[7] = 2.0f; b[11] = 0.0f; b[15] = 4.0f;
BH_Mat4fSub(a, b, r);
BH_VERIFY_DELTA(r[0], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], -1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Mul)
{
float a[16], b[16], r[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 5.0f; b[4] = 1.0f; b[8] = 2.0f; b[12] = 7.0f;
b[1] = 3.0f; b[5] = 1.0f; b[9] = 0.0f; b[13] = 2.0f;
b[2] = 4.0f; b[6] = 2.0f; b[10] = 4.0f; b[14] = 5.0f;
b[3] = 6.0f; b[7] = 2.0f; b[11] = 0.0f; b[15] = 4.0f;
BH_Mat4fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 78.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 27.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 60.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 28.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 24.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 22.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 18.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 18.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 75.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 29.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 53.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 26.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scale)
{
float a[16], r[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
BH_Mat4fScale(a, 10, r);
BH_VERIFY_DELTA(r[0], 50.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 40.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 70.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 50.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 30.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Transpose)
{
float a[16], r[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
BH_Mat4fTranspose(a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 3.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Trace)
{
float a[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
BH_VERIFY_DELTA(BH_Mat4fTrace(a), 12.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Det)
{
float a[16], b[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 5.0f; b[4] = 1.0f; b[8] = 2.0f; b[12] = 7.0f;
b[1] = 3.0f; b[5] = 1.0f; b[9] = 0.0f; b[13] = 2.0f;
b[2] = 4.0f; b[6] = 2.0f; b[10] = 4.0f; b[14] = 5.0f;
b[3] = 6.0f; b[7] = 2.0f; b[11] = 0.0f; b[15] = 4.0f;
BH_VERIFY_DELTA(BH_Mat4fDet(a), 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_Mat4fDet(b), 0.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Inverse)
{
float a[16], b[16], r[16];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 5.0f; b[4] = 1.0f; b[8] = 2.0f; b[12] = 7.0f;
b[1] = 3.0f; b[5] = 1.0f; b[9] = 0.0f; b[13] = 2.0f;
b[2] = 4.0f; b[6] = 2.0f; b[10] = 4.0f; b[14] = 5.0f;
b[3] = 6.0f; b[7] = 2.0f; b[11] = 0.0f; b[15] = 4.0f;
BH_VERIFY(BH_Mat4fInverse(a, r) == BH_OK);
BH_VERIFY_DELTA(r[0], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 1.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.6000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.8000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], -0.4000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], -0.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], -0.4000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 1.8000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 0.6000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Mat4fInverse(b, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(Translation)
{
float r[16];
BH_Mat4fFromTranslation(1.0f, 2.0f, 3.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scaling)
{
float r[16];
BH_Mat4fFromScale(1.0f, 2.0f, 3.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Apply)
{
float a[16];
float b[4];
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 2.0f; b[1] = -1.0f; b[2] = 4.0f; b[3] = 0.0f;
BH_Mat4fApplyVec4f(a, b, b);
BH_VERIFY_DELTA(b[0], 17.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[2], 15.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[3], 4.0000f, ACCEPTABLE_DELTA);
b[0] = 2.0f; b[1] = -1.0f; b[2] = 4.0f;
BH_Mat4fApplyVec3f(a, b, b);
BH_VERIFY_DELTA(b[0], 24.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[2], 20.0000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Identity);
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(Transpose);
BH_UNIT_ADD(Trace);
BH_UNIT_ADD(Det);
BH_UNIT_ADD(Inverse);
BH_UNIT_ADD(Translation);
BH_UNIT_ADD(Scaling);
BH_UNIT_ADD(Apply);
return BH_UnitRun();
}

View File

@@ -5,827 +5,7 @@
#define ACCEPTABLE_DELTA 0.0001f
static int checkVec4f(void)
{
float a[4], b[4], c[4], r[4];
float value;
a[0] = 1.0f; a[1] = 2.0f; a[2] = 3.0f; a[3] = 4.0f;
b[0] = 5.0f; b[1] = 6.0f; b[2] = 7.0f; b[3] = 8.0f;
c[0] = 1.5f; c[1] = 2.5f; c[2] = 3.5f; c[3] = 4.5f;
BH_Vec4fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 12.0000f, ACCEPTABLE_DELTA);
BH_Vec4fSub(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], -4.0000f, ACCEPTABLE_DELTA);
BH_Vec4fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 12.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 21.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 32.0000f, ACCEPTABLE_DELTA);
BH_Vec4fScale(a, 10.0f, r);
BH_VERIFY_DELTA(r[0], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 40.0000f, ACCEPTABLE_DELTA);
BH_Vec4fMulAdd(a, b, c, r);
BH_VERIFY_DELTA(r[0], 6.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 14.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 24.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 36.5000f, ACCEPTABLE_DELTA);
BH_Vec4fNegate(a, r);
BH_VERIFY_DELTA(r[0], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], -4.0000f, ACCEPTABLE_DELTA);
value = BH_Vec4fDot(a, b);
BH_VERIFY_DELTA(value, 70.0000f, ACCEPTABLE_DELTA);
value = BH_Vec4fLength(a);
BH_VERIFY_DELTA(value, sqrt(30.0f), ACCEPTABLE_DELTA);
BH_Vec4fNormal(a, r);
BH_VERIFY_DELTA(r[0], 1.0f / sqrt(30.0f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f / sqrt(30.0f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0f / sqrt(30.0f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0f / sqrt(30.0f), ACCEPTABLE_DELTA);
BH_Vec4fMin(a, b, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f, ACCEPTABLE_DELTA);
BH_Vec4fMax(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
BH_Vec4fLerp(a, b, 0.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f, ACCEPTABLE_DELTA);
BH_Vec4fLerp(a, b, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 6.0000f, ACCEPTABLE_DELTA);
BH_Vec4fLerp(a, b, 1.0f, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
return 0;
}
static int checkVec3f(void)
{
float a[3], b[3], c[3], r[3];
float value;
a[0] = 1.0f; a[1] = 2.0f; a[2] = 3.0f;
b[0] = 5.0f; b[1] = 6.0f; b[2] = 7.0f;
c[0] = 1.5f; c[1] = 2.5f; c[2] = 3.5f;
BH_Vec3fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 6.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0f, ACCEPTABLE_DELTA);
BH_Vec3fSub(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -4.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -4.0f, ACCEPTABLE_DELTA);
BH_Vec3fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 12.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 21.0f, ACCEPTABLE_DELTA);
BH_Vec3fScale(a, 10.0f, r);
BH_VERIFY_DELTA(r[0], 10.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 20.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 30.0f, ACCEPTABLE_DELTA);
BH_Vec3fMulAdd(a, b, c, r);
BH_VERIFY_DELTA(r[0], 6.5f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 14.5f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 24.5f, ACCEPTABLE_DELTA);
BH_Vec3fNegate(a, r);
BH_VERIFY_DELTA(r[0], -1.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0f, ACCEPTABLE_DELTA);
value = BH_Vec3fDot(a, b);
BH_VERIFY_DELTA(value, 38.0f, ACCEPTABLE_DELTA);
BH_Vec3fCross(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -4.0f, ACCEPTABLE_DELTA);
value = BH_Vec3fLength(a);
BH_VERIFY_DELTA(value, sqrt(14.0f), ACCEPTABLE_DELTA);
BH_Vec3fNormal(a, r);
BH_VERIFY_DELTA(r[0], 1.0f / sqrt(14.0f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f / sqrt(14.0f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0f / sqrt(14.0f), ACCEPTABLE_DELTA);
BH_Vec3fMin(a, b, r);
BH_VERIFY_DELTA(r[0], 1.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0f, ACCEPTABLE_DELTA);
BH_Vec3fMax(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0f, ACCEPTABLE_DELTA);
BH_Vec3fLerp(a, b, 0.0f, r);
BH_VERIFY_DELTA(r[0], 1.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0f, ACCEPTABLE_DELTA);
BH_Vec3fLerp(a, b, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0f, ACCEPTABLE_DELTA);
BH_Vec3fLerp(a, b, 1.0f, r);
BH_VERIFY_DELTA(r[0], 5.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0f, ACCEPTABLE_DELTA);
return 0;
}
static int checkVec2f(void)
{
float a[2], b[2], c[2], r[2];
float value;
a[0] = 1.0f; a[1] = 2.0f;
b[0] = 5.0f; b[1] = 6.0f;
c[0] = 1.5f; c[1] = 2.5f;
BH_Vec2fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 6.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0f, ACCEPTABLE_DELTA);
BH_Vec2fSub(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -4.0f, ACCEPTABLE_DELTA);
BH_Vec2fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 12.0f, ACCEPTABLE_DELTA);
BH_Vec2fScale(a, 10.0f, r);
BH_VERIFY_DELTA(r[0], 10.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 20.0f, ACCEPTABLE_DELTA);
BH_Vec2fMulAdd(a, b, c, r);
BH_VERIFY_DELTA(r[0], 6.5f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 14.5f, ACCEPTABLE_DELTA);
BH_Vec2fNegate(a, r);
BH_VERIFY_DELTA(r[0], -1.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0f, ACCEPTABLE_DELTA);
value = BH_Vec2fDot(a, b);
BH_VERIFY_DELTA(value, 17.0f, ACCEPTABLE_DELTA);
value = BH_Vec2fCross(a, b);
BH_VERIFY_DELTA(value, -4.0f, ACCEPTABLE_DELTA);
value = BH_Vec2fLength(a);
BH_VERIFY_DELTA(value, sqrt(5.0f), ACCEPTABLE_DELTA);
BH_Vec2fNormal(a, r);
BH_VERIFY_DELTA(r[0], 1.0f / sqrt(5.0f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f / sqrt(5.0f), ACCEPTABLE_DELTA);
BH_Vec2fMin(a, b, r);
BH_VERIFY_DELTA(r[0], 1.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f, ACCEPTABLE_DELTA);
BH_Vec2fMax(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a, b, 0.0f, r);
BH_VERIFY_DELTA(r[0], 1.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a, b, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.0f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a, b, 1.0f, r);
BH_VERIFY_DELTA(r[0], 5.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0f, ACCEPTABLE_DELTA);
return 0;
}
static int checkVec4i(void)
{
int a[4], b[4], c[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
c[0] = 4; c[1] = 3; c[2] = 2; c[3] = 1;
BH_Vec4iAdd(a, b, r);
BH_VERIFY(r[0] == 6);
BH_VERIFY(r[1] == 8);
BH_VERIFY(r[2] == 10);
BH_VERIFY(r[3] == 12);
BH_Vec4iSub(a, b, r);
BH_VERIFY(r[0] == -4);
BH_VERIFY(r[1] == -4);
BH_VERIFY(r[2] == -4);
BH_VERIFY(r[3] == -4);
BH_Vec4iMul(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 12);
BH_VERIFY(r[2] == 21);
BH_VERIFY(r[3] == 32);
BH_Vec4iScale(a, 10, r);
BH_VERIFY(r[0] == 10);
BH_VERIFY(r[1] == 20);
BH_VERIFY(r[2] == 30);
BH_VERIFY(r[3] == 40);
BH_Vec4iMulAdd(a, b, c, r);
BH_VERIFY(r[0] == 9);
BH_VERIFY(r[1] == 15);
BH_VERIFY(r[2] == 23);
BH_VERIFY(r[3] == 33);
BH_Vec4iNegate(a, r);
BH_VERIFY(r[0] == -1);
BH_VERIFY(r[1] == -2);
BH_VERIFY(r[2] == -3);
BH_VERIFY(r[3] == -4);
BH_Vec4iMin(a, b, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_VERIFY(r[2] == 3);
BH_VERIFY(r[3] == 4);
BH_Vec4iMax(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_VERIFY(r[2] == 7);
BH_VERIFY(r[3] == 8);
return 0;
}
static int checkVec3i(void)
{
int a[3], b[3], c[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
c[0] = 4; c[1] = 3; c[2] = 2;
BH_Vec3iAdd(a, b, r);
BH_VERIFY(r[0] == 6);
BH_VERIFY(r[1] == 8);
BH_VERIFY(r[2] == 10);
BH_Vec3iSub(a, b, r);
BH_VERIFY(r[0] == -4);
BH_VERIFY(r[1] == -4);
BH_VERIFY(r[2] == -4);
BH_Vec3iMul(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 12);
BH_VERIFY(r[2] == 21);
BH_Vec3iScale(a, 10, r);
BH_VERIFY(r[0] == 10);
BH_VERIFY(r[1] == 20);
BH_VERIFY(r[2] == 30);
BH_Vec3iMulAdd(a, b, c, r);
BH_VERIFY(r[0] == 9);
BH_VERIFY(r[1] == 15);
BH_VERIFY(r[2] == 23);
BH_Vec3iNegate(a, r);
BH_VERIFY(r[0] == -1);
BH_VERIFY(r[1] == -2);
BH_VERIFY(r[2] == -3);
BH_Vec3iMin(a, b, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_VERIFY(r[2] == 3);
BH_Vec3iMax(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_VERIFY(r[2] == 7);
return 0;
}
static int checkVec2i(void)
{
int a[2], b[2], c[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
c[0] = 4; c[1] = 3;
BH_Vec2iAdd(a, b, r);
BH_VERIFY(r[0] == 6);
BH_VERIFY(r[1] == 8);
BH_Vec2iSub(a, b, r);
BH_VERIFY(r[0] == -4);
BH_VERIFY(r[1] == -4);
BH_Vec2iMul(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 12);
BH_Vec2iScale(a, 10, r);
BH_VERIFY(r[0] == 10);
BH_VERIFY(r[1] == 20);
BH_Vec2iMulAdd(a, b, c, r);
BH_VERIFY(r[0] == 9);
BH_VERIFY(r[1] == 15);
BH_Vec2iNegate(a, r);
BH_VERIFY(r[0] == -1);
BH_VERIFY(r[1] == -2);
BH_Vec2iMin(a, b, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_Vec2iMax(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
return 0;
}
static int checkQuat(void)
{
float a[4], b[3], r[4];
float roll, pitch, yaw, angle;
a[0] = -0.9018f; a[1] = -0.0010f; a[2] = -0.4099f; a[3] = 0.1370f;
b[0] = -0.9104f; b[1] = -0.0010f; b[2] = -0.4138f;
BH_Quat4fIdentity(r);
BH_VERIFY_DELTA(r[0], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 1.000f, ACCEPTABLE_DELTA);
BH_Quat4fConjugate(a, r);
BH_VERIFY_DELTA(r[0], 0.9018f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.4099f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.1370f, ACCEPTABLE_DELTA);
BH_Quat4fToEuler(a, &roll, &pitch, &yaw);
BH_VERIFY_DELTA(roll, -2.7671f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(pitch, -0.8324f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(yaw, -0.1649f, ACCEPTABLE_DELTA);
BH_Quat4fFromEuler(-2.7671f, -0.8324f, -0.1649f, r);
BH_VERIFY_DELTA(r[0], -0.9018f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -0.4099f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.1370f, ACCEPTABLE_DELTA);
BH_Quat4fFromAxis(b, 2.8668f, r);
BH_VERIFY_DELTA(r[0], -0.9018f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -0.4099f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.1370f, ACCEPTABLE_DELTA);
BH_Quat4fToAxis(a, r, &angle);
BH_VERIFY_DELTA(r[0], -0.9104f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -0.4138f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(angle, 2.8668f, ACCEPTABLE_DELTA);
BH_Quat4fInverse(a, r);
BH_Quat4fMul(a, r, r);
BH_VERIFY_DELTA(r[0], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 1.000f, ACCEPTABLE_DELTA);
return 0;
}
static int checkMat4f(void)
{
float a[16], b[16], r[16];
float value;
a[0] = 5.0f; a[4] = 1.0f; a[8] = 2.0f; a[12] = 7.0f;
a[1] = 3.0f; a[5] = 0.0f; a[9] = 0.0f; a[13] = 2.0f;
a[2] = 1.0f; a[6] = 3.0f; a[10] = 4.0f; a[14] = 5.0f;
a[3] = 2.0f; a[7] = 0.0f; a[11] = 0.0f; a[15] = 3.0f;
b[0] = 5.0f; b[4] = 1.0f; b[8] = 2.0f; b[12] = 7.0f;
b[1] = 3.0f; b[5] = 1.0f; b[9] = 0.0f; b[13] = 2.0f;
b[2] = 4.0f; b[6] = 2.0f; b[10] = 4.0f; b[14] = 5.0f;
b[3] = 6.0f; b[7] = 2.0f; b[11] = 0.0f; b[15] = 4.0f;
BH_Mat4fIdentity(r);
BH_VERIFY(r[0] == 1.0f);
BH_VERIFY(r[1] == 0.0f);
BH_VERIFY(r[2] == 0.0f);
BH_VERIFY(r[3] == 0.0f);
BH_VERIFY(r[4] == 0.0f);
BH_VERIFY(r[5] == 1.0f);
BH_VERIFY(r[6] == 0.0f);
BH_VERIFY(r[7] == 0.0f);
BH_VERIFY(r[8] == 0.0f);
BH_VERIFY(r[9] == 0.0f);
BH_VERIFY(r[10] == 1.0f);
BH_VERIFY(r[11] == 0.0f);
BH_VERIFY(r[12] == 0.0f);
BH_VERIFY(r[13] == 0.0f);
BH_VERIFY(r[14] == 0.0f);
BH_VERIFY(r[15] == 1.0f);
BH_Mat4fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 10.0f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 14.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 7.0000f, ACCEPTABLE_DELTA);
BH_Mat4fSub(a, b, r);
BH_VERIFY_DELTA(r[0], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], -1.0000f, ACCEPTABLE_DELTA);
BH_Mat4fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 78.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 27.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 60.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 28.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 24.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 22.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 18.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 18.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 75.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 29.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 53.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 26.0000f, ACCEPTABLE_DELTA);
BH_Mat4fScale(a, 10, r);
BH_VERIFY_DELTA(r[0], 50.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 40.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 70.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 50.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 30.0000f, ACCEPTABLE_DELTA);
BH_Mat4fTranspose(a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 3.0000f, ACCEPTABLE_DELTA);
value = BH_Mat4fTrace(a);
BH_VERIFY_DELTA(value, 12.0000f, ACCEPTABLE_DELTA);
value = BH_Mat4fDet(a);
BH_VERIFY_DELTA(value, 10.0000f, ACCEPTABLE_DELTA);
value = BH_Mat4fDet(b);
BH_VERIFY_DELTA(value, 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Mat4fInverse(a, r) == BH_OK);
BH_VERIFY_DELTA(r[0], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 1.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.6000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.8000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], -0.4000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], -0.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], -0.4000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 1.8000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 0.6000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Mat4fInverse(b, r) != BH_OK);
BH_Mat4fFromTranslation(1.0f, 2.0f, 3.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 1.0000f, ACCEPTABLE_DELTA);
BH_Mat4fFromScale(1.0f, 2.0f, 3.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[9], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[10], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[11], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[12], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[13], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[14], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[15], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
static int checkMat3f(void)
{
float a[9], b[9], r[9];
float value;
a[0] = 5.0f; a[3] = 1.0f; a[6] = 2.0f;
a[1] = 3.0f; a[4] = 0.0f; a[7] = 0.0f;
a[2] = 1.0f; a[5] = 3.0f; a[8] = 4.0f;
b[0] = 2.0f; b[3] = 1.0f; b[6] = 2.0f;
b[1] = 3.0f; b[4] = 1.0f; b[7] = 0.0f;
b[2] = 4.0f; b[5] = 2.0f; b[8] = 4.0f;
BH_Mat3fIdentity(r);
BH_VERIFY(r[0] == 1.0f);
BH_VERIFY(r[1] == 0.0f);
BH_VERIFY(r[2] == 0.0f);
BH_VERIFY(r[3] == 0.0f);
BH_VERIFY(r[4] == 1.0f);
BH_VERIFY(r[5] == 0.0f);
BH_VERIFY(r[6] == 0.0f);
BH_VERIFY(r[7] == 0.0f);
BH_VERIFY(r[8] == 1.0f);
BH_Mat3fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 8.0000f, ACCEPTABLE_DELTA);
BH_Mat3fSub(a, b, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 0.0000f, ACCEPTABLE_DELTA);
BH_Mat3fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 21.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 27.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 12.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 18.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 18.0000f, ACCEPTABLE_DELTA);
BH_Mat3fScale(a, 10, r);
BH_VERIFY_DELTA(r[0], 50.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 40.0000f, ACCEPTABLE_DELTA);
BH_Mat3fTranspose(a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 4.0000f, ACCEPTABLE_DELTA);
value = BH_Mat3fTrace(a);
BH_VERIFY_DELTA(value, 9.0000f, ACCEPTABLE_DELTA);
value = BH_Mat3fDet(a);
BH_VERIFY_DELTA(value, 6.0000f, ACCEPTABLE_DELTA);
value = BH_Mat3fDet(b);
BH_VERIFY_DELTA(value, 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Mat3fInverse(a, r) == BH_OK);
BH_VERIFY_DELTA(r[0], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 1.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.3333f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], -2.3333f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], -0.5000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Mat3fInverse(b, r) != BH_OK);
BH_Mat3fFromTranslation(1.0f, 2.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 1.0000f, ACCEPTABLE_DELTA);
BH_Mat3fFromScale(1.0f, 2.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[4], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[5], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[6], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[7], 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[8], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
int checkQuatMat4f(void)
BH_UNIT_TEST(QuatMat4fParity)
{
float a[16], b[16], c[4];
@@ -859,75 +39,12 @@ int checkQuatMat4f(void)
}
int checkVecMat4f(void)
{
float a[16] =
{
5.0f, 3.0f, 1.0f, 2.0f,
1.0f, 0.0f, 3.0f, 0.0f,
2.0f, 0.0f, 4.0f, 0.0f,
7.0f, 2.0f, 5.0f, 3.0f
};
float b[4];
b[0] = 2.0f; b[1] = -1.0f; b[2] = 4.0f; b[3] = 0.0f;
BH_Mat4fApplyVec4f(a, b, b);
BH_VERIFY_DELTA(b[0], 17.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[2], 15.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[3], 4.0000f, ACCEPTABLE_DELTA);
b[0] = 2.0f; b[1] = -1.0f; b[2] = 4.0f;
BH_Mat4fApplyVec3f(a, b, b);
BH_VERIFY_DELTA(b[0], 24.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[2], 20.0000f, ACCEPTABLE_DELTA);
return 0;
}
int checkVecMat3f(void)
{
float a[9] =
{
0.0f, 1.0f, -3.0f,
-3.0f, -4.0f, 4.0f,
-2.0f, -2.0f, 1.0f,
};
float b[3];
b[0] = 2.0f; b[1] = -1.0f; b[2] = 4.0f;
BH_Mat3fApplyVec3f(a, b, b);
BH_VERIFY_DELTA(b[0], -5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[2], -6.0000f, ACCEPTABLE_DELTA);
b[0] = 2.0f; b[1] = -1.0f;
BH_Mat3fApplyVec2f(a, b, b);
BH_VERIFY_DELTA(b[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(b[1], 4.0000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UnitAdd("Vec4f", checkVec4f);
BH_UnitAdd("Vec3f", checkVec3f);
BH_UnitAdd("Vec2f", checkVec2f);
BH_UnitAdd("Vec4i", checkVec4i);
BH_UnitAdd("Vec3i", checkVec3i);
BH_UnitAdd("Vec2i", checkVec2i);
BH_UnitAdd("Quat", checkQuat);
BH_UnitAdd("Mat4f", checkMat4f);
BH_UnitAdd("Mat3f", checkMat3f);
BH_UnitAdd("QuatMat4f", checkQuatMat4f);
BH_UnitAdd("VecMat4f", checkVecMat4f);
BH_UnitAdd("VecMat3f", checkVecMat3f);
BH_UNIT_ADD(QuatMat4fParity);
return BH_UnitRun();
}

96
test/src/TestPlane.c Normal file
View File

@@ -0,0 +1,96 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(FromPoints)
{
float a[3], b[3], c[3], r[4];
a[0] = 1; a[1] = -2; a[2] = 1;
b[0] = 4; b[1] = -2; b[2] = -2;
c[0] = 4; c[1] = 1; c[2] = 4;
BH_VERIFY(BH_PlaneFromPoints(a, b, c, r) == BH_OK);
BH_VERIFY_DELTA(r[0],-0.4082f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.8165f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2],-0.4082f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3],-2.4495f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Degenerate)
{
float a[3], b[3], c[3], r[4];
a[0] = 1; a[1] = -2; a[2] = 1;
b[0] = 1; b[1] = -2; b[2] = 1;
c[0] = 4; c[1] = 1; c[2] = 4;
BH_VERIFY(BH_PlaneFromPoints(a, b, c, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(Distance)
{
float a[3], b[3], c[3], r[4];
a[0] = 1; a[1] = -2; a[2] = 1;
b[0] = 4; b[1] = -2; b[2] = -2;
c[0] = 4; c[1] = 1; c[2] = 4;
BH_VERIFY(BH_PlaneFromPoints(a, b, c, r) == BH_OK);
BH_VERIFY_DELTA(BH_PlaneDistance(r, a), 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_PlaneDistance(r, b), 0.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_PlaneDistance(r, c), 0.0000f, ACCEPTABLE_DELTA);
a[0] = 3; a[1] = 4; a[2] = 5;
b[0] = 2; b[1] = -1; b[2] = 6;
BH_VERIFY_DELTA(BH_PlaneDistance(r, a), 2.4495f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_PlaneDistance(r, b), -1.6330f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(ClosestPoint)
{
float a[3], b[3], c[3], r[4];
a[0] = 1; a[1] = -2; a[2] = 1;
b[0] = 4; b[1] = -2; b[2] = -2;
c[0] = 4; c[1] = 1; c[2] = 4;
BH_VERIFY(BH_PlaneFromPoints(a, b, c, r) == BH_OK);
b[0] = 3; b[1] = 4; b[2] = 5;
BH_PlaneClosestPoint(r, b, c);
BH_VERIFY_DELTA(c[0], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(c[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(c[2], 6.0000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(FromPoints);
BH_UNIT_ADD(Degenerate);
BH_UNIT_ADD(Distance);
BH_UNIT_ADD(ClosestPoint);
return BH_UnitRun();
}

131
test/src/TestQuat.c Normal file
View File

@@ -0,0 +1,131 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(Identity)
{
float r[4];
BH_Quat4fIdentity(r);
BH_VERIFY_DELTA(r[0], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 1.000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Conjugate)
{
float a[4], r[4];
a[0] = -0.9018f; a[1] = -0.0010f; a[2] = -0.4099f; a[3] = 0.1370f;
BH_Quat4fConjugate(a, r);
BH_VERIFY_DELTA(r[0], 0.9018f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.4099f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.1370f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(ToEuler)
{
float a[4];
float roll, pitch, yaw;
a[0] = -0.9018f; a[1] = -0.0010f; a[2] = -0.4099f; a[3] = 0.1370f;
BH_Quat4fToEuler(a, &roll, &pitch, &yaw);
BH_VERIFY_DELTA(roll, -2.7671f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(pitch, -0.8324f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(yaw, -0.1649f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(FromEuler)
{
float r[4];
BH_Quat4fFromEuler(-2.7671f, -0.8324f, -0.1649f, r);
BH_VERIFY_DELTA(r[0], -0.9018f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -0.4099f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.1370f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(ToAxis)
{
float a[4], r[3];
float angle;
a[0] = -0.9018f; a[1] = -0.0010f; a[2] = -0.4099f; a[3] = 0.1370f;
BH_Quat4fToAxis(a, r, &angle);
BH_VERIFY_DELTA(r[0], -0.9104f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -0.4138f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(angle, 2.8668f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(FromAxis)
{
float a[3], r[4];
a[0] = -0.9104f; a[1] = -0.0010f; a[2] = -0.4138f;
BH_Quat4fFromAxis(a, 2.8668f, r);
BH_VERIFY_DELTA(r[0], -0.9018f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -0.0010f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -0.4099f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.1370f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(InverseMultiply)
{
float a[4], r[4];
a[0] = -0.9018f; a[1] = -0.0010f; a[2] = -0.4099f; a[3] = 0.1370f;
BH_Quat4fInverse(a, r);
BH_Quat4fMul(a, r, r);
BH_VERIFY_DELTA(r[0], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 0.000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 1.000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Identity);
BH_UNIT_ADD(Conjugate);
BH_UNIT_ADD(ToEuler);
BH_UNIT_ADD(FromEuler);
BH_UNIT_ADD(ToAxis);
BH_UNIT_ADD(FromAxis);
BH_UNIT_ADD(InverseMultiply);
return BH_UnitRun();
}

196
test/src/TestRay2f.c Normal file
View File

@@ -0,0 +1,196 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(RayIntersectLine)
{
float a[2], b[2], p[2], d[2], r[3];
float time;
a[0] = 4.0000f; a[1] = 9.0000f;
b[0] = 2.0000f; b[1] = 5.0000f;
p[0] = -5.0000f; p[1] = 3.0000f;
d[0] = 0.8944f; d[1] = 0.4472f;
BH_VERIFY(BH_LineFromPoints(a, b, r) == BH_OK);
BH_VERIFY(BH_Ray2fIntersectLine(p, d, r, &time, r) == BH_OK);
BH_VERIFY_DELTA(time, 8.9443f, ACCEPTABLE_DELTA * 10);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec2fScale(d, time, r);
BH_Vec2fAdd(p, r, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
d[0] = -2.0000f; d[1] = -4.0000f;
BH_VERIFY(BH_LineFromPoints(a, b, r) == BH_OK);
BH_VERIFY(BH_Ray2fIntersectLine(p, d, r, &time, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(RayIntersectRay)
{
float p1[2], d1[2], p2[2], d2[2], r[2];
float time;
p1[0] = -5.0000f; p1[1] = 3.0000f;
d1[0] = 0.8944f; d1[1] = 0.4472f;
p2[0] = 4.0000f; p2[1] = 9.0000f;
d2[0] = -0.4472f; d2[1] =-0.8944f;
BH_VERIFY(BH_Ray2fIntersectRay(p1, d1, p2, d2, &time, r) == BH_OK);
BH_VERIFY_DELTA(time, 8.9443f, ACCEPTABLE_DELTA * 10);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec2fScale(d1, time, r);
BH_Vec2fAdd(p1, r, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY(BH_Ray2fIntersectRay(p1, d1, p2, d1, &time, r) != BH_OK);
d1[0] = 0.0000f; d1[1] = 1.0000f;
BH_VERIFY(BH_Ray2fIntersectRay(p1, d1, p2, d2, &time, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(RayIntersectSegment)
{
float p[2], d[2], a[2], b[2], r[2];
float time;
p[0] = -5.0000f; p[1] = 3.0000f;
d[0] = 0.8944f; d[1] = 0.4472f;
a[0] = 4.0000f; a[1] = 9.0000f;
b[0] = 2.0000f; b[1] = 5.0000f;
BH_VERIFY(BH_Ray2fIntersectSegment(p, d, a, b, &time, r) == BH_OK);
BH_VERIFY_DELTA(time, 8.9443f, ACCEPTABLE_DELTA * 10);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec2fScale(d, time, r);
BH_Vec2fAdd(p, r, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
d[0] = -2.0000f; d[1] = -4.0000f;
BH_VERIFY(BH_Ray2fIntersectSegment(p, d, a, b, &time, r) != BH_OK);
d[0] = 1.0000f; d[1] = 0.0000f;
BH_VERIFY(BH_Ray2fIntersectSegment(p, d, a, b, &time, r) != BH_OK);
return 0;
}
BH_UNIT_TEST(SegmentIntersectLine)
{
float a1[2], b1[2], a2[2], b2[2], r[3];
float time;
a1[0] = -5.0000f; a1[1] = 3.0000f;
b1[0] = 5.0000f; b1[1] = 8.0000f;
a2[0] = 4.0000f; a2[1] = 9.0000f;
b2[0] = 2.0000f; b2[1] = 5.0000f;
BH_VERIFY(BH_LineFromPoints(a2, b2, r) == BH_OK);
BH_VERIFY(BH_Segment2fIntersectLine(a1, b1, r, &time, r) == BH_OK);
BH_VERIFY_DELTA(time, 0.8000f, ACCEPTABLE_DELTA * 10);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a1, b1, time, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(SegmentIntersectSegment)
{
float a1[2], b1[2], a2[2], b2[2], r[2];
float time;
a1[0] = -5.0000f; a1[1] = 3.0000f;
b1[0] = 5.0000f; b1[1] = 8.0000f;
a2[0] = 4.0000f; a2[1] = 9.0000f;
b2[0] = 2.0000f; b2[1] = 5.0000f;
BH_VERIFY(BH_Segment2fIntersectSegment(a1, b1, a2, b2, &time, r) == BH_OK);
BH_VERIFY_DELTA(time, 0.8000f, ACCEPTABLE_DELTA * 10);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a1, b1, time, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Time)
{
float a1[2], b1[2], a2[2], b2[2], r[2];
float time1, time2;
a1[0] = -5.0000f; a1[1] = 3.0000f;
b1[0] = 10.0000f; b1[1] = 5.0000f;
a2[0] = 4.0000f; a2[1] = 9.0000f;
b2[0] = -2.0000f; b2[1] =-4.0000f;
BH_VERIFY(BH_Ray2fIntersectTime(a1, b1, a2, b2, &time1, &time2) == BH_OK);
BH_VERIFY_DELTA(time1, 0.8000f, ACCEPTABLE_DELTA * 10);
BH_VERIFY_DELTA(time2, 0.5000f, ACCEPTABLE_DELTA * 10);
BH_Vec2fScale(b1, time1, r);
BH_Vec2fAdd(a1, r, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec2fScale(b2, time2, r);
BH_Vec2fAdd(a2, r, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 7.0000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(RayIntersectLine);
BH_UNIT_ADD(RayIntersectRay);
BH_UNIT_ADD(RayIntersectSegment);
BH_UNIT_ADD(SegmentIntersectLine);
BH_UNIT_ADD(SegmentIntersectSegment);
BH_UNIT_ADD(Time);
return BH_UnitRun();
}

99
test/src/TestRay3f.c Normal file
View File

@@ -0,0 +1,99 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(RayIntersectTriangle)
{
float a[3], b[3], c[3], p[3], d[3], out[3], t;
a[0] =-3.0000f; a[1] = 1.0000f; a[2] = 2.0000f;
b[0] =-5.0000f; b[1] =-2.0000f; b[2] = 0.0000f;
c[0] =-6.0000f; c[1] = 2.5000f; c[2] =-1.0000f;
p[0] =-1.5000f; p[1] = 1.0000f; p[2] = 1.0000f;
d[0] =-1.0000f; d[1] = 0.0000f; d[2] = 0.0000f;
BH_VERIFY(BH_Ray3fIntersectTriangle(p, d, a, b, c, &t, out) == BH_OK);
BH_VERIFY_DELTA(t, 2.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[0],-4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[2], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(SegmentIntersectTriangle)
{
float a[3], b[3], c[3], d[3], f[3], out[3], t;
a[0] =-3.0000f; a[1] = 1.0000f; a[2] = 2.0000f;
b[0] =-5.0000f; b[1] =-2.0000f; b[2] = 0.0000f;
c[0] =-6.0000f; c[1] = 2.5000f; c[2] =-1.0000f;
d[0] =-1.5000f; d[1] = 1.0000f; d[2] = 1.0000f;
f[0] =-6.0000f; f[1] = 1.0000f; f[2] = 1.0000f;
BH_VERIFY(BH_Segment3fIntersectTriangle(d, f, a, b, c, &t, out) == BH_OK);
BH_VERIFY_DELTA(out[0],-4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[2], 1.0000f, ACCEPTABLE_DELTA);
BH_Vec3fLerp(d, f, t, out);
BH_VERIFY_DELTA(out[0],-4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[2], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Barycentric)
{
float a[3], b[3], c[3], p[3], d[3], out[3], t;
a[0] =-3.0000f; a[1] = 1.0000f; a[2] = 2.0000f;
b[0] =-5.0000f; b[1] =-2.0000f; b[2] = 0.0000f;
c[0] =-6.0000f; c[1] = 2.5000f; c[2] =-1.0000f;
p[0] =-1.5000f; p[1] = 1.0000f; p[2] = 1.0000f;
d[0] =-1.0000f; d[1] = 0.0000f; d[2] = 0.0000f;
BH_VERIFY(BH_Ray3fIntersectTriangle(p, d, a, b, c, &t, out) == BH_OK);
(void)t;
BH_Triangle3fBarycentric(a, b, c, out, out);
BH_VERIFY(out[0] >= 0.0f);
BH_VERIFY(out[1] >= 0.0f);
BH_VERIFY(out[2] >= 0.0f);
BH_VERIFY(out[0] <= 1.0f);
BH_VERIFY(out[1] <= 1.0f);
BH_VERIFY(out[2] <= 1.0f);
BH_VERIFY_DELTA(out[0] + out[1] + out[2], 1.0000f, ACCEPTABLE_DELTA);
BH_Vec3fBarycentric(a, b, c, out[1], out[2], out);
BH_VERIFY_DELTA(out[0],-4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[1], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(out[2], 1.0000f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(RayIntersectTriangle);
BH_UNIT_ADD(SegmentIntersectTriangle);
BH_UNIT_ADD(Barycentric);
return BH_UnitRun();
}

284
test/src/TestVec2f.c Normal file
View File

@@ -0,0 +1,284 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(Add)
{
float a[2], b[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_Vec2fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Sub)
{
float a[2], b[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_Vec2fSub(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Mul)
{
float a[2], b[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_Vec2fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 12.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scale)
{
float a[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
BH_Vec2fScale(a, 10.0000f, r);
BH_VERIFY_DELTA(r[0], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 20.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(MulAdd)
{
float a[2], b[2], c[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
c[0] = 1.5000f; c[1] = 2.5000f;
BH_Vec2fMulAdd(a, b, c, r);
BH_VERIFY_DELTA(r[0], 6.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 14.5000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Negate)
{
float a[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
BH_Vec2fNegate(a, r);
BH_VERIFY_DELTA(r[0], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Dot)
{
float a[2], b[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_VERIFY_DELTA(BH_Vec2fDot(a, b), 17.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Cross)
{
float a[2], b[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_VERIFY_DELTA(BH_Vec2fCross(a, b), -4.0f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Length)
{
float a[2];
a[0] = 1.0000f; a[1] = 2.0000f;
BH_VERIFY_DELTA(BH_Vec2fLength(a), sqrt(5.0000f), ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Normal)
{
float a[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
BH_Vec2fNormal(a, r);
BH_VERIFY_DELTA(r[0], 1.0000f / sqrt(5.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f / sqrt(5.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_Vec2fNormalEx(a, r), sqrt(5.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[0], 1.0000f / sqrt(5.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f / sqrt(5.0000f), ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Min)
{
float a[2], b[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_Vec2fMin(a, b, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_Vec2fMin(b, a, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Max)
{
float a[2], b[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_Vec2fMax(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_Vec2fMax(b, a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Lerp)
{
float a[2], b[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
BH_Vec2fLerp(a, b, 0.0000f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a, b, 0.5000f, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.0000f, ACCEPTABLE_DELTA);
BH_Vec2fLerp(a, b, 1.0000f, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Project)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 4.0000f; b[1] = 3.0000f;
BH_Vec2fProject(a, b, r);
BH_VERIFY_DELTA(r[0], 1.6000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 1.2000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Barycentric)
{
float a[2], b[2], c[2], r[2];
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 5.0000f; b[1] = 6.0000f;
c[0] = 1.5000f; c[1] = 2.5000f;
BH_Vec2fBarycentric(a, b, c, 0.5f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.2500f, ACCEPTABLE_DELTA);
BH_Vec2fBarycentric(a, b, c, 0.25f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 2.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.2500f, ACCEPTABLE_DELTA);
a[0] = 1.0000f; a[1] = 2.0000f;
b[0] = 4.0000f; b[1] = 3.0000f;
c[0] = 4.0000f; c[1] = 4.0000f;
BH_Vec2fBarycentric(a, b, c, 0.0f, 0.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_Vec2fBarycentric(a, b, c, 0.5f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.5000f, ACCEPTABLE_DELTA);
BH_Vec2fBarycentric(a, b, c, 0.25f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.2500f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(MulAdd);
BH_UNIT_ADD(Negate);
BH_UNIT_ADD(Dot);
BH_UNIT_ADD(Cross);
BH_UNIT_ADD(Length);
BH_UNIT_ADD(Normal);
BH_UNIT_ADD(Min);
BH_UNIT_ADD(Max);
BH_UNIT_ADD(Lerp);
BH_UNIT_ADD(Project);
BH_UNIT_ADD(Barycentric);
return BH_UnitRun();
}

147
test/src/TestVec2i.c Normal file
View File

@@ -0,0 +1,147 @@
#include <BH/Math.h>
#include <BH/Unit.h>
BH_UNIT_TEST(Add)
{
int a[2], b[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
BH_Vec2iAdd(a, b, r);
BH_VERIFY(r[0] == 6);
BH_VERIFY(r[1] == 8);
return 0;
}
BH_UNIT_TEST(Sub)
{
int a[2], b[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
BH_Vec2iSub(a, b, r);
BH_VERIFY(r[0] == -4);
BH_VERIFY(r[1] == -4);
return 0;
}
BH_UNIT_TEST(Mul)
{
int a[2], b[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
BH_Vec2iMul(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 12);
return 0;
}
BH_UNIT_TEST(Scale)
{
int a[2], r[2];
a[0] = 1; a[1] = 2;
BH_Vec2iScale(a, 10, r);
BH_VERIFY(r[0] == 10);
BH_VERIFY(r[1] == 20);
return 0;
}
BH_UNIT_TEST(MulAdd)
{
int a[2], b[2], c[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
c[0] = 4; c[1] = 3;
BH_Vec2iMulAdd(a, b, c, r);
BH_VERIFY(r[0] == 9);
BH_VERIFY(r[1] == 15);
return 0;
}
BH_UNIT_TEST(Negate)
{
int a[2], r[2];
a[0] = 1; a[1] = 2;
BH_Vec2iNegate(a, r);
BH_VERIFY(r[0] == -1);
BH_VERIFY(r[1] == -2);
return 0;
}
BH_UNIT_TEST(Min)
{
int a[2], b[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
BH_Vec2iMin(a, b, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_Vec2iMin(b, a, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
return 0;
}
BH_UNIT_TEST(Max)
{
int a[2], b[2], r[2];
a[0] = 1; a[1] = 2;
b[0] = 5; b[1] = 6;
BH_Vec2iMax(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_Vec2iMax(b, a, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(MulAdd);
BH_UNIT_ADD(Negate);
BH_UNIT_ADD(Min);
BH_UNIT_ADD(Max);
return BH_UnitRun();
}

309
test/src/TestVec3f.c Normal file
View File

@@ -0,0 +1,309 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(Add)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Sub)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fSub(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Mul)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 12.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 21.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scale)
{
float a[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
BH_Vec3fScale(a, 10.0000f, r);
BH_VERIFY_DELTA(r[0], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 30.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(MulAdd)
{
float a[3], b[3], c[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
c[0] = 1.5000f; c[1] = 2.5000f; c[2] = 3.5000f;
BH_Vec3fMulAdd(a, b, c, r);
BH_VERIFY_DELTA(r[0], 6.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 14.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 24.5000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Negate)
{
float a[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
BH_Vec3fNegate(a, r);
BH_VERIFY_DELTA(r[0], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Dot)
{
float a[3], b[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_VERIFY_DELTA(BH_Vec3fDot(a, b), 38.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Cross)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fCross(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Length)
{
float a[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
BH_VERIFY_DELTA(BH_Vec3fLength(a), sqrt(14.0000f), ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Normal)
{
float a[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
BH_Vec3fNormal(a, r);
BH_VERIFY_DELTA(r[0], 1.0000f / sqrt(14.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f / sqrt(14.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f / sqrt(14.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_Vec3fNormalEx(a, r), sqrt(14.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[0], 1.0000f / sqrt(14.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f / sqrt(14.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f / sqrt(14.0000f), ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Min)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fMin(a, b, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_Vec3fMin(b, a, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Max)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fMax(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
BH_Vec3fMax(b, a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Lerp)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
BH_Vec3fLerp(a, b, 0.0000f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_Vec3fLerp(a, b, 0.5000f, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_Vec3fLerp(a, b, 1.0000f, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Project)
{
float a[3], b[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 4.0000f; b[1] = 3.0000f; b[2] = 2.0000f;
BH_Vec3fProject(a, b, r);
BH_VERIFY_DELTA(r[0], 2.2069f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 1.6552f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 1.1034f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Barycentric)
{
float a[3], b[3], c[3], r[3];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f;
c[0] = 1.5000f; c[1] = 2.5000f; c[2] = 3.5000f;
BH_Vec3fBarycentric(a, b, c, 0.5f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.2500f, ACCEPTABLE_DELTA);
BH_Vec3fBarycentric(a, b, c, 0.25f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 2.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 4.2500f, ACCEPTABLE_DELTA);
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f;
b[0] = 4.0000f; b[1] = 3.0000f; b[2] = 2.0000f;
c[0] = 4.0000f; c[1] = 4.0000f; c[2] = 4.0000f;
BH_Vec3fBarycentric(a, b, c, 0.0f, 0.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_Vec3fBarycentric(a, b, c, 0.5f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_Vec3fBarycentric(a, b, c, 0.25f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.2500f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(MulAdd);
BH_UNIT_ADD(Negate);
BH_UNIT_ADD(Dot);
BH_UNIT_ADD(Cross);
BH_UNIT_ADD(Length);
BH_UNIT_ADD(Normal);
BH_UNIT_ADD(Min);
BH_UNIT_ADD(Max);
BH_UNIT_ADD(Lerp);
BH_UNIT_ADD(Project);
BH_UNIT_ADD(Barycentric);
return BH_UnitRun();
}

157
test/src/TestVec3i.c Normal file
View File

@@ -0,0 +1,157 @@
#include <BH/Math.h>
#include <BH/Unit.h>
BH_UNIT_TEST(Add)
{
int a[3], b[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
BH_Vec3iAdd(a, b, r);
BH_VERIFY(r[0] == 6);
BH_VERIFY(r[1] == 8);
BH_VERIFY(r[2] == 10);
return 0;
}
BH_UNIT_TEST(Sub)
{
int a[3], b[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
BH_Vec3iSub(a, b, r);
BH_VERIFY(r[0] == -4);
BH_VERIFY(r[1] == -4);
BH_VERIFY(r[2] == -4);
return 0;
}
BH_UNIT_TEST(Mul)
{
int a[3], b[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
BH_Vec3iMul(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 12);
BH_VERIFY(r[2] == 21);
return 0;
}
BH_UNIT_TEST(Scale)
{
int a[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
BH_Vec3iScale(a, 10, r);
BH_VERIFY(r[0] == 10);
BH_VERIFY(r[1] == 20);
BH_VERIFY(r[2] == 30);
return 0;
}
BH_UNIT_TEST(MulAdd)
{
int a[3], b[3], c[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
c[0] = 4; c[1] = 3; c[2] = 2;
BH_Vec3iMulAdd(a, b, c, r);
BH_VERIFY(r[0] == 9);
BH_VERIFY(r[1] == 15);
BH_VERIFY(r[2] == 23);
return 0;
}
BH_UNIT_TEST(Negate)
{
int a[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
BH_Vec3iNegate(a, r);
BH_VERIFY(r[0] == -1);
BH_VERIFY(r[1] == -2);
BH_VERIFY(r[2] == -3);
return 0;
}
BH_UNIT_TEST(Min)
{
int a[3], b[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
BH_Vec3iMin(a, b, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_VERIFY(r[2] == 3);
BH_Vec3iMin(b, a, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_VERIFY(r[2] == 3);
return 0;
}
BH_UNIT_TEST(Max)
{
int a[3], b[3], r[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5; b[1] = 6; b[2] = 7;
BH_Vec3iMax(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_VERIFY(r[2] == 7);
BH_Vec3iMax(b, a, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_VERIFY(r[2] == 7);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(MulAdd);
BH_UNIT_ADD(Negate);
BH_UNIT_ADD(Min);
BH_UNIT_ADD(Max);
return BH_UnitRun();
}

313
test/src/TestVec4f.c Normal file
View File

@@ -0,0 +1,313 @@
#include <BH/Math.h>
#include <BH/Unit.h>
#define ACCEPTABLE_DELTA 0.0001f
BH_UNIT_TEST(Add)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_Vec4fAdd(a, b, r);
BH_VERIFY_DELTA(r[0], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 8.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 12.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Sub)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_Vec4fSub(a, b, r);
BH_VERIFY_DELTA(r[0], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], -4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Mul)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_Vec4fMul(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 12.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 21.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 32.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Scale)
{
float a[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
BH_Vec4fScale(a, 10.0000f, r);
BH_VERIFY_DELTA(r[0], 10.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 20.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 30.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 40.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(MulAdd)
{
float a[4], b[4], c[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
c[0] = 1.5000f; c[1] = 2.5000f; c[2] = 3.5000f; c[3] = 4.5000f;
BH_Vec4fMulAdd(a, b, c, r);
BH_VERIFY_DELTA(r[0], 6.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 14.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 24.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 36.5000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Negate)
{
float a[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
BH_Vec4fNegate(a, r);
BH_VERIFY_DELTA(r[0], -1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], -2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], -3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], -4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Dot)
{
float a[4], b[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_VERIFY_DELTA(BH_Vec4fDot(a, b), 70.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Length)
{
float a[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
BH_VERIFY_DELTA(BH_Vec4fLength(a), sqrt(30.0000f), ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Normal)
{
float a[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
BH_Vec4fNormal(a, r);
BH_VERIFY_DELTA(r[0], 1.0f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(BH_Vec4fNormalEx(a, r), sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[0], 1.0000f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f / sqrt(30.0000f), ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f / sqrt(30.0000f), ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Min)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_Vec4fMin(a, b, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f, ACCEPTABLE_DELTA);
BH_Vec4fMin(b, a, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Max)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_Vec4fMax(a, b, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
BH_Vec4fMax(b, a, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Lerp)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
BH_Vec4fLerp(a, b, 0.0000f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f, ACCEPTABLE_DELTA);
BH_Vec4fLerp(a, b, 0.5000f, r);
BH_VERIFY_DELTA(r[0], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 6.0000f, ACCEPTABLE_DELTA);
BH_Vec4fLerp(a, b, 1.0000f, r);
BH_VERIFY_DELTA(r[0], 5.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 6.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 7.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 8.0000f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Project)
{
float a[4], b[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 4.0000f; b[1] = 3.0000f; b[2] = 2.0000f; b[3] = 1.0000f;
BH_Vec4fProject(a, b, r);
BH_VERIFY_DELTA(r[0], 2.6667f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 1.3333f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 0.6667f, ACCEPTABLE_DELTA);
return 0;
}
BH_UNIT_TEST(Barycentric)
{
float a[4], b[4], c[4], r[4];
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 5.0000f; b[1] = 6.0000f; b[2] = 7.0000f; b[3] = 8.0000f;
c[0] = 1.5000f; c[1] = 2.5000f; c[2] = 3.5000f; c[3] = 4.5000f;
BH_Vec4fBarycentric(a, b, c, 0.5f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 4.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 5.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 6.2500f, ACCEPTABLE_DELTA);
BH_Vec4fBarycentric(a, b, c, 0.25f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 2.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 4.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 5.2500f, ACCEPTABLE_DELTA);
a[0] = 1.0000f; a[1] = 2.0000f; a[2] = 3.0000f; a[3] = 4.0000f;
b[0] = 4.0000f; b[1] = 3.0000f; b[2] = 2.0000f; b[3] = 1.0000f;
c[0] = 4.0000f; c[1] = 4.0000f; c[2] = 4.0000f; c[3] = 4.0000f;
BH_Vec4fBarycentric(a, b, c, 0.0f, 0.0f, r);
BH_VERIFY_DELTA(r[0], 1.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 2.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 4.0000f, ACCEPTABLE_DELTA);
BH_Vec4fBarycentric(a, b, c, 0.5f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 4.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.5000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.0000f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 2.5000f, ACCEPTABLE_DELTA);
BH_Vec4fBarycentric(a, b, c, 0.25f, 0.5f, r);
BH_VERIFY_DELTA(r[0], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[1], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[2], 3.2500f, ACCEPTABLE_DELTA);
BH_VERIFY_DELTA(r[3], 3.2500f, ACCEPTABLE_DELTA);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(MulAdd);
BH_UNIT_ADD(Negate);
BH_UNIT_ADD(Dot);
BH_UNIT_ADD(Length);
BH_UNIT_ADD(Normal);
BH_UNIT_ADD(Min);
BH_UNIT_ADD(Max);
BH_UNIT_ADD(Lerp);
BH_UNIT_ADD(Project);
BH_UNIT_ADD(Barycentric);
return BH_UnitRun();
}

167
test/src/TestVec4i.c Normal file
View File

@@ -0,0 +1,167 @@
#include <BH/Math.h>
#include <BH/Unit.h>
BH_UNIT_TEST(Add)
{
int a[4], b[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
BH_Vec4iAdd(a, b, r);
BH_VERIFY(r[0] == 6);
BH_VERIFY(r[1] == 8);
BH_VERIFY(r[2] == 10);
BH_VERIFY(r[3] == 12);
return 0;
}
BH_UNIT_TEST(Sub)
{
int a[4], b[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
BH_Vec4iSub(a, b, r);
BH_VERIFY(r[0] == -4);
BH_VERIFY(r[1] == -4);
BH_VERIFY(r[2] == -4);
BH_VERIFY(r[3] == -4);
return 0;
}
BH_UNIT_TEST(Mul)
{
int a[4], b[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
BH_Vec4iMul(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 12);
BH_VERIFY(r[2] == 21);
BH_VERIFY(r[3] == 32);
return 0;
}
BH_UNIT_TEST(Scale)
{
int a[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
BH_Vec4iScale(a, 10, r);
BH_VERIFY(r[0] == 10);
BH_VERIFY(r[1] == 20);
BH_VERIFY(r[2] == 30);
BH_VERIFY(r[3] == 40);
return 0;
}
BH_UNIT_TEST(MulAdd)
{
int a[4], b[4], c[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
c[0] = 4; c[1] = 3; c[2] = 2; c[3] = 1;
BH_Vec4iMulAdd(a, b, c, r);
BH_VERIFY(r[0] == 9);
BH_VERIFY(r[1] == 15);
BH_VERIFY(r[2] == 23);
BH_VERIFY(r[3] == 33);
return 0;
}
BH_UNIT_TEST(Negate)
{
int a[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
BH_Vec4iNegate(a, r);
BH_VERIFY(r[0] == -1);
BH_VERIFY(r[1] == -2);
BH_VERIFY(r[2] == -3);
BH_VERIFY(r[3] == -4);
return 0;
}
BH_UNIT_TEST(Min)
{
int a[4], b[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
BH_Vec4iMin(a, b, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_VERIFY(r[2] == 3);
BH_VERIFY(r[3] == 4);
BH_Vec4iMin(b, a, r);
BH_VERIFY(r[0] == 1);
BH_VERIFY(r[1] == 2);
BH_VERIFY(r[2] == 3);
BH_VERIFY(r[3] == 4);
return 0;
}
BH_UNIT_TEST(Max)
{
int a[4], b[4], r[4];
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
b[0] = 5; b[1] = 6; b[2] = 7; b[3] = 8;
BH_Vec4iMax(a, b, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_VERIFY(r[2] == 7);
BH_VERIFY(r[3] == 8);
BH_Vec4iMax(b, a, r);
BH_VERIFY(r[0] == 5);
BH_VERIFY(r[1] == 6);
BH_VERIFY(r[2] == 7);
BH_VERIFY(r[3] == 8);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(Add);
BH_UNIT_ADD(Sub);
BH_UNIT_ADD(Mul);
BH_UNIT_ADD(Scale);
BH_UNIT_ADD(MulAdd);
BH_UNIT_ADD(Negate);
BH_UNIT_ADD(Min);
BH_UNIT_ADD(Max);
return BH_UnitRun();
}

View File

@@ -28,12 +28,20 @@ typedef int (*BH_UnitCallback)(void);
if (BH_VERIFY_DELTA < 0.0) \
BH_VERIFY_DELTA = -BH_VERIFY_DELTA; \
if (BH_VERIFY_DELTA > (e)) { \
printf("%s:%d\t%s (differs by %f)\n", __FILE__, __LINE__, #x " == " #y, BH_VERIFY_DELTA); \
printf("%s:%d\t%s (differs by %f)\n", \
__FILE__, __LINE__, #x " == " #y, BH_VERIFY_DELTA); \
return -1; \
} \
} while(0)
#define BH_UNIT_TEST(name) \
static int unit##name(void)
#define BH_UNIT_ADD(name) \
BH_UnitAdd(#name, unit##name)
/**
* Adds unit test \a cb with name \a name for the testing.

View File

@@ -55,6 +55,7 @@ void BH_UnitAdd(const char *name, BH_UnitCallback cb)
int BH_UnitRun(void)
{
BH_Unit *current;
int result = 0;
printf("Running tests...\n");
current = root;
@@ -64,15 +65,16 @@ int BH_UnitRun(void)
if (current->cb())
{
printf("\tFAIL\n");
BH_UnitCleanup();
return -1;
result = -1;
}
else
printf("\tPASS\n");
fflush(stdout);
current = current->next;
}
BH_UnitCleanup();
return 0;
return result;
}