From b6c89d9ffbb08c5286448de4773290f0924a420b Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 4 Dec 2018 06:36:23 +0200 Subject: [PATCH] - fixed watcom build - added gph-cmath C math library - dropping oldmik, don't bother with music for watcom builds. final build will be djgpp anyway. --- Makefile | 28 +-- src/cgmath/cgmath.h | 238 ++++++++++++++++++++ src/cgmath/cgmmat.inl | 577 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cgmath/cgmmisc.inl | 154 +++++++++++++ src/cgmath/cgmquat.inl | 159 +++++++++++++ src/cgmath/cgmray.inl | 39 ++++ src/cgmath/cgmvec3.inl | 188 ++++++++++++++++ src/cgmath/cgmvec4.inl | 153 +++++++++++++ src/music.c | 91 +------- src/noise.c | 48 ++-- src/polytmpl.h | 4 +- src/scene.h | 10 + src/tilemaze.c | 1 + tools/gen_wobj | 6 + 14 files changed, 1575 insertions(+), 121 deletions(-) create mode 100644 src/cgmath/cgmath.h create mode 100644 src/cgmath/cgmmat.inl create mode 100644 src/cgmath/cgmmisc.inl create mode 100644 src/cgmath/cgmquat.inl create mode 100644 src/cgmath/cgmray.inl create mode 100644 src/cgmath/cgmvec3.inl create mode 100644 src/cgmath/cgmvec4.inl create mode 100644 src/scene.h create mode 100755 tools/gen_wobj diff --git a/Makefile b/Makefile index 9f9a98e..4675768 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,25 @@ -demoobj = main.obj demo.obj screen.obj cfgopt.obj music.obj gfxutil.obj & -3dgfx.obj polyfill.obj polyclip.obj metasurf.obj mesh.obj meshload.obj & -bsptree.obj -scrobj = tunnel.obj fract.obj grise.obj polytest.obj plasma.obj bump.obj & -thunder.obj metaball.obj greets.obj infcubes.obj -sysobj = gfx.obj vbe.obj watdpmi.obj timer.obj keyb.obj mouse.obj sball.obj & -logger.obj tinyfps.obj util.obj dynarr.obj rbtree.obj -obj = $(baseobj) $(demoobj) $(sysobj) $(scrobj) +obj = 3dgfx.obj bsptree.obj bump.obj cfgopt.obj demo.obj djdpmi.obj dynarr.obj & +fract.obj gfx.obj gfxutil.obj greets.obj grise.obj hairball.obj infcubes.obj & +keyb.obj logger.obj main.obj mesh.obj meshload.obj metaball.obj metasurf.obj & +mouse.obj music.obj noise.obj plasma.obj polyclip.obj polyfill.obj polytest.obj & +rbtree.obj sball.obj screen.obj smoketxt.obj thunder.obj tilemaze.obj timer.obj & +tinyfps.obj treestor.obj ts_text.obj tunnel.obj util.obj vbe.obj watdpmi.obj + bin = demo.exe -libs = imago.lib mikmod.lib +libs = imago.lib def = -dM_PI=3.141592653589793 opt = -5 -fp5 -otexan -oh -oi -ei dbg = -d1 !ifdef __UNIX__ -incpath = -Isrc -Isrc/dos -Ilibs/imago/src -Ilibs/oldmik/src -libpath = libpath libs/imago libpath libs/oldmik +incpath = -Isrc -Isrc/dos -Ilibs/imago/src +libpath = libpath libs/imago RM = rm -f !else -incpath = -Isrc -Isrc\dos -Ilibs\imago\src -Ilibs\oldmik\src -libpath = libpath libs\imago libpath libs\oldmik +incpath = -Isrc -Isrc\dos -Ilibs\imago\src +libpath = libpath libs\imago RM = del !endif @@ -48,9 +47,6 @@ cflags.occ: Makefile cxxflags.occ: Makefile %write $@ $(CXXFLAGS) -music.obj: music.c - $(CC) -fo=$@ @cflags.occ -zu $[* - .c.obj: .autodepend $(CC) -fo=$@ @cflags.occ $[* diff --git a/src/cgmath/cgmath.h b/src/cgmath/cgmath.h new file mode 100644 index 0000000..f8f776b --- /dev/null +++ b/src/cgmath/cgmath.h @@ -0,0 +1,238 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + * + * Function prefixes signify the data type of their operand(s): + * - cgm_v... functions are operations on cgm_vec3 vectors + * - cgm_w... functions are operations on cgm_vec4 vectors + * - cgm_q... functions are operations on cgm_quat quaternions (w + xi + yj + zk) + * - cgm_m... functions are operations on 4x4 matrices (stored as linear 16 float arrays) + * - cgm_r... functions are operations on cgm_ray rays + * + * NOTE: *ALL* matrix arguments are pointers to 16 floats. Even the functions + * which operate on 3x3 matrices, actually use the upper 3x3 of a 4x4 matrix, + * and still expect an array of 16 floats. + * + * NOTE: matrices are treated by all operations as column-major, to match OpenGL + * conventions, so everything is pretty much transposed. +*/ +#ifndef CGMATH_H_ +#define CGMATH_H_ + +#include +#include + +typedef struct { + float x, y, z; +} cgm_vec3; + +typedef struct { + float x, y, z, w; +} cgm_vec4, cgm_quat; + +typedef struct { + cgm_vec3 origin, dir; +} cgm_ray; + +typedef enum cgm_euler_mode { + CGM_EULER_XYZ, + CGM_EULER_XZY, + CGM_EULER_YXZ, + CGM_EULER_YZX, + CGM_EULER_ZXY, + CGM_EULER_ZYX, + CGM_EULER_ZXZ, + CGM_EULER_ZYZ, + CGM_EULER_YXY, + CGM_EULER_YZY, + CGM_EULER_XYX, + CGM_EULER_XZX +} cgm_euler_mode; + +#ifdef __cplusplus +extern "C" { +#endif + +/* --- operations on cgm_vec3 --- */ +static inline void cgm_vcons(cgm_vec3 *v, float x, float y, float z); + +static inline void cgm_vadd(cgm_vec3 *a, const cgm_vec3 *b); +static inline void cgm_vsub(cgm_vec3 *a, const cgm_vec3 *b); +static inline void cgm_vmul(cgm_vec3 *a, const cgm_vec3 *b); +static inline void cgm_vscale(cgm_vec3 *v, float s); +static inline void cgm_vmul_m4v3(cgm_vec3 *v, const float *m); /* m4x4 * v */ +static inline void cgm_vmul_v3m4(cgm_vec3 *v, const float *m); /* v * m4x4 */ +static inline void cgm_vmul_m3v3(cgm_vec3 *v, const float *m); /* m3x3 * v (m still 16 floats) */ +static inline void cgm_vmul_v3m3(cgm_vec3 *v, const float *m); /* v * m3x3 (m still 16 floats) */ + +static inline float cgm_vdot(const cgm_vec3 *a, const cgm_vec3 *b); +static inline void cgm_vcross(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b); +static inline float cgm_vlength(const cgm_vec3 *v); +static inline float cgm_vlength_sq(const cgm_vec3 *v); +static inline float cgm_vdist(const cgm_vec3 *a, const cgm_vec3 *b); +static inline float cgm_vdist_sq(const cgm_vec3 *a, const cgm_vec3 *b); +static inline void cgm_vnormalize(cgm_vec3 *v); + +static inline void cgm_vreflect(cgm_vec3 *v, const cgm_vec3 *n); +static inline void cgm_vrefract(cgm_vec3 *v, const cgm_vec3 *n, float ior); + +static inline void cgm_vrotate_quat(cgm_vec3 *v, const cgm_quat *q); +static inline void cgm_vrotate_axis(cgm_vec3 *v, int axis, float angle); +static inline void cgm_vrotate(cgm_vec3 *v, float angle, float x, float y, float z); +static inline void cgm_vrotate_euler(cgm_vec3 *v, float a, float b, float c, enum cgm_euler_mode mode); + +static inline void cgm_vlerp(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b, float t); + +/* --- operations on cgm_vec4 --- */ +static inline void cgm_wcons(cgm_vec4 *v, float x, float y, float z, float w); + +static inline void cgm_wadd(cgm_vec4 *a, const cgm_vec4 *b); +static inline void cgm_wsub(cgm_vec4 *a, const cgm_vec4 *b); +static inline void cgm_wmul(cgm_vec4 *a, const cgm_vec4 *b); +static inline void cgm_wscale(cgm_vec4 *v, float s); + +static inline void cgm_wmul_m4v4(cgm_vec4 *v, const float *m); +static inline void cgm_wmul_v4m4(cgm_vec4 *v, const float *m); +static inline void cgm_wmul_m34v4(cgm_vec4 *v, const float *m); /* doesn't affect w */ +static inline void cgm_wmul_v4m43(cgm_vec4 *v, const float *m); /* doesn't affect w */ +static inline void cgm_wmul_m3v4(cgm_vec4 *v, const float *m); /* (m still 16 floats) */ +static inline void cgm_wmul_v4m3(cgm_vec4 *v, const float *m); /* (m still 16 floats) */ + +static inline float cgm_wlength(const cgm_vec4 *v); +static inline float cgm_wlength_sq(const cgm_vec4 *v); +static inline float cgm_wdist(const cgm_vec4 *a, const cgm_vec4 *b); +static inline float cgm_wdist_sq(const cgm_vec4 *a, const cgm_vec4 *b); +static inline void cgm_wnormalize(cgm_vec4 *v); + +static inline void cgm_wlerp(cgm_vec4 *res, const cgm_vec4 *a, const cgm_vec4 *b, float t); + +/* --- operations on quaternions --- */ +static inline void cgm_qcons(cgm_quat *q, float x, float y, float z, float w); + +static inline void cgm_qneg(cgm_quat *q); +static inline void cgm_qadd(cgm_quat *a, const cgm_quat *b); +static inline void cgm_qsub(cgm_quat *a, const cgm_quat *b); +static inline void cgm_qmul(cgm_quat *a, const cgm_quat *b); + +static inline float cgm_qlength(const cgm_quat *q); +static inline float cgm_qlength_sq(const cgm_quat *q); +static inline void cgm_qnormalize(cgm_quat *q); +static inline void cgm_qconjugate(cgm_quat *q); +static inline void cgm_qinvert(cgm_quat *q); + +static inline void cgm_qrotation(cgm_quat *q, const cgm_vec3 *axis, float angle); +static inline void cgm_qrotate(cgm_quat *q, const cgm_vec3 *axis, float angle); + +static inline void cgm_qslerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t); +static inline void cgm_qlerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t); + +/* --- operations on matrices --- */ +static inline void cgm_mcopy(float *dest, const float *src); +static inline void cgm_mzero(float *m); +static inline void cgm_midentity(float *m); + +static inline void cgm_mmul(float *a, const float *b); + +static inline void cgm_msubmatrix(float *m, int row, int col); +static inline void cgm_mupper3(float *m); +static inline float cgm_msubdet(const float *m, int row, int col); +static inline float cgm_mcofactor(const float *m, int row, int col); +static inline float cgm_mdet(const float *m); +static inline void cgm_mtranspose(float *m); +static inline void cgm_mcofmatrix(float *m); +static inline int cgm_minverse(float *m); /* returns 0 on success, -1 for singular */ + +static inline void cgm_mtranslation(float *m, float x, float y, float z); +static inline void cgm_mscaling(float *m, float sx, float sy, float sz); +static inline void cgm_mrotation_x(float *m, float angle); +static inline void cgm_mrotation_y(float *m, float angle); +static inline void cgm_mrotation_z(float *m, float angle); +static inline void cgm_mrotation_axis(float *m, int idx, float angle); +static inline void cgm_mrotation(float *m, float angle, float x, float y, float z); +static inline void cgm_mrotation_euler(float *m, float a, float b, float c, int mode); + +static inline void cgm_mtranslate(float *m, float x, float y, float z); +static inline void cgm_mscale(float *m, float sx, float sy, float sz); +static inline void cgm_mrotate_x(float *m, float angle); +static inline void cgm_mrotate_y(float *m, float angle); +static inline void cgm_mrotate_z(float *m, float angle); +static inline void cgm_mrotate_axis(float *m, int idx, float angle); +static inline void cgm_mrotate(float *m, float angle, float x, float y, float z); +static inline void cgm_mrotate_euler(float *m, float a, float b, float c, int mode); + +static inline void cgm_mpretranslate(float *m, float x, float y, float z); +static inline void cgm_mprescale(float *m, float sx, float sy, float sz); +static inline void cgm_mprerotate_x(float *m, float angle); +static inline void cgm_mprerotate_y(float *m, float angle); +static inline void cgm_mprerotate_z(float *m, float angle); +static inline void cgm_mprerotate_axis(float *m, int idx, float angle); +static inline void cgm_mprerotate(float *m, float angle, float x, float y, float z); +static inline void cgm_mprerotate_euler(float *m, float a, float b, float c, int mode); + +static inline void cgm_mget_translation(const float *m, cgm_vec3 *res); +static inline void cgm_mget_rotation(const float *m, cgm_quat *res); +static inline void cgm_mget_scaling(const float *m, cgm_vec3 *res); +static inline void cgm_mget_frustum_plane(const float *m, int p, cgm_vec4 *res); + +static inline void cgm_mlookat(float *m, const cgm_vec3 *pos, const cgm_vec3 *targ, + const cgm_vec3 *up); +static inline void cgm_minv_lookat(float *m, const cgm_vec3 *pos, const cgm_vec3 *targ, + const cgm_vec3 *up); +static inline void cgm_mortho(float *m, float left, float right, float bot, float top, + float znear, float zfar); +static inline void cgm_mfrustum(float *m, float left, float right, float bot, float top, + float znear, float zfar); +static inline void cgm_mperspective(float *m, float vfov, float aspect, float znear, float zfar); + +static inline void cgm_mmirror(float *m, float a, float b, float c, float d); + +/* --- operations on rays --- */ +static inline void cgm_rcons(cgm_ray *r, float x, float y, float z, float dx, float dy, float dz); + +static inline void cgm_rmul_mr(cgm_ray *ray, const float *m); /* m4x4 * ray */ +static inline void cgm_rmul_rm(cgm_ray *ray, const float *m); /* ray * m4x4 */ + +static inline void cgm_rreflect(cgm_ray *ray, const cgm_vec3 *n); +static inline void cgm_rrefract(cgm_ray *ray, const cgm_vec3 *n, float ior); + +/* --- miscellaneous utility functions --- */ +static inline float cgm_deg_to_rad(float deg); +static inline float cgm_rad_to_deg(float rad); + +static inline float cgm_smoothstep(float a, float b, float x); +static inline float cgm_bezier(float a, float b, float c, float d, float t); + +static inline void cgm_discrand(cgm_vec3 *v, float rad); +static inline void cgm_sphrand(cgm_vec3 *v, float rad); + +static inline void cgm_unproject(cgm_vec3 *res, const cgm_vec3 *norm_scrpos, + const float *inv_viewproj); +static inline void cgm_glu_unproject(float winx, float winy, float winz, + const float *view, const float *proj, const int *vp, + float *objx, float *objy, float *objz); + +static inline void cgm_pick_ray(cgm_ray *ray, float nx, float ny, + const float *viewmat, const float *projmat); + +static inline void cgm_raypos(cgm_vec3 *p, const cgm_ray *ray, float t); + +/* calculate barycentric coordinates of point pt in triangle (a, b, c) */ +static inline void cgm_bary(cgm_vec3 *bary, const cgm_vec3 *a, + const cgm_vec3 *b, const cgm_vec3 *c, const cgm_vec3 *pt); + +#include "cgmvec3.inl" +#include "cgmvec4.inl" +#include "cgmquat.inl" +#include "cgmmat.inl" +#include "cgmray.inl" +#include "cgmmisc.inl" + +#ifdef __cplusplus +} +#endif + +#endif /* CGMATH_H_ */ diff --git a/src/cgmath/cgmmat.inl b/src/cgmath/cgmmat.inl new file mode 100644 index 0000000..62edc8b --- /dev/null +++ b/src/cgmath/cgmmat.inl @@ -0,0 +1,577 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + */ +static inline void cgm_mcopy(float *dest, const float *src) +{ + memcpy(dest, src, 16 * sizeof(float)); +} + +static inline void cgm_mzero(float *m) +{ + static float z[16]; + cgm_mcopy(m, z); +} + +static inline void cgm_midentity(float *m) +{ + static float id[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + cgm_mcopy(m, id); +} + +static inline void cgm_mmul(float *a, const float *b) +{ + int i, j; + float res[16]; + float *resptr = res; + float *arow = a; + + for(i=0; i<4; i++) { + for(j=0; j<4; j++) { + *resptr++ = arow[0] * b[j] + arow[1] * b[4 + j] + + arow[2] * b[8 + j] + arow[3] * b[12 + j]; + } + arow += 4; + } + cgm_mcopy(a, res); +} + +static inline void cgm_msubmatrix(float *m, int row, int col) +{ + float orig[16]; + int i, j, subi, subj; + + cgm_mcopy(orig, m); + + subi = 0; + for(i=0; i<4; i++) { + if(i == row) continue; + + subj = 0; + for(j=0; j<4; j++) { + if(j == col) continue; + + m[subi * 4 + subj++] = orig[i * 4 + j]; + } + subi++; + } + + cgm_mupper3(m); +} + +static inline void cgm_mupper3(float *m) +{ + m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0.0f; + m[15] = 1.0f; +} + +static inline float cgm_msubdet(const float *m, int row, int col) +{ + float tmp[16]; + float subdet00, subdet01, subdet02; + + cgm_mcopy(tmp, m); + cgm_msubmatrix(tmp, row, col); + + subdet00 = tmp[5] * tmp[10] - tmp[6] * tmp[9]; + subdet01 = tmp[4] * tmp[10] - tmp[6] * tmp[8]; + subdet02 = tmp[4] * tmp[9] - tmp[5] * tmp[8]; + + return tmp[0] * subdet00 - tmp[1] * subdet01 + tmp[2] * subdet02; +} + +static inline float cgm_mcofactor(const float *m, int row, int col) +{ + float min = cgm_msubdet(m, row, col); + return (row + col) & 1 ? -min : min; +} + +static inline float cgm_mdet(const float *m) +{ + return m[0] * cgm_msubdet(m, 0, 0) - m[1] * cgm_msubdet(m, 0, 1) + + m[2] * cgm_msubdet(m, 0, 2) - m[3] * cgm_msubdet(m, 0, 3); +} + +static inline void cgm_mtranspose(float *m) +{ + int i, j; + for(i=0; i<4; i++) { + for(j=0; jx = m[12]; + res->y = m[13]; + res->z = m[14]; +} + +/* Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + * article "Quaternion Calculus and Fast Animation". + * adapted from: http://www.geometrictools.com/LibMathematics/Algebra/Wm5Quaternion.inl + */ +static inline void cgm_mget_rotation(const float *m, cgm_quat *res) +{ + static const int next[3] = {1, 2, 0}; + float quat[4]; + int i, j, k; + + float trace = m[0] + m[5] + m[10]; + float root; + + if(trace > 0.0f) { + // |w| > 1/2 + root = sqrt(trace + 1.0f); // 2w + res->w = 0.5f * root; + root = 0.5f / root; // 1 / 4w + res->x = (m[6] - m[9]) * root; + res->y = (m[8] - m[2]) * root; + res->z = (m[1] - m[4]) * root; + } else { + // |w| <= 1/2 + i = 0; + if(m[5] > m[0]) { + i = 1; + } + if(m[10] > m[i * 4 + i]) { + i = 2; + } + j = next[i]; + k = next[j]; + + root = sqrt(m[i * 4 + i] - m[j * 4 + j] - m[k * 4 + k] + 1.0f); + quat[i + 1] = 0.5f * root; + root = 0.5f / root; + quat[0] = (m[j + 4 + k] - m[k * 4 + j]) * root; + quat[j + 1] = (m[i * 4 + j] - m[j * 4 + i]) * root; + quat[k + 1] = (m[i * 4 + k] - m[k * 4 + i]) * root; + res->w = quat[0]; + res->x = quat[1]; + res->y = quat[2]; + res->z = quat[3]; + } +} + +static inline void cgm_mget_scaling(const float *m, cgm_vec3 *res) +{ + res->x = sqrt(m[0] * m[0] + m[4] * m[4] + m[8] * m[8]); + res->y = sqrt(m[1] * m[1] + m[5] * m[5] + m[9] * m[9]); + res->z = sqrt(m[2] * m[2] + m[6] * m[6] + m[10] * m[10]); +} + +static inline void cgm_mget_frustum_plane(const float *m, int p, cgm_vec4 *res) +{ + int row = p >> 1; + const float *rowptr = m + row * 4; + + if((p & 1) == 0) { + res->x = m[12] + rowptr[0]; + res->y = m[13] + rowptr[1]; + res->z = m[14] + rowptr[2]; + res->w = m[15] + rowptr[3]; + } else { + res->x = m[12] - rowptr[0]; + res->y = m[13] - rowptr[1]; + res->z = m[14] - rowptr[2]; + res->w = m[15] - rowptr[3]; + } +} + +static inline void cgm_mlookat(float *m, const cgm_vec3 *pos, const cgm_vec3 *targ, + const cgm_vec3 *up) +{ + float trans[16]; + cgm_vec3 dir = *targ, right, vup; + + cgm_vsub(&dir, pos); + cgm_vnormalize(&dir); + cgm_vcross(&right, &dir, up); + cgm_vnormalize(&right); + cgm_vcross(&vup, &right, &dir); + cgm_vnormalize(&vup); + + cgm_midentity(m); + m[0] = right.x; + m[1] = right.y; + m[2] = right.z; + m[4] = vup.x; + m[5] = vup.y; + m[6] = vup.z; + m[8] = -dir.x; + m[9] = -dir.y; + m[10] = -dir.z; + + cgm_mtranslation(trans, pos->x, pos->y, pos->z); + cgm_mmul(m, trans); +} + +static inline void cgm_minv_lookat(float *m, const cgm_vec3 *pos, const cgm_vec3 *targ, + const cgm_vec3 *up) +{ + float rot[16]; + cgm_vec3 dir = *targ, right, vup; + + cgm_vsub(&dir, pos); + cgm_vnormalize(&dir); + cgm_vcross(&right, &dir, up); + cgm_vnormalize(&right); + cgm_vcross(&vup, &right, &dir); + cgm_vnormalize(&vup); + + cgm_midentity(rot); + rot[0] = right.x; + rot[4] = right.y; + rot[8] = right.z; + rot[1] = vup.x; + rot[5] = vup.y; + rot[9] = vup.z; + rot[2] = -dir.x; + rot[6] = -dir.y; + rot[10] = -dir.z; + + cgm_mtranslation(m, -pos->x, -pos->y, -pos->z); + cgm_mmul(m, rot); +} + +static inline void cgm_mortho(float *m, float left, float right, float bot, float top, + float znear, float zfar) +{ + float dx = right - left; + float dy = top - bot; + float dz = zfar - znear; + + cgm_midentity(m); + m[0] = 2.0f / dx; + m[5] = 2.0f / dy; + m[10] = -2.0f / dz; + m[12] = -(right + left) / dx; + m[13] = -(top + bot) / dy; + m[14] = -(zfar + znear) / dz; +} + +static inline void cgm_mfrustum(float *m, float left, float right, float bot, float top, + float znear, float zfar) +{ + float dx = right - left; + float dy = top - bot; + float dz = zfar - znear; + + cgm_mzero(m); + m[0] = 2.0f * znear / dx; + m[5] = 2.0f * znear / dy; + m[8] = (right + left) / dx; + m[9] = (top + bot) / dy; + m[10] = -(zfar + znear) / dz; + m[14] = -2.0f * zfar * znear / dz; + m[11] = -1.0f; +} + +static inline void cgm_mperspective(float *m, float vfov, float aspect, float znear, float zfar) +{ + float s = 1.0f / (float)tan(vfov / 2.0f); + float range = znear - zfar; + + cgm_mzero(m); + m[0] = s / aspect; + m[5] = s; + m[10] = (znear + zfar) / range; + m[14] = 2.0f * znear * zfar / range; + m[11] = -1.0f; +} + +static inline void cgm_mmirror(float *m, float a, float b, float c, float d) +{ + m[0] = 1.0f - 2.0f * a * a; + m[5] = 1.0f - 2.0f * b * b; + m[10] = 1.0f - 2.0f * c * c; + m[15] = 1.0f; + + m[1] = m[4] = -2.0f * a * b; + m[2] = m[8] = -2.0f * a * c; + m[6] = m[9] = -2.0f * b * c; + + m[12] = -2.0f * a * d; + m[13] = -2.0f * b * d; + m[14] = -2.0f * c * d; + + m[3] = m[7] = m[11] = 0.0f; +} diff --git a/src/cgmath/cgmmisc.inl b/src/cgmath/cgmmisc.inl new file mode 100644 index 0000000..6cfa37d --- /dev/null +++ b/src/cgmath/cgmmisc.inl @@ -0,0 +1,154 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + */ +#include + +static inline float cgm_deg_to_rad(float deg) +{ + return M_PI * deg / 180.0f; +} + +static inline float cgm_rad_to_deg(float rad) +{ + return 180.0f * rad / M_PI; +} + +static inline float cgm_smoothstep(float a, float b, float x) +{ + if(x < a) return 0.0f; + if(x >= b) return 1.0f; + + x = (x - a) / (b - a); + return x * x * (3.0f - 2.0f * x); +} + +static inline float cgm_lerp(float a, float b, float t) +{ + return a + (b - a) * t; +} + +static inline float cgm_bezier(float a, float b, float c, float d, float t) +{ + float omt, omt3, t3, f; + t3 = t * t * t; + omt = 1.0f - t; + omt3 = omt * omt * omt; + f = 3.0f * t * omt; + + return (a * omt3) + (b * f * omt) + (c * f * t) + (d * t3); +} + +static inline void cgm_discrand(cgm_vec3 *pt, float rad) +{ + float theta = 2.0f * M_PI * (float)rand() / RAND_MAX; + float r = sqrt((float)rand() / RAND_MAX) * rad; + pt->x = cos(theta) * r; + pt->y = sin(theta) * r; + pt->z = 0.0f; +} + +static inline void cgm_sphrand(cgm_vec3 *pt, float rad) +{ + float u, v, theta, phi; + + u = (float)rand() / RAND_MAX; + v = (float)rand() / RAND_MAX; + + theta = 2.0f * M_PI * u; + phi = acos(2.0f * v - 1.0f); + + pt->x = cos(theta) * sin(phi) * rad; + pt->y = sin(theta) * sin(phi) * rad; + pt->z = cos(phi) * rad; +} + +static inline void cgm_unproject(cgm_vec3 *res, const cgm_vec3 *norm_scrpos, + const float *inv_viewproj) +{ + cgm_vec4 pos; + + pos.x = 2.0f * norm_scrpos->x - 1.0f; + pos.y = 2.0f * norm_scrpos->y - 1.0f; + pos.z = 2.0f * norm_scrpos->z - 1.0f; + pos.w = 1.0f; + + cgm_wmul_m4v4(&pos, inv_viewproj); + + res->x = pos.x / pos.w; + res->y = pos.y / pos.w; + res->z = pos.z / pos.w; +} + +static inline void cgm_glu_unproject(float winx, float winy, float winz, + const float *view, const float *proj, const int *vp, + float *objx, float *objy, float *objz) +{ + cgm_vec3 npos, res; + float inv_pv[16]; + + cgm_mcopy(inv_pv, proj); + cgm_mmul(inv_pv, view); + + npos.x = (winx - vp[0]) / vp[2]; + npos.y = (winy - vp[1]) / vp[4]; + npos.z = winz; + + cgm_unproject(&res, &npos, inv_pv); + + *objx = res.x; + *objy = res.y; + *objz = res.z; +} + +static inline void cgm_pick_ray(cgm_ray *ray, float nx, float ny, + const float *viewmat, const float *projmat) +{ + cgm_vec3 npos, farpt; + float inv_pv[16]; + + cgm_mcopy(inv_pv, projmat); + cgm_mmul(inv_pv, viewmat); + + cgm_vcons(&npos, nx, ny, 0.0f); + cgm_unproject(&ray->origin, &npos, inv_pv); + npos.z = 1.0f; + cgm_unproject(&farpt, &npos, inv_pv); + + ray->dir.x = farpt.x - ray->origin.x; + ray->dir.y = farpt.y - ray->origin.y; + ray->dir.z = farpt.z - ray->origin.z; +} + +static inline void cgm_raypos(cgm_vec3 *p, const cgm_ray *ray, float t) +{ + p->x = ray->origin.x + ray->dir.x * t; + p->y = ray->origin.y + ray->dir.y * t; + p->z = ray->origin.z + ray->dir.z * t; +} + +static inline void cgm_bary(cgm_vec3 *bary, const cgm_vec3 *a, + const cgm_vec3 *b, const cgm_vec3 *c, const cgm_vec3 *pt) +{ + float d00, d01, d11, d20, d21, denom; + cgm_vec3 v0 = *b, v1 = *c, v2 = *pt; + + cgm_vsub(&v0, a); + cgm_vsub(&v1, a); + cgm_vsub(&v2, a); + + d00 = cgm_vdot(&v0, &v0); + d01 = cgm_vdot(&v0, &v1); + d11 = cgm_vdot(&v1, &v1); + d20 = cgm_vdot(&v2, &v0); + d21 = cgm_vdot(&v2, &v1); + denom = d00 * d11 - d01 * d01; + + bary->y = (d11 * d20 - d01 * d21) / denom; + bary->z = (d00 * d21 - d01 * d20) / denom; + bary->x = 1.0f - bary->y - bary->z; +} diff --git a/src/cgmath/cgmquat.inl b/src/cgmath/cgmquat.inl new file mode 100644 index 0000000..4b29fd2 --- /dev/null +++ b/src/cgmath/cgmquat.inl @@ -0,0 +1,159 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + */ +static inline void cgm_qcons(cgm_quat *q, float x, float y, float z, float w) +{ + q->x = x; + q->y = y; + q->z = z; + q->w = w; +} + + +static inline void cgm_qneg(cgm_quat *q) +{ + q->x = -q->x; + q->y = -q->y; + q->z = -q->z; + q->w = -q->w; +} + +static inline void cgm_qadd(cgm_quat *a, const cgm_quat *b) +{ + a->x += b->x; + a->y += b->y; + a->z += b->z; + a->w += b->w; +} + +static inline void cgm_qsub(cgm_quat *a, const cgm_quat *b) +{ + a->x -= b->x; + a->y -= b->y; + a->z -= b->z; + a->w -= b->w; +} + +static inline void cgm_qmul(cgm_quat *a, const cgm_quat *b) +{ + float x, y, z, dot; + cgm_vec3 cross; + + dot = a->x * b->x + a->y * b->y + a->z * b->z; + cgm_vcross(&cross, (cgm_vec3*)a, (cgm_vec3*)b); + + x = a->w * b->x + b->w * a->x + cross.x; + y = a->w * b->y + b->w * a->y + cross.y; + z = a->w * b->z + b->w * a->z + cross.z; + a->w = a->w * b->w - dot; + a->x = x; + a->y = y; + a->z = z; +} + +static inline float cgm_qlength(const cgm_quat *q) +{ + return sqrt(q->x * q->x + q->y * q->y + q->z * q->z + q->w * q->w); +} + +static inline float cgm_qlength_sq(const cgm_quat *q) +{ + return q->x * q->x + q->y * q->y + q->z * q->z + q->w * q->w; +} + +static inline void cgm_qnormalize(cgm_quat *q) +{ + float len = cgm_qlength(q); + if(len != 0.0f) { + float s = 1.0f / len; + q->x *= s; + q->y *= s; + q->z *= s; + q->w *= s; + } +} + +static inline void cgm_qconjugate(cgm_quat *q) +{ + q->x = -q->x; + q->y = -q->y; + q->z = -q->z; +} + +static inline void cgm_qinvert(cgm_quat *q) +{ + float len_sq = cgm_qlength_sq(q); + cgm_qconjugate(q); + if(len_sq != 0.0f) { + float s = 1.0f / len_sq; + q->x *= s; + q->y *= s; + q->z *= s; + q->w *= s; + } +} + +static inline void cgm_qrotation(cgm_quat *q, const cgm_vec3 *axis, float angle) +{ + float hangle = angle * 0.5f; + float sin_ha = sin(hangle); + q->w = cos(hangle); + q->x = axis->x * sin_ha; + q->y = axis->y * sin_ha; + q->z = axis->z * sin_ha; +} + +static inline void cgm_qrotate(cgm_quat *q, const cgm_vec3 *axis, float angle) +{ + cgm_quat qrot; + cgm_qrotation(&qrot, axis, angle); + cgm_qmul(q, &qrot); +} + +static inline void cgm_qslerp(cgm_quat *res, const cgm_quat *quat1, const cgm_quat *q2, float t) +{ + float angle, dot, a, b, sin_angle; + cgm_quat q1 = *quat1; + + dot = quat1->x * q2->x + quat1->y * q2->y + quat1->z * q2->z + quat1->w * q2->w; + if(dot < 0.0f) { + /* make sure we inteprolate across the shortest arc */ + cgm_qneg(&q1); + dot = -dot; + } + + /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to + * floating point imprecisions + */ + if(dot < -1.0f) dot = -1.0f; + if(dot > 1.0f) dot = 1.0f; + angle = acos(dot); + + sin_angle = sin(angle); + if(sin_angle == 0.0f) { + /* use linear interpolation to avoid div/zero */ + a = 1.0f; + b = t; + } else { + a = sin((1.0f - t) * angle) / sin_angle; + b = sin(t * angle) / sin_angle; + } + + res->x = q1.x * a + q2->x * b; + res->y = q1.y * a + q2->y * b; + res->z = q1.z * a + q2->z * b; + res->w = q1.w * a + q2->w * b; +} + +static inline void cgm_qlerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t) +{ + res->x = a->x + (b->x - a->x) * t; + res->y = a->y + (b->y - a->y) * t; + res->z = a->z + (b->z - a->z) * t; + res->w = a->w + (b->w - a->w) * t; +} diff --git a/src/cgmath/cgmray.inl b/src/cgmath/cgmray.inl new file mode 100644 index 0000000..063a7e0 --- /dev/null +++ b/src/cgmath/cgmray.inl @@ -0,0 +1,39 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + */ +static inline void cgm_rcons(cgm_ray *r, float x, float y, float z, float dx, float dy, float dz) +{ + r->origin.x = x; + r->origin.y = y; + r->origin.z = z; + r->dir.x = dx; + r->dir.y = dy; + r->dir.z = dz; +} + +static inline void cgm_rmul_mr(cgm_ray *ray, const float *m) +{ + cgm_vmul_m4v3(&ray->origin, m); + cgm_vmul_m3v3(&ray->dir, m); +} + +static inline void cgm_rmul_rm(cgm_ray *ray, const float *m) +{ + cgm_vmul_v3m4(&ray->origin, m); + cgm_vmul_v3m3(&ray->dir, m); +} + +static inline void cgm_rreflect(cgm_ray *ray, const cgm_vec3 *n) +{ + cgm_vreflect(&ray->dir, n); +} + +static inline void cgm_rrefract(cgm_ray *ray, const cgm_vec3 *n, float ior) +{ + cgm_vrefract(&ray->dir, n, ior); +} diff --git a/src/cgmath/cgmvec3.inl b/src/cgmath/cgmvec3.inl new file mode 100644 index 0000000..88211c4 --- /dev/null +++ b/src/cgmath/cgmvec3.inl @@ -0,0 +1,188 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + */ +static inline void cgm_vcons(cgm_vec3 *v, float x, float y, float z) +{ + v->x = x; + v->y = y; + v->z = z; +} + +static inline void cgm_vadd(cgm_vec3 *a, const cgm_vec3 *b) +{ + a->x += b->x; + a->y += b->y; + a->z += b->z; +} + +static inline void cgm_vsub(cgm_vec3 *a, const cgm_vec3 *b) +{ + a->x -= b->x; + a->y -= b->y; + a->z -= b->z; +} + +static inline void cgm_vmul(cgm_vec3 *a, const cgm_vec3 *b) +{ + a->x *= b->x; + a->y *= b->y; + a->z *= b->z; +} + +static inline void cgm_vscale(cgm_vec3 *v, float s) +{ + v->x *= s; + v->y *= s; + v->z *= s; +} + +static inline void cgm_vmul_m4v3(cgm_vec3 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[4] + v->z * m[8] + m[12]; + float y = v->x * m[1] + v->y * m[5] + v->z * m[9] + m[13]; + v->z = v->x * m[2] + v->y * m[6] + v->z * m[10] + m[14]; + v->x = x; + v->y = y; +} + +static inline void cgm_vmul_v3m4(cgm_vec3 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[1] + v->z * m[2] + m[3]; + float y = v->x * m[4] + v->y * m[5] + v->z * m[6] + m[7]; + v->z = v->x * m[8] + v->y * m[9] + v->z * m[10] + m[11]; + v->x = x; + v->y = y; +} + +static inline void cgm_vmul_m3v3(cgm_vec3 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[4] + v->z * m[8]; + float y = v->x * m[1] + v->y * m[5] + v->z * m[9]; + v->z = v->x * m[2] + v->y * m[6] + v->z * m[10]; + v->x = x; + v->y = y; +} + +static inline void cgm_vmul_v3m3(cgm_vec3 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[1] + v->z * m[2]; + float y = v->x * m[4] + v->y * m[5] + v->z * m[6]; + v->z = v->x * m[8] + v->y * m[9] + v->z * m[10]; + v->x = x; + v->y = y; +} + +static inline float cgm_vdot(const cgm_vec3 *a, const cgm_vec3 *b) +{ + return a->x * b->x + a->y * b->y + a->z * b->z; +} + +static inline void cgm_vcross(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b) +{ + res->x = a->y * b->z - a->z * b->y; + res->y = a->z * b->x - a->x * b->z; + res->z = a->x * b->y - a->y * b->x; +} + +static inline float cgm_vlength(const cgm_vec3 *v) +{ + return sqrt(v->x * v->x + v->y * v->y + v->z * v->z); +} + +static inline float cgm_vlength_sq(const cgm_vec3 *v) +{ + return v->x * v->x + v->y * v->y + v->z * v->z; +} + +static inline float cgm_vdist(const cgm_vec3 *a, const cgm_vec3 *b) +{ + float dx = a->x - b->x; + float dy = a->y - b->y; + float dz = a->z - b->z; + return sqrt(dx * dx + dy * dy + dz * dz); +} + +static inline float cgm_vdist_sq(const cgm_vec3 *a, const cgm_vec3 *b) +{ + float dx = a->x - b->x; + float dy = a->y - b->y; + float dz = a->z - b->z; + return dx * dx + dy * dy + dz * dz; +} + +static inline void cgm_vnormalize(cgm_vec3 *v) +{ + float len = cgm_vlength(v); + if(len != 0.0f) { + float s = 1.0f / len; + v->x *= s; + v->y *= s; + v->z *= s; + } +} + +static inline void cgm_vreflect(cgm_vec3 *v, const cgm_vec3 *n) +{ + float ndotv2 = cgm_vdot(v, n) * 2.0f; + v->x -= n->x * ndotv2; + v->y -= n->y * ndotv2; + v->z -= n->z * ndotv2; +} + +static inline void cgm_vrefract(cgm_vec3 *v, const cgm_vec3 *n, float ior) +{ + float ndotv = cgm_vdot(v, n); + float k = 1.0f - ior * ior * (1.0f - ndotv * ndotv); + if(k < 0.0f) { + cgm_vreflect(v, n); /* TIR */ + } else { + float sqrt_k = sqrt(k); + v->x = ior * v->x - (ior * ndotv + sqrt_k) * n->x; + v->y = ior * v->y - (ior * ndotv + sqrt_k) * n->y; + v->z = ior * v->z - (ior * ndotv + sqrt_k) * n->z; + } +} + +static inline void cgm_vrotate_quat(cgm_vec3 *v, const cgm_quat *q) +{ + cgm_quat vq, inv_q = *q, tmp_q = *q; + + cgm_qcons(&vq, v->x, v->y, v->z, 0.0f); + cgm_qinvert(&inv_q); + cgm_qmul(&tmp_q, &vq); + cgm_qmul(&vq, &inv_q); + cgm_vcons(v, vq.x, vq.y, vq.z); +} + +static inline void cgm_vrotate_axis(cgm_vec3 *v, int axis, float angle) +{ + float m[16]; + cgm_mrotation_axis(m, axis, angle); + cgm_vmul_m3v3(v, m); +} + +static inline void cgm_vrotate(cgm_vec3 *v, float angle, float x, float y, float z) +{ + float m[16]; + cgm_mrotation(m, angle, x, y, z); + cgm_vmul_m3v3(v, m); +} + +static inline void cgm_vrotate_euler(cgm_vec3 *v, float a, float b, float c, enum cgm_euler_mode mode) +{ + float m[16]; + cgm_mrotation_euler(m, a, b, c, mode); + cgm_vmul_m3v3(v, m); +} + +static inline void cgm_vlerp(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b, float t) +{ + res->x = a->x + (b->x - a->x) * t; + res->y = a->y + (b->y - a->y) * t; + res->z = a->z + (b->z - a->z) * t; +} diff --git a/src/cgmath/cgmvec4.inl b/src/cgmath/cgmvec4.inl new file mode 100644 index 0000000..1c143c2 --- /dev/null +++ b/src/cgmath/cgmvec4.inl @@ -0,0 +1,153 @@ +/* gph-cmath - C graphics math library + * Copyright (C) 2018 John Tsiombikas + * + * This program is free software. Feel free to use, modify, and/or redistribute + * it under the terms of the MIT/X11 license. See LICENSE for details. + * If you intend to redistribute parts of the code without the LICENSE file + * replace this paragraph with the full contents of the LICENSE file. + */ +static inline void cgm_wcons(cgm_vec4 *v, float x, float y, float z, float w) +{ + v->x = x; + v->y = y; + v->z = z; + v->w = w; +} + +static inline void cgm_wadd(cgm_vec4 *a, const cgm_vec4 *b) +{ + a->x += b->x; + a->y += b->y; + a->z += b->z; + a->w += b->w; +} + +static inline void cgm_wsub(cgm_vec4 *a, const cgm_vec4 *b) +{ + a->x -= b->x; + a->y -= b->y; + a->z -= b->z; + a->w -= b->w; +} + +static inline void cgm_wmul(cgm_vec4 *a, const cgm_vec4 *b) +{ + a->x *= b->x; + a->y *= b->y; + a->z *= b->z; + a->w *= b->w; +} + +static inline void cgm_wscale(cgm_vec4 *v, float s) +{ + v->x *= s; + v->y *= s; + v->z *= s; + v->w *= s; +} + +static inline void cgm_wmul_m4v4(cgm_vec4 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[4] + v->z * m[8] + v->w * m[12]; + float y = v->x * m[1] + v->y * m[5] + v->z * m[9] + v->w * m[13]; + float z = v->x * m[2] + v->y * m[6] + v->z * m[10] + v->w * m[14]; + v->w = v->x * m[3] + v->y * m[7] + v->z * m[11] + v->w * m[15]; + v->x = x; + v->y = y; + v->z = z; +} + +static inline void cgm_wmul_v4m4(cgm_vec4 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[1] + v->z * m[2] + v->w * m[3]; + float y = v->x * m[4] + v->y * m[5] + v->z * m[6] + v->w * m[7]; + float z = v->x * m[8] + v->y * m[9] + v->z * m[10] + v->w * m[11]; + v->w = v->x * m[12] + v->y * m[13] + v->z * m[14] + v->w * m[15]; + v->x = x; + v->y = y; + v->z = z; +} + +static inline void cgm_wmul_m34v4(cgm_vec4 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[4] + v->z * m[8] + v->w * m[12]; + float y = v->x * m[1] + v->y * m[5] + v->z * m[9] + v->w * m[13]; + v->z = v->x * m[2] + v->y * m[6] + v->z * m[10] + v->w * m[14]; + v->x = x; + v->y = y; +} + +static inline void cgm_wmul_v4m43(cgm_vec4 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[1] + v->z * m[2] + v->w * m[3]; + float y = v->x * m[4] + v->y * m[5] + v->z * m[6] + v->w * m[7]; + v->z = v->x * m[8] + v->y * m[9] + v->z * m[10] + v->w * m[11]; + v->x = x; + v->y = y; +} + +static inline void cgm_wmul_m3v4(cgm_vec4 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[4] + v->z * m[8]; + float y = v->x * m[1] + v->y * m[5] + v->z * m[9]; + v->z = v->x * m[2] + v->y * m[6] + v->z * m[10]; + v->x = x; + v->y = y; +} + +static inline void cgm_wmul_v4m3(cgm_vec4 *v, const float *m) +{ + float x = v->x * m[0] + v->y * m[1] + v->z * m[2]; + float y = v->x * m[4] + v->y * m[5] + v->z * m[6]; + v->z = v->x * m[8] + v->y * m[9] + v->z * m[10]; + v->x = x; + v->y = y; +} + +static inline float cgm_wlength(const cgm_vec4 *v) +{ + return sqrt(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w); +} + +static inline float cgm_wlength_sq(const cgm_vec4 *v) +{ + return v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w; +} + +static inline float cgm_wdist(const cgm_vec4 *a, const cgm_vec4 *b) +{ + float dx = a->x - b->x; + float dy = a->y - b->y; + float dz = a->z - b->z; + float dw = a->w - b->w; + return sqrt(dx * dx + dy * dy + dz * dz + dw * dw); +} + +static inline float cgm_wdist_sq(const cgm_vec4 *a, const cgm_vec4 *b) +{ + float dx = a->x - b->x; + float dy = a->y - b->y; + float dz = a->z - b->z; + float dw = a->w - b->w; + return dx * dx + dy * dy + dz * dz + dw * dw; +} + +static inline void cgm_wnormalize(cgm_vec4 *v) +{ + float len = cgm_wlength(v); + if(len != 0.0f) { + float s = 1.0f / len; + v->x *= s; + v->y *= s; + v->z *= s; + v->w *= s; + } +} + +static inline void cgm_wlerp(cgm_vec4 *res, const cgm_vec4 *a, const cgm_vec4 *b, float t) +{ + res->x = a->x + (b->x - a->x) * t; + res->y = a->y + (b->y - a->y) * t; + res->z = a->z + (b->z - a->z) * t; + res->w = a->w + (b->w - a->w) * t; +} diff --git a/src/music.c b/src/music.c index 11b9c44..fe8ed6d 100644 --- a/src/music.c +++ b/src/music.c @@ -1,20 +1,13 @@ #include #include "music.h" -#ifndef NO_MUSIC -#include "mikmod.h" - #ifdef __WATCOMC__ -#define USE_OLDMIK -typedef UNIMOD MODULE; - -static void update_callback(void); -static void MikMod_RegisterAllDrivers(void); -static void MikMod_RegisterAllLoaders(void); -#else -#define USE_NEWMIK +#define NO_MUSIC #endif +#ifndef NO_MUSIC +#include "mikmod.h" + static MODULE *mod; static int initialized; @@ -23,7 +16,6 @@ static int init(void) MikMod_RegisterAllDrivers(); MikMod_RegisterAllLoaders(); -#ifdef USE_NEWMIK md_mode |= DMODE_SOFT_MUSIC | DMODE_16BITS | DMODE_STEREO | DMODE_INTERP; if(MikMod_Init("") != 0) { fprintf(stderr, "mikmod init failed: %s\n", @@ -31,26 +23,6 @@ static int init(void) return -1; } -#else - md_mixfreq = 44100; - md_dmabufsize = 20000; - md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_INTERP; - md_device = 0; - - MD_RegisterPlayer(update_callback); - - if(!MD_Init()) { - fprintf(stderr, "mikmod init failed: %s\n", myerr); - return -1; - } - printf("using mikmod driver %s\n", md_driver->Name); - printf(" %d bits, %s, %s mixing at %d Hz\n", md_mode & DMODE_16BITS ? 16 : 8, - md_mode & DMODE_STEREO ? "stereo" : "mono", - md_mode & DMODE_INTERP ? "interpolated" : "normal", - md_mixfreq); - - atexit(MD_Exit); -#endif return 0; } @@ -63,22 +35,11 @@ int music_open(const char *fname) initialized = 1; } -#ifdef USE_NEWMIK if(!(mod = Player_Load(fname, 64, 0))) { fprintf(stderr, "failed to load music: %s: %s\n", fname, MikMod_strerror(MikMod_errno)); return -1; } -#else - if(!(mod = ML_LoadFN((char*)fname))) { - fprintf(stderr, "failed to load music: %s: %s\n", fname, myerr); - return -1; - } - - MP_Init(mod); - md_numchn = mod->numchn; - printf("opened module %s (%d channels)\n", fname, md_numchn); -#endif return 0; } @@ -87,72 +48,28 @@ void music_close(void) if(mod) { printf("shutting down music playback\n"); music_stop(); -#ifdef USE_NEWMIK Player_Free(mod); -#else - ML_Free(mod); -#endif mod = 0; } } void music_play(void) { -#ifdef USE_NEWMIK Player_Start(mod); -#else - MD_PlayStart(); -#endif } void music_stop(void) { -#ifdef USE_NEWMIK Player_Stop(); -#else - MD_PlayStop(); -#endif } void music_update(void) { -#ifdef USE_NEWMIK if(Player_Active()) { MikMod_Update(); } -#else - MD_Update(); -#endif -} - -#ifdef USE_OLDMIK -static void update_callback(void) -{ - MP_HandleTick(); - MD_SetBPM(mp_bpm); } -static void MikMod_RegisterAllDrivers(void) -{ - MD_RegisterDriver(&drv_nos); - MD_RegisterDriver(&drv_ss); - MD_RegisterDriver(&drv_sb); - MD_RegisterDriver(&drv_gus); -} - -static void MikMod_RegisterAllLoaders(void) -{ - ML_RegisterLoader(&load_m15); - ML_RegisterLoader(&load_mod); - ML_RegisterLoader(&load_mtm); - ML_RegisterLoader(&load_s3m); - ML_RegisterLoader(&load_stm); - ML_RegisterLoader(&load_ult); - ML_RegisterLoader(&load_uni); - ML_RegisterLoader(&load_xm); -} -#endif - #else /* NO_MUSIC */ int music_open(const char *fname) diff --git a/src/noise.c b/src/noise.c index b3b3f9c..4401e5a 100644 --- a/src/noise.c +++ b/src/noise.c @@ -320,8 +320,9 @@ float pnoise4(float x, float y, float z, float w, int per_x, int per_y, int per_ float fbm1(float x, int octaves) { + int i; float res = 0.0f, freq = 1.0f; - for(int i=0; i pv[botidx].y) botidx = i; } - int winding = 0; + winding = 0; for(i=0; i> 4) * ((pv[next].y + pv[i].y) >> 4); diff --git a/src/scene.h b/src/scene.h new file mode 100644 index 0000000..b55bec9 --- /dev/null +++ b/src/scene.h @@ -0,0 +1,10 @@ +#ifndef SCENE_H_ +#define SCENE_H_ + +#include "cgmath/cgmath.h" + +struct scene { + int num_obj; +}; + +#endif /* SCENE_H_ */ diff --git a/src/tilemaze.c b/src/tilemaze.c index 7407bd4..6e2aa54 100644 --- a/src/tilemaze.c +++ b/src/tilemaze.c @@ -5,6 +5,7 @@ #include "mesh.h" #include "treestor.h" #include "dynarr.h" +#include "scene.h" struct object { char *name; diff --git a/tools/gen_wobj b/tools/gen_wobj new file mode 100755 index 0000000..a6a5f72 --- /dev/null +++ b/tools/gen_wobj @@ -0,0 +1,6 @@ +#!/bin/sh +# tool to generate object file lists for watcom make +# run from project root + +obj=`find src \( -name '*.c' -o -name '*.asm' \) | xargs basename -a | sort | uniq | sed 's/\(\.c\|\.asm\)$/.obj/g'` +echo 'obj =' $obj -- 1.7.10.4