Skip to content

Commit 0538757

Browse files
authored
Merge pull request #42 from dizcza/tests
Added tests, fixed a bug, and more
2 parents 3db0026 + ffcb15d commit 0538757

5 files changed

Lines changed: 349 additions & 73 deletions

File tree

.circleci/config.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: 2.1
2+
3+
jobs:
4+
linmath-test:
5+
machine:
6+
image: ubuntu-1604:201903-01
7+
steps:
8+
- run: gcc --version
9+
- checkout
10+
- run:
11+
command: |
12+
gcc -O0 -o linmath_test.o linmath_test.c -lm
13+
./linmath_test.o
14+
name: linmath tests gcc -O0
15+
- run:
16+
command: |
17+
gcc -O1 -o linmath_test.o linmath_test.c -lm
18+
./linmath_test.o
19+
name: linmath tests gcc -O1
20+
- run:
21+
command: |
22+
gcc -O2 -o linmath_test.o linmath_test.c -lm
23+
./linmath_test.o
24+
name: linmath tests gcc -O2
25+
- run:
26+
command: |
27+
gcc -O3 -o linmath_test.o linmath_test.c -lm
28+
./linmath_test.o
29+
name: linmath tests gcc -O3
30+
31+
32+
workflows:
33+
main:
34+
jobs:
35+
- linmath-test

README renamed to README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# linmath.h -- A small library for linear math as required for computer graphics
22

3+
[![CircleCI](https://circleci.com/gh/datenwolf/linmath.h.svg?style=svg)](https://app.circleci.com/pipelines/github/datenwolf/linmath.h)
4+
5+
36
linmath.h provides the most used types required for programming computer graphics:
47

58
vec3 -- 3 element vector of floats

linmath.h

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef LINMATH_H
22
#define LINMATH_H
33

4+
#include <string.h>
45
#include <math.h>
56
#include <string.h>
67

@@ -58,6 +59,12 @@ LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
5859
int i; \
5960
for(i=0; i<n; ++i) \
6061
r[i] = a[i]>b[i] ? a[i] : b[i]; \
62+
} \
63+
LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) \
64+
{ \
65+
int i; \
66+
for(i=0; i<n; ++i) \
67+
r[i] = src[i]; \
6168
}
6269

6370
LINMATH_H_DEFINE_VEC(2)
@@ -79,15 +86,15 @@ LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
7986
r[i] = v[i] - p*n[i];
8087
}
8188

82-
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
89+
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b)
8390
{
8491
r[0] = a[1]*b[2] - a[2]*b[1];
8592
r[1] = a[2]*b[0] - a[0]*b[2];
8693
r[2] = a[0]*b[1] - a[1]*b[0];
8794
r[3] = 1.f;
8895
}
8996

90-
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 v, vec4 n)
97+
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n)
9198
{
9299
float p = 2.f*vec4_mul_inner(v, n);
93100
int i;
@@ -103,61 +110,59 @@ LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
103110
for(j=0; j<4; ++j)
104111
M[i][j] = i==j ? 1.f : 0.f;
105112
}
106-
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 N)
113+
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N)
107114
{
108-
int i, j;
115+
int i;
109116
for(i=0; i<4; ++i)
110-
for(j=0; j<4; ++j)
111-
M[i][j] = N[i][j];
117+
vec4_dup(M[i], N[i]);
112118
}
113-
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 M, int i)
119+
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i)
114120
{
115121
int k;
116122
for(k=0; k<4; ++k)
117123
r[k] = M[k][i];
118124
}
119-
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 M, int i)
125+
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i)
120126
{
121127
int k;
122128
for(k=0; k<4; ++k)
123129
r[k] = M[i][k];
124130
}
125-
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 N)
131+
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N)
126132
{
133+
// Note: if M and N are the same, the user has to
134+
// explicitly make a copy of M and set it to N.
127135
int i, j;
128136
for(j=0; j<4; ++j)
129137
for(i=0; i<4; ++i)
130138
M[i][j] = N[j][i];
131139
}
132-
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b)
140+
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b)
133141
{
134142
int i;
135143
for(i=0; i<4; ++i)
136144
vec4_add(M[i], a[i], b[i]);
137145
}
138-
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b)
146+
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b)
139147
{
140148
int i;
141149
for(i=0; i<4; ++i)
142150
vec4_sub(M[i], a[i], b[i]);
143151
}
144-
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 a, float k)
152+
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k)
145153
{
146154
int i;
147155
for(i=0; i<4; ++i)
148156
vec4_scale(M[i], a[i], k);
149157
}
150-
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z)
158+
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x, float y, float z)
151159
{
152-
int i;
153160
vec4_scale(M[0], a[0], x);
154161
vec4_scale(M[1], a[1], y);
155162
vec4_scale(M[2], a[2], z);
156-
for(i = 0; i < 4; ++i) {
157-
M[3][i] = a[3][i];
158-
}
163+
vec4_dup(M[3], a[3]);
159164
}
160-
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
165+
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b)
161166
{
162167
mat4x4 temp;
163168
int k, r, c;
@@ -168,7 +173,7 @@ LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
168173
}
169174
mat4x4_dup(M, temp);
170175
}
171-
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
176+
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v)
172177
{
173178
int i, j;
174179
for(j=0; j<4; ++j) {
@@ -194,13 +199,13 @@ LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float
194199
M[3][i] += vec4_mul_inner(r, t);
195200
}
196201
}
197-
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
202+
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a, vec3 const b)
198203
{
199204
int i, j;
200205
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
201206
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
202207
}
203-
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle)
208+
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y, float z, float angle)
204209
{
205210
float s = sinf(angle);
206211
float c = cosf(angle);
@@ -228,13 +233,13 @@ LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
228233
mat4x4_add(T, T, C);
229234
mat4x4_add(T, T, S);
230235

231-
T[3][3] = 1.;
236+
T[3][3] = 1.f;
232237
mat4x4_mul(R, M, T);
233238
} else {
234239
mat4x4_dup(R, M);
235240
}
236241
}
237-
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
242+
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle)
238243
{
239244
float s = sinf(angle);
240245
float c = cosf(angle);
@@ -246,7 +251,7 @@ LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
246251
};
247252
mat4x4_mul(Q, M, R);
248253
}
249-
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
254+
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle)
250255
{
251256
float s = sinf(angle);
252257
float c = cosf(angle);
@@ -258,7 +263,7 @@ LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
258263
};
259264
mat4x4_mul(Q, M, R);
260265
}
261-
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
266+
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle)
262267
{
263268
float s = sinf(angle);
264269
float c = cosf(angle);
@@ -270,7 +275,7 @@ LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
270275
};
271276
mat4x4_mul(Q, M, R);
272277
}
273-
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 M)
278+
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M)
274279
{
275280
float s[6];
276281
float c[6];
@@ -311,10 +316,10 @@ LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 M)
311316
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
312317
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
313318
}
314-
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
319+
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M)
315320
{
316321
mat4x4_dup(R, M);
317-
float s = 1.;
322+
float s = 1.f;
318323
vec3 h;
319324

320325
vec3_norm(R[2], R[2]);
@@ -370,7 +375,7 @@ LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, floa
370375
{
371376
/* NOTE: Degrees are an unhandy unit to work with.
372377
* linmath.h uses radians for everything! */
373-
float const a = 1.f / tan(y_fov / 2.f);
378+
float const a = 1.f / tanf(y_fov / 2.f);
374379

375380
m[0][0] = a / aspect;
376381
m[0][1] = 0.f;
@@ -392,7 +397,7 @@ LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, floa
392397
m[3][2] = -((2.f * f * n) / (f - n));
393398
m[3][3] = 0.f;
394399
}
395-
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
400+
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center, vec3 const up)
396401
{
397402
/* Adapted from Android's OpenGL Matrix.java. */
398403
/* See the OpenGL GLUT documentation for gluLookAt for a description */
@@ -435,24 +440,18 @@ LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
435440
}
436441

437442
typedef float quat[4];
443+
#define quat_add vec4_add
444+
#define quat_sub vec4_sub
445+
#define quat_norm vec4_norm
446+
#define quat_scale vec4_scale
447+
#define quat_mul_inner vec4_mul_inner
448+
438449
LINMATH_H_FUNC void quat_identity(quat q)
439450
{
440451
q[0] = q[1] = q[2] = 0.f;
441452
q[3] = 1.f;
442453
}
443-
LINMATH_H_FUNC void quat_add(quat r, quat a, quat b)
444-
{
445-
int i;
446-
for(i=0; i<4; ++i)
447-
r[i] = a[i] + b[i];
448-
}
449-
LINMATH_H_FUNC void quat_sub(quat r, quat a, quat b)
450-
{
451-
int i;
452-
for(i=0; i<4; ++i)
453-
r[i] = a[i] - b[i];
454-
}
455-
LINMATH_H_FUNC void quat_mul(quat r, quat p, quat q)
454+
LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q)
456455
{
457456
vec3 w;
458457
vec3_mul_cross(r, p, q);
@@ -462,37 +461,22 @@ LINMATH_H_FUNC void quat_mul(quat r, quat p, quat q)
462461
vec3_add(r, r, w);
463462
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
464463
}
465-
LINMATH_H_FUNC void quat_scale(quat r, quat v, float s)
466-
{
467-
int i;
468-
for(i=0; i<4; ++i)
469-
r[i] = v[i] * s;
470-
}
471-
LINMATH_H_FUNC float quat_inner_product(quat a, quat b)
472-
{
473-
float p = 0.f;
474-
int i;
475-
for(i=0; i<4; ++i)
476-
p += b[i]*a[i];
477-
return p;
478-
}
479-
LINMATH_H_FUNC void quat_conj(quat r, quat q)
464+
LINMATH_H_FUNC void quat_conj(quat r, quat const q)
480465
{
481466
int i;
482467
for(i=0; i<3; ++i)
483468
r[i] = -q[i];
484469
r[3] = q[3];
485470
}
486-
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 axis) {
487-
vec3 v;
488-
vec3_scale(v, axis, sinf(angle / 2));
489-
int i;
490-
for(i=0; i<3; ++i)
491-
r[i] = v[i];
492-
r[3] = cosf(angle / 2);
471+
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
472+
vec3 axis_norm;
473+
vec3_norm(axis_norm, axis);
474+
float s = sinf(angle / 2);
475+
float c = cosf(angle / 2);
476+
vec3_scale(r, axis_norm, s);
477+
r[3] = c;
493478
}
494-
#define quat_norm vec4_norm
495-
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat q, vec3 v)
479+
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v)
496480
{
497481
/*
498482
* Method by Fabian 'ryg' Giessen (of Farbrausch)
@@ -512,7 +496,7 @@ v' = v + q.w * t + cross(q.xyz, t)
512496
vec3_add(r, v, t);
513497
vec3_add(r, r, u);
514498
}
515-
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat q)
499+
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q)
516500
{
517501
float a = q[3];
518502
float b = q[0];
@@ -542,18 +526,21 @@ LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat q)
542526
M[3][3] = 1.f;
543527
}
544528

545-
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q)
529+
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q)
546530
{
547-
/* XXX: The way this is written only works for othogonal matrices. */
531+
/* XXX: The way this is written only works for orthogonal matrices. */
548532
/* TODO: Take care of non-orthogonal case. */
549533
quat_mul_vec3(R[0], q, M[0]);
550534
quat_mul_vec3(R[1], q, M[1]);
551535
quat_mul_vec3(R[2], q, M[2]);
552536

553537
R[3][0] = R[3][1] = R[3][2] = 0.f;
554-
R[3][3] = 1.f;
538+
R[0][3] = M[0][3];
539+
R[1][3] = M[1][3];
540+
R[2][3] = M[2][3];
541+
R[3][3] = M[3][3]; // typically 1.0, but here we make it general
555542
}
556-
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 M)
543+
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M)
557544
{
558545
float r=0.f;
559546
int i;
@@ -583,7 +570,7 @@ LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 M)
583570
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
584571
}
585572

586-
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s)
573+
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a, vec2 const _b, float s)
587574
{
588575
vec2 a; memcpy(a, _a, sizeof(a));
589576
vec2 b; memcpy(b, _b, sizeof(b));

linmath_test.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <stdio.h>
2+
3+
#include "linmath_test.h"
4+
5+
int main() {
6+
linmath_test_run_all();
7+
printf("linmath tests passed\n");
8+
return 0;
9+
}

0 commit comments

Comments
 (0)