Merge pull request #25406 from aqnuep/gridmap_improvements

GridMap editor fixes and improvements
This commit is contained in:
Rémi Verschelde 2019-05-01 12:47:00 +02:00 committed by GitHub
commit 3cfab06080
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 285 additions and 143 deletions

View File

@ -67,9 +67,6 @@ void GridMapEditor::_menu_option(int p_option) {
floor->set_value(floor->get_value() + 1);
} break;
case MENU_OPTION_CONFIGURE: {
} break;
case MENU_OPTION_LOCK_VIEW: {
int index = options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW);
@ -121,14 +118,15 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CURSOR_ROTATE_Y: {
Basis r;
if (input_action == INPUT_DUPLICATE) {
if (input_action == INPUT_PASTE) {
r.set_orthogonal_index(selection.duplicate_rot);
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 1, 0), -Math_PI / 2.0);
selection.duplicate_rot = r.get_orthogonal_index();
_update_duplicate_indicator();
paste_indicator.orientation = r.get_orthogonal_index();
_update_paste_indicator();
break;
}
r.set_orthogonal_index(cursor_rot);
r.rotate(Vector3(0, 1, 0), -Math_PI / 2.0);
cursor_rot = r.get_orthogonal_index();
@ -137,12 +135,12 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CURSOR_ROTATE_X: {
Basis r;
if (input_action == INPUT_DUPLICATE) {
if (input_action == INPUT_PASTE) {
r.set_orthogonal_index(selection.duplicate_rot);
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(1, 0, 0), -Math_PI / 2.0);
selection.duplicate_rot = r.get_orthogonal_index();
_update_duplicate_indicator();
paste_indicator.orientation = r.get_orthogonal_index();
_update_paste_indicator();
break;
}
@ -154,12 +152,12 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CURSOR_ROTATE_Z: {
Basis r;
if (input_action == INPUT_DUPLICATE) {
if (input_action == INPUT_PASTE) {
r.set_orthogonal_index(selection.duplicate_rot);
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 0, 1), -Math_PI / 2.0);
selection.duplicate_rot = r.get_orthogonal_index();
_update_duplicate_indicator();
paste_indicator.orientation = r.get_orthogonal_index();
_update_paste_indicator();
break;
}
@ -171,6 +169,15 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CURSOR_BACK_ROTATE_Y: {
Basis r;
if (input_action == INPUT_PASTE) {
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 1, 0), Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
_update_paste_indicator();
break;
}
r.set_orthogonal_index(cursor_rot);
r.rotate(Vector3(0, 1, 0), Math_PI / 2.0);
cursor_rot = r.get_orthogonal_index();
@ -179,6 +186,15 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CURSOR_BACK_ROTATE_X: {
Basis r;
if (input_action == INPUT_PASTE) {
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(1, 0, 0), Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
_update_paste_indicator();
break;
}
r.set_orthogonal_index(cursor_rot);
r.rotate(Vector3(1, 0, 0), Math_PI / 2.0);
cursor_rot = r.get_orthogonal_index();
@ -187,6 +203,15 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CURSOR_BACK_ROTATE_Z: {
Basis r;
if (input_action == INPUT_PASTE) {
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 0, 1), Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
_update_paste_indicator();
break;
}
r.set_orthogonal_index(cursor_rot);
r.rotate(Vector3(0, 0, 1), Math_PI / 2.0);
cursor_rot = r.get_orthogonal_index();
@ -194,10 +219,10 @@ void GridMapEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CURSOR_CLEAR_ROTATION: {
if (input_action == INPUT_DUPLICATE) {
if (input_action == INPUT_PASTE) {
selection.duplicate_rot = 0;
_update_duplicate_indicator();
paste_indicator.orientation = 0;
_update_paste_indicator();
break;
}
@ -205,28 +230,33 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_DUPLICATE_SELECTS: {
int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS);
case MENU_OPTION_PASTE_SELECTS: {
int idx = options->get_popup()->get_item_index(MENU_OPTION_PASTE_SELECTS);
options->get_popup()->set_item_checked(idx, !options->get_popup()->is_item_checked(idx));
} break;
case MENU_OPTION_SELECTION_DUPLICATE:
case MENU_OPTION_SELECTION_DUPLICATE: // fallthrough
case MENU_OPTION_SELECTION_CUT: {
if (!(selection.active && input_action == INPUT_NONE))
return;
if (last_mouseover == Vector3(-1, -1, -1)) //nono mouseovering anythin
break;
last_mouseover = selection.begin;
VS::get_singleton()->instance_set_transform(grid_instance[edit_axis], Transform(Basis(), grid_ofs));
_set_clipboard_data();
input_action = INPUT_DUPLICATE;
selection.click = last_mouseover;
selection.current = last_mouseover;
selection.duplicate_rot = 0;
_update_duplicate_indicator();
break;
if (p_option == MENU_OPTION_SELECTION_CUT) {
_delete_selection();
}
input_action = INPUT_PASTE;
paste_indicator.click = selection.begin;
paste_indicator.current = selection.begin;
paste_indicator.begin = selection.begin;
paste_indicator.end = selection.end;
paste_indicator.orientation = 0;
_update_paste_indicator();
} break;
case MENU_OPTION_SELECTION_CLEAR: {
if (!selection.active)
return;
break;
_delete_selection();
@ -315,17 +345,28 @@ void GridMapEditor::_validate_selection() {
_update_selection_transform();
}
void GridMapEditor::_set_selection(bool p_active, const Vector3 p_begin, const Vector3 p_end) {
selection.active = p_active;
selection.begin = p_begin;
selection.end = p_end;
selection.click = p_begin;
selection.current = p_end;
_update_selection_transform();
}
bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click) {
if (!spatial_editor)
return false;
if (selected_palette < 0 && input_action != INPUT_COPY && input_action != INPUT_SELECT && input_action != INPUT_DUPLICATE)
if (selected_palette < 0 && input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE)
return false;
Ref<MeshLibrary> mesh_library = node->get_mesh_library();
if (mesh_library.is_null())
return false;
if (input_action != INPUT_COPY && input_action != INPUT_SELECT && input_action != INPUT_DUPLICATE && !mesh_library->has_item(selected_palette))
if (input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE && !mesh_library->has_item(selected_palette))
return false;
Camera *camera = p_camera;
@ -386,13 +427,17 @@ bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, boo
cursor_origin = (Vector3(cell[0], cell[1], cell[2]) + Vector3(0.5 * node->get_center_x(), 0.5 * node->get_center_y(), 0.5 * node->get_center_z())) * node->get_cell_size();
cursor_visible = true;
if (input_action == INPUT_SELECT || input_action == INPUT_PASTE) {
cursor_visible = false;
}
_update_cursor_transform();
}
if (input_action == INPUT_DUPLICATE) {
if (input_action == INPUT_PASTE) {
selection.current = Vector3(cell[0], cell[1], cell[2]);
_update_duplicate_indicator();
paste_indicator.current = Vector3(cell[0], cell[1], cell[2]);
_update_paste_indicator();
} else if (input_action == INPUT_SELECT) {
@ -403,7 +448,7 @@ bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, boo
_validate_selection();
return true;
} else if (input_action == INPUT_COPY) {
} else if (input_action == INPUT_PICK) {
int item = node->get_cell_item(cell[0], cell[1], cell[2]);
if (item >= 0) {
@ -456,10 +501,9 @@ void GridMapEditor::_delete_selection() {
}
}
}
undo_redo->add_do_method(this, "_set_selection", !selection.active, selection.begin, selection.end);
undo_redo->add_undo_method(this, "_set_selection", selection.active, selection.begin, selection.end);
undo_redo->commit_action();
selection.active = false;
_validate_selection();
}
void GridMapEditor::_fill_selection() {
@ -479,49 +523,26 @@ void GridMapEditor::_fill_selection() {
}
}
}
undo_redo->add_do_method(this, "_set_selection", !selection.active, selection.begin, selection.end);
undo_redo->add_undo_method(this, "_set_selection", selection.active, selection.begin, selection.end);
undo_redo->commit_action();
selection.active = false;
_validate_selection();
}
void GridMapEditor::_update_duplicate_indicator() {
void GridMapEditor::_clear_clipboard_data() {
if (!selection.active || input_action != INPUT_DUPLICATE) {
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
Transform xf;
xf.basis.set_zero();
VisualServer::get_singleton()->instance_set_transform(duplicate_instance, xf);
return;
VisualServer::get_singleton()->free(E->get().instance);
}
Transform xf;
xf.scale(Vector3(1, 1, 1) * (Vector3(1, 1, 1) + (selection.end - selection.begin)) * node->get_cell_size());
xf.origin = (selection.begin + (selection.current - selection.click)) * node->get_cell_size();
Basis rot;
rot.set_orthogonal_index(selection.duplicate_rot);
xf.basis = rot * xf.basis;
VisualServer::get_singleton()->instance_set_transform(duplicate_instance, node->get_global_transform() * xf);
clipboard_items.clear();
}
struct __Item {
Vector3 pos;
int rot;
int item;
};
void GridMapEditor::_duplicate_paste() {
void GridMapEditor::_set_clipboard_data() {
if (!selection.active)
return;
_clear_clipboard_data();
int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS);
bool reselect = options->get_popup()->is_item_checked(idx);
List<__Item> items;
Basis rot;
rot.set_orthogonal_index(selection.duplicate_rot);
Ref<MeshLibrary> meshLibrary = node->get_mesh_library();
for (int i = selection.begin.x; i <= selection.end.x; i++) {
@ -532,44 +553,94 @@ void GridMapEditor::_duplicate_paste() {
int itm = node->get_cell_item(i, j, k);
if (itm == GridMap::INVALID_CELL_ITEM)
continue;
int orientation = node->get_cell_item_orientation(i, j, k);
__Item item;
Vector3 rel = Vector3(i, j, k) - selection.begin;
rel = rot.xform(rel);
Ref<Mesh> mesh = meshLibrary->get_item_mesh(itm);
ClipboardItem item;
item.cell_item = itm;
item.grid_offset = Vector3(i, j, k) - selection.begin;
item.orientation = node->get_cell_item_orientation(i, j, k);
item.instance = VisualServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
clipboard_items.push_back(item);
}
}
}
}
void GridMapEditor::_update_paste_indicator() {
if (input_action != INPUT_PASTE) {
Transform xf;
xf.basis.set_zero();
VisualServer::get_singleton()->instance_set_transform(paste_instance, xf);
return;
}
Vector3 center = 0.5 * Vector3(node->get_center_x(), node->get_center_y(), node->get_center_z());
Vector3 scale = (Vector3(1, 1, 1) + (paste_indicator.end - paste_indicator.begin)) * node->get_cell_size();
Transform xf;
xf.scale(scale);
xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size();
Basis rot;
rot.set_orthogonal_index(paste_indicator.orientation);
xf.basis = rot * xf.basis;
xf.translate((-center * node->get_cell_size()) / scale);
VisualServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf);
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
ClipboardItem &item = E->get();
xf = Transform();
xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size();
xf.basis = rot * xf.basis;
xf.translate(item.grid_offset * node->get_cell_size());
Basis item_rot;
item_rot.set_orthogonal_index(item.orientation);
xf.basis = item_rot * xf.basis;
VisualServer::get_singleton()->instance_set_transform(item.instance, node->get_global_transform() * xf);
}
}
void GridMapEditor::_do_paste() {
int idx = options->get_popup()->get_item_index(MENU_OPTION_PASTE_SELECTS);
bool reselect = options->get_popup()->is_item_checked(idx);
Basis rot;
rot.set_orthogonal_index(paste_indicator.orientation);
Vector3 ofs = paste_indicator.current - paste_indicator.click;
undo_redo->create_action(TTR("GridMap Paste Selection"));
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
ClipboardItem &item = E->get();
Vector3 pos = rot.xform(item.grid_offset) + paste_indicator.begin + ofs;
Basis orm;
orm.set_orthogonal_index(orientation);
orm.set_orthogonal_index(item.orientation);
orm = rot * orm;
item.pos = selection.begin + rel;
item.item = itm;
item.rot = orm.get_orthogonal_index();
items.push_back(item);
}
}
}
Vector3 ofs = selection.current - selection.click;
if (items.size()) {
undo_redo->create_action(TTR("GridMap Duplicate Selection"));
for (List<__Item>::Element *E = items.front(); E; E = E->next()) {
__Item &it = E->get();
Vector3 pos = it.pos + ofs;
undo_redo->add_do_method(node, "set_cell_item", pos.x, pos.y, pos.z, it.item, it.rot);
undo_redo->add_do_method(node, "set_cell_item", pos.x, pos.y, pos.z, item.cell_item, orm.get_orthogonal_index());
undo_redo->add_undo_method(node, "set_cell_item", pos.x, pos.y, pos.z, node->get_cell_item(pos.x, pos.y, pos.z), node->get_cell_item_orientation(pos.x, pos.y, pos.z));
}
undo_redo->commit_action();
}
if (reselect) {
selection.begin += ofs;
selection.end += ofs;
selection.click = selection.begin;
selection.current = selection.end;
_validate_selection();
undo_redo->add_do_method(this, "_set_selection", true, paste_indicator.begin + ofs, paste_indicator.end + ofs);
undo_redo->add_undo_method(this, "_set_selection", selection.active, selection.begin, selection.end);
}
undo_redo->commit_action();
_clear_clipboard_data();
}
bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event) {
@ -596,28 +667,31 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
if (mb->get_button_index() == BUTTON_LEFT) {
if (input_action == INPUT_DUPLICATE) {
//paste
_duplicate_paste();
if (input_action == INPUT_PASTE) {
_do_paste();
input_action = INPUT_NONE;
_update_duplicate_indicator();
_update_paste_indicator();
} else if (mb->get_shift()) {
input_action = INPUT_SELECT;
last_selection = selection;
} else if (mb->get_command()) {
input_action = INPUT_COPY;
input_action = INPUT_PICK;
} else {
input_action = INPUT_PAINT;
set_items.clear();
}
} else if (mb->get_button_index() == BUTTON_RIGHT) {
if (input_action == INPUT_DUPLICATE) {
if (input_action == INPUT_PASTE) {
_clear_clipboard_data();
input_action = INPUT_NONE;
_update_duplicate_indicator();
} else if (mb->get_shift()) {
_update_paste_indicator();
return true;
} else if (selection.active) {
_set_selection(false);
return true;
} else {
input_action = INPUT_ERASE;
set_items.clear();
} else {
return false;
}
} else {
return false;
@ -650,13 +724,21 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
return set_items.size() > 0;
}
if (mb->get_button_index() == BUTTON_LEFT && input_action == INPUT_SELECT) {
undo_redo->create_action("GridMap Selection");
undo_redo->add_do_method(this, "_set_selection", selection.active, selection.begin, selection.end);
undo_redo->add_undo_method(this, "_set_selection", last_selection.active, last_selection.begin, last_selection.end);
undo_redo->commit_action();
}
if (mb->get_button_index() == BUTTON_LEFT && input_action != INPUT_NONE) {
set_items.clear();
input_action = INPUT_NONE;
return true;
}
if (mb->get_button_index() == BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_DUPLICATE)) {
if (mb->get_button_index() == BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_PASTE)) {
input_action = INPUT_NONE;
return true;
}
@ -670,6 +752,45 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
return do_input_action(p_camera, mm->get_position(), false);
}
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
if (k->is_pressed()) {
if (k->get_scancode() == KEY_ESCAPE) {
if (input_action == INPUT_PASTE) {
_clear_clipboard_data();
input_action = INPUT_NONE;
_update_paste_indicator();
return true;
} else if (selection.active) {
_set_selection(false);
return true;
} else {
selected_palette = -1;
mesh_library_palette->unselect_all();
update_palette();
_update_cursor_instance();
return true;
}
}
if (k->get_shift() && selection.active && input_action != INPUT_PASTE) {
if (k->get_scancode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) {
selection.click[edit_axis]--;
_validate_selection();
return true;
}
if (k->get_scancode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) {
selection.click[edit_axis]++;
_validate_selection();
return true;
}
}
}
}
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
@ -818,7 +939,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
input_action = INPUT_NONE;
selection.active = false;
_update_selection_transform();
_update_duplicate_indicator();
_update_paste_indicator();
spatial_editor = Object::cast_to<SpatialEditorPlugin>(editor->get_editor_plugin_screen());
@ -953,13 +1074,15 @@ void GridMapEditor::_notification(int p_what) {
}
selection_instance = VisualServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world()->get_scenario());
duplicate_instance = VisualServer::get_singleton()->instance_create2(duplicate_mesh, get_tree()->get_root()->get_world()->get_scenario());
paste_instance = VisualServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world()->get_scenario());
_update_selection_transform();
_update_duplicate_indicator();
_update_paste_indicator();
} break;
case NOTIFICATION_EXIT_TREE: {
_clear_clipboard_data();
for (int i = 0; i < 3; i++) {
VS::get_singleton()->free(grid_instance[i]);
@ -970,9 +1093,9 @@ void GridMapEditor::_notification(int p_what) {
}
VisualServer::get_singleton()->free(selection_instance);
VisualServer::get_singleton()->free(duplicate_instance);
VisualServer::get_singleton()->free(paste_instance);
selection_instance = RID();
duplicate_instance = RID();
paste_instance = RID();
} break;
case NOTIFICATION_PROCESS: {
@ -1065,6 +1188,7 @@ void GridMapEditor::_bind_methods() {
ClassDB::bind_method("_configure", &GridMapEditor::_configure);
ClassDB::bind_method("_item_selected_cbk", &GridMapEditor::_item_selected_cbk);
ClassDB::bind_method("_floor_changed", &GridMapEditor::_floor_changed);
ClassDB::bind_method("_set_selection", &GridMapEditor::_set_selection);
ClassDB::bind_method(D_METHOD("_set_display_mode", "mode"), &GridMapEditor::_set_display_mode);
}
@ -1128,15 +1252,12 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
options->get_popup()->add_item(TTR("Cursor Back Rotate Z"), MENU_OPTION_CURSOR_BACK_ROTATE_Z, KEY_MASK_SHIFT + KEY_D);
options->get_popup()->add_item(TTR("Cursor Clear Rotation"), MENU_OPTION_CURSOR_CLEAR_ROTATION, KEY_W);
options->get_popup()->add_separator();
options->get_popup()->add_check_item("Duplicate Selects", MENU_OPTION_DUPLICATE_SELECTS);
options->get_popup()->add_check_item("Paste Selects", MENU_OPTION_PASTE_SELECTS);
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Create Area"), MENU_OPTION_SELECTION_MAKE_AREA, KEY_CONTROL + KEY_C);
options->get_popup()->add_item(TTR("Create Exterior Connector"), MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR);
options->get_popup()->add_item(TTR("Erase Area"), MENU_OPTION_REMOVE_AREA);
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Duplicate Selection"), MENU_OPTION_SELECTION_DUPLICATE, KEY_MASK_SHIFT + KEY_C);
options->get_popup()->add_item(TTR("Clear Selection"), MENU_OPTION_SELECTION_CLEAR, KEY_MASK_SHIFT + KEY_X);
options->get_popup()->add_item(TTR("Fill Selection"), MENU_OPTION_SELECTION_FILL, KEY_MASK_SHIFT + KEY_F);
options->get_popup()->add_item(TTR("Duplicate Selection"), MENU_OPTION_SELECTION_DUPLICATE, KEY_MASK_CTRL + KEY_C);
options->get_popup()->add_item(TTR("Cut Selection"), MENU_OPTION_SELECTION_CUT, KEY_MASK_CTRL + KEY_X);
options->get_popup()->add_item(TTR("Clear Selection"), MENU_OPTION_SELECTION_CLEAR, KEY_DELETE);
options->get_popup()->add_item(TTR("Fill Selection"), MENU_OPTION_SELECTION_FILL, KEY_MASK_CTRL + KEY_F);
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Settings"), MENU_OPTION_GRIDMAP_SETTINGS);
@ -1211,7 +1332,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
last_mouseover = Vector3(-1, -1, -1);
selection_mesh = VisualServer::get_singleton()->mesh_create();
duplicate_mesh = VisualServer::get_singleton()->mesh_create();
paste_mesh = VisualServer::get_singleton()->mesh_create();
{
//selection mesh create
@ -1319,12 +1440,12 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh, 1, outer_mat->get_rid());
d[VS::ARRAY_VERTEX] = triangles;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(duplicate_mesh, VS::PRIMITIVE_TRIANGLES, d);
VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh, 0, inner_mat->get_rid());
VisualServer::get_singleton()->mesh_add_surface_from_arrays(paste_mesh, VS::PRIMITIVE_TRIANGLES, d);
VisualServer::get_singleton()->mesh_surface_set_material(paste_mesh, 0, inner_mat->get_rid());
d[VS::ARRAY_VERTEX] = lines;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(duplicate_mesh, VS::PRIMITIVE_LINES, d);
VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh, 1, outer_mat->get_rid());
VisualServer::get_singleton()->mesh_add_surface_from_arrays(paste_mesh, VS::PRIMITIVE_LINES, d);
VisualServer::get_singleton()->mesh_surface_set_material(paste_mesh, 1, outer_mat->get_rid());
for (int i = 0; i < 3; i++) {
d[VS::ARRAY_VERTEX] = square[i];
@ -1341,6 +1462,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
GridMapEditor::~GridMapEditor() {
_clear_clipboard_data();
for (int i = 0; i < 3; i++) {
if (grid[i].is_valid())
@ -1359,9 +1482,9 @@ GridMapEditor::~GridMapEditor() {
if (selection_instance.is_valid())
VisualServer::get_singleton()->free(selection_instance);
VisualServer::get_singleton()->free(duplicate_mesh);
if (duplicate_instance.is_valid())
VisualServer::get_singleton()->free(duplicate_instance);
VisualServer::get_singleton()->free(paste_mesh);
if (paste_instance.is_valid())
VisualServer::get_singleton()->free(paste_instance);
}
void GridMapEditorPlugin::_notification(int p_what) {

View File

@ -54,9 +54,9 @@ class GridMapEditor : public VBoxContainer {
INPUT_NONE,
INPUT_PAINT,
INPUT_ERASE,
INPUT_COPY,
INPUT_PICK,
INPUT_SELECT,
INPUT_DUPLICATE,
INPUT_PASTE,
};
enum ClipMode {
@ -116,8 +116,17 @@ class GridMapEditor : public VBoxContainer {
RID selection_instance;
RID selection_level_mesh[3];
RID selection_level_instance[3];
RID duplicate_mesh;
RID duplicate_instance;
RID paste_mesh;
RID paste_instance;
struct ClipboardItem {
int cell_item;
Vector3 grid_offset;
int orientation;
RID instance;
};
List<ClipboardItem> clipboard_items;
Ref<SpatialMaterial> indicator_mat;
Ref<SpatialMaterial> inner_mat;
@ -132,9 +141,19 @@ class GridMapEditor : public VBoxContainer {
Vector3 current;
Vector3 begin;
Vector3 end;
int duplicate_rot;
bool active;
} selection;
Selection last_selection;
struct PasteIndicator {
Vector3 click;
Vector3 current;
Vector3 begin;
Vector3 end;
int orientation;
};
PasteIndicator paste_indicator;
bool cursor_visible;
Transform cursor_transform;
@ -148,7 +167,6 @@ class GridMapEditor : public VBoxContainer {
enum Menu {
MENU_OPTION_CONFIGURE,
MENU_OPTION_NEXT_LEVEL,
MENU_OPTION_PREV_LEVEL,
MENU_OPTION_LOCK_VIEW,
@ -165,13 +183,11 @@ class GridMapEditor : public VBoxContainer {
MENU_OPTION_CURSOR_BACK_ROTATE_X,
MENU_OPTION_CURSOR_BACK_ROTATE_Z,
MENU_OPTION_CURSOR_CLEAR_ROTATION,
MENU_OPTION_DUPLICATE_SELECTS,
MENU_OPTION_SELECTION_MAKE_AREA,
MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR,
MENU_OPTION_PASTE_SELECTS,
MENU_OPTION_SELECTION_DUPLICATE,
MENU_OPTION_SELECTION_CUT,
MENU_OPTION_SELECTION_CLEAR,
MENU_OPTION_SELECTION_FILL,
MENU_OPTION_REMOVE_AREA,
MENU_OPTION_GRIDMAP_SETTINGS
};
@ -200,10 +216,13 @@ class GridMapEditor : public VBoxContainer {
void _icon_size_changed(float p_value);
void _update_duplicate_indicator();
void _duplicate_paste();
void _clear_clipboard_data();
void _set_clipboard_data();
void _update_paste_indicator();
void _do_paste();
void _update_selection_transform();
void _validate_selection();
void _set_selection(bool p_active, const Vector3 p_begin = Vector3(), const Vector3 p_end = Vector3());
void _floor_changed(float p_value);