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