changeset 1081:7df95aefb9c6

Make bspline functions more flexible.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 02 Mar 2015 05:30:30 +0200
parents 76b7d1d20545
children dec84b805399
files src/dmcurves.c src/dmcurves.h
diffstat 2 files changed, 76 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/dmcurves.c	Mon Mar 02 05:00:50 2015 +0200
+++ b/src/dmcurves.c	Mon Mar 02 05:30:30 2015 +0200
@@ -33,17 +33,19 @@
 }
 
 
-int dmBSplineGenerate(DMVector *dst, const int ndst, const DMVector *points, const int npoints, const int slod)
+int dmBSplineGenerate(const DMVector *points, const int npoints, const int slod,
+    int (*callback)(void *data, const int ndst, const int nc, float x, float y, float z),
+    void *data, const int ndst)
 {
     int cv, j;
-    DMVector *curr = dst;
 
-    for (cv = -3, j = 0; j != npoints + 1 && j < ndst; j++, cv++, curr++)
+    for (cv = -3, j = 0; j != npoints + 1; j++, cv++)
     {
         // for each section of curve, draw 'lod' number of divisions
         int i;
         for (i = 0; i != slod; i++)
         {
+            int ret;
             const float t = (float) i / slod;
             const float it = 1.0f - t;
 
@@ -56,24 +58,74 @@
             const float b3 = t3 / 6.0f;
 
             // Calculate coordinates 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;
+            if ((ret = callback(data, ndst, j,
+                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
+                ,
+                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
+                ,
+                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
+                )) != DMERR_OK)
+                return ret;
         }
     }
 
-    return (j == ndst) ? DMERR_OK : DMERR_BOUNDS;
+    return DMERR_OK;
+}
+
+
+/*
+static int dmSplineAddGL(void *data, const int ndst, const int nc, float x, float y, float z)
+{
+    (void) data;
+    glVertex3f(x, y, z);
+    return DMERR_OK;
+}
+
+
+int dmGLBSpline(const DMVector *points, const int npoints, const int slod)
+{
+    // begin drawing our curve
+    glBegin(GL_LINE_STRIP);
+
+    return dmBSplineGenerate(points, npoints, slod, dmSplineAddGL, NULL, 0);
+
+    // we need to specify the last point on the curve
+    glVertex3fv(points[npoints - 1]);
+    glEnd();
+}
+*/
+
+
+static int dmSplineAddVector(void *data, const int ndst, const int nc, float x, float y, float z)
+{
+    if (nc < ndst)
+    {
+        DMVector **dst = (DMVector **) data;
+
+        (*dst)->x = x;
+        (*dst)->y = y;
+        (*dst)->z = z;
+
+        (*dst)++;
+        return DMERR_OK;
+    }
+    else
+        return DMERR_BOUNDS;
+}
+
+
+int dmBSplineGenerateArray(DMVector *dst, const int ndst, const DMVector *points, const int npoints, const int slod)
+{
+    return dmBSplineGenerate(points, npoints, slod, dmSplineAddVector, &dst, ndst);
 }
 
 
@@ -88,5 +140,5 @@
     if ((*dst = dmCalloc(*ndst, sizeof(DMVector))) == NULL)
         return DMERR_MALLOC;
 
-    return dmBSplineGenerate(*dst, *ndst, points, npoints, slod);
+    return dmBSplineGenerate(points, npoints, slod, dmSplineAddVector, *dst, *ndst);
 }
--- a/src/dmcurves.h	Mon Mar 02 05:00:50 2015 +0200
+++ b/src/dmcurves.h	Mon Mar 02 05:30:30 2015 +0200
@@ -71,7 +71,11 @@
 }
 
 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);
+int dmBSplineGenerateArray(DMVector *dst, const int ndst, const DMVector *points, const int npoints, const int slod);
+
+int dmBSplineGenerate(const DMVector *points, const int npoints, const int slod,
+    int (*callback)(void *data, const int ndst, const int nc, float x, float y, float z),
+    void *data, const int ndst);
 
 
 #ifdef __cplusplus