Mercurial > hg > dmlib
view src/dmcurves.c @ 1283:642a0dd98c6e
Oops, forgot to adjust the writing and reading when adding two members to
the PCX header struct.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 18 Aug 2017 02:52:35 +0300 |
parents | 7df95aefb9c6 |
children |
line wrap: on
line source
/* * DMLib * -- Curve and spline functions * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2015 Tecnic Software productions (TNSP) */ #include "dmcurves.h" void dmLerpInit(DMLerpContext *ctx, DMFloat start, DMFloat end, DMFloat nsteps) { ctx->start = start; ctx->end = end; ctx->nsteps = nsteps; } DMFloat dmCatmullRom(const DMFloat t, const DMFloat p0, const DMFloat p1, const DMFloat p2, const DMFloat p3) { const DMFloat q = t * t; return ( (2 * p1) + (-p0 + p2) * t + (2 * p0 - 5 * p1 + 4 * p2 - p3) * q + ( -p0 + 3 * p1 - 3 * p2 + p3) * q * t ) * 0.5f; } 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(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; 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; // 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 coordinates of the curve point 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 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); } 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(points, npoints, slod, dmSplineAddVector, *dst, *ndst); }