Mercurial > hg > dmlib
view src/dmcurves.c @ 2208:90ec1ec89c56
Revamp the palette handling in lib64gfx somewhat, add helper functions to
lib64util for handling external palette file options and add support for
specifying one of the "internal" palettes or external (.act) palette file to
gfxconv and 64vw.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 Jun 2019 05:01:12 +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); }