summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2019-12-18 14:11:08 -0800
committerVito Caputo <vcaputo@pengaru.com>2019-12-18 14:11:08 -0800
commite34a7f986a6f45719554f50b5215affcf60325f7 (patch)
tree9da560a6d267109a78398140ddcfae3df1c5ddae /src
parent5f53f51e411189fc669c24be3852b42fa5121db5 (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')
-rw-r--r--src/libs/din/din.c21
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);
© All Rights Reserved