Пример #1
0
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);
}
Пример #2
0
// 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;
}