heman_image* heman_distance_create_cf(heman_image* src) { heman_image* positive = heman_image_create(src->width, src->height, 1); heman_image* negative = heman_image_create(src->width, src->height, 1); heman_image* coordfield = heman_image_create(src->width, src->height, 2); int size = src->height * src->width; HEMAN_FLOAT* pptr = positive->data; HEMAN_FLOAT* nptr = negative->data; HEMAN_FLOAT* sptr = src->data; for (int i = 0; i < size; ++i) { HEMAN_FLOAT val = 0; for (int b = 0; b < src->nbands; ++b) { val += *sptr++; } *pptr++ = val ? INF : 0; *nptr++ = val ? 0 : INF; } HEMAN_FLOAT* cdata = coordfield->data; for (int y = 0; y < src->height; y++) { for (int x = 0; x < src->width; x++) { *cdata++ = x; *cdata++ = y; } } // transform_to_coordfield(positive, coordfield); transform_to_coordfield(negative, coordfield); heman_image_destroy(negative); heman_image_destroy(positive); return coordfield; }
heman_image* make_island(int seed, heman_image* grad) { heman_image* hmap = heman_generate_island_heightmap(HEIGHT, HEIGHT, seed); heman_image* albedo = heman_color_apply_gradient(hmap, -0.5, 0.5, grad); heman_image* island = heman_lighting_apply(hmap, albedo, 1, 1, 0.75, LIGHTPOS); heman_image_destroy(hmap); heman_image_destroy(albedo); return island; }
heman_image* heman_distance_create_cpcf(heman_image* src) { heman_image* negative = heman_image_create(src->width, src->height, 1); int size = src->height * src->width; HEMAN_FLOAT* nptr = negative->data; HEMAN_FLOAT* sptr = src->data; for (int i = 0; i < size; ++i) { HEMAN_FLOAT val = 0; for (int b = 0; b < src->nbands; ++b) { val += *sptr++; } *nptr++ = val ? 0 : INF; } heman_image* coordfield = heman_distance_identity_cpcf(src->width, src->height); transform_to_coordfield(negative, coordfield); heman_image_destroy(negative); return coordfield; }
heman_image* heman_ops_sobel(heman_image* img, heman_color rgb) { int width = img->width; int height = img->height; assert(img->nbands == 3); heman_image* result = heman_image_create(width, height, 3); heman_image* gray = heman_color_to_grayscale(img); HEMAN_FLOAT inv = 1.0f / 255.0f; kmVec3 edge_rgb; edge_rgb.x = (HEMAN_FLOAT)(rgb >> 16) * inv; edge_rgb.y = (HEMAN_FLOAT)((rgb >> 8) & 0xff) * inv; edge_rgb.z = (HEMAN_FLOAT)(rgb & 0xff) * inv; #pragma omp parallel for for (int y = 0; y < height; y++) { kmVec3* dst = (kmVec3*) result->data + y * width; const kmVec3* src = (kmVec3*) img->data + y * width; for (int x = 0; x < width; x++) { int xm1 = MAX(x - 1, 0); int xp1 = MIN(x + 1, width - 1); int ym1 = MAX(y - 1, 0); int yp1 = MIN(y + 1, height - 1); HEMAN_FLOAT t00 = *heman_image_texel(gray, xm1, ym1); HEMAN_FLOAT t10 = *heman_image_texel(gray, x, ym1); HEMAN_FLOAT t20 = *heman_image_texel(gray, xp1, ym1); HEMAN_FLOAT t01 = *heman_image_texel(gray, xm1, 0); HEMAN_FLOAT t21 = *heman_image_texel(gray, xp1, 0); HEMAN_FLOAT t02 = *heman_image_texel(gray, xm1, yp1); HEMAN_FLOAT t12 = *heman_image_texel(gray, x, yp1); HEMAN_FLOAT t22 = *heman_image_texel(gray, xp1, yp1); HEMAN_FLOAT gx = t00 + 2.0 * t01 + t02 - t20 - 2.0 * t21 - t22; HEMAN_FLOAT gy = t00 + 2.0 * t10 + t20 - t02 - 2.0 * t12 - t22; HEMAN_FLOAT is_edge = gx * gx + gy * gy > 1e-5; kmVec3Lerp(dst++, src++, &edge_rgb, is_edge); } } heman_image_destroy(gray); return result; }
heman_image* heman_ops_warp_points(heman_image* img, int seed, int octaves, heman_points* pts) { int width = img->width; int height = img->height; heman_image* mapping = heman_distance_identity_cpcf(width, height); heman_image* retval = heman_ops_warp_core(img, mapping, seed, octaves); HEMAN_FLOAT* src = pts->data; for (int k = 0; k < pts->width; k++, src += pts->nbands) { HEMAN_FLOAT x = src[0]; HEMAN_FLOAT y = src[1]; int i = x * mapping->width; int j = y * mapping->height; if (i < 0 || i >= mapping->width || j < 0 || j >= mapping->height) { continue; } HEMAN_FLOAT* texel = heman_image_texel(mapping, i, j); src[0] = texel[0] / mapping->width; src[1] = texel[1] / mapping->height; } heman_image_destroy(mapping); return retval; }
heman_image* heman_distance_create_sdf(heman_image* src) { assert(src->nbands == 1 && "Distance field input must have only 1 band."); heman_image* positive = heman_image_create(src->width, src->height, 1); heman_image* negative = heman_image_create(src->width, src->height, 1); int size = src->height * src->width; HEMAN_FLOAT* pptr = positive->data; HEMAN_FLOAT* nptr = negative->data; HEMAN_FLOAT* sptr = src->data; for (int i = 0; i < size; ++i, ++sptr) { *pptr++ = *sptr ? INF : 0; *nptr++ = *sptr ? 0 : INF; } transform_to_distance(positive); transform_to_distance(negative); HEMAN_FLOAT inv = 1.0f / src->width; pptr = positive->data; nptr = negative->data; for (int i = 0; i < size; ++i, ++pptr, ++nptr) { *pptr = (sqrt(*pptr) - sqrt(*nptr)) * inv; } heman_image_destroy(negative); return positive; }
int main(int argc, char** argv) { heman_image* grad = heman_color_create_gradient( 256, COUNT(CP_COLORS), CP_LOCATIONS, CP_COLORS); heman_image* tiles[4]; tiles[0] = make_planet(1000, grad); tiles[1] = make_planet(1001, grad); heman_image* planets = heman_ops_stitch_vertical(tiles, 2); heman_image_destroy(tiles[0]); heman_image_destroy(tiles[1]); tiles[0] = make_island(1000, grad); tiles[1] = make_island(1001, grad); tiles[2] = make_island(1002, grad); tiles[3] = make_island(1003, grad); heman_image* rows[2]; rows[0] = heman_ops_stitch_horizontal(tiles, 2); rows[1] = heman_ops_stitch_horizontal(tiles + 2, 2); heman_image* islands = heman_ops_stitch_vertical(rows, 2); heman_image_destroy(tiles[0]); heman_image_destroy(tiles[1]); heman_image_destroy(tiles[2]); heman_image_destroy(tiles[3]); heman_image_destroy(rows[0]); heman_image_destroy(rows[1]); tiles[0] = planets; tiles[1] = islands; heman_image* final = heman_ops_stitch_horizontal(tiles, 2); heman_image_destroy(planets); heman_image_destroy(islands); hut_write_image(OUTFOLDER "stitched.png", final, 0, 1); heman_image_destroy(final); heman_image_destroy(grad); }