diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2019-12-18 14:11:08 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2019-12-18 14:11:08 -0800 |
commit | e34a7f986a6f45719554f50b5215affcf60325f7 (patch) | |
tree | 9da560a6d267109a78398140ddcfae3df1c5ddae /src/libs | |
parent | 5f53f51e411189fc669c24be3852b42fa5121db5 (diff) |
libs/din: fix scaling overflow, add asserts
Phil reported a crash in swab, illuminating an overflow in how the unit
cube was being scaled to the noise field dimensions.
Added some asserts enforcing critical assumptions as well, though it
will probably cost some FPS in din-heavy modules like swab.
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/din/din.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/libs/din/din.c b/src/libs/din/din.c index 02f8ea6..ad87642 100644 --- a/src/libs/din/din.c +++ b/src/libs/din/din.c @@ -1,6 +1,7 @@ /* implements a classical perlin noise function */ /* https://en.wikipedia.org/wiki/Perlin_noise */ +#include <assert.h> #include <stdlib.h> #include "din.h" @@ -43,6 +44,10 @@ din_t * din_new(int width, int height, int depth) { din_t *din; + assert(width > 1); + assert(height > 1); + assert(depth > 1); + din = calloc(1, sizeof(din_t) + (sizeof(v3f_t) * (width * height * depth))); if (!din) return NULL; @@ -67,6 +72,10 @@ static inline float dotgradient(const din_t *din, int x, int y, int z, const v3f { v3f_t distance = v3f_sub(coordinate, &(v3f_t){.x = x, .y = y, .z = z}); + assert(x < din->width); + assert(y < din->height); + assert(z < din->depth); + return v3f_dot(&din->grid[z * din->width * din->height + y * din->width + x], &distance); } @@ -103,9 +112,15 @@ float din(din_t *din, v3f_t *coordinate) float tx, ty, tz; float n0, n1; - coordinate->x = 1.f + (coordinate->x * .5f + .5f) * (float)(din->width - 2); - coordinate->y = 1.f + (coordinate->y * .5f + .5f) * (float)(din->height - 2); - coordinate->z = 1.f + (coordinate->z * .5f + .5f) * (float)(din->depth - 2); + assert(din); + assert(coordinate); + assert(coordinate->x >= -1.f && coordinate->x <= 1.f); + assert(coordinate->y >= -1.f && coordinate->y <= 1.f); + assert(coordinate->z >= -1.f && coordinate->z <= 1.f); + + coordinate->x = .5f + (coordinate->x * .5f + .5f) * (float)(din->width - 2); + coordinate->y = .5f + (coordinate->y * .5f + .5f) * (float)(din->height - 2); + coordinate->z = .5f + (coordinate->z * .5f + .5f) * (float)(din->depth - 2); x0 = floorf(coordinate->x); y0 = floorf(coordinate->y); |