Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_replace_color(
    heman_image* source, heman_color color, heman_image* texture)
{
    assert(source->nbands == 3);
    assert(texture->nbands == 3);
    int height = source->height;
    int width = source->width;
    assert(texture->width == width);
    assert(texture->height == height);
    HEMAN_FLOAT inv = 1.0f / 255.0f;
    HEMAN_FLOAT r = (HEMAN_FLOAT)(color >> 16) * inv;
    HEMAN_FLOAT g = (HEMAN_FLOAT)((color >> 8) & 0xff) * inv;
    HEMAN_FLOAT b = (HEMAN_FLOAT)(color & 0xff) * inv;
    heman_image* result = heman_image_create(width, height, 3);

#pragma omp parallel for
    for (int y = 0; y < height; y++) {
        HEMAN_FLOAT* dst = result->data + y * width * 3;
        HEMAN_FLOAT* src = source->data + y * width * 3;
        HEMAN_FLOAT* tex = texture->data + y * width * 3;
        for (int x = 0; x < width; x++, src += 3, dst += 3, tex += 3) {
            if ((src[0] == r) && (src[1] == g) && (src[2] == b)) {
                dst[0] = tex[0];
                dst[1] = tex[1];
                dst[2] = tex[2];
            } else {
                dst[0] = src[0];
                dst[1] = src[1];
                dst[2] = src[2];
            }
        }
    }

    return result;
}
Ejemplo n.º 3
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_extract_mask(heman_image* source, heman_color color, int invert)
{
    assert(source->nbands == 3);
    HEMAN_FLOAT inv = 1.0f / 255.0f;
    HEMAN_FLOAT r = (HEMAN_FLOAT)(color >> 16) * inv;
    HEMAN_FLOAT g = (HEMAN_FLOAT)((color >> 8) & 0xff) * inv;
    HEMAN_FLOAT b = (HEMAN_FLOAT)(color & 0xff) * inv;
    int height = source->height;
    int width = source->width;
    heman_image* result = heman_image_create(width, height, 1);

#pragma omp parallel for
    for (int y = 0; y < height; y++) {
        HEMAN_FLOAT* dst = result->data + y * width;
        HEMAN_FLOAT* src = source->data + y * width * 3;
        for (int x = 0; x < width; x++, src += 3) {
            HEMAN_FLOAT val =((src[0] == r) && (src[1] == g) && (src[2] == b));
            if (!invert) {
                val = 1 - val;
            }
            *dst++ = val;
        }
    }

    return result;
}
Ejemplo n.º 4
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_emboss(heman_image* img, int mode)
{
    int seed = 1;
    int octaves = 4;

    struct osn_context* ctx;
    open_simplex_noise(seed, &ctx);
    int width = img->width;
    int height = img->height;
    assert(img->nbands == 1);
    heman_image* result = heman_image_create(width, height, 1);
    HEMAN_FLOAT invw = 1.0 / width;
    HEMAN_FLOAT invh = 1.0 / height;
    HEMAN_FLOAT inv = MIN(invw, invh);
    float gain = 0.6;
    float lacunarity = 2.0;
    float land_amplitude = 0.0005;
    float land_frequency = 256.0;
    float ocean_amplitude = 0.5;
    float ocean_frequency = 1.0;

#pragma omp parallel for
    for (int y = 0; y < height; y++) {
        HEMAN_FLOAT* dst = result->data + y * width;
        for (int x = 0; x < width; x++) {
            HEMAN_FLOAT z = *heman_image_texel(img, x, y);
            if (z > 0 && mode == 1) {
                float s = x * inv;
                float t = y * inv;
                float a = land_amplitude;
                float f = land_frequency;
                for (int i = 0; i < octaves; i++) {
                    z += NOISEX(s, t, a, f);
                    a *= gain;
                    f *= lacunarity;
                }
            } else if (z <= 0 && mode == -1) {
                z = MAX(z, -0.1);
                float soften = fabsf(z);
                float s = x * inv;
                float t = y * inv;
                float a = ocean_amplitude;
                float f = ocean_frequency;
                for (int i = 0; i < octaves; i++) {
                    z += soften * NOISEX(s, t, a, f);
                    a *= gain;
                    f *= lacunarity;
                }
            }
            *dst++ = z;
        }
    }

    open_simplex_noise_free(ctx);
    return result;
}
Ejemplo n.º 5
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_step(heman_image* hmap, HEMAN_FLOAT threshold)
{
    assert(hmap->nbands == 1);
    heman_image* result = heman_image_create(hmap->width, hmap->height, 1);
    int size = hmap->height * hmap->width;
    HEMAN_FLOAT* src = hmap->data;
    HEMAN_FLOAT* dst = result->data;
    for (int i = 0; i < size; ++i) {
        *dst++ = (*src++) >= threshold ? 1 : 0;
    }
    return result;
}
Ejemplo n.º 6
0
heman_image* heman_distance_identity_cpcf(int width, int height)
{
    heman_image* retval = heman_image_create(width, height, 2);
    HEMAN_FLOAT* cdata = retval->data;
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            *cdata++ = x;
            *cdata++ = y;
        }
    }
    return retval;
}
Ejemplo n.º 7
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_max(heman_image* imga, heman_image* imgb)
{
    assert(imga->width == imgb->width);
    assert(imga->height == imgb->height);
    assert(imga->nbands == imgb->nbands);
    heman_image* result = heman_image_create(imga->width, imga->height, imga->nbands);
    int size = imga->height * imga->width * imga->nbands;
    HEMAN_FLOAT* srca = imga->data;
    HEMAN_FLOAT* srcb = imgb->data;
    HEMAN_FLOAT* dst = result->data;
    for (int i = 0; i < size; ++i, ++dst, ++srca, ++srcb) {
        *dst = MAX(*srca, *srcb);
    }
    return result;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_normalize_f32(
    heman_image* source, HEMAN_FLOAT minv, HEMAN_FLOAT maxv)
{
    heman_image* result =
        heman_image_create(source->width, source->height, source->nbands);
    HEMAN_FLOAT* src = source->data;
    HEMAN_FLOAT* dst = result->data;
    HEMAN_FLOAT scale = 1.0f / (maxv - minv);
    int size = source->height * source->width * source->nbands;
    for (int i = 0; i < size; ++i) {
        HEMAN_FLOAT v = (*src++ - minv) * scale;
        *dst++ = CLAMP(v, 0, 1);
    }
    return result;
}
Ejemplo n.º 10
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_sweep(heman_image* hmap)
{
    assert(hmap->nbands == 1);
    heman_image* result = heman_image_create(hmap->height, 1, 1);
    HEMAN_FLOAT* dst = result->data;
    const HEMAN_FLOAT* src = hmap->data;
    HEMAN_FLOAT invw = 1.0f / hmap->width;
    for (int y = 0; y < hmap->height; y++) {
        HEMAN_FLOAT acc = 0;
        for (int x = 0; x < hmap->width; x++) {
            acc += *src++;
        }
        *dst++ = (acc * invw);
    }
    return result;
}
Ejemplo n.º 11
0
heman_image* heman_distance_from_cpcf(heman_image* cf)
{
    assert(cf->nbands == 2 && "Coordinate field input must have 2 bands.");
    heman_image* udf = heman_image_create(cf->width, cf->height, 1);
    HEMAN_FLOAT* dptr = udf->data;
    HEMAN_FLOAT* sptr = cf->data;
    HEMAN_FLOAT scale = 1.0f / sqrt(SQR(cf->width) + SQR(cf->height));
    for (int y = 0; y < cf->height; y++) {
        for (int x = 0; x < cf->width; x++) {
            HEMAN_FLOAT u = *sptr++;
            HEMAN_FLOAT v = *sptr++;
            HEMAN_FLOAT dist = sqrt(SQR(u - x) + SQR(v - y)) * scale;
            *dptr++ = dist;
        }
    }
    return udf;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_stitch_vertical(heman_image** images, int count)
{
    assert(count > 0);
    int width = images[0]->width;
    int height = images[0]->height;
    int nbands = images[0]->nbands;
    for (int i = 1; i < count; i++) {
        assert(images[i]->width == width);
        assert(images[i]->height == height);
        assert(images[i]->nbands == nbands);
    }
    heman_image* result = heman_image_create(width, height * count, nbands);
    int size = width * height * nbands;
    HEMAN_FLOAT* dst = result->data;
    for (int tile = 0; tile < count; tile++) {
        memcpy(dst, images[tile]->data, size * sizeof(float));
        dst += size;
    }
    return result;
}
Ejemplo n.º 14
0
Archivo: ops.c Proyecto: vr3d/heman
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;
}
Ejemplo n.º 15
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_stitch_horizontal(heman_image** images, int count)
{
    assert(count > 0);
    int width = images[0]->width;
    int height = images[0]->height;
    int nbands = images[0]->nbands;
    for (int i = 1; i < count; i++) {
        assert(images[i]->width == width);
        assert(images[i]->height == height);
        assert(images[i]->nbands == nbands);
    }
    heman_image* result = heman_image_create(width * count, height, nbands);

#pragma omp parallel for
    for (int y = 0; y < height; y++) {
        for (int tile = 0; tile < count; tile++) {
            copy_row(images[tile], result, tile * width, y);
        }
    }

    return result;
}
Ejemplo n.º 16
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_laplacian(heman_image* heightmap)
{
    assert(heightmap->nbands == 1);
    int width = heightmap->width;
    int height = heightmap->height;
    heman_image* result = heman_image_create(width, height, 1);
    int maxx = width - 1;
    int maxy = height - 1;

#pragma omp parallel for
    for (int y = 0; y < height; y++) {
        int y1 = MIN(y + 1, maxy);
        HEMAN_FLOAT* dst = result->data + y * width;
        for (int x = 0; x < width; x++) {
            int x1 = MIN(x + 1, maxx);
            HEMAN_FLOAT p = *heman_image_texel(heightmap, x, y);
            HEMAN_FLOAT px = *heman_image_texel(heightmap, x1, y);
            HEMAN_FLOAT py = *heman_image_texel(heightmap, x, y1);
            *dst++ = (p - px) * (p - px) + (p - py) * (p - py);
        }
    }

    return result;
}
Ejemplo n.º 17
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_merge_political(
    heman_image* hmap, heman_image* cmap, heman_color ocean)
{
    assert(hmap->nbands == 1);
    assert(cmap->nbands == 3);
    heman_image* result = heman_image_create(hmap->width, hmap->height, 4);
    HEMAN_FLOAT* pheight = hmap->data;
    HEMAN_FLOAT* pcolour = cmap->data;
    HEMAN_FLOAT* pmerged = result->data;
    HEMAN_FLOAT inv = 1.0f / 255.0f;
    HEMAN_FLOAT oceanr = (HEMAN_FLOAT)(ocean >> 16) * inv;
    HEMAN_FLOAT oceang = (HEMAN_FLOAT)((ocean >> 8) & 0xff) * inv;
    HEMAN_FLOAT oceanb = (HEMAN_FLOAT)(ocean & 0xff) * inv;
    int size = hmap->height * hmap->width;
    float minh = 1000;
    float maxh = -1000;
    for (int i = 0; i < size; ++i) {
        minh = MIN(minh, pheight[i]);
        maxh = MIN(maxh, pheight[i]);
    }
    for (int i = 0; i < size; ++i) {
        HEMAN_FLOAT h = *pheight++;
        if (h < 0) {
            *pmerged++ = oceanr;
            *pmerged++ = oceang;
            *pmerged++ = oceanb;
            pcolour += 3;
        } else {
            *pmerged++ = *pcolour++;
            *pmerged++ = *pcolour++;
            *pmerged++ = *pcolour++;
        }
        *pmerged++ = (h - minh) / (maxh - minh);
    }
    return result;
}
Ejemplo n.º 18
0
Archivo: ops.c Proyecto: vr3d/heman
heman_image* heman_ops_warp_core(heman_image* img, heman_image* secondary,
    int seed, int octaves)
{
    struct osn_context* ctx;
    open_simplex_noise(seed, &ctx);
    int width = img->width;
    int height = img->height;
    int nbands = img->nbands;
    heman_image* result = heman_image_create(width, height, nbands);
    heman_image* result2 = secondary ? heman_image_create(width, height, secondary->nbands) : 0;
    HEMAN_FLOAT invw = 1.0 / width;
    HEMAN_FLOAT invh = 1.0 / height;
    HEMAN_FLOAT inv = MIN(invw, invh);
    HEMAN_FLOAT aspect = (float) width / height;
    float gain = 0.6;
    float lacunarity = 2.0;
    float initial_amplitude = 0.05;
    float initial_frequency = 8.0;

#pragma omp parallel for
    for (int y = 0; y < height; y++) {
        HEMAN_FLOAT* dst = result->data + y * width * nbands;
        for (int x = 0; x < width; x++) {

            float a = initial_amplitude;
            float f = initial_frequency;

            HEMAN_FLOAT* src;

            // This is a little hack that modulates noise according to
            // elevation, to prevent "swimming" at high elevations.
            if (nbands == 4) {
                src = heman_image_texel(img, x, y);
                HEMAN_FLOAT elev = 1 - src[3];
                a *= pow(elev, 4);
            }

            float s = x * inv;
            float t = y * inv;
            float u = x * invw;
            float v = y * invh;
            for (int i = 0; i < octaves; i++) {
                u += NOISEX(s, t, a, f);
                v += aspect * NOISEY(s, t, a, f);
                a *= gain;
                f *= lacunarity;
            }
            int i = CLAMP(u * width, 0, width - 1);
            int j = CLAMP(v * height, 0, height - 1);
            src = heman_image_texel(img, i, j);
            for (int n = 0; n < nbands; n++) {
                *dst++ = *src++;
            }
            if (secondary) {
                src = heman_image_texel(secondary, x, y);
                HEMAN_FLOAT* dst2 = heman_image_texel(result2, i, j);
                for (int n = 0; n < secondary->nbands; n++) {
                    *dst2++ = *src++;
                }
            }
        }
    }
    open_simplex_noise_free(ctx);
    if (secondary) {
        free(secondary->data);
        secondary->data = result2->data;
        free(result2);
    }
    return result;
}