コード例 #1
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;
}
コード例 #2
0
ファイル: tools.c プロジェクト: Indy9000/goxel
static int tool_pick_color_iter(goxel_t *goxel, const inputs_t *inputs,
                                int state, const vec2_t *view_size,
                                bool inside)
{
    bool snaped;
    vec3_t pos, normal;
    uvec4b_t color;
    mesh_t *mesh = goxel->layers_mesh;
    const bool pressed = inputs->mouse_down[0];
    goxel_set_help_text(goxel, "Click on a voxel to pick the color");
    snaped = inside && goxel_unproject_on_mesh(goxel, view_size,
                            &inputs->mouse_pos, mesh, &pos, &normal);
    if (!snaped) return 0;
    color = mesh_get_at(mesh, &pos);
    color.a = 255;
    goxel_set_help_text(goxel, "%d %d %d", color.r, color.g, color.b);
    if (pressed) goxel->painter.color = color;
    return 0;
}
コード例 #3
0
ファイル: tools.c プロジェクト: Indy9000/goxel
static int tool_set_plane_iter(goxel_t *goxel, const inputs_t *inputs,
                               int state, const vec2_t *view_size,
                               bool inside)
{
    bool snaped;
    vec3_t pos, normal;
    mesh_t *mesh = goxel->layers_mesh;
    const bool pressed = inputs->mouse_down[0];
    goxel_set_help_text(goxel, "Click on the mesh to set plane.");
    snaped = inside && goxel_unproject_on_mesh(goxel, view_size,
                            &inputs->mouse_pos, mesh, &pos, &normal);
    if (snaped && pressed) {
        vec3_iadd(&pos, normal);
        goxel->plane = plane_from_normal(pos, normal);
    }
    return 0;
}
コード例 #4
0
ファイル: tools.c プロジェクト: Indy9000/goxel
static int tool_cube_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 up = !down;
    int snaped = 0;
    vec3_t pos, normal;
    box_t box;
    uvec4b_t box_color = HEXCOLOR(0xffff00ff);
    mesh_t *mesh = goxel->image->active_layer->mesh;

    if (inside)
        snaped = goxel_unproject(goxel, view_size, &inputs->mouse_pos,
                                 &pos, &normal);
    if (snaped) {
        if (    snaped == SNAP_MESH && goxel->painter.op == OP_ADD &&
                !goxel->snap_offset)
            vec3_iadd(&pos, normal);
        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 (!snaped) return STATE_CANCEL;
        goxel_set_help_text(goxel, "Click and drag to draw.");
        goxel->tool_start_pos = pos;
        box = get_box(&goxel->tool_start_pos, &pos, &normal, 0,
                      &goxel->plane);
        mesh_set(&mesh, goxel->tool_origin_mesh);
        mesh_op(mesh, &goxel->painter, &box);
        render_box(&goxel->rend, &box, false, &box_color, false);
        if (down) {
            state = STATE_PAINT;
            goxel->painting = true;
        }
    }
    if (state == STATE_PAINT) {
        goxel_set_help_text(goxel, "Drag.");
        box = get_box(&goxel->tool_start_pos, &pos, &normal, 0, &goxel->plane);
        render_box(&goxel->rend, &box, false, &box_color, false);
        mesh_set(&mesh, goxel->tool_origin_mesh);
        mesh_op(mesh, &goxel->painter, &box);
        goxel_update_meshes(goxel, false);
        if (up) {
            state = STATE_PAINT2;
            goxel->tool_plane = plane_from_normal(pos, goxel->plane.u);
        }
    }
    if (state == STATE_PAINT2) {
        goxel_set_help_text(goxel, "Adjust height.");
        render_plane(&goxel->rend, &goxel->tool_plane, &goxel->grid_color);
        pos = vec3_add(goxel->tool_plane.p,
                    vec3_project(vec3_sub(pos, goxel->tool_plane.p),
                                 goxel->plane.n));
        box = get_box(&goxel->tool_start_pos, &pos, &normal, 0,
                      &goxel->plane);
        render_box(&goxel->rend, &box, false, &box_color, false);
        mesh_set(&mesh, goxel->tool_origin_mesh);
        mesh_op(mesh, &goxel->painter, &box);
        goxel_update_meshes(goxel, false);
        if (down) {
            mesh_set(&mesh, goxel->tool_origin_mesh);
            mesh_op(mesh, &goxel->painter, &box);
            goxel_update_meshes(goxel, true);
            goxel->painting = false;
            image_history_push(goxel->image);
            return STATE_WAIT_UP;
        }
    }
    if (state == STATE_WAIT_UP) {
        goxel->tool_plane = plane_null;
        if (up) state = STATE_IDLE;
    }
    return state;
}
コード例 #5
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;
}
コード例 #6
0
ファイル: tools.c プロジェクト: Indy9000/goxel
// XXX: this is very close to tool_cube_iter.
static int tool_selection_iter(goxel_t *goxel, const inputs_t *inputs,
                               int state, const vec2_t *view_size,
                               bool inside)
{
    extern const mat4_t FACES_MATS[6];
    const bool down = inputs->mouse_down[0];
    const bool up = !down;
    int snaped = 0;
    int face = -1;
    vec3_t pos, normal;
    plane_t face_plane;
    box_t box;
    uvec4b_t box_color = HEXCOLOR(0xffff00ff);

    // See if we can snap on a selection face.
    if (inside && !box_is_null(goxel->selection) &&
            IS_IN(state, STATE_IDLE, STATE_SNAPED, STATE_SNAPED_FACE)) {
        goxel->tool_snape_face = -1;
        if (goxel_unproject_on_box(goxel, view_size, &inputs->mouse_pos,
                               &goxel->selection, &pos, &normal, &face)) {
            goxel->tool_snape_face = face;
            state = STATE_SNAPED_FACE;
        }
    }
    if (!box_is_null(goxel->selection) && goxel->tool_snape_face != -1)
        face_plane.mat = mat4_mul(goxel->selection.mat,
                                  FACES_MATS[goxel->tool_snape_face]);

    if (inside && face == -1)
        snaped = goxel_unproject(goxel, view_size, &inputs->mouse_pos,
                                 &pos, &normal);
    if (snaped) {
        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;
        goxel->tool_snape_face = -1;
        if (snaped) state = STATE_SNAPED;
    }
    if (state == STATE_SNAPED) {
        if (!snaped) return STATE_CANCEL;
        goxel_set_help_text(goxel, "Click and drag to set selection.");
        goxel->tool_start_pos = pos;
        box = get_box(&goxel->tool_start_pos, &pos, &normal, 0,
                      &goxel->plane);
        render_box(&goxel->rend, &box, false, &box_color, false);
        if (down) {
            state = STATE_PAINT;
            goxel->painting = true;
        }
    }
    if (state == STATE_PAINT) {
        goxel_set_help_text(goxel, "Drag.");
        goxel->selection = get_box(&goxel->tool_start_pos, &pos, &normal, 0,
                                   &goxel->plane);
        if (up) {
            state = STATE_PAINT2;
            goxel->tool_plane = plane_from_normal(pos, goxel->plane.u);
        }
    }
    if (state == STATE_PAINT2) {
        goxel_set_help_text(goxel, "Adjust height.");
        render_plane(&goxel->rend, &goxel->tool_plane, &goxel->grid_color);
        pos = vec3_add(goxel->tool_plane.p,
                    vec3_project(vec3_sub(pos, goxel->tool_plane.p),
                                 goxel->plane.n));
        goxel->selection = get_box(&goxel->tool_start_pos, &pos, &normal, 0,
                                   &goxel->plane);
        if (down) {
            goxel->painting = false;
            return STATE_WAIT_UP;
        }
    }
    if (state == STATE_WAIT_UP) {
        goxel->tool_plane = plane_null;
        goxel->selection = box_get_bbox(goxel->selection);
        return up ? STATE_IDLE : STATE_WAIT_UP;
    }
    if (IS_IN(state, STATE_SNAPED_FACE, STATE_MOVE_FACE))
        goxel_set_help_text(goxel, "Drag to move face");
    if (state == STATE_SNAPED_FACE) {
        if (face == -1) return STATE_IDLE;
        render_img(&goxel->rend, NULL, &face_plane.mat);
        if (down) {
            state = STATE_MOVE_FACE;
            goxel->tool_plane = plane(pos, normal,
                                      vec3_normalized(face_plane.u));
        }
    }
    if (state == STATE_MOVE_FACE) {
        if (up) return STATE_IDLE;
        goxel_unproject_on_plane(goxel, view_size, &inputs->mouse_pos,
                                 &goxel->tool_plane, &pos, &normal);
        pos = vec3_add(goxel->tool_plane.p,
                    vec3_project(vec3_sub(pos, goxel->tool_plane.p),
                                 vec3_normalized(face_plane.n)));
        pos.x = round(pos.x);
        pos.y = round(pos.y);
        pos.z = round(pos.z);
        goxel->selection = box_move_face(goxel->selection,
                                         goxel->tool_snape_face, pos);
    }
    return state;
}