diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/gdscript/gdscript.h | 5 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 11 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_functions.cpp | 16 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_functions.h | 1 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 13 | ||||
| -rw-r--r-- | modules/gridmap/grid_map_editor_plugin.cpp | 387 | ||||
| -rw-r--r-- | modules/gridmap/grid_map_editor_plugin.h | 43 | ||||
| -rw-r--r-- | modules/mono/glue/Managed/Files/Mathf.cs | 29 | ||||
| -rw-r--r-- | modules/mono/glue/Managed/Files/MathfEx.cs | 10 | ||||
| -rw-r--r-- | modules/mono/utils/string_utils.cpp | 3 | ||||
| -rw-r--r-- | modules/pvr/texture_loader_pvr.cpp | 7 |
11 files changed, 349 insertions, 176 deletions
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 1d75d9e2fe..38009b878d 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -407,9 +407,10 @@ public: csi.resize(_debug_call_stack_pos); for (int i = 0; i < _debug_call_stack_pos; i++) { csi.write[_debug_call_stack_pos - i - 1].line = _call_stack[i].line ? *_call_stack[i].line : 0; - if (_call_stack[i].function) + if (_call_stack[i].function) { csi.write[_debug_call_stack_pos - i - 1].func = _call_stack[i].function->get_name(); - csi.write[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_path(); + csi.write[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_path(); + } } return csi; } diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 69bf114c8e..bcf3140fa6 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2178,7 +2178,6 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Set<String> &r_result, String &r_arghint) { Variant base = p_base.value; GDScriptParser::DataType base_type = p_base.type; - bool _static = false; const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2191,12 +2190,10 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con return; } } - if (!_static) { - for (int i = 0; i < base_type.class_type->functions.size(); i++) { - if (base_type.class_type->functions[i]->name == p_method) { - r_arghint = _make_arguments_hint(base_type.class_type->functions[i], p_argidx); - return; - } + for (int i = 0; i < base_type.class_type->functions.size(); i++) { + if (base_type.class_type->functions[i]->name == p_method) { + r_arghint = _make_arguments_hint(base_type.class_type->functions[i], p_argidx); + return; } } diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 7552bc6bff..5ebcddfd7c 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -72,6 +72,7 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { "is_zero_approx", "ease", "decimals", + "step_decimals", "stepify", "lerp", "inverse_lerp", @@ -339,6 +340,13 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(1); VALIDATE_ARG_NUM(0); r_ret = Math::step_decimals((double)*p_args[0]); + ERR_EXPLAIN("GDScript method 'decimals' is deprecated and has been renamed to 'step_decimals', please update your code accordingly."); + WARN_DEPRECATED + } break; + case MATH_STEP_DECIMALS: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret = Math::step_decimals((double)*p_args[0]); } break; case MATH_STEPIFY: { VALIDATE_ARG_COUNT(2); @@ -1452,6 +1460,7 @@ bool GDScriptFunctions::is_deterministic(Function p_func) { case MATH_ISINF: case MATH_EASE: case MATH_DECIMALS: + case MATH_STEP_DECIMALS: case MATH_STEPIFY: case MATH_LERP: case MATH_INVERSE_LERP: @@ -1626,7 +1635,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case MATH_DECIMALS: { MethodInfo mi("decimals", PropertyInfo(Variant::REAL, "step")); - mi.return_val.type = Variant::REAL; + mi.return_val.type = Variant::INT; + return mi; + } break; + case MATH_STEP_DECIMALS: { + MethodInfo mi("step_decimals", PropertyInfo(Variant::REAL, "step")); + mi.return_val.type = Variant::INT; return mi; } break; case MATH_STEPIFY: { diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h index 0dbd172acf..c594480ff8 100644 --- a/modules/gdscript/gdscript_functions.h +++ b/modules/gdscript/gdscript_functions.h @@ -63,6 +63,7 @@ public: MATH_ISZEROAPPROX, MATH_EASE, MATH_DECIMALS, + MATH_STEP_DECIMALS, MATH_STEPIFY, MATH_LERP, MATH_INVERSE_LERP, diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 80af094c2c..51ec0c1442 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -282,7 +282,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s switch (tokenizer->get_token()) { case GDScriptTokenizer::TK_CURSOR: { - completion_cursor = StringName(); completion_type = COMPLETION_GET_NODE; completion_class = current_class; completion_function = current_function; @@ -2870,8 +2869,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { lv->assign_op = op; lv->assign = assigned; - lv->assign_op = op; - if (!_end_statement()) { _set_error("Expected end of statement (var)"); return; @@ -6226,8 +6223,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { return DataType(); } #ifdef DEBUG_ENABLED - if (var_op == Variant::OP_DIVIDE && argument_a_type.has_type && argument_a_type.kind == DataType::BUILTIN && argument_a_type.builtin_type == Variant::INT && - argument_b_type.has_type && argument_b_type.kind == DataType::BUILTIN && argument_b_type.builtin_type == Variant::INT) { + if (var_op == Variant::OP_DIVIDE && argument_a_type.kind == DataType::BUILTIN && argument_a_type.builtin_type == Variant::INT && + argument_b_type.kind == DataType::BUILTIN && argument_b_type.builtin_type == Variant::INT) { _add_warning(GDScriptWarning::INTEGER_DIVISION, op->line); } #endif // DEBUG_ENABLED @@ -6938,10 +6935,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat #ifdef DEBUG_ENABLED if (current_function && !for_completion && !is_static && p_call->arguments[0]->type == Node::TYPE_SELF && current_function->_static) { - if (current_function && current_function->_static && p_call->arguments[0]->type == Node::TYPE_SELF) { - _set_error("Can't call non-static function from a static function.", p_call->line); - return DataType(); - } + _set_error("Can't call non-static function from a static function.", p_call->line); + return DataType(); } if (check_types && !is_static && !is_initializer && base_type.is_meta_type) { diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 17eb6f674c..657aa1f9ce 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -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,97 +523,124 @@ 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::_clear_clipboard_data() { + + for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { + + VisualServer::get_singleton()->free(E->get().instance); + } + + clipboard_items.clear(); } -void GridMapEditor::_update_duplicate_indicator() { +void GridMapEditor::_set_clipboard_data() { - if (!selection.active || input_action != INPUT_DUPLICATE) { + _clear_clipboard_data(); + + Ref<MeshLibrary> meshLibrary = node->get_mesh_library(); + + for (int i = selection.begin.x; i <= selection.end.x; i++) { + + for (int j = selection.begin.y; j <= selection.end.y; j++) { + + for (int k = selection.begin.z; k <= selection.end.z; k++) { + + int itm = node->get_cell_item(i, j, k); + if (itm == GridMap::INVALID_CELL_ITEM) + continue; + + 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(duplicate_instance, xf); + 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(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(); + 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(selection.duplicate_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(duplicate_instance, node->get_global_transform() * xf); -} + VisualServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf); -struct __Item { - Vector3 pos; - int rot; - int item; -}; -void GridMapEditor::_duplicate_paste() { + for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - if (!selection.active) - return; + ClipboardItem &item = E->get(); - int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS); - bool reselect = options->get_popup()->is_item_checked(idx); + 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); + } +} - List<__Item> items; +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(selection.duplicate_rot); + rot.set_orthogonal_index(paste_indicator.orientation); - for (int i = selection.begin.x; i <= selection.end.x; i++) { + Vector3 ofs = paste_indicator.current - paste_indicator.click; + undo_redo->create_action(TTR("GridMap Paste Selection")); - for (int j = selection.begin.y; j <= selection.end.y; j++) { + for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - for (int k = selection.begin.z; k <= selection.end.z; k++) { + ClipboardItem &item = E->get(); - 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); - - Basis orm; - orm.set_orthogonal_index(orientation); - orm = rot * orm; - - item.pos = selection.begin + rel; - item.item = itm; - item.rot = orm.get_orthogonal_index(); - items.push_back(item); - } - } - } + Vector3 pos = rot.xform(item.grid_offset) + paste_indicator.begin + ofs; - 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; + Basis orm; + orm.set_orthogonal_index(item.orientation); + orm = rot * orm; - undo_redo->add_do_method(node, "set_cell_item", pos.x, pos.y, pos.z, it.item, it.rot); - 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(); + 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)); } 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_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_check_item("Paste Selects", MENU_OPTION_PASTE_SELECTS); 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) { diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 59b8ac13da..8e1948ea7d 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -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); diff --git a/modules/mono/glue/Managed/Files/Mathf.cs b/modules/mono/glue/Managed/Files/Mathf.cs index 947fbb6665..ff26c7fddf 100644 --- a/modules/mono/glue/Managed/Files/Mathf.cs +++ b/modules/mono/glue/Managed/Files/Mathf.cs @@ -79,14 +79,27 @@ namespace Godot return (real_t)Math.Cosh(s); } - public static int Decimals(real_t step) - { - return Decimals((decimal)step); - } - - public static int Decimals(decimal step) - { - return BitConverter.GetBytes(decimal.GetBits(step)[3])[2]; + public static int StepDecimals(real_t step) + { + double[] sd = new double[] { + 0.9999, + 0.09999, + 0.009999, + 0.0009999, + 0.00009999, + 0.000009999, + 0.0000009999, + 0.00000009999, + 0.000000009999, + }; + double abs = Mathf.Abs(step); + double decs = abs - (int)abs; // Strip away integer part + for (int i = 0; i < sd.Length; i++) { + if (decs >= sd[i]) { + return i; + } + } + return 0; } public static real_t Deg2Rad(real_t deg) diff --git a/modules/mono/glue/Managed/Files/MathfEx.cs b/modules/mono/glue/Managed/Files/MathfEx.cs index d6eb65b097..b96f01bc2e 100644 --- a/modules/mono/glue/Managed/Files/MathfEx.cs +++ b/modules/mono/glue/Managed/Files/MathfEx.cs @@ -21,6 +21,16 @@ namespace Godot public const real_t Epsilon = 1e-06f; #endif + public static int DecimalCount(real_t s) + { + return DecimalCount((decimal)s); + } + + public static int DecimalCount(decimal s) + { + return BitConverter.GetBytes(decimal.GetBits(s)[3])[2]; + } + public static int CeilToInt(real_t s) { return (int)Math.Ceiling(s); diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp index 0ef66577fe..1fdddd3925 100644 --- a/modules/mono/utils/string_utils.cpp +++ b/modules/mono/utils/string_utils.cpp @@ -33,6 +33,7 @@ #include "core/os/file_access.h" #include <stdio.h> +#include <stdlib.h> namespace { @@ -210,7 +211,7 @@ String str_format(const char *p_format, ...) { #endif #if defined(MINGW_ENABLED) || defined(_MSC_VER) -#define vsnprintf vsnprintf_s +#define vsnprintf(m_buffer, m_count, m_format, m_argptr) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_argptr) #endif String str_format(const char *p_format, va_list p_list) { diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 82f323e8cf..8f6ffcc83f 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -192,9 +192,9 @@ static void _compress_pvrtc4(Image *p_img) { Ref<Image> img = p_img->duplicate(); bool make_mipmaps = false; - if (img->get_width() % 8 || img->get_height() % 8) { + if (!img->is_size_po2() || img->get_width() != img->get_height()) { make_mipmaps = img->has_mipmaps(); - img->resize(img->get_width() + (8 - (img->get_width() % 8)), img->get_height() + (8 - (img->get_height() % 8))); + img->resize_to_po2(true); } img->convert(Image::FORMAT_RGBA8); if (!img->has_mipmaps() && make_mipmaps) @@ -204,7 +204,7 @@ static void _compress_pvrtc4(Image *p_img) { Ref<Image> new_img; new_img.instance(); - new_img->create(img->get_width(), img->get_height(), true, use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4); + new_img->create(img->get_width(), img->get_height(), img->has_mipmaps(), use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4); PoolVector<uint8_t> data = new_img->get_data(); { @@ -221,7 +221,6 @@ static void _compress_pvrtc4(Image *p_img) { /* red and Green colors are swapped. */ new (dp) Javelin::ColorRgba<unsigned char>(r[ofs + 4 * j + 2], r[ofs + 4 * j + 1], r[ofs + 4 * j], r[ofs + 4 * j + 3]); } - new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h); Javelin::PvrTcEncoder::EncodeRgba4Bpp(&wr[ofs], bm); } |