コード例 #1
0
ファイル: image.c プロジェクト: renokun/heman
void heman_image_sample(heman_image* img, float u, float v, HEMAN_FLOAT* result)
{
    int x = CLAMP(img->width * u, 0, img->width - 1);
    int y = CLAMP(img->height * v, 0, img->height - 1);
    HEMAN_FLOAT* data = heman_image_texel(img, x, y);
    for (int b = 0; b < img->nbands; ++b) {
        *result++ = *data++;
    }
}
コード例 #2
0
ファイル: ops.c プロジェクト: 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;
}
コード例 #3
0
ファイル: ops.c プロジェクト: vr3d/heman
static void copy_row(heman_image* src, heman_image* dst, int dstx, int y)
{
    int width = src->width;
    if (src->nbands == 1) {
        for (int x = 0; x < width; x++) {
            HEMAN_FLOAT* srcp = heman_image_texel(src, x, y);
            HEMAN_FLOAT* dstp = heman_image_texel(dst, dstx + x, y);
            *dstp = *srcp;
        }
        return;
    }
    for (int x = 0; x < width; x++) {
        HEMAN_FLOAT* srcp = heman_image_texel(src, x, y);
        HEMAN_FLOAT* dstp = heman_image_texel(dst, dstx + x, y);
        int nbands = src->nbands;
        while (nbands--) {
            *dstp++ = *srcp++;
        }
    }
}
コード例 #4
0
ファイル: ops.c プロジェクト: 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;
}
コード例 #5
0
ファイル: export.c プロジェクト: vr3d/heman
void heman_export_ply(heman_image* img, const char* filename)
{
    assert(img->nbands == 1);
    FILE* fout = fopen(filename, "wb");
    int ncols = (img->width - 1);
    int nrows = (img->height - 1);
    int ncells = ncols * nrows;
    int nverts = img->width * img->height;
    fprintf(fout,
        "ply\n"
        "format binary_little_endian 1.0\n"
        "comment heman\n"
        "element vertex %d\n"
        "property float32 x\n"
        "property float32 y\n"
        "property float32 z\n"
        "element face %d\n"
        "property list int32 int32 vertex_indices\n"
        "end_header\n",
        nverts, ncells);
    float invw = 2.0f / img->width;
    float invh = 2.0f / img->height;
    float vert[3];
    for (int j = 0; j < img->height; j++) {
        for (int i = 0; i < img->width; i++) {
            vert[0] = -1 + i * invw;
            vert[1] = -1 + j * invh;
            vert[2] = *heman_image_texel(img, i, j);
            fwrite(vert, sizeof(vert), 1, fout);
        }
    }
    int face[5];
    face[0] = 4;
    for (int j = 0; j < nrows; j++) {
        int p = j * img->width;
        for (int i = 0; i < ncols; i++, p++) {
            face[1] = p;
            face[2] = p + 1;
            face[3] = p + img->width + 1;
            face[4] = p + img->width;
            fwrite(face, sizeof(face), 1, fout);
        }
    }
    fclose(fout);
}
コード例 #6
0
ファイル: ops.c プロジェクト: 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;
}
コード例 #7
0
ファイル: ops.c プロジェクト: vr3d/heman
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;
}
コード例 #8
0
ファイル: ops.c プロジェクト: 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;
}
コード例 #9
0
ファイル: export.c プロジェクト: vr3d/heman
void heman_export_with_colors_ply(
    heman_image* hmap, heman_image* colors, const char* filename)
{
    int width = hmap->width;
    int height = hmap->height;
    assert(hmap->nbands == 1);
    assert(colors->nbands == 3);
    assert(colors->width == width);
    assert(colors->height == height);
    FILE* fout = fopen(filename, "wb");
    int ncols = (hmap->width - 1);
    int nrows = (hmap->height - 1);
    int ncells = ncols * nrows;
    int nverts = hmap->width * hmap->height;
    unsigned char* colordata = malloc(width * height * 3);
    heman_export_u8(colors, 0.0, 1.0, colordata);
    fprintf(fout,
        "ply\n"
        "format binary_little_endian 1.0\n"
        "comment heman\n"
        "element vertex %d\n"
        "property float32 x\n"
        "property float32 y\n"
        "property float32 z\n"
        "property uchar red\n"
        "property uchar green\n"
        "property uchar blue\n"
        "property uchar alpha\n"
        "element face %d\n"
        "property list int32 int32 vertex_indices\n"
        "end_header\n",
        nverts, ncells);
    float invw = 2.0f / width;
    float invh = 2.0f / height;
    heman_byte* pcolor = colordata;
    float vert[3];
    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i++) {
            vert[0] = -1 + i * invw;
            vert[1] = -1 + j * invh;
            vert[2] = *heman_image_texel(hmap, i, j);
            fwrite(vert, sizeof(vert), 1, fout);
            fwrite(pcolor, 3, 1, fout);
            pcolor += 3;
            fputc(255, fout);
        }
    }
    int face[5];
    face[0] = 4;
    for (int j = 0; j < nrows; j++) {
        int p = j * width;
        for (int i = 0; i < ncols; i++, p++) {
            face[1] = p;
            face[2] = p + 1;
            face[3] = p + hmap->width + 1;
            face[4] = p + hmap->width;
            fwrite(face, sizeof(face), 1, fout);
        }
    }
    fclose(fout);
    free(colordata);
}