From 67e7582d6314029cacbbfdb20378720827a678de Mon Sep 17 00:00:00 2001 From: Mikhail Romanko Date: Mon, 24 Feb 2025 09:37:22 +0300 Subject: 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). --- include/BH/Math.h | 505 +++++++++++++++++++++++- src/Math.c | 553 ++++++++++++++++++++++++++- test/reference/matrix3f.wxmx | Bin 5986 -> 6738 bytes test/reference/matrix4f.wxmx | Bin 7100 -> 8271 bytes test/reference/plane.wxmx | Bin 0 -> 72771 bytes test/reference/point2f.wxmx | Bin 8202 -> 9961 bytes test/reference/point3f.wxmx | Bin 8290 -> 10396 bytes test/reference/point4f.wxmx | Bin 8910 -> 10865 bytes test/src/TestLine.c | 84 ++++ test/src/TestMat3f.c | 316 +++++++++++++++ test/src/TestMat4f.c | 404 ++++++++++++++++++++ test/src/TestMath.c | 889 +------------------------------------------ test/src/TestPlane.c | 96 +++++ test/src/TestQuat.c | 131 +++++++ test/src/TestRay2f.c | 196 ++++++++++ test/src/TestRay3f.c | 99 +++++ test/src/TestVec2f.c | 284 ++++++++++++++ test/src/TestVec2i.c | 147 +++++++ test/src/TestVec3f.c | 309 +++++++++++++++ test/src/TestVec3i.c | 157 ++++++++ test/src/TestVec4f.c | 313 +++++++++++++++ test/src/TestVec4i.c | 167 ++++++++ unit/include/BH/Unit.h | 10 +- unit/src/Unit.c | 10 +- 24 files changed, 3755 insertions(+), 915 deletions(-) create mode 100644 test/reference/plane.wxmx create mode 100644 test/src/TestLine.c create mode 100644 test/src/TestMat3f.c create mode 100644 test/src/TestMat4f.c create mode 100644 test/src/TestPlane.c create mode 100644 test/src/TestQuat.c create mode 100644 test/src/TestRay2f.c create mode 100644 test/src/TestRay3f.c create mode 100644 test/src/TestVec2f.c create mode 100644 test/src/TestVec2i.c create mode 100644 test/src/TestVec3f.c create mode 100644 test/src/TestVec3i.c create mode 100644 test/src/TestVec4f.c create mode 100644 test/src/TestVec4i.c diff --git a/include/BH/Math.h b/include/BH/Math.h index 5ce9540..bda5b6d 100644 --- a/include/BH/Math.h +++ b/include/BH/Math.h @@ -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 at Target vector - * \param up Up vector - * \param out Output 4x4 matrix + * \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 */ diff --git a/src/Math.c b/src/Math.c index 58ebcd3..3d37354 100644 --- a/src/Math.c +++ b/src/Math.c @@ -1,4 +1,5 @@ #include + #include #include @@ -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; +} diff --git a/test/reference/matrix3f.wxmx b/test/reference/matrix3f.wxmx index 592ce61..cbc4cc5 100644 Binary files a/test/reference/matrix3f.wxmx and b/test/reference/matrix3f.wxmx differ diff --git a/test/reference/matrix4f.wxmx b/test/reference/matrix4f.wxmx index 0195e40..3344823 100644 Binary files a/test/reference/matrix4f.wxmx and b/test/reference/matrix4f.wxmx differ diff --git a/test/reference/plane.wxmx b/test/reference/plane.wxmx new file mode 100644 index 0000000..8f63ee1 Binary files /dev/null and b/test/reference/plane.wxmx differ diff --git a/test/reference/point2f.wxmx b/test/reference/point2f.wxmx index 76cb024..1188b9d 100644 Binary files a/test/reference/point2f.wxmx and b/test/reference/point2f.wxmx differ diff --git a/test/reference/point3f.wxmx b/test/reference/point3f.wxmx index a8c30c8..d02b2d7 100644 Binary files a/test/reference/point3f.wxmx and b/test/reference/point3f.wxmx differ diff --git a/test/reference/point4f.wxmx b/test/reference/point4f.wxmx index 10af820..d062ad6 100644 Binary files a/test/reference/point4f.wxmx and b/test/reference/point4f.wxmx differ diff --git a/test/src/TestLine.c b/test/src/TestLine.c new file mode 100644 index 0000000..ce9ced7 --- /dev/null +++ b/test/src/TestLine.c @@ -0,0 +1,84 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestMat3f.c b/test/src/TestMat3f.c new file mode 100644 index 0000000..7d71502 --- /dev/null +++ b/test/src/TestMat3f.c @@ -0,0 +1,316 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestMat4f.c b/test/src/TestMat4f.c new file mode 100644 index 0000000..d4ada01 --- /dev/null +++ b/test/src/TestMat4f.c @@ -0,0 +1,404 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestMath.c b/test/src/TestMath.c index 90549fb..9896e6a 100644 --- a/test/src/TestMath.c +++ b/test/src/TestMath.c @@ -5,830 +5,10 @@ #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]; - + BH_Mat4fFromEuler(-2.7671f, -0.8324f, -0.1649f, a); BH_Quat4fFromEuler(-2.7671f, -0.8324f, -0.1649f, c); @@ -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(); } diff --git a/test/src/TestPlane.c b/test/src/TestPlane.c new file mode 100644 index 0000000..f405a69 --- /dev/null +++ b/test/src/TestPlane.c @@ -0,0 +1,96 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestQuat.c b/test/src/TestQuat.c new file mode 100644 index 0000000..55e86d5 --- /dev/null +++ b/test/src/TestQuat.c @@ -0,0 +1,131 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestRay2f.c b/test/src/TestRay2f.c new file mode 100644 index 0000000..811cd96 --- /dev/null +++ b/test/src/TestRay2f.c @@ -0,0 +1,196 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestRay3f.c b/test/src/TestRay3f.c new file mode 100644 index 0000000..6a80270 --- /dev/null +++ b/test/src/TestRay3f.c @@ -0,0 +1,99 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestVec2f.c b/test/src/TestVec2f.c new file mode 100644 index 0000000..92db45f --- /dev/null +++ b/test/src/TestVec2f.c @@ -0,0 +1,284 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestVec2i.c b/test/src/TestVec2i.c new file mode 100644 index 0000000..cf216d8 --- /dev/null +++ b/test/src/TestVec2i.c @@ -0,0 +1,147 @@ +#include +#include + + +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(); +} diff --git a/test/src/TestVec3f.c b/test/src/TestVec3f.c new file mode 100644 index 0000000..9e07aeb --- /dev/null +++ b/test/src/TestVec3f.c @@ -0,0 +1,309 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestVec3i.c b/test/src/TestVec3i.c new file mode 100644 index 0000000..f8ab9ee --- /dev/null +++ b/test/src/TestVec3i.c @@ -0,0 +1,157 @@ +#include +#include + + +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(); +} diff --git a/test/src/TestVec4f.c b/test/src/TestVec4f.c new file mode 100644 index 0000000..3e0e877 --- /dev/null +++ b/test/src/TestVec4f.c @@ -0,0 +1,313 @@ +#include +#include + + +#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(); +} diff --git a/test/src/TestVec4i.c b/test/src/TestVec4i.c new file mode 100644 index 0000000..ebd682c --- /dev/null +++ b/test/src/TestVec4i.c @@ -0,0 +1,167 @@ +#include +#include + + +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(); +} diff --git a/unit/include/BH/Unit.h b/unit/include/BH/Unit.h index 3b3b2b6..c715c23 100644 --- a/unit/include/BH/Unit.h +++ b/unit/include/BH/Unit.h @@ -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. diff --git a/unit/src/Unit.c b/unit/src/Unit.c index 57d80b1..a0b61e1 100644 --- a/unit/src/Unit.c +++ b/unit/src/Unit.c @@ -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; } - printf("\tPASS\n"); + else + printf("\tPASS\n"); + fflush(stdout); current = current->next; } BH_UnitCleanup(); - return 0; + return result; } -- cgit v1.2.3