Exemplo n.º 1
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;
}
Exemplo n.º 2
0
// Get the raytracing ray of the camera at a given screen position.
void camera_get_ray(const camera_t *camera, const vec2_t *win,
                    const vec4_t *view, vec3_t *o, vec3_t *d)
{
    // XXX: ugly algo.
    mat4_t inv;
    vec3_t p;
    vec3_t norm_pos = vec3((2 * win->x - view->v[0]) / view->v[2] - 1,
                           (2 * win->y - view->v[1]) / view->v[3] - 1,
                           - 1);
    if (camera->ortho) {
        inv = mat4_inverted(mat4_mul(camera->proj_mat, camera->view_mat));
        *o = mat4_mul_vec(inv, vec4(norm_pos.x, norm_pos.y, 0, 1)).xyz;
        *d = mat4_mul_vec(inv, vec4(0, 0, -1, 0)).xyz;
    } else {
        inv = mat4_inverted(camera->view_mat);
        *o = mat4_mul_vec(inv, vec4(0, 0, 0, 1)).xyz;
        inv = mat4_mul(camera->proj_mat, camera->view_mat);
        mat4_invert(&inv);
        p = mat4_mul_vec3(inv, norm_pos);
        *d = vec3_sub(p, *o);
    }
}
Exemplo n.º 3
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];

    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;
}