summaryrefslogtreecommitdiff
path: root/src/m4f-3dx.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/m4f-3dx.h')
-rw-r--r--src/m4f-3dx.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/m4f-3dx.h b/src/m4f-3dx.h
new file mode 100644
index 0000000..384641b
--- /dev/null
+++ b/src/m4f-3dx.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018-2020 - Vito Caputo - <vcaputo@pengaru.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _M4F_3DX_H
+#define _M4F_3DX_H
+
+#include <math.h>
+
+#include "m4f.h"
+#include "v3f.h"
+
+/* helpers for manipulating 3D transformation matrices */
+
+/* XXX: note this is column-major */
+
+/* adjust the matrix m to translate by v, returning the resulting matrix */
+/* if m is NULL the identity vector is assumed */
+static inline m4f_t m4f_translate(const m4f_t *m, const v3f_t *v)
+{
+ m4f_t identity = m4f_identity();
+ m4f_t translate = m4f_identity();
+
+ if (!m)
+ m = &identity;
+
+ translate.m[3][0] = v->x;
+ translate.m[3][1] = v->y;
+ translate.m[3][2] = v->z;
+
+ return m4f_mult(m, &translate);
+}
+
+
+/* adjust the matrix m to scale by v, returning the resulting matrix */
+/* if m is NULL the identity vector is assumed */
+static inline m4f_t m4f_scale(const m4f_t *m, const v3f_t *v)
+{
+ m4f_t identity = m4f_identity();
+ m4f_t scale = {};
+
+ if (!m)
+ m = &identity;
+
+ scale.m[0][0] = v->x;
+ scale.m[1][1] = v->y;
+ scale.m[2][2] = v->z;
+ scale.m[3][3] = 1.f;
+
+ return m4f_mult(m, &scale);
+}
+
+
+/* adjust the matrix m to rotate around the specified axis by radians, returning the resulting matrix */
+/* axis is expected to be a unit vector */
+/* if m is NULL the identity vector is assumed */
+static inline m4f_t m4f_rotate(const m4f_t *m, const v3f_t *axis, float radians)
+{
+ m4f_t identity = m4f_identity();
+ float cos_r = cosf(radians);
+ float sin_r = sinf(radians);
+ m4f_t rotate;
+
+ if (!m)
+ m = &identity;
+
+ rotate.m[0][0] = cos_r + axis->x * axis->x * (1.f - cos_r);
+ rotate.m[0][1] = axis->y * axis->x * (1.f - cos_r) + axis->z * sin_r;
+ rotate.m[0][2] = axis->z * axis->x * (1.f - cos_r) - axis->y * sin_r;
+ rotate.m[0][3] = 0.f;
+
+ rotate.m[1][0] = axis->x * axis->y * (1.f - cos_r) - axis->z * sin_r;
+ rotate.m[1][1] = cos_r + axis->y * axis->y * (1.f - cos_r);
+ rotate.m[1][2] = axis->z * axis->y * (1.f - cos_r) + axis->x * sin_r;
+ rotate.m[1][3] = 0.f;
+
+ rotate.m[2][0] = axis->x * axis->z * (1.f - cos_r) + axis->y * sin_r;
+ rotate.m[2][1] = axis->y * axis->z * (1.f - cos_r) - axis->x * sin_r;
+ rotate.m[2][2] = cos_r + axis->z * axis->z * (1.f - cos_r);
+ rotate.m[2][3] = 0.f;
+
+ rotate.m[3][0] = 0.f;
+ rotate.m[3][1] = 0.f;
+ rotate.m[3][2] = 0.f;
+ rotate.m[3][3] = 1.f;
+
+ return m4f_mult(m, &rotate);
+}
+
+
+/* this is a simple perpsective projection matrix taken from an opengl tutorial */
+static inline m4f_t m4f_frustum(float bot, float top, float left, float right, float nnear, float ffar)
+{
+ m4f_t m = {};
+
+ m.m[0][0] = 2 * nnear / (right - left);
+
+ m.m[1][1] = 2 * nnear / (top - bot);
+
+ m.m[2][0] = (right + left) / (right - left);;
+ m.m[2][1] = (top + bot) / (top - bot);
+ m.m[2][2] = -(ffar + nnear) / (ffar - nnear);
+ m.m[2][3] = -1;
+
+ m.m[3][2] = -2 * ffar * nnear / (ffar - nnear);
+
+ return m;
+}
+
+#endif
© All Rights Reserved