예제 #1
0
void camera_update(camera_t *camera)
{
    float size;

    camera->fovy = 20.;
    if (camera->move_to_target) {
        camera->move_to_target = !vec3_ilerp_const(
                &camera->ofs, vec3_neg(camera->target), camera->dist / 128);
    }
    // Update the camera mats
    camera->view_mat = mat4_identity;
    mat4_itranslate(&camera->view_mat, 0, 0, -camera->dist);
    mat4_imul_quat(&camera->view_mat, camera->rot);
    mat4_itranslate(&camera->view_mat,
           camera->ofs.x, camera->ofs.y, camera->ofs.z);

    if (camera->ortho) {
        size = camera->dist;
        camera->proj_mat = mat4_ortho(
                -size, +size,
                -size / camera->aspect, +size / camera->aspect,
                0, 1000);
    } else {
        camera->proj_mat = mat4_perspective(
                camera->fovy, camera->aspect, 1, 1000);
    }
}
예제 #2
0
파일: move.c 프로젝트: IJDykeman/wangTiles
static int on_move(gesture3d_t *gest, void *user)
{
    float face_plane[4][4];
    cursor_t *curs = gest->cursor;
    tool_move_t *tool = user;
    float n[3], pos[3], d[3], ofs[3], v[3];
    layer_t *layer = goxel->image->active_layer;
    float mat[4][4];

    if (box_is_null(tool->box)) return GESTURE_FAILED;

    if (gest->type == GESTURE_HOVER) {
        goxel_set_help_text(goxel, "Drag to move face");
        if (curs->snaped != SNAP_LAYER_OUT) return GESTURE_FAILED;
        tool->snap_face = get_face(curs->normal);
        curs->snap_offset = 0;
        curs->snap_mask &= ~SNAP_ROUNDED;
        mat4_mul(tool->box, FACES_MATS[tool->snap_face], face_plane);
        render_img(&goxel->rend, NULL, face_plane, EFFECT_NO_SHADING);
        if (curs->flags & CURSOR_PRESSED) {
            gest->type = GESTURE_DRAG;
            vec3_normalize(face_plane[0], v);
            plane_from_vectors(goxel->tool_plane, curs->pos, curs->normal, v);
            image_history_push(goxel->image);
        }
        return 0;
    }
    if (gest->type == GESTURE_DRAG) {
        goxel_set_help_text(goxel, "Drag to move face");
        curs->snap_offset = 0;
        curs->snap_mask &= ~SNAP_ROUNDED;
        mat4_mul(tool->box, FACES_MATS[tool->snap_face], face_plane);

        vec3_normalize(face_plane[2], n);
        vec3_sub(curs->pos, goxel->tool_plane[3], v);
        vec3_project(v, n, v);
        vec3_add(goxel->tool_plane[3], v, pos);
        pos[0] = round(pos[0]);
        pos[1] = round(pos[1]);
        pos[2] = round(pos[2]);
        vec3_add(tool->box[3], face_plane[2], d);
        vec3_sub(pos, d, ofs);
        vec3_project(ofs, n, ofs);

        mat4_set_identity(mat);
        mat4_itranslate(mat, ofs[0], ofs[1], ofs[2]);
        do_move(layer, mat);

        if (gest->state == GESTURE_END) {
            gest->type = GESTURE_HOVER;
            mat4_copy(plane_null, goxel->tool_plane);
        }
        return 0;
    }
    return 0;
}
예제 #3
0
파일: move.c 프로젝트: IJDykeman/wangTiles
static void do_move(layer_t *layer, const float mat[4][4])
{
    float m[4][4];

    mat4_set_identity(m);
    // Change referential to the mesh origin.
    // XXX: maybe this should be done in mesh_move directy??
    mat4_itranslate(m, -0.5, -0.5, -0.5);
    mat4_imul(m, mat);
    mat4_itranslate(m, +0.5, +0.5, +0.5);

    if (layer->base_id || layer->image) {
        mat4_mul(mat, layer->mat, layer->mat);
        layer->base_mesh_key = 0;
    } else {
        mesh_move(layer->mesh, m);
        if (!box_is_null(layer->box)) {
            mat4_mul(mat, layer->box, layer->box);
            box_get_bbox(layer->box, layer->box);
        }
    }
    goxel_update_meshes(goxel, -1);
}
예제 #4
0
static int tool_laser_iter(goxel_t *goxel, const inputs_t *inputs, int state,
                           const vec2_t *view_size, bool inside)
{
    vec3_t pos, normal;
    box_t box;
    painter_t painter = goxel->painter;
    mesh_t *mesh = goxel->image->active_layer->mesh;
    const bool down = inputs->mouse_down[0];
    // XXX: would be nice if we got the vec4_t view instead of view_size,
    // and why input->pos is not already in win pos?
    vec4_t view = vec4(0, 0, view_size->x, view_size->y);
    vec2_t win = inputs->mouse_pos;
    win.y = view_size->y - win.y;

    painter.op = OP_SUB;
    painter.shape = &shape_cylinder;
    // Create the tool box from the camera along the visible ray.
    camera_get_ray(&goxel->camera, &win, &view, &pos, &normal);
    box.mat = mat4_identity;
    box.w = mat4_mul_vec(mat4_inverted(goxel->camera.view_mat),
                     vec4(1, 0, 0, 0)).xyz;
    box.h = mat4_mul_vec(mat4_inverted(goxel->camera.view_mat),
                     vec4(0, 1, 0, 0)).xyz;
    box.d = mat4_mul_vec(mat4_inverted(goxel->camera.view_mat),
                     vec4(0, 0, 1, 0)).xyz;
    box.d = vec3_neg(normal);
    box.p = pos;
    // Just a large value for the size of the laser box.
    mat4_itranslate(&box.mat, 0, 0, -1024);
    mat4_iscale(&box.mat, goxel->tool_radius, goxel->tool_radius, 1024);
    render_box(&goxel->rend, &box, false, NULL, false);
    if (state == STATE_IDLE) {
        if (down) {
            state = STATE_PAINT;
            image_history_push(goxel->image);
        }
    }
    if (state == STATE_PAINT) {
        if (!down) {
            return STATE_IDLE;
        }
        mesh_op(mesh, &painter, &box);
        goxel_update_meshes(goxel, -1);
    }
    return state;
}
예제 #5
0
파일: tools.c 프로젝트: Indy9000/goxel
static int tool_laser_iter(goxel_t *goxel, const inputs_t *inputs, int state,
                           const vec2_t *view_size, bool inside)
{
    vec3_t pos, normal;
    box_t box;
    painter_t painter = goxel->painter;
    mesh_t *mesh = goxel->image->active_layer->mesh;
    const bool down = inputs->mouse_down[0];

    painter.op = OP_SUB;
    painter.shape = &shape_cylinder;
    // Create the laser box with an inifinity width.
    goxel_unproject_on_screen(goxel, view_size, &inputs->mouse_pos,
                              &pos, &normal);
    box.mat = mat4_identity;
    box.w = mat4_mul_vec(mat4_inverted(goxel->camera.view_mat),
                     vec4(1, 0, 0, 0)).xyz;
    box.h = mat4_mul_vec(mat4_inverted(goxel->camera.view_mat),
                     vec4(0, 1, 0, 0)).xyz;
    box.d = mat4_mul_vec(mat4_inverted(goxel->camera.view_mat),
                     vec4(0, 0, 1, 0)).xyz;
    box.p = pos;
    mat4_itranslate(&box.mat, 0, 0, -128);
    mat4_iscale(&box.mat, goxel->tool_radius, goxel->tool_radius, 128);
    render_box(&goxel->rend, &box, false, NULL, false);
    if (state == STATE_IDLE) {
        if (down) state = STATE_PAINT;
    }
    if (state == STATE_PAINT) {
        if (!down) {
            image_history_push(goxel->image);
            return STATE_IDLE;
        }
        mesh_op(mesh, &painter, &box);
        goxel_update_meshes(goxel, false);
    }
    return state;
}
예제 #6
0
void wavefront_export(const mesh_t *mesh, const char *path)
{
    // XXX: Merge faces that can be merged into bigger ones.
    //      Allow to chose between quads or triangles.
    //      Also export mlt file for the colors.
    block_t *block;
    voxel_vertex_t* verts;
    vec3_t v;
    int nb_quads, i, j;
    mat4_t mat;
    FILE *out;
    const int N = BLOCK_SIZE;
    UT_array *lines;
    line_t line, face, *line_ptr;

    utarray_new(lines, &line_icd);
    verts = calloc(N * N * N * 6 * 4, sizeof(*verts));
    face = (line_t){"f "};
    MESH_ITER_BLOCKS(mesh, block) {
        mat = mat4_identity;
        mat4_itranslate(&mat, block->pos.x, block->pos.y, block->pos.z);
        mat4_itranslate(&mat, -N / 2 + 0.5, -N / 2 + 0.5, -N / 2 + 0.5);

        nb_quads = block_generate_vertices(block->data, 0, verts);
        for (i = 0; i < nb_quads; i++) {
            // Put the vertices.
            for (j = 0; j < 4; j++) {
                v = vec3(verts[i * 4 + j].pos.x,
                         verts[i * 4 + j].pos.y,
                         verts[i * 4 + j].pos.z);
                v = mat4_mul_vec3(mat, v);
                line = (line_t){"v ", .v = v};
                face.vs[j] = lines_add(lines, &line);
            }
            // Put the normals
            for (j = 0; j < 4; j++) {
                v = vec3(verts[i * 4 + j].normal.x,
                         verts[i * 4 + j].normal.y,
                         verts[i * 4 + j].normal.z);
                line = (line_t){"vn", .vn = v};
                face.vns[j] = lines_add(lines, &line);
            }
            lines_add(lines, &face);
        }
    }
    out = fopen(path, "w");
    fprintf(out, "# Goxel " GOXEL_VERSION_STR "\n");
    line_ptr = NULL;
    while( (line_ptr = (line_t*)utarray_next(lines, line_ptr))) {
        if (strncmp(line_ptr->type, "v ", 2) == 0)
            fprintf(out, "v %g %g %g\n", VEC3_SPLIT(line_ptr->v));
    }
    while( (line_ptr = (line_t*)utarray_next(lines, line_ptr))) {
        if (strncmp(line_ptr->type, "vn", 2) == 0)
            fprintf(out, "vn %g %g %g\n", VEC3_SPLIT(line_ptr->vn));
    }
    while( (line_ptr = (line_t*)utarray_next(lines, line_ptr))) {
        if (strncmp(line_ptr->type, "f ", 2) == 0)
            fprintf(out, "f %d//%d %d//%d %d//%d %d//%d\n",
                         line_ptr->vs[0], line_ptr->vns[0],
                         line_ptr->vs[1], line_ptr->vns[1],
                         line_ptr->vs[2], line_ptr->vns[2],
                         line_ptr->vs[3], line_ptr->vns[3]);
    }
    fclose(out);
    utarray_free(lines);
}

void ply_export(const mesh_t *mesh, const char *path)
{
    block_t *block;
    voxel_vertex_t* verts;
    vec3_t v;
    uvec3b_t c;
    int nb_quads, i, j;
    mat4_t mat;
    FILE *out;
    const int N = BLOCK_SIZE;
    UT_array *lines;
    line_t line, face, *line_ptr;

    utarray_new(lines, &line_icd);
    verts = calloc(N * N * N * 6 * 4, sizeof(*verts));
    face = (line_t){"f "};
    MESH_ITER_BLOCKS(mesh, block) {
        mat = mat4_identity;
        mat4_itranslate(&mat, block->pos.x, block->pos.y, block->pos.z);
        mat4_itranslate(&mat, -N / 2 + 0.5, -N / 2 + 0.5, -N / 2 + 0.5);

        nb_quads = block_generate_vertices(block->data, 0, verts);
        for (i = 0; i < nb_quads; i++) {
            // Put the vertices.
            for (j = 0; j < 4; j++) {
                v = vec3(verts[i * 4 + j].pos.x,
                         verts[i * 4 + j].pos.y,
                         verts[i * 4 + j].pos.z);
                v = mat4_mul_vec3(mat, v);
                c = verts[i * 4 + j].color.rgb;
                line = (line_t){"v ", .v = v, .c = c};
                face.vs[j] = lines_add(lines, &line);
            }
            // Put the normals
            for (j = 0; j < 4; j++) {
                v = vec3(verts[i * 4 + j].normal.x,
                         verts[i * 4 + j].normal.y,
                         verts[i * 4 + j].normal.z);
                line = (line_t){"vn", .vn = v};
                face.vns[j] = lines_add(lines, &line);
            }
            lines_add(lines, &face);
        }
    }
    out = fopen(path, "w");
    fprintf(out, "ply\n");
    fprintf(out, "format ascii 1.0\n");
    fprintf(out, "comment Generated from Goxel " GOXEL_VERSION_STR "\n");
    fprintf(out, "element vertex %d\n", lines_count(lines, "v "));
    fprintf(out, "property float x\n");
    fprintf(out, "property float y\n");
    fprintf(out, "property float z\n");
    fprintf(out, "property uchar red\n");
    fprintf(out, "property uchar green\n");
    fprintf(out, "property uchar blue\n");
    fprintf(out, "element face %d\n", lines_count(lines, "f "));
    fprintf(out, "property list uchar int vertex_index\n");
    fprintf(out, "end_header\n");
    line_ptr = NULL;
    while( (line_ptr = (line_t*)utarray_next(lines, line_ptr))) {
        if (strncmp(line_ptr->type, "v ", 2) == 0)
            fprintf(out, "%g %g %g %d %d %d\n",
                    VEC3_SPLIT(line_ptr->v),
                    VEC3_SPLIT(line_ptr->c));
    }
    while( (line_ptr = (line_t*)utarray_next(lines, line_ptr))) {
        if (strncmp(line_ptr->type, "f ", 2) == 0)
            fprintf(out, "4 %d %d %d %d\n", line_ptr->vs[0] - 1,
                                            line_ptr->vs[1] - 1,
                                            line_ptr->vs[2] - 1,
                                            line_ptr->vs[3] - 1);
    }
    fclose(out);
    utarray_free(lines);
}

static void export_as_obj(goxel_t *goxel, const char *path)
{
    wavefront_export(goxel->layers_mesh, path);
}