changeset 976:1b439304ff3c

Add new module dmcurves, that will contain functions for spline generation etc and the LERP functions. Move LERP functions from dmlib.h to dmcurves.h.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 27 Feb 2015 16:16:59 +0200
parents 139b801f8d1c
children 4a6dece98cb2
files Makefile.gen src/dmcurves.c src/dmcurves.h src/dmlib.h
diffstat 4 files changed, 169 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.gen	Fri Feb 27 14:49:02 2015 +0200
+++ b/Makefile.gen	Fri Feb 27 16:16:59 2015 +0200
@@ -278,7 +278,7 @@
 DMLIB_OBJS += \
 	dmfile.o dmbstr.o dmlib.o dmlerp.o dmstring.o \
 	dmargs.o dmvecmat.o dmperlin.o dmimage.o \
-	dmwav.o	dmengine.o dmfft.o dmzlib.o
+	dmwav.o	dmcurves.o dmengine.o dmfft.o dmzlib.o
 
 
 TESTS_TARGETS = $(addprefix $(TESTS_BINPATH),$(addsuffix $(EXEEXT),$(TESTS_BINARIES)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dmcurves.c	Fri Feb 27 16:16:59 2015 +0200
@@ -0,0 +1,75 @@
+/*
+ * DMLib
+ * -- Curve and spline functions
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2015 Tecnic Software productions (TNSP)
+ */
+#include "dmcurves.h"
+
+
+static inline const DMVector *dmSplineGetPoint(const DMVector *points, const int npoints, const int n)
+{
+    return (n < 0) ? &points[0] : ((n < npoints) ? &points[n] : &points[npoints - 1]);
+}
+
+
+int dmBSplineGenerate(DMVector *dst, const int ndst, const DMVector *points, const int npoints, const int slod)
+{
+    int cv, j;
+    DMVector *curr = dst;
+
+    for (cv = -3, j = 0; j != npoints + 1 && j < ndst; j++, cv++, curr++)
+    {
+        // for each section of curve, draw 'lod' number of divisions
+        int i;
+        for (i = 0; i != slod; i++)
+        {
+            // use the parametric time value 0.0 to 1.0 for this curve segment
+            const float t = (float) i / slod;
+
+            // inverse value of 't'
+            const float it = 1.0f - t;
+
+            // calculate blending functions for cubic bspline
+            const float t2 = t * t;
+            const float t3 = t2 * t;
+            const float b0 = it * it * it / 6.0f;
+            const float b1 = ( 3*t3 - 6*t2 + 4) / 6.0f;
+            const float b2 = (-3*t3 + 3*t2 + 3*t + 1) / 6.0f;
+            const float b3 = t3 / 6.0f;
+
+            // calculate the x,y and z of the curve point
+            curr->x = b0 * dmSplineGetPoint(points, npoints, cv + 0)->x +
+                      b1 * dmSplineGetPoint(points, npoints, cv + 1)->x +
+                      b2 * dmSplineGetPoint(points, npoints, cv + 2)->x +
+                      b3 * dmSplineGetPoint(points, npoints, cv + 3)->x;
+
+            curr->y = b0 * dmSplineGetPoint(points, npoints, cv + 0)->y +
+                      b1 * dmSplineGetPoint(points, npoints, cv + 1)->y +
+                      b2 * dmSplineGetPoint(points, npoints, cv + 2)->y +
+                      b3 * dmSplineGetPoint(points, npoints, cv + 3)->y;
+
+            curr->z = b0 * dmSplineGetPoint(points, npoints, cv + 0)->z +
+                      b1 * dmSplineGetPoint(points, npoints, cv + 1)->z +
+                      b2 * dmSplineGetPoint(points, npoints, cv + 2)->z +
+                      b3 * dmSplineGetPoint(points, npoints, cv + 3)->z;
+        }
+    }
+
+    return (j == ndst) ? DMERR_OK : DMERR_BOUNDS;
+}
+
+
+int dmBSplineGenerateAlloc(DMVector **dst, int *ndst, const DMVector *points, const int npoints, const int slod)
+{
+    if (ndst == NULL || dst == NULL)
+        return DMERR_NULLPTR;
+
+    if ((*ndst = dmBSplineGetNPoints(npoints, slod)) <= 0)
+        return DMERR_INVALID_DATA;
+
+    if ((*dst = dmCalloc(*ndst, sizeof(DMVector))) == NULL)
+        return DMERR_MALLOC;
+
+    return dmBSplineGenerate(*dst, *ndst, points, npoints, slod);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dmcurves.h	Fri Feb 27 16:16:59 2015 +0200
@@ -0,0 +1,93 @@
+/*
+ * DMLib
+ * -- Wav file writing
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2012 Tecnic Software productions (TNSP)
+ */
+#ifndef DMCURVES_H
+#define DMCURVES_H
+
+#include "dmlib.h"
+#include "dmvecmat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Generic parameter interpolation
+ */
+#define DMM_S_CURVE(t)     ((t) * (t) * (3.0f - 2.0f * (t)))
+#define DMM_LERP(t, a, b)  ((a) + (t) * ((b) - (a)))
+
+typedef struct
+{
+    DMFloat start, end, nsteps;
+} DMLerpContext;
+
+
+void       dmLerpInit(DMLerpContext *ctx, DMFloat start, DMFloat end, DMFloat nsteps);
+DMFloat    dmCatmullRom(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3);
+
+
+static inline DMFloat dmClamp10(const DMFloat a)
+{
+    return (a < 0.0f ? 0.0f : (a > 1.0f ? 1.0f : a));
+}
+
+
+static inline int dmClamp(const int v, const int min, const int max)
+{
+    return (v < min ? min : (v > max ? max : v));
+}
+
+
+static inline DMFloat dmLerpSCurve(DMLerpContext *ctx, const DMFloat step)
+{
+    const DMFloat n = step / ctx->nsteps;
+    const DMFloat v = DMM_S_CURVE(n);
+    return DMM_LERP(v, ctx->start, ctx->end);
+}
+
+
+static inline DMFloat dmLerpSCurveClamp(DMLerpContext *ctx, const DMFloat step)
+{
+    const DMFloat n = dmClamp10(step / ctx->nsteps);
+    const DMFloat v = DMM_S_CURVE(n);
+    return DMM_LERP(v, ctx->start, ctx->end);
+}
+
+
+static inline DMFloat dmLerp1(DMLerpContext *ctx, const DMFloat step)
+{
+    const DMFloat v = step / ctx->nsteps;
+    return DMM_LERP(v, ctx->start, ctx->end);
+}
+
+
+static inline DMFloat dmLerp1Clamp(DMLerpContext *ctx, const DMFloat step)
+{
+    const DMFloat v = dmClamp10(step / ctx->nsteps);
+    return DMM_LERP(v, ctx->start, ctx->end);
+}
+
+
+static inline DMFloat dmCatmullRomClamp(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3)
+{
+    return dmCatmullRom(dmClamp10(t), p0, p1, p2, p3);
+}
+
+
+static inline int dmBSplineGetNPoints(const int npoints, const int slod)
+{
+    return npoints * slod;
+}
+
+int dmBSplineGenerateAlloc(DMVector **dst, int *ndst, const DMVector *points, const int npoints, const int slod);
+int dmBSplineGenerate(DMVector *dst, const int ndst, const DMVector *points, const int npoints, const int slod);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DMCURVES_H
--- a/src/dmlib.h	Fri Feb 27 14:49:02 2015 +0200
+++ b/src/dmlib.h	Fri Feb 27 16:16:59 2015 +0200
@@ -206,69 +206,6 @@
 }
 
 
-/* Generic parameter interpolation
- */
-#define DMM_S_CURVE(t)     ((t) * (t) * (3.0f - 2.0f * (t)))
-#define DMM_LERP(t, a, b)  ((a) + (t) * ((b) - (a)))
-
-typedef struct
-{
-    DMFloat start, end, nsteps;
-} DMLerpContext;
-
-
-void       dmLerpInit(DMLerpContext *ctx, DMFloat start, DMFloat end, DMFloat nsteps);
-DMFloat    dmCatmullRom(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3);
-
-
-static inline DMFloat dmClamp10(const DMFloat a)
-{
-    return (a < 0.0f ? 0.0f : (a > 1.0f ? 1.0f : a));
-}
-
-
-static inline int dmClamp(const int v, const int min, const int max)
-{
-    return (v < min ? min : (v > max ? max : v));
-}
-
-
-static inline DMFloat dmLerpSCurve(DMLerpContext *ctx, const DMFloat step)
-{
-    const DMFloat n = step / ctx->nsteps;
-    const DMFloat v = DMM_S_CURVE(n);
-    return DMM_LERP(v, ctx->start, ctx->end);
-}
-
-
-static inline DMFloat dmLerpSCurveClamp(DMLerpContext *ctx, const DMFloat step)
-{
-    const DMFloat n = dmClamp10(step / ctx->nsteps);
-    const DMFloat v = DMM_S_CURVE(n);
-    return DMM_LERP(v, ctx->start, ctx->end);
-}
-
-
-static inline DMFloat dmLerp1(DMLerpContext *ctx, const DMFloat step)
-{
-    const DMFloat v = step / ctx->nsteps;
-    return DMM_LERP(v, ctx->start, ctx->end);
-}
-
-
-static inline DMFloat dmLerp1Clamp(DMLerpContext *ctx, const DMFloat step)
-{
-    const DMFloat v = dmClamp10(step / ctx->nsteps);
-    return DMM_LERP(v, ctx->start, ctx->end);
-}
-
-
-static inline DMFloat dmCatmullRomClamp(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3)
-{
-    return dmCatmullRom(dmClamp10(t), p0, p1, p2, p3);
-}
-
-
 /* Arbitrary line drawing
  */
 #ifdef DM_GFX_LINES