コード例 #1
0
ファイル: tools.c プロジェクト: guillaumechereau/goxel
static int tool_procedural_iter(goxel_t *goxel, const inputs_t *inputs,
                                int state, const vec2_t *view_size,
                                bool inside)
{
    int snaped = 0;
    vec3_t pos, normal;
    box_t box;
    gox_proc_t *proc = &goxel->proc;
    const bool down = inputs->mouse_down[0];

    if (proc->state == PROC_PARSE_ERROR) return 0;

    // XXX: duplicate code with tool_brush_iter.
    if (inside)
        snaped = goxel_unproject(
                goxel, view_size, &inputs->mouse_pos,
                goxel->painter.op == OP_ADD && !goxel->snap_offset,
                &pos, &normal);
    if (snaped) {
        if (goxel->tool == TOOL_BRUSH && goxel->snap_offset)
            vec3_iaddk(&pos, normal, goxel->snap_offset * goxel->tool_radius);
        pos.x = round(pos.x - 0.5) + 0.5;
        pos.y = round(pos.y - 0.5) + 0.5;
        pos.z = round(pos.z - 0.5) + 0.5;
        box = bbox_from_extents(pos, 0.5, 0.5, 0.5);
        render_box(&goxel->rend, &box, false, NULL, false);
    }
    if (state == STATE_IDLE) {
        if (snaped) state = STATE_SNAPED;
    }
    if (state == STATE_SNAPED) {
        if (!snaped) return STATE_IDLE;
        if (down) {
            image_history_push(goxel->image);
            proc_stop(proc);
            proc_start(proc, &box);
            state = STATE_PAINT;
        }
    }
    if (state == STATE_PAINT) {
        if (!down) state = STATE_IDLE;
    }
    return state;
}
コード例 #2
0
ファイル: tools.c プロジェクト: Indy9000/goxel
static int tool_brush_iter(goxel_t *goxel, const inputs_t *inputs, int state,
                           const vec2_t *view_size, bool inside)
{
    const bool down = inputs->mouse_down[0];
    const bool pressed = down && !goxel->painting;
    const bool released = !down && goxel->painting;
    int snaped = 0;
    vec3_t pos, normal;
    box_t box;
    painter_t painter2;
    mesh_t *mesh = goxel->image->active_layer->mesh;

    if (inside)
        snaped = goxel_unproject(goxel, view_size, &inputs->mouse_pos,
                                 &pos, &normal);
    goxel_set_help_text(goxel, "Brush: use shift to draw lines, "
                               "ctrl to pick color");
    if (snaped) {
        if (    snaped == SNAP_MESH && goxel->painter.op == OP_ADD &&
                !goxel->snap_offset)
            vec3_iadd(&pos, normal);
        if (goxel->tool == TOOL_BRUSH && goxel->snap_offset)
            vec3_iaddk(&pos, normal, goxel->snap_offset * goxel->tool_radius);
        pos.x = round(pos.x - 0.5) + 0.5;
        pos.y = round(pos.y - 0.5) + 0.5;
        pos.z = round(pos.z - 0.5) + 0.5;
    }
    if (state == STATE_IDLE) {
        goxel->tool_t = 0;
        if (snaped) state = STATE_SNAPED;
    }
    if (state == STATE_SNAPED) {
        if (goxel->tool_t == 0) {
            goxel->tool_t = 1;
            mesh_set(&goxel->tool_origin_mesh, mesh);
            if (!inputs->keys[KEY_SHIFT])
                mesh_set(&goxel->pick_mesh, goxel->layers_mesh);
            goxel->tool_last_op.op = 0; // Discard last op.
        }
        if (!snaped) return STATE_CANCEL;
        if (inputs->keys[KEY_SHIFT])
            render_line(&goxel->rend, &goxel->tool_start_pos, &pos, NULL);
        if (check_can_skip(goxel, pos, down, goxel->painter.op))
            return state;
        box = get_box(&pos, NULL, &normal, goxel->tool_radius, NULL);

        mesh_set(&mesh, goxel->tool_origin_mesh);
        mesh_op(mesh, &goxel->painter, &box);
        goxel_update_meshes(goxel, false);

        if (inputs->keys[KEY_SHIFT]) {
            render_line(&goxel->rend, &goxel->tool_start_pos, &pos, NULL);
            if (pressed) {
                painter2 = goxel->painter;
                painter2.shape = &shape_cylinder;
                box = get_box(&goxel->tool_start_pos, &pos, &normal,
                              goxel->tool_radius, NULL);
                mesh_op(mesh, &painter2, &box);
                goxel_update_meshes(goxel, false);
                goxel->tool_start_pos = pos;
                mesh_set(&goxel->tool_origin_mesh, mesh);
            }
        }
        if (pressed) {
            mesh_set(&mesh, goxel->tool_origin_mesh);
            state = STATE_PAINT;
            goxel->tool_last_op.op = 0;
            goxel->painting = true;
        }
    }
    if (state == STATE_PAINT) {
        if (check_can_skip(goxel, pos, down, goxel->painter.op))
            return state;
        if (released) {
            image_history_push(goxel->image);
            goxel->painting = false;
            goxel->last_pos = pos;
            if (inputs->keys[KEY_SHIFT])
                return STATE_WAIT_KEY_UP;
            mesh_set(&goxel->pick_mesh, goxel->layers_mesh);
            return STATE_IDLE;
        }
        box = get_box(&pos, NULL, &normal, goxel->tool_radius, NULL);
        mesh_op(mesh, &goxel->painter, &box);
        goxel_update_meshes(goxel, false);
        goxel->tool_start_pos = pos;
    }
    if (state == STATE_WAIT_KEY_UP) {
        goxel->tool_t = 0;
        if (!inputs->keys[KEY_SHIFT]) state = STATE_IDLE;
        if (snaped) state = STATE_SNAPED;
    }
    return state;
}