summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/SCsub169
-rw-r--r--editor/animation_track_editor.cpp70
-rw-r--r--editor/animation_track_editor_plugins.cpp8
-rw-r--r--editor/audio_stream_preview.cpp4
-rw-r--r--editor/code_editor.cpp29
-rw-r--r--editor/code_editor.h4
-rw-r--r--editor/collada/collada.cpp64
-rw-r--r--editor/collada/collada.h4
-rw-r--r--editor/connections_dialog.cpp2
-rw-r--r--editor/create_dialog.cpp145
-rw-r--r--editor/create_dialog.h2
-rw-r--r--editor/doc/doc_data.cpp33
-rw-r--r--editor/editor_about.cpp2
-rw-r--r--editor/editor_autoload_settings.cpp2
-rw-r--r--editor/editor_builders.py412
-rw-r--r--editor/editor_data.cpp63
-rw-r--r--editor/editor_data.h3
-rw-r--r--editor/editor_export.cpp24
-rw-r--r--editor/editor_file_dialog.cpp10
-rw-r--r--editor/editor_file_system.cpp2
-rw-r--r--editor/editor_help.cpp44
-rw-r--r--editor/editor_inspector.cpp78
-rw-r--r--editor/editor_inspector.h3
-rw-r--r--editor/editor_log.cpp32
-rw-r--r--editor/editor_log.h9
-rw-r--r--editor/editor_node.cpp146
-rw-r--r--editor/editor_node.h4
-rw-r--r--editor/editor_plugin.cpp13
-rw-r--r--editor/editor_plugin.h2
-rw-r--r--editor/editor_profiler.cpp26
-rw-r--r--editor/editor_profiler.h2
-rw-r--r--editor/editor_properties.cpp170
-rw-r--r--editor/editor_properties.h19
-rw-r--r--editor/editor_resource_preview.cpp4
-rw-r--r--editor/editor_resource_preview.h4
-rw-r--r--editor/editor_settings.cpp22
-rw-r--r--editor/editor_spin_slider.cpp31
-rw-r--r--editor/editor_spin_slider.h4
-rw-r--r--editor/editor_themes.cpp11
-rw-r--r--editor/export_template_manager.cpp22
-rw-r--r--editor/export_template_manager.h2
-rw-r--r--editor/fileserver/editor_file_server.cpp4
-rw-r--r--editor/filesystem_dock.cpp17
-rw-r--r--editor/find_in_files.cpp2
-rw-r--r--editor/groups_editor.cpp6
-rw-r--r--editor/icons/SCsub90
-rw-r--r--editor/icons/editor_icons_builders.py96
-rw-r--r--editor/icons/icon_add_atlas_tile.svg3
-rw-r--r--editor/icons/icon_add_autotile.svg3
-rw-r--r--editor/icons/icon_add_single_tile.svg3
-rw-r--r--editor/icons/icon_information_sign.svg70
-rw-r--r--editor/icons/icon_texture_3_d.svg75
-rw-r--r--editor/icons/icon_texture_array.svg77
-rw-r--r--editor/import/editor_import_collada.cpp50
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp75
-rw-r--r--editor/import/editor_scene_importer_gltf.h1
-rw-r--r--editor/import/resource_importer_csv_translation.cpp2
-rw-r--r--editor/import/resource_importer_image.cpp79
-rw-r--r--editor/import/resource_importer_image.h27
-rw-r--r--editor/import/resource_importer_layered_texture.cpp274
-rw-r--r--editor/import/resource_importer_layered_texture.h57
-rw-r--r--editor/import/resource_importer_obj.cpp9
-rw-r--r--editor/import/resource_importer_scene.cpp2
-rw-r--r--editor/import/resource_importer_wav.cpp134
-rw-r--r--editor/import/resource_importer_wav.h113
-rw-r--r--editor/inspector_dock.cpp5
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp4
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp4
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp4
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp37
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp62
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h2
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp2
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp20
-rw-r--r--editor/plugins/editor_preview_plugins.cpp95
-rw-r--r--editor/plugins/editor_preview_plugins.h35
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp22
-rw-r--r--editor/plugins/path_editor_plugin.cpp93
-rw-r--r--editor/plugins/path_editor_plugin.h18
-rw-r--r--editor/plugins/script_editor_plugin.cpp55
-rw-r--r--editor/plugins/script_text_editor.cpp188
-rw-r--r--editor/plugins/script_text_editor.h6
-rw-r--r--editor/plugins/shader_editor_plugin.cpp11
-rw-r--r--editor/plugins/skeleton_editor_plugin.cpp6
-rw-r--r--editor/plugins/skeleton_ik_editor_plugin.cpp110
-rw-r--r--editor/plugins/skeleton_ik_editor_plugin.h65
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp699
-rw-r--r--editor/plugins/spatial_editor_plugin.h162
-rw-r--r--editor/plugins/sprite_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp28
-rw-r--r--editor/plugins/texture_region_editor_plugin.h5
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp35
-rw-r--r--editor/plugins/tile_map_editor_plugin.h1
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp1906
-rw-r--r--editor/plugins/tile_set_editor_plugin.h160
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp5
-rw-r--r--editor/project_manager.cpp37
-rw-r--r--editor/project_manager.h6
-rw-r--r--editor/project_settings_editor.cpp26
-rw-r--r--editor/project_settings_editor.h2
-rw-r--r--editor/property_editor.cpp2
-rw-r--r--editor/property_editor.h2
-rw-r--r--editor/quick_open.cpp5
-rw-r--r--editor/scene_tree_dock.cpp263
-rw-r--r--editor/scene_tree_dock.h5
-rw-r--r--editor/script_editor_debugger.cpp14
-rw-r--r--editor/settings_config_dialog.cpp34
-rw-r--r--editor/settings_config_dialog.h2
-rw-r--r--editor/spatial_editor_gizmos.cpp3266
-rw-r--r--editor/spatial_editor_gizmos.h497
-rw-r--r--editor/translations/af.po4
-rw-r--r--editor/translations/ar.po19
-rw-r--r--editor/translations/bg.po5
-rw-r--r--editor/translations/bn.po5
-rw-r--r--editor/translations/ca.po5
-rw-r--r--editor/translations/cs.po5
-rw-r--r--editor/translations/da.po5
-rw-r--r--editor/translations/de.po25
-rw-r--r--editor/translations/de_CH.po5
-rw-r--r--editor/translations/editor.pot4
-rw-r--r--editor/translations/el.po32
-rw-r--r--editor/translations/es.po286
-rw-r--r--editor/translations/es_AR.po5
-rw-r--r--editor/translations/fa.po22
-rw-r--r--editor/translations/fi.po36
-rw-r--r--editor/translations/fr.po23
-rw-r--r--editor/translations/he.po4
-rw-r--r--editor/translations/hi.po4
-rw-r--r--editor/translations/hu.po5
-rw-r--r--editor/translations/id.po39
-rw-r--r--editor/translations/is.po4
-rw-r--r--editor/translations/it.po17
-rw-r--r--editor/translations/ja.po5
-rw-r--r--editor/translations/ko.po13
-rw-r--r--editor/translations/lt.po4
-rw-r--r--editor/translations/ms.po19
-rw-r--r--editor/translations/nb.po16
-rw-r--r--editor/translations/nl.po16
-rw-r--r--editor/translations/pl.po33
-rw-r--r--editor/translations/pr.po4
-rw-r--r--editor/translations/pt_BR.po20
-rw-r--r--editor/translations/pt_PT.po5
-rw-r--r--editor/translations/ro.po5
-rw-r--r--editor/translations/ru.po30
-rw-r--r--editor/translations/sk.po5
-rw-r--r--editor/translations/sl.po122
-rw-r--r--editor/translations/sr_Cyrl.po5
-rw-r--r--editor/translations/sr_Latn.po4
-rw-r--r--editor/translations/sv.po23
-rw-r--r--editor/translations/ta.po4
-rw-r--r--editor/translations/th.po5
-rw-r--r--editor/translations/tr.po15
-rw-r--r--editor/translations/uk.po5
-rw-r--r--editor/translations/ur_PK.po4
-rw-r--r--editor/translations/vi.po216
-rw-r--r--editor/translations/zh_CN.po5
-rw-r--r--editor/translations/zh_HK.po5
-rw-r--r--editor/translations/zh_TW.po281
161 files changed, 7520 insertions, 4893 deletions
diff --git a/editor/SCsub b/editor/SCsub
index a9343f7f36..4fa287c33b 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -5,149 +5,14 @@ env.editor_sources = []
import os
import os.path
-from compat import encode_utf8, byte_to_str, open_utf8, escape_string
-
-def make_certs_header(target, source, env):
-
- src = source[0].srcnode().abspath
- dst = target[0].srcnode().abspath
- f = open(src, "rb")
- g = open_utf8(dst, "w")
- buf = f.read()
- decomp_size = len(buf)
- import zlib
- buf = zlib.compress(buf)
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _CERTS_RAW_H\n")
- g.write("#define _CERTS_RAW_H\n")
- g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
- g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
- g.write("static const unsigned char _certs_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
- g.write("};\n")
- g.write("#endif")
-
- g.close()
- f.close()
-
-
-def make_doc_header(target, source, env):
-
- dst = target[0].srcnode().abspath
- g = open_utf8(dst, "w")
- buf = ""
- docbegin = ""
- docend = ""
- for s in source:
- src = s.srcnode().abspath
- if not src.endswith(".xml"):
- continue
- with open_utf8(src, "r") as f:
- content = f.read()
- buf += content
-
- buf = encode_utf8(docbegin + buf + docend)
- decomp_size = len(buf)
- import zlib
- buf = zlib.compress(buf)
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _DOC_DATA_RAW_H\n")
- g.write("#define _DOC_DATA_RAW_H\n")
- g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
- g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
- g.write("static const unsigned char _doc_data_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
- g.write("};\n")
-
- g.write("#endif")
-
- g.close()
-
-
-def make_fonts_header(target, source, env):
-
- dst = target[0].srcnode().abspath
-
- g = open_utf8(dst, "w")
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _EDITOR_FONTS_H\n")
- g.write("#define _EDITOR_FONTS_H\n")
-
- # saving uncompressed, since freetype will reference from memory pointer
- xl_names = []
- for i in range(len(source)):
- with open(source[i].srcnode().abspath, "rb")as f:
- buf = f.read()
-
- name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0]
-
- g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n")
- g.write("static const unsigned char _font_" + name + "[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
-
- g.write("};\n")
-
- g.write("#endif")
-
- g.close()
-
+from platform_methods import run_in_subprocess
+from compat import open_utf8
+import editor_builders
-def make_translations_header(target, source, env):
-
- dst = target[0].srcnode().abspath
-
- g = open_utf8(dst, "w")
-
- g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- g.write("#ifndef _EDITOR_TRANSLATIONS_H\n")
- g.write("#define _EDITOR_TRANSLATIONS_H\n")
-
- import zlib
- import os.path
-
- paths = [node.srcnode().abspath for node in source]
- sorted_paths = sorted(paths, key=lambda path: os.path.splitext(os.path.basename(path))[0])
-
- xl_names = []
- for i in range(len(sorted_paths)):
- with open(sorted_paths[i], "rb") as f:
- buf = f.read()
- decomp_size = len(buf)
- buf = zlib.compress(buf)
- name = os.path.splitext(os.path.basename(sorted_paths[i]))[0]
-
- g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n")
- for i in range(len(buf)):
- g.write("\t" + byte_to_str(buf[i]) + ",\n")
-
- g.write("};\n")
-
- xl_names.append([name, len(buf), str(decomp_size)])
-
- g.write("struct EditorTranslationList {\n")
- g.write("\tconst char* lang;\n")
- g.write("\tint comp_size;\n")
- g.write("\tint uncomp_size;\n")
- g.write("\tconst unsigned char* data;\n")
- g.write("};\n\n")
- g.write("static EditorTranslationList _editor_translations[] = {\n")
- for x in xl_names:
- g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ", _translation_" + x[0] + "_compressed},\n")
- g.write("\t{NULL, 0, 0, NULL}\n")
- g.write("};\n")
-
- g.write("#endif")
-
- g.close()
def _make_doc_data_class_path(to_path):
- g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w")
+ # NOTE: It is safe to generate this file here, since this is still executed serially
+ g = open_utf8(os.path.join(to_path, "doc_data_class_path.gen.h"), "w")
g.write("static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n")
g.write("struct _DocDataClassPath { const char* name; const char* path; };\n")
@@ -169,6 +34,8 @@ if env['tools']:
reg_exporters += '\tregister_' + e + '_exporter();\n'
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
reg_exporters += '}\n'
+
+ # NOTE: It is safe to generate this file here, since this is still executed serially
with open_utf8("register_exporters.gen.cpp", "w") as f:
f.write(reg_exporters_inc)
f.write(reg_exporters)
@@ -192,24 +59,38 @@ if env['tools']:
docs = sorted(docs)
env.Depends("#editor/doc_data_compressed.gen.h", docs)
- env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, make_doc_header)
+ env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header))
+
# Certificates
env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt")
- env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", make_certs_header)
+ env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(editor_builders.make_certs_header))
import glob
+
path = env.Dir('.').abspath
# Translations
tlist = glob.glob(path + "/translations/*.po")
env.Depends('#editor/translations.gen.h', tlist)
- env.CommandNoCache('#editor/translations.gen.h', tlist, make_translations_header)
+ env.CommandNoCache('#editor/translations.gen.h', tlist, run_in_subprocess(editor_builders.make_translations_header))
# Fonts
flist = glob.glob(path + "/../thirdparty/fonts/*.ttf")
flist.append(glob.glob(path + "/../thirdparty/fonts/*.otf"))
env.Depends('#editor/builtin_fonts.gen.h', flist)
- env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, make_fonts_header)
+ env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, run_in_subprocess(editor_builders.make_fonts_header))
+
+ # Authors
+ env.Depends('#editor/authors.gen.h', "../AUTHORS.md")
+ env.CommandNoCache('#editor/authors.gen.h', "../AUTHORS.md", run_in_subprocess(editor_builders.make_authors_header))
+
+ # Donors
+ env.Depends('#editor/donors.gen.h', "../DONORS.md")
+ env.CommandNoCache('#editor/donors.gen.h', "../DONORS.md", run_in_subprocess(editor_builders.make_donors_header))
+
+ # License
+ env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"])
+ env.CommandNoCache('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(editor_builders.make_license_header))
env.add_source_files(env.editor_sources, "*.cpp")
env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"])
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 42d5ea120e..4c4830ad7a 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -231,10 +231,10 @@ public:
if (Variant::can_convert(args[idx].get_type(), t)) {
Variant old = args[idx];
Variant *ptrs[1] = { &old };
- args[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
+ args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
} else {
- args[idx] = Variant::construct(t, NULL, 0, err);
+ args.write[idx] = Variant::construct(t, NULL, 0, err);
}
change_notify_deserved = true;
d_new["args"] = args;
@@ -248,7 +248,7 @@ public:
_fix_node_path(value);
}
- args[idx] = value;
+ args.write[idx] = value;
d_new["args"] = args;
mergeable = true;
}
@@ -3014,12 +3014,12 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b
if (res.is_valid()) {
property_info_base = res;
if (r_current_val) {
- *r_current_val = res->get(leftover_path[leftover_path.size() - 1]);
+ *r_current_val = res->get_indexed(leftover_path);
}
} else if (node) {
property_info_base = node;
if (r_current_val) {
- *r_current_val = node->get(leftover_path[leftover_path.size() - 1]);
+ *r_current_val = node->get_indexed(leftover_path);
}
}
@@ -3053,31 +3053,31 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
subindices.push_back("");
} break;
case Variant::VECTOR2: {
- subindices.push_back(".x");
- subindices.push_back(".y");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
} break;
case Variant::VECTOR3: {
- subindices.push_back(".x");
- subindices.push_back(".y");
- subindices.push_back(".z");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
+ subindices.push_back(":z");
} break;
case Variant::QUAT: {
- subindices.push_back(".x");
- subindices.push_back(".y");
- subindices.push_back(".z");
- subindices.push_back(".w");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
+ subindices.push_back(":z");
+ subindices.push_back(":w");
} break;
case Variant::COLOR: {
- subindices.push_back(".r");
- subindices.push_back(".g");
- subindices.push_back(".b");
- subindices.push_back(".a");
+ subindices.push_back(":r");
+ subindices.push_back(":g");
+ subindices.push_back(":b");
+ subindices.push_back(":a");
} break;
case Variant::PLANE: {
- subindices.push_back(".x");
- subindices.push_back(".y");
- subindices.push_back(".z");
- subindices.push_back(".d");
+ subindices.push_back(":x");
+ subindices.push_back(":y");
+ subindices.push_back(":z");
+ subindices.push_back(":d");
} break;
default: {
if (r_valid) {
@@ -3288,35 +3288,23 @@ void AnimationTrackEditor::_update_tracks() {
if (root && root->has_node_and_resource(path)) {
RES res;
+ NodePath base_path;
Vector<StringName> leftover_path;
Node *node = root->get_node_and_resource(path, res, leftover_path, true);
+ PropertyInfo pinfo = _find_hint_for_track(i, base_path);
Object *object = node;
if (res.is_valid()) {
object = res.ptr();
- } else {
- object = node;
}
if (object && !leftover_path.empty()) {
- //not a property (value track?)
- PropertyInfo pinfo;
- pinfo.name = leftover_path[leftover_path.size() - 1];
- //now let's see if we can get more info about it
-
- List<PropertyInfo> plist;
- object->get_property_list(&plist);
-
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (E->get().name == leftover_path[leftover_path.size() - 1]) {
- pinfo = E->get();
- break;
- }
+ if (pinfo.name.empty()) {
+ pinfo.name = leftover_path[leftover_path.size() - 1];
}
for (int j = 0; j < track_edit_plugins.size(); j++) {
- track_edit = track_edit_plugins[j]->create_value_track_edit(object, pinfo.type, pinfo.name, pinfo.hint, pinfo.hint_string, pinfo.usage);
+ track_edit = track_edit_plugins.write[j]->create_value_track_edit(object, pinfo.type, pinfo.name, pinfo.hint, pinfo.hint_string, pinfo.usage);
if (track_edit) {
break;
}
@@ -3327,7 +3315,7 @@ void AnimationTrackEditor::_update_tracks() {
if (animation->track_get_type(i) == Animation::TYPE_AUDIO) {
for (int j = 0; j < track_edit_plugins.size(); j++) {
- track_edit = track_edit_plugins[j]->create_audio_track_edit();
+ track_edit = track_edit_plugins.write[j]->create_audio_track_edit();
if (track_edit) {
break;
}
@@ -3344,7 +3332,7 @@ void AnimationTrackEditor::_update_tracks() {
if (node && Object::cast_to<AnimationPlayer>(node)) {
for (int j = 0; j < track_edit_plugins.size(); j++) {
- track_edit = track_edit_plugins[j]->create_animation_track_edit(node);
+ track_edit = track_edit_plugins.write[j]->create_animation_track_edit(node);
if (track_edit) {
break;
}
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index d0c91f10d9..6d444c5422 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -271,8 +271,8 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
int idx = i - from_x;
- lines[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
- lines[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
+ lines.write[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
+ lines.write[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
}
Vector<Color> color;
@@ -883,8 +883,8 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
int idx = i - from_x;
- lines[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
- lines[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
+ lines.write[idx * 2 + 0] = Vector2(i, rect.position.y + min * rect.size.y);
+ lines.write[idx * 2 + 1] = Vector2(i, rect.position.y + max * rect.size.y);
}
Vector<Color> color;
diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp
index 6ee4d7f4b0..6ae5ec43a9 100644
--- a/editor/audio_stream_preview.cpp
+++ b/editor/audio_stream_preview.cpp
@@ -118,8 +118,8 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
uint8_t pfrom = CLAMP((min * 0.5 + 0.5) * 255, 0, 255);
uint8_t pto = CLAMP((max * 0.5 + 0.5) * 255, 0, 255);
- preview->preview->preview[(ofs_write + i) * 2 + 0] = pfrom;
- preview->preview->preview[(ofs_write + i) * 2 + 1] = pto;
+ preview->preview->preview.write[(ofs_write + i) * 2 + 0] = pfrom;
+ preview->preview->preview.write[(ofs_write + i) * 2 + 1] = pto;
}
frames_todo -= to_read;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 925f97de8e..9d4333bc29 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -725,7 +725,7 @@ void CodeTextEditor::_complete_request() {
int i = 0;
for (List<String>::Element *E = entries.front(); E; E = E->next()) {
- strs[i++] = E->get();
+ strs.write[i++] = E->get();
}
text_editor->code_complete(strs, forced);
@@ -745,7 +745,7 @@ bool CodeTextEditor::_add_font_size(int p_delta) {
if (font.is_valid()) {
int new_size = CLAMP(font->get_size() + p_delta, 8 * EDSCALE, 96 * EDSCALE);
- zoom_nb->set_text(itos(100 * new_size / 14) + "%");
+ zoom_nb->set_text(itos(100 * new_size / (14 * EDSCALE)) + "%");
if (new_size != font->get_size()) {
EditorSettings::get_singleton()->set("interface/editor/code_font_size", new_size / EDSCALE);
@@ -1246,6 +1246,29 @@ CodeTextEditor::CodeTextEditor() {
status_bar->add_child(memnew(Label)); //to keep the height if the other labels are not visible
+ warning_label = memnew(Label);
+ status_bar->add_child(warning_label);
+ warning_label->set_align(Label::ALIGN_RIGHT);
+ warning_label->set_valign(Label::VALIGN_CENTER);
+ warning_label->set_v_size_flags(SIZE_FILL);
+ warning_label->set_default_cursor_shape(CURSOR_POINTING_HAND);
+ warning_label->set_mouse_filter(MOUSE_FILTER_STOP);
+ warning_label->set_text(TTR("Warnings:"));
+ warning_label->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
+
+ warning_count_label = memnew(Label);
+ status_bar->add_child(warning_count_label);
+ warning_count_label->set_valign(Label::VALIGN_CENTER);
+ warning_count_label->set_v_size_flags(SIZE_FILL);
+ warning_count_label->set_autowrap(true); // workaround to prevent resizing the label on each change, do not touch
+ warning_count_label->set_clip_text(true); // workaround to prevent resizing the label on each change, do not touch
+ warning_count_label->set_custom_minimum_size(Size2(40, 1) * EDSCALE);
+ warning_count_label->set_align(Label::ALIGN_RIGHT);
+ warning_count_label->set_default_cursor_shape(CURSOR_POINTING_HAND);
+ warning_count_label->set_mouse_filter(MOUSE_FILTER_STOP);
+ warning_count_label->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
+ warning_count_label->set_text("0");
+
Label *zoom_txt = memnew(Label);
status_bar->add_child(zoom_txt);
zoom_txt->set_align(Label::ALIGN_RIGHT);
@@ -1318,7 +1341,7 @@ CodeTextEditor::CodeTextEditor() {
font_resize_val = 0;
font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
- zoom_nb->set_text(itos(100 * font_size / 14) + "%");
+ zoom_nb->set_text(itos(100 * font_size / (14 * EDSCALE)) + "%");
font_resize_timer = memnew(Timer);
add_child(font_resize_timer);
font_resize_timer->set_one_shot(true);
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 903f61d87d..ee47eff9a8 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -142,6 +142,8 @@ class CodeTextEditor : public VBoxContainer {
TextEdit *text_editor;
FindReplaceBar *find_replace_bar;
HBoxContainer *status_bar;
+ Label *warning_label;
+ Label *warning_count_label;
Label *line_nb;
Label *col_nb;
@@ -214,6 +216,8 @@ public:
void update_line_and_column() { _line_col_changed(); }
TextEdit *get_text_edit() { return text_editor; }
FindReplaceBar *get_find_replace_bar() { return find_replace_bar; }
+ Label *get_warning_label() const { return warning_label; }
+ Label *get_warning_count_label() const { return warning_count_label; }
virtual void apply_code() {}
void set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func, void *p_ud);
diff --git a/editor/collada/collada.cpp b/editor/collada/collada.cpp
index 734229d014..fa7e37eb1f 100644
--- a/editor/collada/collada.cpp
+++ b/editor/collada/collada.cpp
@@ -191,7 +191,7 @@ Transform Collada::Node::get_global_transform() const {
return default_transform;
}
-Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
+Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
int i = 0;
@@ -225,22 +225,22 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
ret.resize(16);
Transform tr;
// i wonder why collada matrices are transposed, given that's opposed to opengl..
- ret[0] = interp.basis.elements[0][0];
- ret[1] = interp.basis.elements[0][1];
- ret[2] = interp.basis.elements[0][2];
- ret[4] = interp.basis.elements[1][0];
- ret[5] = interp.basis.elements[1][1];
- ret[6] = interp.basis.elements[1][2];
- ret[8] = interp.basis.elements[2][0];
- ret[9] = interp.basis.elements[2][1];
- ret[10] = interp.basis.elements[2][2];
- ret[3] = interp.origin.x;
- ret[7] = interp.origin.y;
- ret[11] = interp.origin.z;
- ret[12] = 0;
- ret[13] = 0;
- ret[14] = 0;
- ret[15] = 1;
+ ret.write[0] = interp.basis.elements[0][0];
+ ret.write[1] = interp.basis.elements[0][1];
+ ret.write[2] = interp.basis.elements[0][2];
+ ret.write[4] = interp.basis.elements[1][0];
+ ret.write[5] = interp.basis.elements[1][1];
+ ret.write[6] = interp.basis.elements[1][2];
+ ret.write[8] = interp.basis.elements[2][0];
+ ret.write[9] = interp.basis.elements[2][1];
+ ret.write[10] = interp.basis.elements[2][2];
+ ret.write[3] = interp.origin.x;
+ ret.write[7] = interp.origin.y;
+ ret.write[11] = interp.origin.z;
+ ret.write[12] = 0;
+ ret.write[13] = 0;
+ ret.write[14] = 0;
+ ret.write[15] = 1;
return ret;
} else {
@@ -249,7 +249,7 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) {
dest.resize(keys[i].data.size());
for (int j = 0; j < dest.size(); j++) {
- dest[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
+ dest.write[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
}
return dest;
//interpolate one by one
@@ -452,7 +452,7 @@ Transform Collada::_read_transform(XMLParser &parser) {
Vector<float> farr;
farr.resize(16);
for (int i = 0; i < 16; i++) {
- farr[i] = array[i].to_double();
+ farr.write[i] = array[i].to_double();
}
return _read_transform_from_array(farr);
@@ -1104,7 +1104,7 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
int from = prim.indices.size();
prim.indices.resize(from + values.size());
for (int i = 0; i < values.size(); i++)
- prim.indices[from + i] = values[i];
+ prim.indices.write[from + i] = values[i];
} else if (prim.vertex_size > 0) {
prim.indices = values;
@@ -1884,7 +1884,7 @@ void Collada::_parse_animation(XMLParser &parser) {
track.keys.resize(key_count);
for (int j = 0; j < key_count; j++) {
- track.keys[j].time = time_keys[j];
+ track.keys.write[j].time = time_keys[j];
state.animation_length = MAX(state.animation_length, time_keys[j]);
}
@@ -1905,9 +1905,9 @@ void Collada::_parse_animation(XMLParser &parser) {
ERR_CONTINUE((output.size() / stride) != key_count);
for (int j = 0; j < key_count; j++) {
- track.keys[j].data.resize(output_len);
+ track.keys.write[j].data.resize(output_len);
for (int k = 0; k < output_len; k++)
- track.keys[j].data[k] = output[l + j * stride + k]; //super weird but should work:
+ track.keys.write[j].data.write[k] = output[l + j * stride + k]; //super weird but should work:
}
if (sampler.has("INTERPOLATION")) {
@@ -1919,9 +1919,9 @@ void Collada::_parse_animation(XMLParser &parser) {
for (int j = 0; j < key_count; j++) {
if (interps[j] == "BEZIER")
- track.keys[j].interp_type = AnimationTrack::INTERP_BEZIER;
+ track.keys.write[j].interp_type = AnimationTrack::INTERP_BEZIER;
else
- track.keys[j].interp_type = AnimationTrack::INTERP_LINEAR;
+ track.keys.write[j].interp_type = AnimationTrack::INTERP_LINEAR;
}
}
@@ -1939,8 +1939,8 @@ void Collada::_parse_animation(XMLParser &parser) {
ERR_CONTINUE(outangents.size() != key_count * 2 * names.size());
for (int j = 0; j < key_count; j++) {
- track.keys[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
- track.keys[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
+ track.keys.write[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
+ track.keys.write[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
}
}
@@ -2118,7 +2118,7 @@ void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
for (int i = 0; i < nj->children.size(); i++) {
- _joint_set_owner(nj->children[i], p_owner);
+ _joint_set_owner(nj->children.write[i], p_owner);
}
}
}
@@ -2147,7 +2147,7 @@ void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton
}
for (int i = 0; i < node->children.size(); i++) {
- _create_skeletons(&node->children[i], p_skeleton);
+ _create_skeletons(&node->children.write[i], p_skeleton);
}
}
@@ -2314,7 +2314,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
for (int i = 0; i < gp->children.size(); i++) {
if (gp->children[i] == parent) {
- gp->children[i] = node;
+ gp->children.write[i] = node;
found = true;
break;
}
@@ -2330,7 +2330,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
if (p_vscene->root_nodes[i] == parent) {
- p_vscene->root_nodes[i] = node;
+ p_vscene->root_nodes.write[i] = node;
found = true;
break;
}
@@ -2466,7 +2466,7 @@ void Collada::_optimize() {
VisualScene &vs = E->get();
for (int i = 0; i < vs.root_nodes.size(); i++) {
- _create_skeletons(&vs.root_nodes[i]);
+ _create_skeletons(&vs.root_nodes.write[i]);
}
for (int i = 0; i < vs.root_nodes.size(); i++) {
diff --git a/editor/collada/collada.h b/editor/collada/collada.h
index ec3284bc5c..7535162f74 100644
--- a/editor/collada/collada.h
+++ b/editor/collada/collada.h
@@ -312,7 +312,7 @@ public:
total += weights[i].weight;
if (total)
for (int i = 0; i < 4; i++)
- weights[i].weight /= total;
+ weights.write[i].weight /= total;
}
}
@@ -515,7 +515,7 @@ public:
Key() { interp_type = INTERP_LINEAR; }
};
- Vector<float> get_value_at_time(float p_time);
+ Vector<float> get_value_at_time(float p_time) const;
Vector<Key> keys;
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index c4f4e28fec..da73a3930a 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -51,7 +51,7 @@ public:
if (name.begins_with("bind/")) {
int which = name.get_slice("/", 1).to_int() - 1;
ERR_FAIL_INDEX_V(which, params.size(), false);
- params[which] = p_value;
+ params.write[which] = p_value;
} else
return false;
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 6b2a072e20..5dd5b7fcc5 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -40,6 +40,11 @@
void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {
+ type_list.clear();
+ ClassDB::get_class_list(&type_list);
+ ScriptServer::get_global_class_list(&type_list);
+ type_list.sort_custom<StringName::AlphCompare>();
+
recent->clear();
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ);
@@ -81,7 +86,7 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {
memdelete(f);
}
- _update_favorite_list();
+ _save_and_update_favorite_list();
// Restore valid window bounds or pop up at default size.
if (EditorSettings::get_singleton()->has_setting("interface/dialogs/create_new_node_bounds")) {
@@ -173,10 +178,28 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
if (p_types.has(p_type))
return;
- if (!ClassDB::is_parent_class(p_type, base_type) || p_type == base_type)
+
+ bool cpp_type = ClassDB::class_exists(p_type);
+ EditorData &ed = EditorNode::get_singleton()->get_editor_data();
+
+ if (p_type == base_type)
return;
- String inherits = ClassDB::get_parent_class(p_type);
+ if (cpp_type) {
+ if (!ClassDB::is_parent_class(p_type, base_type))
+ return;
+ } else {
+ if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type))
+ return;
+
+ String script_path = ScriptServer::get_global_class_path(p_type);
+ if (script_path.find("res://addons/", 0) != -1) {
+ if (!EditorNode::get_singleton()->is_addon_plugin_enabled(script_path.get_slicec('/', 3)))
+ return;
+ }
+ }
+
+ String inherits = cpp_type ? ClassDB::get_parent_class(p_type) : ed.script_class_get_base(p_type);
TreeItem *parent = p_root;
@@ -189,17 +212,32 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
if (p_types.has(inherits))
parent = p_types[inherits];
+ else if (ScriptServer::is_global_class(inherits))
+ return;
}
+ bool can_instance = (cpp_type && ClassDB::can_instance(p_type)) || ScriptServer::is_global_class(p_type);
+
TreeItem *item = search_options->create_item(parent);
- item->set_text(0, p_type);
- if (!ClassDB::can_instance(p_type)) {
+ if (cpp_type) {
+ item->set_text(0, p_type);
+ } else {
+ item->set_metadata(0, p_type);
+ item->set_text(0, p_type + " (" + ScriptServer::get_global_class_path(p_type).get_file() + ")");
+ }
+ if (!can_instance) {
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
item->set_selectable(0, false);
} else {
bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type);
String to_select_type = *to_select ? (*to_select)->get_text(0) : "";
- bool current_item_is_preffered = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type);
+ to_select_type = to_select_type.split(" ")[0];
+ bool current_item_is_preffered;
+ if (cpp_type) {
+ current_item_is_preffered = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type);
+ } else {
+ current_item_is_preffered = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type);
+ }
if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) {
current_item_is_preffered = true;
}
@@ -217,16 +255,19 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
// don't collapse the root node
collapse &= (item != p_root);
// don't collapse abstract nodes on the first tree level
- collapse &= ((parent != p_root) || (ClassDB::can_instance(p_type)));
+ collapse &= ((parent != p_root) || (can_instance));
item->set_collapsed(collapse);
}
const String &description = EditorHelp::get_doc_data()->class_list[p_type].brief_description;
item->set_tooltip(0, description);
- if (has_icon(p_type, "EditorIcons")) {
+ if (cpp_type && has_icon(p_type, "EditorIcons")) {
item->set_icon(0, get_icon(p_type, "EditorIcons"));
+ } else if (!cpp_type && has_icon(ScriptServer::get_global_class_base(p_type), "EditorIcons")) {
+
+ item->set_icon(0, get_icon(ScriptServer::get_global_class_base(p_type), "EditorIcons"));
}
p_types[p_type] = item;
@@ -243,47 +284,38 @@ void CreateDialog::_update_search() {
_parse_fs(EditorFileSystem::get_singleton()->get_filesystem());
*/
- List<StringName> global_classes;
- ScriptServer::get_global_class_list(&global_classes);
-
- Map<String, List<String> > global_class_map;
- for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
- String base = ScriptServer::get_global_class_base(E->get());
- if (!global_class_map.has(base)) {
- global_class_map[base] = List<String>();
- }
- global_class_map[base].push_back(E->get());
- }
-
HashMap<String, TreeItem *> types;
TreeItem *root = search_options->create_item();
+ EditorData &ed = EditorNode::get_singleton()->get_editor_data();
root->set_text(0, base_type);
if (has_icon(base_type, "EditorIcons")) {
root->set_icon(0, get_icon(base_type, "EditorIcons"));
}
- List<StringName>::Element *I = type_list.front();
TreeItem *to_select = search_box->get_text() == base_type ? root : NULL;
- for (; I; I = I->next()) {
+ for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {
String type = I->get();
+ bool cpp_type = ClassDB::class_exists(type);
if (base_type == "Node" && type.begins_with("Editor"))
continue; // do not show editor nodes
- if (!ClassDB::can_instance(type))
+ if (cpp_type && !ClassDB::can_instance(type))
continue; // can't create what can't be instanced
bool skip = false;
- for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
- if (ClassDB::is_parent_class(type, E->get()))
- skip = true;
+ if (cpp_type) {
+ for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
+ if (ClassDB::is_parent_class(type, E->get()))
+ skip = true;
+ }
+ if (skip)
+ continue;
}
- if (skip)
- continue;
if (search_box->get_text() == "") {
add_type(type, types, root, &to_select);
@@ -291,7 +323,7 @@ void CreateDialog::_update_search() {
bool found = false;
String type = I->get();
- while (type != "" && ClassDB::is_parent_class(type, base_type) && type != base_type) {
+ while (type != "" && (cpp_type ? ClassDB::is_parent_class(type, base_type) : ed.script_class_is_parent(type, base_type)) && type != base_type) {
if (search_box->get_text().is_subsequence_ofi(type)) {
found = true;
@@ -305,32 +337,6 @@ void CreateDialog::_update_search() {
add_type(I->get(), types, root, &to_select);
}
- if (global_class_map.has(type) && ClassDB::is_parent_class(type, base_type)) {
- for (List<String>::Element *J = global_class_map[type].front(); J; J = J->next()) {
- bool show = search_box->get_text().is_subsequence_ofi(J->get());
-
- if (!show)
- continue;
-
- if (!types.has(type))
- add_type(type, types, root, &to_select);
-
- TreeItem *ti;
- if (types.has(type))
- ti = types[type];
- else
- ti = search_options->get_root();
-
- TreeItem *item = search_options->create_item(ti);
- item->set_metadata(0, J->get());
- item->set_text(0, J->get() + " (" + ScriptServer::get_global_class_path(J->get()).get_file() + ")");
- item->set_icon(0, _get_editor_icon(type));
- if (!to_select || J->get() == search_box->get_text()) {
- to_select = item;
- }
- }
- }
-
if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
//there are custom types based on this... cool.
@@ -419,6 +425,8 @@ void CreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", this, "_confirmed");
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
favorite->set_icon(get_icon("Favorites", "EditorIcons"));
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -537,8 +545,7 @@ void CreateDialog::_favorite_toggled() {
favorite->set_pressed(false);
}
- _save_favorite_list();
- _update_favorite_list();
+ _save_and_update_favorite_list();
}
void CreateDialog::_save_favorite_list() {
@@ -548,8 +555,11 @@ void CreateDialog::_save_favorite_list() {
if (f) {
for (int i = 0; i < favorite_list.size(); i++) {
-
- f->store_line(favorite_list[i]);
+ String l = favorite_list[i];
+ String name = l.split(" ")[0];
+ if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name)))
+ continue;
+ f->store_line(l);
}
memdelete(f);
}
@@ -560,11 +570,15 @@ void CreateDialog::_update_favorite_list() {
favorites->clear();
TreeItem *root = favorites->create_item();
for (int i = 0; i < favorite_list.size(); i++) {
- TreeItem *ti = favorites->create_item(root);
String l = favorite_list[i];
+ String name = l.split(" ")[0];
+ if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name)))
+ continue;
+ TreeItem *ti = favorites->create_item(root);
ti->set_text(0, l);
ti->set_icon(0, _get_editor_icon(l));
}
+ emit_signal("favorites_updated");
}
void CreateDialog::_history_selected() {
@@ -667,6 +681,10 @@ void CreateDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
}
+ _save_and_update_favorite_list();
+}
+
+void CreateDialog::_save_and_update_favorite_list() {
_save_favorite_list();
_update_favorite_list();
}
@@ -682,21 +700,20 @@ void CreateDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_favorite_selected"), &CreateDialog::_favorite_selected);
ClassDB::bind_method(D_METHOD("_history_activated"), &CreateDialog::_history_activated);
ClassDB::bind_method(D_METHOD("_favorite_activated"), &CreateDialog::_favorite_activated);
+ ClassDB::bind_method(D_METHOD("_save_and_update_favorite_list"), &CreateDialog::_save_and_update_favorite_list);
ClassDB::bind_method("get_drag_data_fw", &CreateDialog::get_drag_data_fw);
ClassDB::bind_method("can_drop_data_fw", &CreateDialog::can_drop_data_fw);
ClassDB::bind_method("drop_data_fw", &CreateDialog::drop_data_fw);
ADD_SIGNAL(MethodInfo("create"));
+ ADD_SIGNAL(MethodInfo("favorites_updated"));
}
CreateDialog::CreateDialog() {
is_replace_mode = false;
- ClassDB::get_class_list(&type_list);
- type_list.sort_custom<StringName::AlphCompare>();
-
set_resizable(true);
HSplitContainer *hsc = memnew(HSplitContainer);
@@ -762,4 +779,6 @@ CreateDialog::CreateDialog() {
type_blacklist.insert("PluginScript"); // PluginScript must be initialized before use, which is not possible here
type_blacklist.insert("ScriptCreateDialog"); // This is an exposed editor Node that doesn't have an Editor prefix.
+
+ EDITOR_DEF("interface/editors/derive_script_globals_by_name", true);
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f8eec231a4..6df9eebc8c 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -90,6 +90,8 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+ void _save_and_update_favorite_list();
+
public:
Object *instance_selected();
String get_selected_type();
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index 542dca74e0..91a29f5717 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -58,7 +58,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.methods.size(); i++) {
- MethodDoc &m = c.methods[i];
+ MethodDoc &m = c.methods.write[i];
for (int j = 0; j < cf.methods.size(); j++) {
@@ -72,13 +72,13 @@ void DocData::merge_from(const DocData &p_data) {
Vector<bool> arg_used;
arg_used.resize(arg_count);
for (int l = 0; l < arg_count; ++l)
- arg_used[l] = false;
+ arg_used.write[l] = false;
// also there is no guarantee that argument ordering will match, so we
// have to check one by one so we make sure we have an exact match
for (int k = 0; k < arg_count; ++k) {
for (int l = 0; l < arg_count; ++l)
if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
- arg_used[l] = true;
+ arg_used.write[l] = true;
break;
}
}
@@ -98,7 +98,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.signals.size(); i++) {
- MethodDoc &m = c.signals[i];
+ MethodDoc &m = c.signals.write[i];
for (int j = 0; j < cf.signals.size(); j++) {
@@ -113,7 +113,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.constants.size(); i++) {
- ConstantDoc &m = c.constants[i];
+ ConstantDoc &m = c.constants.write[i];
for (int j = 0; j < cf.constants.size(); j++) {
@@ -128,7 +128,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.properties.size(); i++) {
- PropertyDoc &p = c.properties[i];
+ PropertyDoc &p = c.properties.write[i];
for (int j = 0; j < cf.properties.size(); j++) {
@@ -146,7 +146,7 @@ void DocData::merge_from(const DocData &p_data) {
for (int i = 0; i < c.theme_properties.size(); i++) {
- PropertyDoc &p = c.theme_properties[i];
+ PropertyDoc &p = c.theme_properties.write[i];
for (int j = 0; j < cf.theme_properties.size(); j++) {
@@ -535,13 +535,14 @@ void DocData::generate(bool p_basic_types) {
}
List<StringName> constants;
- Variant::get_numeric_constants_for_type(Variant::Type(i), &constants);
+ Variant::get_constants_for_type(Variant::Type(i), &constants);
for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
ConstantDoc constant;
constant.name = E->get();
- constant.value = itos(Variant::get_numeric_constant_value(Variant::Type(i), E->get()));
+ Variant value = Variant::get_constant_value(Variant::Type(i), E->get());
+ constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string();
c.constants.push_back(constant);
}
}
@@ -1020,7 +1021,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
for (int i = 0; i < c.methods.size(); i++) {
- MethodDoc &m = c.methods[i];
+ const MethodDoc &m = c.methods[i];
String qualifiers;
if (m.qualifiers != "")
@@ -1040,7 +1041,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
for (int j = 0; j < m.arguments.size(); j++) {
- ArgumentDoc &a = m.arguments[j];
+ const ArgumentDoc &a = m.arguments[j];
String enum_text;
if (a.enumeration != String()) {
@@ -1075,7 +1076,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
if (c.properties[i].enumeration != String()) {
enum_text = " enum=\"" + c.properties[i].enumeration + "\"";
}
- PropertyDoc &p = c.properties[i];
+ const PropertyDoc &p = c.properties[i];
_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + enum_text + ">");
_write_string(f, 3, p.description.strip_edges().xml_escape());
_write_string(f, 2, "</member>");
@@ -1090,11 +1091,11 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 1, "<signals>");
for (int i = 0; i < c.signals.size(); i++) {
- MethodDoc &m = c.signals[i];
+ const MethodDoc &m = c.signals[i];
_write_string(f, 2, "<signal name=\"" + m.name + "\">");
for (int j = 0; j < m.arguments.size(); j++) {
- ArgumentDoc &a = m.arguments[j];
+ const ArgumentDoc &a = m.arguments[j];
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">");
_write_string(f, 3, "</argument>");
}
@@ -1113,7 +1114,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
for (int i = 0; i < c.constants.size(); i++) {
- ConstantDoc &k = c.constants[i];
+ const ConstantDoc &k = c.constants[i];
if (k.enumeration != String()) {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
} else {
@@ -1132,7 +1133,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 1, "<theme_items>");
for (int i = 0; i < c.theme_properties.size(); i++) {
- PropertyDoc &p = c.theme_properties[i];
+ const PropertyDoc &p = c.theme_properties[i];
_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">");
_write_string(f, 2, "</theme_item>");
}
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 4b09db0a9e..e4602f0f94 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -113,7 +113,7 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St
EditorAbout::EditorAbout() {
set_title(TTR("Thanks from the Godot community!"));
- get_ok()->set_text(TTR("Thanks!"));
+ get_ok()->set_text(TTR("OK"));
set_hide_on_ok(true);
set_resizable(true);
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 2f0982e5d9..d12c85861b 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -598,7 +598,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
int i = 0;
for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
- orders[i++] = E->get().order;
+ orders.write[i++] = E->get().order;
}
orders.sort();
diff --git a/editor/editor_builders.py b/editor/editor_builders.py
new file mode 100644
index 0000000000..6c2f9e298e
--- /dev/null
+++ b/editor/editor_builders.py
@@ -0,0 +1,412 @@
+"""Functions used to generate source files during build time
+
+All such functions are invoked in a subprocess on Windows to prevent build flakiness.
+
+"""
+import os
+import os.path
+from platform_methods import subprocess_main
+from compat import encode_utf8, byte_to_str, open_utf8, escape_string
+
+
+def make_certs_header(target, source, env):
+
+ src = source[0]
+ dst = target[0]
+ f = open(src, "rb")
+ g = open_utf8(dst, "w")
+ buf = f.read()
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _CERTS_RAW_H\n")
+ g.write("#define _CERTS_RAW_H\n")
+ g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _certs_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+ g.write("};\n")
+ g.write("#endif")
+
+ g.close()
+ f.close()
+
+
+def make_doc_header(target, source, env):
+
+ dst = target[0]
+ g = open_utf8(dst, "w")
+ buf = ""
+ docbegin = ""
+ docend = ""
+ for src in source:
+ if not src.endswith(".xml"):
+ continue
+ with open_utf8(src, "r") as f:
+ content = f.read()
+ buf += content
+
+ buf = encode_utf8(docbegin + buf + docend)
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _DOC_DATA_RAW_H\n")
+ g.write("#define _DOC_DATA_RAW_H\n")
+ g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
+ g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
+ g.write("static const unsigned char _doc_data_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
+def make_fonts_header(target, source, env):
+
+ dst = target[0]
+
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_FONTS_H\n")
+ g.write("#define _EDITOR_FONTS_H\n")
+
+ # saving uncompressed, since freetype will reference from memory pointer
+ xl_names = []
+ for i in range(len(source)):
+ with open(source[i], "rb")as f:
+ buf = f.read()
+
+ name = os.path.splitext(os.path.basename(source[i]))[0]
+
+ g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n")
+ g.write("static const unsigned char _font_" + name + "[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
+def make_translations_header(target, source, env):
+
+ dst = target[0]
+
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_TRANSLATIONS_H\n")
+ g.write("#define _EDITOR_TRANSLATIONS_H\n")
+
+ import zlib
+ import os.path
+
+ sorted_paths = sorted(source, key=lambda path: os.path.splitext(os.path.basename(path))[0])
+
+ xl_names = []
+ for i in range(len(sorted_paths)):
+ with open(sorted_paths[i], "rb") as f:
+ buf = f.read()
+ decomp_size = len(buf)
+ buf = zlib.compress(buf)
+ name = os.path.splitext(os.path.basename(sorted_paths[i]))[0]
+
+ g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n")
+ for i in range(len(buf)):
+ g.write("\t" + byte_to_str(buf[i]) + ",\n")
+
+ g.write("};\n")
+
+ xl_names.append([name, len(buf), str(decomp_size)])
+
+ g.write("struct EditorTranslationList {\n")
+ g.write("\tconst char* lang;\n")
+ g.write("\tint comp_size;\n")
+ g.write("\tint uncomp_size;\n")
+ g.write("\tconst unsigned char* data;\n")
+ g.write("};\n\n")
+ g.write("static EditorTranslationList _editor_translations[] = {\n")
+ for x in xl_names:
+ g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ", _translation_" + x[0] + "_compressed},\n")
+ g.write("\t{NULL, 0, 0, NULL}\n")
+ g.write("};\n")
+
+ g.write("#endif")
+
+ g.close()
+
+
+def make_authors_header(target, source, env):
+
+ sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"]
+ sections_id = ["dev_founders", "dev_lead", "dev_manager", "dev_names"]
+
+ src = source[0]
+ dst = target[0]
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_AUTHORS_H\n")
+ g.write("#define _EDITOR_AUTHORS_H\n")
+
+ current_section = ""
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading:
+ if line.startswith(" "):
+ g.write("\t\"" + escape_string(line.strip()) + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for i in range(len(sections)):
+ if line.strip().endswith(sections[i]):
+ current_section = escape_string(sections_id[i])
+ reading = True
+ g.write("static const char *" + current_section + "[] = {\n")
+ break
+
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+ g.close()
+ f.close()
+
+def make_donors_header(target, source, env):
+
+ sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"]
+ sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"]
+
+ src = source[0]
+ dst = target[0]
+ f = open_utf8(src, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_DONORS_H\n")
+ g.write("#define _EDITOR_DONORS_H\n")
+
+ current_section = ""
+ reading = False
+
+ def close_section():
+ g.write("\t0\n")
+ g.write("};\n")
+
+ for line in f:
+ if reading >= 0:
+ if line.startswith(" "):
+ g.write("\t\"" + escape_string(line.strip()) + "\",\n")
+ continue
+ if line.startswith("## "):
+ if reading:
+ close_section()
+ reading = False
+ for i in range(len(sections)):
+ if line.strip().endswith(sections[i]):
+ current_section = escape_string(sections_id[i])
+ reading = True
+ g.write("static const char *" + current_section + "[] = {\n")
+ break
+
+ if reading:
+ close_section()
+
+ g.write("#endif\n")
+
+ g.close()
+ f.close()
+
+
+def make_license_header(target, source, env):
+
+ src_copyright = source[0]
+ src_license = source[1]
+ dst = target[0]
+ f = open_utf8(src_license, "r")
+ fc = open_utf8(src_copyright, "r")
+ g = open_utf8(dst, "w")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_LICENSE_H\n")
+ g.write("#define _EDITOR_LICENSE_H\n")
+ g.write("static const char *about_license =")
+
+ for line in f:
+ escaped_string = escape_string(line.strip())
+ g.write("\n\t\"" + escaped_string + "\\n\"")
+
+ g.write(";\n")
+
+ tp_current = 0
+ tp_file = ""
+ tp_comment = ""
+ tp_copyright = ""
+ tp_license = ""
+
+ tp_licensename = ""
+ tp_licensebody = ""
+
+ tp = []
+ tp_licensetext = []
+ for line in fc:
+ if line.startswith("#"):
+ continue
+
+ if line.startswith("Files:"):
+ tp_file = line[6:].strip()
+ tp_current = 1
+ elif line.startswith("Comment:"):
+ tp_comment = line[8:].strip()
+ tp_current = 2
+ elif line.startswith("Copyright:"):
+ tp_copyright = line[10:].strip()
+ tp_current = 3
+ elif line.startswith("License:"):
+ if tp_current != 0:
+ tp_license = line[8:].strip()
+ tp_current = 4
+ else:
+ tp_licensename = line[8:].strip()
+ tp_current = 5
+ elif line.startswith(" "):
+ if tp_current == 1:
+ tp_file += "\n" + line.strip()
+ elif tp_current == 3:
+ tp_copyright += "\n" + line.strip()
+ elif tp_current == 5:
+ if line.strip() == ".":
+ tp_licensebody += "\n"
+ else:
+ tp_licensebody += line[1:]
+ else:
+ if tp_current != 0:
+ if tp_current == 5:
+ tp_licensetext.append([tp_licensename, tp_licensebody])
+
+ tp_licensename = ""
+ tp_licensebody = ""
+ else:
+ added = False
+ for i in tp:
+ if i[0] == tp_comment:
+ i[1].append([tp_file, tp_copyright, tp_license])
+ added = True
+ break
+ if not added:
+ tp.append([tp_comment,[[tp_file, tp_copyright, tp_license]]])
+
+ tp_file = []
+ tp_comment = ""
+ tp_copyright = []
+ tp_license = ""
+ tp_current = 0
+
+ tp_licensetext.append([tp_licensename, tp_licensebody])
+
+ about_thirdparty = ""
+ about_tp_copyright_count = ""
+ about_tp_license = ""
+ about_tp_copyright = ""
+ about_tp_file = ""
+
+ for i in tp:
+ about_thirdparty += "\t\"" + i[0] + "\",\n"
+ about_tp_copyright_count += str(len(i[1])) + ", "
+ for j in i[1]:
+ file_body = ""
+ copyright_body = ""
+ for k in j[0].split("\n"):
+ if file_body != "":
+ file_body += "\\n\"\n"
+ escaped_string = escape_string(k.strip())
+ file_body += "\t\"" + escaped_string
+ for k in j[1].split("\n"):
+ if copyright_body != "":
+ copyright_body += "\\n\"\n"
+ escaped_string = escape_string(k.strip())
+ copyright_body += "\t\"" + escaped_string
+
+ about_tp_file += "\t" + file_body + "\",\n"
+ about_tp_copyright += "\t" + copyright_body + "\",\n"
+ about_tp_license += "\t\"" + j[2] + "\",\n"
+
+ about_license_name = ""
+ about_license_body = ""
+
+ for i in tp_licensetext:
+ body = ""
+ for j in i[1].split("\n"):
+ if body != "":
+ body += "\\n\"\n"
+ escaped_string = escape_string(j.strip())
+ body += "\t\"" + escaped_string
+
+ about_license_name += "\t\"" + i[0] + "\",\n"
+ about_license_body += "\t" + body + "\",\n"
+
+ g.write("static const char *about_thirdparty[] = {\n")
+ g.write(about_thirdparty)
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define THIRDPARTY_COUNT " + str(len(tp)) + "\n")
+
+ g.write("static const int about_tp_copyright_count[] = {\n\t")
+ g.write(about_tp_copyright_count)
+ g.write("0\n};\n")
+
+ g.write("static const char *about_tp_file[] = {\n")
+ g.write(about_tp_file)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_tp_copyright[] = {\n")
+ g.write(about_tp_copyright)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_tp_license[] = {\n")
+ g.write(about_tp_license)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("static const char *about_license_name[] = {\n")
+ g.write(about_license_name)
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define LICENSE_COUNT " + str(len(tp_licensetext)) + "\n")
+
+ g.write("static const char *about_license_body[] = {\n")
+ g.write(about_license_body)
+ g.write("\t0\n")
+ g.write("};\n")
+
+ g.write("#endif\n")
+
+ g.close()
+ fc.close()
+ f.close()
+
+
+if __name__ == '__main__':
+ subprocess_main(globals())
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 4dde893c6d..f4ef11eb36 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -62,7 +62,7 @@ void EditorHistory::cleanup_history() {
fail = true;
} else {
//after level, clip
- history[i].path.resize(j);
+ history.write[i].path.resize(j);
}
break;
@@ -100,14 +100,14 @@ void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int
if (p_property != "" && has_prev) {
//add a sub property
- History &pr = history[current];
+ History &pr = history.write[current];
h = pr;
h.path.resize(h.level + 1);
h.path.push_back(o);
h.level++;
} else if (p_level_change != -1 && has_prev) {
//add a sub property
- History &pr = history[current];
+ History &pr = history.write[current];
h = pr;
ERR_FAIL_INDEX(p_level_change, h.path.size());
h.level = p_level_change;
@@ -206,7 +206,7 @@ ObjectID EditorHistory::get_current() {
if (current < 0 || current >= history.size())
return 0;
- History &h = history[current];
+ History &h = history.write[current];
Object *obj = ObjectDB::get_instance(h.path[h.level].object);
if (!obj)
return 0;
@@ -558,7 +558,7 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
- SWAP(edited_scene[p_idx], edited_scene[p_to_idx]);
+ SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]);
}
void EditorData::remove_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
@@ -644,7 +644,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
//transfer selection
List<Node *> new_selection;
- for (List<Node *>::Element *E = edited_scene[p_idx].selection.front(); E; E = E->next()) {
+ for (List<Node *>::Element *E = edited_scene.write[p_idx].selection.front(); E; E = E->next()) {
NodePath p = edited_scene[p_idx].root->get_path_to(E->get());
Node *new_node = new_scene->get_node(p);
if (new_node)
@@ -654,8 +654,8 @@ bool EditorData::check_and_update_scene(int p_idx) {
new_scene->set_filename(edited_scene[p_idx].root->get_filename());
memdelete(edited_scene[p_idx].root);
- edited_scene[p_idx].root = new_scene;
- edited_scene[p_idx].selection = new_selection;
+ edited_scene.write[p_idx].root = new_scene;
+ edited_scene.write[p_idx].selection = new_selection;
return true;
}
@@ -685,7 +685,7 @@ Node *EditorData::get_edited_scene_root(int p_idx) {
void EditorData::set_edited_scene_root(Node *p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
- edited_scene[current_edited_scene].root = p_root;
+ edited_scene.write[current_edited_scene].root = p_root;
}
int EditorData::get_edited_scene_count() const {
@@ -707,10 +707,10 @@ Vector<EditorData::EditedScene> EditorData::get_edited_scenes() const {
void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
if (p_scene_idx < 0) {
- edited_scene[current_edited_scene].version = version;
+ edited_scene.write[current_edited_scene].version = version;
} else {
ERR_FAIL_INDEX(p_scene_idx, edited_scene.size());
- edited_scene[p_scene_idx].version = version;
+ edited_scene.write[p_scene_idx].version = version;
}
}
@@ -793,7 +793,7 @@ String EditorData::get_scene_path(int p_idx) const {
void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
- edited_scene[current_edited_scene].live_edit_root = p_root;
+ edited_scene.write[current_edited_scene].live_edit_root = p_root;
}
NodePath EditorData::get_edited_scene_live_edit_root() {
@@ -806,7 +806,7 @@ void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHis
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
- EditedScene &es = edited_scene[current_edited_scene];
+ EditedScene &es = edited_scene.write[current_edited_scene];
es.selection = p_selection->get_selected_node_list();
es.history_current = p_history->current;
es.history_stored = p_history->history;
@@ -817,7 +817,7 @@ void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHis
Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) {
ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), Dictionary());
- EditedScene &es = edited_scene[current_edited_scene];
+ EditedScene &es = edited_scene.write[current_edited_scene];
p_history->current = es.history_current;
p_history->history = es.history_stored;
@@ -853,6 +853,41 @@ void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) {
}
}
+bool EditorData::script_class_is_parent(const String &p_class, const String &p_inherits) {
+ if (!ScriptServer::is_global_class(p_class))
+ return false;
+ String base = script_class_get_base(p_class);
+ while (p_inherits != base) {
+ if (ClassDB::class_exists(base)) {
+ return ClassDB::is_parent_class(base, p_inherits);
+ } else if (ScriptServer::is_global_class(base)) {
+ base = script_class_get_base(base);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+StringName EditorData::script_class_get_base(const String &p_class) {
+
+ if (!ScriptServer::is_global_class(p_class))
+ return StringName();
+
+ String path = ScriptServer::get_global_class_path(p_class);
+
+ Ref<Script> script = ResourceLoader::load(path, "Script");
+ if (script.is_null())
+ return StringName();
+
+ Ref<Script> base_script = script->get_base_script();
+ if (base_script.is_null()) {
+ return ScriptServer::get_global_class_base(p_class);
+ }
+
+ return script->get_language()->get_global_class_name(base_script->get_path());
+}
+
EditorData::EditorData() {
current_edited_scene = -1;
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 0ecef8ae31..fac6635cd2 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -211,6 +211,9 @@ public:
void notify_edited_scene_changed();
void notify_resource_saved(const Ref<Resource> &p_resource);
+ bool script_class_is_parent(const String &p_class, const String &p_inherits);
+ StringName script_class_get_base(const String &p_class);
+
EditorData();
};
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 317fffad64..5c911a00ca 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -187,7 +187,7 @@ void EditorExportPreset::remove_patch(int p_idx) {
void EditorExportPreset::set_patch(int p_index, const String &p_path) {
ERR_FAIL_INDEX(p_index, patches.size());
- patches[p_index] = p_path;
+ patches.write[p_index] = p_path;
EditorExport::singleton->save_presets();
}
String EditorExportPreset::get_patch(int p_index) {
@@ -295,7 +295,7 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
MD5Final(&ctx);
sd.md5.resize(16);
for (int i = 0; i < 16; i++) {
- sd.md5[i] = ctx.digest[i];
+ sd.md5.write[i] = ctx.digest[i];
}
}
@@ -584,9 +584,9 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla
//initial export plugin callback
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->get_script_instance()) { //script based
- export_plugins[i]->_export_begin_script(features.features_pv, p_debug, p_path, p_flags);
+ export_plugins.write[i]->_export_begin_script(features.features_pv, p_debug, p_path, p_flags);
} else {
- export_plugins[i]->_export_begin(features.features, p_debug, p_path, p_flags);
+ export_plugins.write[i]->_export_begin(features.features, p_debug, p_path, p_flags);
}
}
}
@@ -594,7 +594,7 @@ EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_pla
EditorExportPlatform::ExportNotifier::~ExportNotifier() {
Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
- export_plugins[i]->_export_end();
+ export_plugins.write[i]->_export_end();
}
}
@@ -632,7 +632,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
}
- export_plugins[i]->_clear();
+ export_plugins.write[i]->_clear();
}
FeatureContainers feature_containers = get_feature_containers(p_preset);
@@ -687,9 +687,9 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
bool do_export = true;
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->get_script_instance()) { //script based
- export_plugins[i]->_export_file_script(path, type, features_pv);
+ export_plugins.write[i]->_export_file_script(path, type, features_pv);
} else {
- export_plugins[i]->_export_file(path, type, features);
+ export_plugins.write[i]->_export_file(path, type, features);
}
if (p_so_func) {
for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
@@ -709,7 +709,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
if (export_plugins[i]->skipped) {
do_export = false;
}
- export_plugins[i]->_clear();
+ export_plugins.write[i]->_clear();
if (!do_export)
break; //apologies, not exporting
@@ -751,7 +751,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<uint8_t> new_file;
new_file.resize(utf8.length());
for (int j = 0; j < utf8.length(); j++) {
- new_file[j] = utf8[j];
+ new_file.write[j] = utf8[j];
}
p_func(p_udata, from + ".remap", new_file, idx, total);
@@ -1130,7 +1130,7 @@ void EditorExport::load_config() {
for (int i = 0; i < export_platforms.size(); i++) {
if (export_platforms[i]->get_name() == platform) {
- preset = export_platforms[i]->create_preset();
+ preset = export_platforms.write[i]->create_preset();
break;
}
}
@@ -1203,7 +1203,7 @@ bool EditorExport::poll_export_platforms() {
bool changed = false;
for (int i = 0; i < export_platforms.size(); i++) {
- if (export_platforms[i]->poll_devices()) {
+ if (export_platforms.write[i]->poll_devices()) {
changed = true;
}
}
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 8a8a21543b..d240f4ed25 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -558,7 +558,9 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p
}
if (single_item_selected) {
item_menu->add_separator();
- item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Show In File Manager"), ITEM_MENU_SHOW_IN_EXPLORER);
+ Dictionary item_meta = item_list->get_item_metadata(p_item);
+ String item_text = item_meta["dir"] ? TTR("Open In File Manager") : TTR("Show In File Manager");
+ item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), item_text, ITEM_MENU_SHOW_IN_EXPLORER);
}
if (item_menu->get_item_count() > 0) {
@@ -582,7 +584,7 @@ void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) {
}
item_menu->add_icon_item(get_icon("Reload", "EditorIcons"), TTR("Refresh"), ITEM_MENU_REFRESH, KEY_F5);
item_menu->add_separator();
- item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Show In File Manager"), ITEM_MENU_SHOW_IN_EXPLORER);
+ item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Open In File Manager"), ITEM_MENU_SHOW_IN_EXPLORER);
item_menu->set_position(item_list->get_global_position() + p_pos);
item_menu->popup();
@@ -1135,7 +1137,7 @@ void EditorFileDialog::_favorite_move_up() {
if (a_idx == -1 || b_idx == -1)
return;
- SWAP(favorited[a_idx], favorited[b_idx]);
+ SWAP(favorited.write[a_idx], favorited.write[b_idx]);
EditorSettings::get_singleton()->set_favorite_dirs(favorited);
@@ -1155,7 +1157,7 @@ void EditorFileDialog::_favorite_move_down() {
if (a_idx == -1 || b_idx == -1)
return;
- SWAP(favorited[a_idx], favorited[b_idx]);
+ SWAP(favorited.write[a_idx], favorited.write[b_idx]);
EditorSettings::get_singleton()->set_favorite_dirs(favorited);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index d8ab41fa05..671ac755b2 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1366,6 +1366,7 @@ void EditorFileSystem::update_script_classes() {
}
ScriptServer::save_global_classes();
+ emit_signal("script_classes_updated");
}
void EditorFileSystem::_queue_update_script_classes() {
@@ -1704,6 +1705,7 @@ void EditorFileSystem::_bind_methods() {
ADD_SIGNAL(MethodInfo("filesystem_changed"));
ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist")));
ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources")));
+ ADD_SIGNAL(MethodInfo("script_classes_updated"));
}
void EditorFileSystem::_update_extensions() {
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 727383b960..60826aa81b 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -253,7 +253,8 @@ void EditorHelpSearch::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
//_update_icons
- search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
connect("confirmed", this, "_confirmed");
_update_search();
@@ -267,7 +268,8 @@ void EditorHelpSearch::_notification(int p_what) {
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
//_update_icons
- search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
} else if (p_what == NOTIFICATION_PROCESS) {
if (search.is_valid()) {
@@ -381,7 +383,8 @@ void EditorHelpIndex::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
//_update_icons
- search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
_update_class_list();
connect("confirmed", this, "_tree_item_selected");
@@ -392,7 +395,8 @@ void EditorHelpIndex::_notification(int p_what) {
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
//_update_icons
- search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
}
}
@@ -541,6 +545,7 @@ void EditorHelp::_class_desc_select(const String &p_select) {
String class_name;
if (select.find(".") != -1) {
class_name = select.get_slice(".", 0);
+ select = select.get_slice(".", 1);
} else {
class_name = "@GlobalScope";
}
@@ -713,16 +718,22 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (p_class == edited_class)
return OK; //already there
+ edited_class = p_class;
+ _update_doc();
+ return OK;
+}
+
+void EditorHelp::_update_doc() {
+
scroll_locked = true;
class_desc->clear();
method_line.clear();
section_line.clear();
- edited_class = p_class;
_init_colors();
- DocData::ClassDoc cd = doc->class_list[p_class]; //make a copy, so we can sort without worrying
+ DocData::ClassDoc cd = doc->class_list[edited_class]; //make a copy, so we can sort without worrying
Ref<Font> doc_font = get_font("doc", "EditorFonts");
Ref<Font> doc_title_font = get_font("doc_title", "EditorFonts");
@@ -734,7 +745,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->push_color(title_color);
class_desc->add_text(TTR("Class:") + " ");
class_desc->push_color(headline_color);
- _add_text(p_class);
+ _add_text(edited_class);
class_desc->pop();
class_desc->pop();
class_desc->pop();
@@ -1214,6 +1225,18 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
constant_line[constants[i].name] = class_desc->get_line_count() - 2;
class_desc->push_font(doc_code_font);
+
+ if (constants[i].value.begins_with("Color(") && constants[i].value.ends_with(")")) {
+ String stripped = constants[i].value.replace(" ", "").replace("Color(", "").replace(")", "");
+ Vector<float> color = stripped.split_floats(",");
+ if (color.size() >= 3) {
+ class_desc->push_color(Color(color[0], color[1], color[2]));
+ static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ class_desc->add_text(String(prefix));
+ class_desc->pop();
+ }
+ }
+
class_desc->push_color(headline_color);
_add_text(constants[i].name);
class_desc->pop();
@@ -1223,6 +1246,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->push_color(value_color);
_add_text(constants[i].value);
class_desc->pop();
+
class_desc->pop();
if (constants[i].description != "") {
class_desc->push_font(doc_font);
@@ -1440,8 +1464,6 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
}
scroll_locked = false;
-
- return OK;
}
void EditorHelp::_request_help(const String &p_string) {
@@ -1738,9 +1760,6 @@ void EditorHelp::_add_text(const String &p_bbcode) {
_add_text_to_rt(p_bbcode, class_desc);
}
-void EditorHelp::_update_doc() {
-}
-
void EditorHelp::generate_doc() {
doc = memnew(DocData);
@@ -1763,6 +1782,7 @@ void EditorHelp::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
class_desc->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor"));
+ _update_doc();
} break;
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 488980db07..99a2b2aa67 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -43,6 +43,9 @@
Size2 EditorProperty::get_minimum_size() const {
Size2 ms;
+ Ref<Font> font = get_font("font", "Tree");
+ ms.height = font->get_height();
+
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -70,12 +73,10 @@ Size2 EditorProperty::get_minimum_size() const {
ms.width += check->get_width() + get_constant("hseparator", "Tree");
}
- if (bottom_editor != NULL) {
- Ref<Font> font = get_font("font", "Tree");
- ms.height += font->get_height();
+ if (bottom_editor != NULL && bottom_editor->is_visible()) {
ms.height += get_constant("vseparation", "Tree");
Size2 bems = bottom_editor->get_combined_minimum_size();
- bems.width += get_constant("item_margin", "Tree");
+ //bems.width += get_constant("item_margin", "Tree");
ms.height += bems.height;
ms.width = MAX(ms.width, bems.width);
}
@@ -98,6 +99,7 @@ void EditorProperty::_notification(int p_what) {
int child_room = size.width * (1.0 - split_ratio);
Ref<Font> font = get_font("font", "Tree");
int height = font->get_height();
+ bool no_children = true;
//compute room needed
for (int i = 0; i < get_child_count(); i++) {
@@ -113,11 +115,16 @@ void EditorProperty::_notification(int p_what) {
Size2 minsize = c->get_combined_minimum_size();
child_room = MAX(child_room, minsize.width);
height = MAX(height, minsize.height);
+ no_children = false;
}
- text_size = MAX(0, size.width - child_room + 4 * EDSCALE);
-
- rect = Rect2(text_size, 0, size.width - text_size, height);
+ if (no_children) {
+ text_size = size.width;
+ rect = Rect2(size.width - 1, 0, 1, height);
+ } else {
+ text_size = MAX(0, size.width - (child_room + 4 * EDSCALE));
+ rect = Rect2(size.width - child_room, 0, child_room, height);
+ }
if (bottom_editor) {
@@ -178,7 +185,7 @@ void EditorProperty::_notification(int p_what) {
draw_style_box(sb, Rect2(Vector2(), size));
}
- if (right_child_rect != Rect2()) {
+ if (draw_top_bg && right_child_rect != Rect2()) {
draw_rect(right_child_rect, dark_color);
}
if (bottom_child_rect != Rect2()) {
@@ -189,7 +196,7 @@ void EditorProperty::_notification(int p_what) {
if (draw_red) {
color = get_color("error_color", "Editor");
} else {
- color = get_color("font_color", "Tree");
+ color = get_color("property_color", "Editor");
}
if (label.find(".") != -1) {
color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides
@@ -787,6 +794,8 @@ void EditorProperty::_bind_methods() {
EditorProperty::EditorProperty() {
+ draw_top_bg = true;
+ object = NULL;
split_ratio = 0.5;
selectable = true;
text_size = 0;
@@ -1613,32 +1622,10 @@ void EditorInspector::update_tree() {
for (List<EditorInspectorPlugin::AddedEditor>::Element *F = editors.front(); F; F = F->next()) {
EditorProperty *ep = Object::cast_to<EditorProperty>(F->get().property_editor);
- current_vbox->add_child(F->get().property_editor);
if (ep) {
-
+ //set all this before the control gets the ENTER_TREE notification
ep->object = object;
- ep->connect("property_changed", this, "_property_changed");
- if (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED) {
- ep->connect("property_changed", this, "_property_changed_update_all", varray(), CONNECT_DEFERRED);
- }
- ep->connect("property_keyed", this, "_property_keyed");
- ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
- ep->connect("property_checked", this, "_property_checked");
- ep->connect("selected", this, "_property_selected");
- ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
- ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
- ep->connect("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
- if (doc_hint != String()) {
- ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
- } else {
- ep->set_tooltip(property_prefix + p.name);
- }
- ep->set_draw_red(draw_red);
- ep->set_use_folding(use_folding);
- ep->set_checkable(checkable);
- ep->set_checked(checked);
- ep->set_keying(keying);
if (F->get().properties.size()) {
@@ -1664,8 +1651,35 @@ void EditorInspector::update_tree() {
editor_property_map[prop].push_back(ep);
}
}
+ ep->set_draw_red(draw_red);
+ ep->set_use_folding(use_folding);
+ ep->set_checkable(checkable);
+ ep->set_checked(checked);
+ ep->set_keying(keying);
ep->set_read_only(read_only);
+ }
+
+ current_vbox->add_child(F->get().property_editor);
+
+ if (ep) {
+
+ ep->connect("property_changed", this, "_property_changed");
+ if (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED) {
+ ep->connect("property_changed", this, "_property_changed_update_all", varray(), CONNECT_DEFERRED);
+ }
+ ep->connect("property_keyed", this, "_property_keyed");
+ ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
+ ep->connect("property_checked", this, "_property_checked");
+ ep->connect("selected", this, "_property_selected");
+ ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
+ ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
+ ep->connect("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
+ if (doc_hint != String()) {
+ ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
+ } else {
+ ep->set_tooltip(property_prefix + p.name);
+ }
ep->update_property();
ep->update_reload_status();
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 454622d662..ebe2124a40 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -68,6 +68,7 @@ private:
bool can_revert;
bool use_folding;
+ bool draw_top_bg;
bool _might_be_in_instance();
bool _is_property_different(const Variant &p_current, const Variant &p_orig, int p_usage);
@@ -149,6 +150,8 @@ public:
String get_tooltip_text() const;
+ void set_draw_top_bg(bool p_draw) { draw_top_bg = p_draw; }
+
EditorProperty();
};
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 158eedfb0f..b3ec717d85 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -54,7 +54,11 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f
self->emit_signal("show_request");
*/
- self->add_message(err_str, true);
+ if (p_type == ERR_HANDLER_WARNING) {
+ self->add_message(err_str, MSG_TYPE_WARNING);
+ } else {
+ self->add_message(err_str, MSG_TYPE_ERROR);
+ }
}
void EditorLog::_notification(int p_what) {
@@ -95,22 +99,32 @@ void EditorLog::clear() {
_clear_request();
}
-void EditorLog::add_message(const String &p_msg, bool p_error) {
+void EditorLog::add_message(const String &p_msg, MessageType p_type) {
log->add_newline();
- if (p_error) {
- log->push_color(get_color("error_color", "Editor"));
- Ref<Texture> icon = get_icon("Error", "EditorIcons");
- log->add_image(icon);
- log->add_text(" ");
- tool_button->set_icon(icon);
+ bool restore = p_type != MSG_TYPE_STD;
+ switch (p_type) {
+ case MSG_TYPE_ERROR: {
+ log->push_color(get_color("error_color", "Editor"));
+ Ref<Texture> icon = get_icon("Error", "EditorIcons");
+ log->add_image(icon);
+ log->add_text(" ");
+ tool_button->set_icon(icon);
+ } break;
+ case MSG_TYPE_WARNING: {
+ log->push_color(get_color("warning_color", "Editor"));
+ Ref<Texture> icon = get_icon("Warning", "EditorIcons");
+ log->add_image(icon);
+ log->add_text(" ");
+ tool_button->set_icon(icon);
+ } break;
}
log->add_text(p_msg);
//button->set_text(p_msg);
- if (p_error)
+ if (restore)
log->pop();
}
diff --git a/editor/editor_log.h b/editor/editor_log.h
index f9bc82de7d..8d0310d914 100644
--- a/editor/editor_log.h
+++ b/editor/editor_log.h
@@ -42,6 +42,7 @@
#include "scene/gui/panel_container.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/tool_button.h"
+
class EditorLog : public VBoxContainer {
GDCLASS(EditorLog, VBoxContainer);
@@ -68,7 +69,13 @@ protected:
void _notification(int p_what);
public:
- void add_message(const String &p_msg, bool p_error = false);
+ enum MessageType {
+ MSG_TYPE_STD,
+ MSG_TYPE_ERROR,
+ MSG_TYPE_WARNING
+ };
+
+ void add_message(const String &p_msg, MessageType p_type = MSG_TYPE_STD);
void set_tool_button(ToolButton *p_tool_button);
void deinit();
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b366ebd911..5748de9d1b 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -62,6 +62,8 @@
#include "editor/import/editor_scene_importer_gltf.h"
#include "editor/import/resource_importer_bitmask.h"
#include "editor/import/resource_importer_csv_translation.h"
+#include "editor/import/resource_importer_image.h"
+#include "editor/import/resource_importer_layered_texture.h"
#include "editor/import/resource_importer_obj.h"
#include "editor/import/resource_importer_scene.h"
#include "editor/import/resource_importer_texture.h"
@@ -108,6 +110,7 @@
#include "editor/plugins/shader_graph_editor_plugin.h"
#include "editor/plugins/skeleton_2d_editor_plugin.h"
#include "editor/plugins/skeleton_editor_plugin.h"
+#include "editor/plugins/skeleton_ik_editor_plugin.h"
#include "editor/plugins/spatial_editor_plugin.h"
#include "editor/plugins/sprite_editor_plugin.h"
#include "editor/plugins/sprite_frames_editor_plugin.h"
@@ -598,7 +601,7 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St
Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
if (err != OK) {
- show_accept(TTR("Error saving resource!"), TTR("I see..."));
+ show_accept(TTR("Error saving resource!"), TTR("OK"));
return;
}
@@ -688,15 +691,15 @@ void EditorNode::_dialog_display_save_error(String p_file, Error p_error) {
case ERR_FILE_CANT_WRITE: {
- show_accept(TTR("Can't open file for writing:") + " " + p_file.get_extension(), TTR("I see..."));
+ show_accept(TTR("Can't open file for writing:") + " " + p_file.get_extension(), TTR("OK"));
} break;
case ERR_FILE_UNRECOGNIZED: {
- show_accept(TTR("Requested file format unknown:") + " " + p_file.get_extension(), TTR("I see..."));
+ show_accept(TTR("Requested file format unknown:") + " " + p_file.get_extension(), TTR("OK"));
} break;
default: {
- show_accept(TTR("Error while saving."), TTR("I see..."));
+ show_accept(TTR("Error while saving."), TTR("OK"));
} break;
}
}
@@ -710,23 +713,23 @@ void EditorNode::_dialog_display_load_error(String p_file, Error p_error) {
case ERR_CANT_OPEN: {
- show_accept(vformat(TTR("Can't open '%s'. The file could have been moved or deleted."), p_file.get_file()), TTR("I see..."));
+ show_accept(vformat(TTR("Can't open '%s'. The file could have been moved or deleted."), p_file.get_file()), TTR("OK"));
} break;
case ERR_PARSE_ERROR: {
- show_accept(vformat(TTR("Error while parsing '%s'."), p_file.get_file()), TTR("I see..."));
+ show_accept(vformat(TTR("Error while parsing '%s'."), p_file.get_file()), TTR("OK"));
} break;
case ERR_FILE_CORRUPT: {
- show_accept(vformat(TTR("Unexpected end of file '%s'."), p_file.get_file()), TTR("I see..."));
+ show_accept(vformat(TTR("Unexpected end of file '%s'."), p_file.get_file()), TTR("OK"));
} break;
case ERR_FILE_NOT_FOUND: {
- show_accept(vformat(TTR("Missing '%s' or its dependencies."), p_file.get_file()), TTR("I see..."));
+ show_accept(vformat(TTR("Missing '%s' or its dependencies."), p_file.get_file()), TTR("OK"));
} break;
default: {
- show_accept(vformat(TTR("Error while loading '%s'."), p_file.get_file()), TTR("I see..."));
+ show_accept(vformat(TTR("Error while loading '%s'."), p_file.get_file()), TTR("OK"));
} break;
}
}
@@ -946,8 +949,6 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
int x = (img->get_width() - vp_size) / 2;
int y = (img->get_height() - vp_size) / 2;
- img->convert(Image::FORMAT_RGB8);
-
if (vp_size < preview_size) {
// just square it.
img->crop_from_point(x, y, vp_size, vp_size);
@@ -962,6 +963,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
// We could get better pictures with better filters
img->resize(preview_size, preview_size, Image::INTERPOLATE_CUBIC);
}
+ img->convert(Image::FORMAT_RGB8);
img->flip_y();
@@ -989,7 +991,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
if (!scene) {
- show_accept(TTR("This operation can't be done without a tree root."), TTR("I see..."));
+ show_accept(TTR("This operation can't be done without a tree root."), TTR("OK"));
return;
}
@@ -1017,7 +1019,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
if (err != OK) {
- show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("I see..."));
+ show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("OK"));
return;
}
@@ -1025,7 +1027,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
// (hacky but needed for the tree to update properly)
Node *dummy_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!dummy_scene) {
- show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("I see..."));
+ show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("OK"));
return;
}
memdelete(dummy_scene);
@@ -1187,7 +1189,7 @@ void EditorNode::_dialog_action(String p_file) {
ml = ResourceLoader::load(p_file, "MeshLibrary");
if (ml.is_null()) {
- show_accept(TTR("Can't load MeshLibrary for merging!"), TTR("I see..."));
+ show_accept(TTR("Can't load MeshLibrary for merging!"), TTR("OK"));
return;
}
}
@@ -1200,7 +1202,7 @@ void EditorNode::_dialog_action(String p_file) {
Error err = ResourceSaver::save(p_file, ml);
if (err) {
- show_accept(TTR("Error saving MeshLibrary!"), TTR("I see..."));
+ show_accept(TTR("Error saving MeshLibrary!"), TTR("OK"));
return;
}
@@ -1212,7 +1214,7 @@ void EditorNode::_dialog_action(String p_file) {
tileset = ResourceLoader::load(p_file, "TileSet");
if (tileset.is_null()) {
- show_accept(TTR("Can't load TileSet for merging!"), TTR("I see..."));
+ show_accept(TTR("Can't load TileSet for merging!"), TTR("OK"));
return;
}
@@ -1225,7 +1227,7 @@ void EditorNode::_dialog_action(String p_file) {
Error err = ResourceSaver::save(p_file, tileset);
if (err) {
- show_accept("Error saving TileSet!", "I see...");
+ show_accept(TTR("Error saving TileSet!"), TTR("OK"));
return;
}
} break;
@@ -1502,7 +1504,7 @@ void EditorNode::_edit_current() {
if (main_plugin) {
// special case if use of external editor is true
- if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
+ if (main_plugin->get_name() == "Script" && current_obj->get_class_name() != StringName("VisualScript") && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
if (!changing_scene)
main_plugin->edit(current_obj);
}
@@ -1579,7 +1581,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
Node *scene = editor_data.get_edited_scene_root();
if (!scene) {
- show_accept(TTR("There is no defined scene to run."), TTR("I see..."));
+ show_accept(TTR("There is no defined scene to run."), TTR("OK"));
return;
}
@@ -1633,7 +1635,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
if (scene->get_filename() == "") {
- show_accept(TTR("Current scene was never saved, please save it prior to running."), TTR("I see..."));
+ show_accept(TTR("Current scene was never saved, please save it prior to running."), TTR("OK"));
return;
}
@@ -1664,7 +1666,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
if (error != OK) {
- show_accept(TTR("Could not start subprocess!"), TTR("I see..."));
+ show_accept(TTR("Could not start subprocess!"), TTR("OK"));
return;
}
@@ -1753,6 +1755,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} else {
tab_closing = editor_data.get_edited_scene();
}
+ if (!editor_data.get_edited_scene_root(tab_closing)) {
+ // empty tab
+ _scene_tab_closed(tab_closing);
+ break;
+ }
} // fallthrough
case SCENE_TAB_CLOSE:
@@ -1782,7 +1789,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!scene) {
- show_accept(TTR("This operation can't be done without a tree root."), TTR("I see..."));
+ show_accept(TTR("This operation can't be done without a tree root."), TTR("OK"));
break;
}
@@ -1845,7 +1852,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!editor_data.get_edited_scene_root()) {
- show_accept(TTR("This operation can't be done without a scene."), TTR("I see..."));
+ show_accept(TTR("This operation can't be done without a scene."), TTR("OK"));
break;
}
@@ -1865,7 +1872,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
//Make sure that the scene has a root before trying to convert to tileset
if (!editor_data.get_edited_scene_root()) {
- show_accept(TTR("This operation can't be done without a root node."), TTR("I see..."));
+ show_accept(TTR("This operation can't be done without a root node."), TTR("OK"));
break;
}
@@ -1886,7 +1893,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!editor_data.get_edited_scene_root()) {
- show_accept(TTR("This operation can't be done without a selected node."), TTR("I see..."));
+ show_accept(TTR("This operation can't be done without a selected node."), TTR("OK"));
break;
}
@@ -2047,6 +2054,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
project_settings->popup_project_settings();
} break;
+ case RUN_PROJECT_DATA_FOLDER: {
+
+ OS::get_singleton()->shell_open(OS::get_singleton()->get_user_data_dir());
+ } break;
case FILE_QUIT:
case RUN_PROJECT_MANAGER: {
@@ -2159,7 +2170,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
OS::get_singleton()->set_low_processor_usage_mode(false);
EditorSettings::get_singleton()->set_project_metadata("editor_options", "update_always", true);
- show_accept(TTR("This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report."), TTR("I see..."));
+ show_accept(TTR("This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report."), TTR("OK"));
} break;
case SETTINGS_UPDATE_CHANGES: {
@@ -2179,6 +2190,14 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
settings_config_dialog->popup_edit_settings();
} break;
+ case SETTINGS_EDITOR_DATA_FOLDER: {
+
+ OS::get_singleton()->shell_open(EditorSettings::get_singleton()->get_data_dir());
+ } break;
+ case SETTINGS_EDITOR_CONFIG_FOLDER: {
+
+ OS::get_singleton()->shell_open(EditorSettings::get_singleton()->get_settings_dir());
+ } break;
case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
export_template_manager->popup_manager();
@@ -2765,7 +2784,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
if (!lpath.begins_with("res://")) {
- show_accept(TTR("Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path."), TTR("Ugh"));
+ show_accept(TTR("Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path."), TTR("OK"));
opening_prev = false;
return ERR_FILE_NOT_FOUND;
}
@@ -3833,6 +3852,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
+
if (scene_tabs->get_hovered_tab() >= 0) {
if (mb->get_button_index() == BUTTON_MIDDLE && mb->is_pressed()) {
_scene_tab_closed(scene_tabs->get_hovered_tab());
@@ -3842,6 +3862,26 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
_menu_option_confirm(FILE_NEW_SCENE, true);
}
}
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
+
+ // context menu
+ scene_tabs_context_menu->clear();
+ scene_tabs_context_menu->set_size(Size2(1, 1));
+
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/new_scene"), FILE_NEW_SCENE);
+ if (scene_tabs->get_hovered_tab() >= 0) {
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene"), FILE_SAVE_SCENE);
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_scene_as"), FILE_SAVE_AS_SCENE);
+ }
+ scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/save_all_scenes"), FILE_SAVE_ALL_SCENES);
+ if (scene_tabs->get_hovered_tab() >= 0) {
+ scene_tabs_context_menu->add_separator();
+ scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
+ scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
+ }
+ scene_tabs_context_menu->set_position(mb->get_global_position());
+ scene_tabs_context_menu->popup();
+ }
}
}
@@ -3935,7 +3975,7 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
if (bottom_panel_items[i].control == p_item) {
bottom_panel_items[i].button->raise();
- SWAP(bottom_panel_items[i], bottom_panel_items[bottom_panel_items.size() - 1]);
+ SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]);
break;
}
}
@@ -4526,7 +4566,7 @@ static Node *_resource_get_edited_scene() {
void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_error) {
EditorNode *en = (EditorNode *)p_this;
- en->log->add_message(p_string, p_error);
+ en->log->add_message(p_string, p_error ? EditorLog::MSG_TYPE_ERROR : EditorLog::MSG_TYPE_STD);
}
EditorNode::EditorNode() {
@@ -4627,6 +4667,20 @@ EditorNode::EditorNode() {
import_texture.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_texture);
+ Ref<ResourceImporterLayeredTexture> import_3d;
+ import_3d.instance();
+ import_3d->set_3d(true);
+ ResourceFormatImporter::get_singleton()->add_importer(import_3d);
+
+ Ref<ResourceImporterLayeredTexture> import_array;
+ import_array.instance();
+ import_array->set_3d(false);
+ ResourceFormatImporter::get_singleton()->add_importer(import_array);
+
+ Ref<ResourceImporterImage> import_image;
+ import_image.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(import_image);
+
Ref<ResourceImporterCSVTranslation> import_csv_translation;
import_csv_translation.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
@@ -4719,6 +4773,8 @@ EditorNode::EditorNode() {
EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
EDITOR_DEF_RST("interface/inspector/disable_folding", false);
+ EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
+ EDITOR_DEF("interface/inspector/horizontal_vector3_editing", true);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
EDITOR_DEF("interface/inspector/resources_types_to_open_in_new_inspector", "SpatialMaterial");
EDITOR_DEF("run/auto_save/save_before_running", true);
@@ -4897,6 +4953,7 @@ EditorNode::EditorNode() {
scene_tabs = memnew(Tabs);
scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
+ scene_tabs->set_select_with_rmb(true);
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_LEFT);
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
@@ -4914,6 +4971,11 @@ EditorNode::EditorNode() {
tabbar_container = memnew(HBoxContainer);
scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ scene_tabs_context_menu = memnew(PopupMenu);
+ tabbar_container->add_child(scene_tabs_context_menu);
+ scene_tabs_context_menu->connect("id_pressed", this, "_menu_option");
+ scene_tabs_context_menu->set_hide_on_window_lose_focus(true);
+
srt->add_child(tabbar_container);
tabbar_container->add_child(scene_tabs);
distraction_free = memnew(ToolButton);
@@ -5020,6 +5082,7 @@ EditorNode::EditorNode() {
file_menu->set_tooltip(TTR("Operations with scene files."));
p = file_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE);
@@ -5065,6 +5128,7 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(project_menu);
p = project_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->add_item(TTR("Project Settings"), RUN_SETTINGS);
p->add_separator();
p->connect("id_pressed", this, "_menu_option");
@@ -5078,6 +5142,9 @@ EditorNode::EditorNode() {
tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
p->add_separator();
+ p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
+ p->add_separator();
+
#ifdef OSX_ENABLED
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
#else
@@ -5097,6 +5164,7 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(debug_menu);
p = debug_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->set_hide_on_item_selection(false);
p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
@@ -5121,10 +5189,12 @@ EditorNode::EditorNode() {
settings_menu->set_text(TTR("Editor"));
settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
left_menu_hb->add_child(settings_menu);
- p = settings_menu->get_popup();
+ p = settings_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
p->add_separator();
+
editor_layouts = memnew(PopupMenu);
editor_layouts->set_name("Layouts");
p->add_child(editor_layouts);
@@ -5136,6 +5206,17 @@ EditorNode::EditorNode() {
p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN);
#endif
p->add_separator();
+
+ if (OS::get_singleton()->get_data_path() == OS::get_singleton()->get_config_path()) {
+ // Configuration and data folders are located in the same place (Windows/macOS)
+ p->add_item(TTR("Open Editor Data/Settings Folder"), SETTINGS_EDITOR_DATA_FOLDER);
+ } else {
+ // Separate configuration and data folders (Linux)
+ p->add_item(TTR("Open Editor Data Folder"), SETTINGS_EDITOR_DATA_FOLDER);
+ p->add_item(TTR("Open Editor Settings Folder"), SETTINGS_EDITOR_CONFIG_FOLDER);
+ }
+ p->add_separator();
+
p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
// Help Menu
@@ -5146,6 +5227,7 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(help_menu);
p = help_menu->get_popup();
+ p->set_hide_on_window_lose_focus(true);
p->connect("id_pressed", this, "_menu_option");
p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES);
p->add_icon_item(gui_base->get_icon("HelpSearch", "EditorIcons"), TTR("Search"), HELP_SEARCH);
@@ -5366,6 +5448,7 @@ EditorNode::EditorNode() {
bottom_panel->add_child(bottom_panel_vb);
bottom_panel_hb = memnew(HBoxContainer);
+ bottom_panel_hb->set_custom_minimum_size(Size2(0, 24)); // Adjust for the height of the "Expand Bottom Dock" icon.
bottom_panel_vb->add_child(bottom_panel_hb);
bottom_panel_hb_editors = memnew(HBoxContainer);
@@ -5528,6 +5611,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(SkeletonEditorPlugin(this)));
+ add_editor_plugin(memnew(SkeletonIKEditorPlugin(this)));
add_editor_plugin(memnew(PhysicalBonePlugin(this)));
// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 38e68b2e09..85aa37ec7e 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -154,6 +154,7 @@ private:
RUN_PLAY_CUSTOM_SCENE,
RUN_SCENE_SETTINGS,
RUN_SETTINGS,
+ RUN_PROJECT_DATA_FOLDER,
RUN_PROJECT_MANAGER,
RUN_FILE_SERVER,
RUN_LIVE_DEBUG,
@@ -168,6 +169,8 @@ private:
SETTINGS_LAYOUT_SAVE,
SETTINGS_LAYOUT_DELETE,
SETTINGS_LAYOUT_DEFAULT,
+ SETTINGS_EDITOR_DATA_FOLDER,
+ SETTINGS_EDITOR_CONFIG_FOLDER,
SETTINGS_MANAGE_EXPORT_TEMPLATES,
SETTINGS_PICK_MAIN_SCENE,
SETTINGS_TOGGLE_FULLSCREEN,
@@ -220,6 +223,7 @@ private:
//main tabs
Tabs *scene_tabs;
+ PopupMenu *scene_tabs_context_menu;
Panel *tab_preview_panel;
TextureRect *tab_preview;
int tab_closing;
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 843267d673..a926401558 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -479,15 +479,6 @@ void EditorPlugin::notify_resource_saved(const Ref<Resource> &p_resource) {
emit_signal("resource_saved", p_resource);
}
-Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial *p_spatial) {
- //??
- if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) {
- return get_script_instance()->call("create_spatial_gizmo", p_spatial);
- }
-
- return Ref<SpatialEditorGizmo>();
-}
-
bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
if (get_script_instance() && get_script_instance()->has_method("forward_canvas_gui_input")) {
@@ -765,10 +756,6 @@ void EditorPlugin::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- MethodInfo gizmo = MethodInfo(Variant::OBJECT, "create_spatial_gizmo", PropertyInfo(Variant::OBJECT, "for_spatial", PROPERTY_HINT_RESOURCE_TYPE, "Spatial"));
- gizmo.return_val.hint = PROPERTY_HINT_RESOURCE_TYPE;
- gizmo.return_val.hint_string = "EditorSpatialGizmo";
- ClassDB::add_virtual_method(get_class_static(), gizmo);
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_plugin_name"));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::OBJECT, "get_plugin_icon"));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "has_main_screen"));
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 72e21b2f7f..c417f487dc 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -51,7 +51,6 @@ class Camera;
class EditorSelection;
class EditorExport;
class EditorSettings;
-class SpatialEditorGizmo;
class EditorImportPlugin;
class EditorExportPlugin;
class EditorResourcePreview;
@@ -171,7 +170,6 @@ public:
void notify_scene_closed(const String &scene_filepath);
void notify_resource_saved(const Ref<Resource> &p_resource);
- virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
virtual void forward_draw_over_viewport(Control *p_overlay);
virtual void forward_force_draw_over_viewport(Control *p_overlay);
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index d4a97b7095..67700b59de 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -37,9 +37,9 @@
void EditorProfiler::_make_metric_ptrs(Metric &m) {
for (int i = 0; i < m.categories.size(); i++) {
- m.category_ptrs[m.categories[i].signature] = &m.categories[i];
+ m.category_ptrs[m.categories[i].signature] = &m.categories.write[i];
for (int j = 0; j < m.categories[i].items.size(); j++) {
- m.item_ptrs[m.categories[i].items[j].signature] = &m.categories[i].items[j];
+ m.item_ptrs[m.categories[i].items[j].signature] = &m.categories.write[i].items.write[j];
}
}
}
@@ -50,8 +50,8 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
if (last_metric >= frame_metrics.size())
last_metric = 0;
- frame_metrics[last_metric] = p_metric;
- _make_metric_ptrs(frame_metrics[last_metric]);
+ frame_metrics.write[last_metric] = p_metric;
+ _make_metric_ptrs(frame_metrics.write[last_metric]);
updating_frame = true;
cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number);
@@ -108,7 +108,7 @@ static String _get_percent_txt(float p_value, float p_total) {
return String::num((p_value / p_total) * 100, 1) + "%";
}
-String EditorProfiler::_get_time_as_text(Metric &m, float p_time, int p_calls) {
+String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_calls) {
int dmode = display_mode->get_selected();
@@ -192,18 +192,18 @@ void EditorProfiler::_update_plot() {
float highest = 0;
for (int i = 0; i < frame_metrics.size(); i++) {
- Metric &m = frame_metrics[i];
+ const Metric &m = frame_metrics[i];
if (!m.valid)
continue;
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
- Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+ const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
if (F) {
highest = MAX(F->get()->total_time, highest);
}
- Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+ const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
if (G) {
if (use_self) {
highest = MAX(G->get()->self, highest);
@@ -256,18 +256,18 @@ void EditorProfiler::_update_plot() {
}
//get
- Metric &m = frame_metrics[idx];
+ const Metric &m = frame_metrics[idx];
if (m.valid == false)
continue; //skip because invalid
float value = 0;
- Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+ const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
if (F) {
value = F->get()->total_time;
}
- Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+ const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
if (G) {
if (use_self) {
value = G->get()->self;
@@ -375,7 +375,7 @@ void EditorProfiler::_update_frame() {
variables->clear();
TreeItem *root = variables->create_item();
- Metric &m = frame_metrics[cursor_metric];
+ const Metric &m = frame_metrics[cursor_metric];
int dtime = display_time->get_selected();
@@ -394,7 +394,7 @@ void EditorProfiler::_update_frame() {
}
for (int j = 0; j < m.categories[i].items.size(); j++) {
- Metric::Category::Item &it = m.categories[i].items[j];
+ const Metric::Category::Item &it = m.categories[i].items[j];
TreeItem *item = variables->create_item(category);
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
diff --git a/editor/editor_profiler.h b/editor/editor_profiler.h
index cb451475e7..d445ad58aa 100644
--- a/editor/editor_profiler.h
+++ b/editor/editor_profiler.h
@@ -136,7 +136,7 @@ private:
void _activate_pressed();
void _clear_pressed();
- String _get_time_as_text(Metric &m, float p_time, int p_calls);
+ String _get_time_as_text(const Metric &m, float p_time, int p_calls);
void _make_metric_ptrs(Metric &m);
void _item_edited();
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 0b49b5a801..83a3662f21 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -258,6 +258,51 @@ EditorPropertyPath::EditorPropertyPath() {
global = false;
}
+///////////////////// CLASS NAME /////////////////////////
+
+void EditorPropertyClassName::setup(const String &p_base_type, const String &p_selected_type) {
+
+ base_type = p_base_type;
+ dialog->set_base_type(base_type);
+ selected_type = p_selected_type;
+ property->set_text(selected_type);
+}
+
+void EditorPropertyClassName::update_property() {
+
+ String s = get_edited_object()->get(get_edited_property());
+ property->set_text(s);
+ selected_type = s;
+}
+
+void EditorPropertyClassName::_property_selected() {
+ dialog->popup_create(true);
+}
+
+void EditorPropertyClassName::_dialog_created() {
+ selected_type = dialog->get_selected_type();
+ emit_signal("property_changed", get_edited_property(), selected_type);
+ update_property();
+}
+
+void EditorPropertyClassName::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_dialog_created"), &EditorPropertyClassName::_dialog_created);
+ ClassDB::bind_method(D_METHOD("_property_selected"), &EditorPropertyClassName::_property_selected);
+}
+
+EditorPropertyClassName::EditorPropertyClassName() {
+ property = memnew(Button);
+ property->set_clip_text(true);
+ add_child(property);
+ add_focusable(property);
+ property->set_text(selected_type);
+ property->connect("pressed", this, "_property_selected");
+ dialog = memnew(CreateDialog);
+ dialog->set_base_type(base_type);
+ dialog->connect("create", this, "_dialog_created");
+ add_child(dialog);
+}
+
///////////////////// MEMBER /////////////////////////
void EditorPropertyMember::_property_selected(const String &p_selected) {
@@ -523,6 +568,7 @@ public:
uint32_t value;
Vector<Rect2> flag_rects;
Vector<String> names;
+ Vector<String> tooltips;
virtual Size2 get_minimum_size() const {
Ref<Font> font = get_font("font", "Label");
@@ -531,8 +577,8 @@ public:
virtual String get_tooltip(const Point2 &p_pos) const {
for (int i = 0; i < flag_rects.size(); i++) {
- if (i < names.size() && flag_rects[i].has_point(p_pos)) {
- return names[i];
+ if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) {
+ return tooltips[i];
}
}
return String();
@@ -636,6 +682,7 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
}
Vector<String> names;
+ Vector<String> tooltips;
for (int i = 0; i < 20; i++) {
String name;
@@ -647,12 +694,12 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
name = TTR("Layer") + " " + itos(i + 1);
}
- name += "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i);
-
names.push_back(name);
+ tooltips.push_back(name + "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i));
}
grid->names = names;
+ grid->tooltips = tooltips;
}
void EditorPropertyLayers::_button_pressed() {
@@ -681,6 +728,7 @@ void EditorPropertyLayers::_menu_pressed(int p_menu) {
grid->value |= (1 << p_menu);
}
grid->update();
+ layers->set_item_checked(layers->get_item_index(p_menu), grid->value & (1 << p_menu));
_grid_changed(grid->value);
}
@@ -706,6 +754,7 @@ EditorPropertyLayers::EditorPropertyLayers() {
set_bottom_editor(hb);
layers = memnew(PopupMenu);
add_child(layers);
+ layers->set_hide_on_checkable_item_selection(false);
layers->connect("id_pressed", this, "_menu_pressed");
}
///////////////////// INT /////////////////////////
@@ -1020,18 +1069,35 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo
}
EditorPropertyVector2::EditorPropertyVector2() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[2] = { "x", "y" };
for (int i = 0; i < 2; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_flat(true);
spin[i]->set_label(desc[i]);
- vb->add_child(spin[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
@@ -1146,19 +1212,35 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo
}
EditorPropertyVector3::EditorPropertyVector3() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[3] = { "x", "y", "z" };
for (int i = 0; i < 3; i++) {
spin[i] = memnew(EditorSpinSlider);
- spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
-
- vb->add_child(spin[i]);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
///////////////////// PLANE /////////////////////////
@@ -1210,18 +1292,36 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool
}
EditorPropertyPlane::EditorPropertyPlane() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[4] = { "x", "y", "z", "d" };
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
- spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
- vb->add_child(spin[i]);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
@@ -1274,19 +1374,35 @@ void EditorPropertyQuat::setup(double p_min, double p_max, double p_step, bool p
}
EditorPropertyQuat::EditorPropertyQuat() {
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
+ bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector3_editing");
+
+ BoxContainer *bc;
+
+ if (horizontal) {
+ bc = memnew(HBoxContainer);
+ add_child(bc);
+ set_bottom_editor(bc);
+ } else {
+ bc = memnew(VBoxContainer);
+ add_child(bc);
+ }
+
static const char *desc[4] = { "x", "y", "z", "w" };
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
- spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
-
- vb->add_child(spin[i]);
+ spin[i]->set_label(desc[i]);
+ bc->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
+ if (horizontal) {
+ spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
+ }
+
+ if (!horizontal) {
+ set_label_reference(spin[0]); //show text and buttons around this
}
- set_label_reference(spin[0]); //show text and buttons around this
setting = false;
}
@@ -2607,6 +2723,10 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) {
EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText);
add_property_editor(p_path, editor);
+ } else if (p_hint == PROPERTY_HINT_TYPE_STRING) {
+ EditorPropertyClassName *editor = memnew(EditorPropertyClassName);
+ editor->setup("Object", p_hint_text);
+ add_property_editor(p_path, editor);
} else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
Vector<String> extensions = p_hint_text.split(",");
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 0afb1bf955..ccd73d2539 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -119,6 +119,25 @@ public:
EditorPropertyPath();
};
+class EditorPropertyClassName : public EditorProperty {
+ GDCLASS(EditorPropertyClassName, EditorProperty)
+private:
+ CreateDialog *dialog;
+ Button *property;
+ String selected_type;
+ String base_type;
+ void _property_selected();
+ void _dialog_created();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void setup(const String &p_base_type, const String &p_selected_type);
+ virtual void update_property();
+ EditorPropertyClassName();
+};
+
class EditorPropertyMember : public EditorProperty {
GDCLASS(EditorPropertyMember, EditorProperty)
public:
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index aa67ea03d7..a9eaad47b7 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -46,7 +46,7 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden");
ERR_FAIL_V(false);
}
-Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) {
+Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) const {
if (get_script_instance() && get_script_instance()->has_method("generate")) {
return get_script_instance()->call("generate", p_from);
@@ -55,7 +55,7 @@ Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from) {
ERR_FAIL_V(Ref<Texture>());
}
-Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) {
+Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path) const {
if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) {
return get_script_instance()->call("generate_from_path", p_path);
diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h
index e2276aa11d..74841b1a1e 100644
--- a/editor/editor_resource_preview.h
+++ b/editor/editor_resource_preview.h
@@ -63,8 +63,8 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
- virtual Ref<Texture> generate_from_path(const String &p_path);
+ virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path) const;
EditorResourcePreviewGenerator();
};
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index c8e97b071f..8e079b1f67 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -396,7 +396,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/cursor/block_caret", false);
_initial_set("text_editor/cursor/caret_blink", true);
- _initial_set("text_editor/cursor/caret_blink_speed", 0.65);
+ _initial_set("text_editor/cursor/caret_blink_speed", 0.5);
hints["text_editor/cursor/caret_blink_speed"] = PropertyInfo(Variant::REAL, "text_editor/cursor/caret_blink_speed", PROPERTY_HINT_RANGE, "0.1, 10, 0.01");
_initial_set("text_editor/cursor/right_click_moves_caret", true);
@@ -755,7 +755,7 @@ void EditorSettings::create() {
}
if (dir->change_dir(data_dir) != OK) {
- dir->make_dir(data_dir);
+ dir->make_dir_recursive(data_dir);
if (dir->change_dir(data_dir) != OK) {
ERR_PRINT("Cannot create data directory!");
memdelete(dir);
@@ -771,14 +771,8 @@ void EditorSettings::create() {
// Validate/create cache dir
- if (dir->change_dir(cache_path) != OK) {
- ERR_PRINT("Cannot find path for cache directory!");
- memdelete(dir);
- goto fail;
- }
-
if (dir->change_dir(cache_dir) != OK) {
- dir->make_dir(cache_dir);
+ dir->make_dir_recursive(cache_dir);
if (dir->change_dir(cache_dir) != OK) {
ERR_PRINT("Cannot create cache directory!");
memdelete(dir);
@@ -788,14 +782,8 @@ void EditorSettings::create() {
// Validate/create config dir and subdirectories
- if (dir->change_dir(config_path) != OK) {
- ERR_PRINT("Cannot find path for config directory!");
- memdelete(dir);
- goto fail;
- }
-
if (dir->change_dir(config_dir) != OK) {
- dir->make_dir(config_dir);
+ dir->make_dir_recursive(config_dir);
if (dir->change_dir(config_dir) != OK) {
ERR_PRINT("Cannot create config directory!");
memdelete(dir);
@@ -881,7 +869,7 @@ fail:
Vector<String> list = extra_config->get_value("init_projects", "list");
for (int i = 0; i < list.size(); i++) {
- list[i] = exe_path + "/" + list[i];
+ list.write[i] = exe_path + "/" + list[i];
};
extra_config->set_value("init_projects", "list", list);
};
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 0e6d81d13b..b2c9f9865a 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -30,7 +30,13 @@
#include "editor_spin_slider.h"
#include "editor_scale.h"
+#include "math/expression.h"
#include "os/input.h"
+
+String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
+ return rtos(get_value());
+}
+
String EditorSpinSlider::get_text_value() const {
int zeros = Math::step_decimals(get_step());
return String::num(get_value(), zeros);
@@ -270,10 +276,12 @@ void EditorSpinSlider::_notification(int p_what) {
if (p_what == NOTIFICATION_FOCUS_ENTER) {
/* Sorry, I dont like this, it makes navigating the different fields with arrows more difficult.
* Just press enter to edit.
- * if (!Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && !value_input_just_closed) {
+ * if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && !value_input_just_closed) {
_focus_entered();
}*/
-
+ if ((Input::get_singleton()->is_action_pressed("ui_focus_next") || Input::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) {
+ _focus_entered();
+ }
value_input_just_closed = false;
}
}
@@ -307,6 +315,21 @@ String EditorSpinSlider::get_label() const {
return label;
}
+void EditorSpinSlider::_evaluate_input_text() {
+ String text = value_input->get_text();
+ Ref<Expression> expr;
+ expr.instance();
+ Error err = expr->parse(text);
+ if (err != OK) {
+ return;
+ }
+
+ Variant v = expr->execute(Array(), NULL, false);
+ if (v.get_type() == Variant::NIL)
+ return;
+ set_value(v);
+}
+
//text_entered signal
void EditorSpinSlider::_value_input_entered(const String &p_text) {
value_input_just_closed = true;
@@ -315,13 +338,13 @@ void EditorSpinSlider::_value_input_entered(const String &p_text) {
//modal_closed signal
void EditorSpinSlider::_value_input_closed() {
- set_value(value_input->get_text().to_double());
+ _evaluate_input_text();
value_input_just_closed = true;
}
//focus_exited signal
void EditorSpinSlider::_value_focus_exited() {
- set_value(value_input->get_text().to_double());
+ _evaluate_input_text();
// focus is not on the same element after the vlalue_input was exited
// -> focus is on next element
// -> TAB was pressed
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index fb32534ef4..e48eb171b8 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -73,6 +73,8 @@ class EditorSpinSlider : public Range {
bool use_custom_label_color;
Color custom_label_color;
+ void _evaluate_input_text();
+
protected:
void _notification(int p_what);
void _gui_input(const Ref<InputEvent> &p_event);
@@ -82,6 +84,8 @@ protected:
void _focus_entered();
public:
+ String get_tooltip(const Point2 &p_pos) const;
+
String get_text_value() const;
void set_label(const String &p_label);
String get_label() const;
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 18cc52a5c6..3995eb3dd6 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -175,7 +175,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
const Color warning_color = p_theme->get_color("warning_color", "Editor");
dark_icon_color_dictionary[Color::html("#ff5d5d")] = error_color;
dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color;
- dark_icon_color_dictionary[Color::html("#ffdd65")] = warning_color;
+ dark_icon_color_dictionary[Color::html("#dbab09")] = warning_color;
List<String> exceptions;
exceptions.push_back("EditorPivot");
@@ -365,11 +365,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("mono_color", "Editor", mono_color);
Color success_color = accent_color.linear_interpolate(Color(0.2, 1, 0.2), 0.6) * 1.2;
- Color warning_color = accent_color.linear_interpolate(Color(1, 1, 0), 0.7) * 1.2;
+ Color warning_color = accent_color.linear_interpolate(Color(1, 1, 0), 0.7) * 1.0;
Color error_color = accent_color.linear_interpolate(Color(1, 0, 0), 0.8) * 1.7;
+ Color property_color = font_color.linear_interpolate(Color(0.5, 0.5, 0.5), 0.5);
+
if (!dark_theme) {
// yellow on white themes is a P.I.T.A.
- warning_color = accent_color.linear_interpolate(Color(1, 0.8, 0), 0.9);
+ warning_color = accent_color.linear_interpolate(Color(0.9, 0.7, 0), 0.9);
warning_color = warning_color.linear_interpolate(mono_color, 0.2);
success_color = success_color.linear_interpolate(mono_color, 0.2);
error_color = error_color.linear_interpolate(mono_color, 0.2);
@@ -377,6 +379,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("success_color", "Editor", success_color);
theme->set_color("warning_color", "Editor", warning_color);
theme->set_color("error_color", "Editor", error_color);
+ theme->set_color("property_color", "Editor", property_color);
// 2d grid color
const Color grid_minor_color = mono_color * Color(1.0, 1.0, 1.0, 0.07);
@@ -825,6 +828,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color", "LineEdit", font_color);
theme->set_color("cursor_color", "LineEdit", font_color);
theme->set_color("selection_color", "LineEdit", font_color_selection);
+ theme->set_color("clear_button_color", "LineEdit", font_color);
+ theme->set_color("clear_button_color_pressed", "LineEdit", accent_color);
// TextEdit
theme->set_stylebox("normal", "TextEdit", style_widget);
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index 931785333f..6c9d1568fa 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -178,7 +178,7 @@ void ExportTemplateManager::_uninstall_template_confirm() {
_update_template_list();
}
-void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_progress) {
+bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_progress) {
FileAccess *fa = NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&fa);
@@ -187,7 +187,7 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
if (!pkg) {
EditorNode::get_singleton()->show_warning(TTR("Can't open export templates zip."));
- return;
+ return false;
}
int ret = unzGoToFirstFile(pkg);
@@ -221,7 +221,7 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
if (data_str.get_slice_count(".") < 3) {
EditorNode::get_singleton()->show_warning(vformat(TTR("Invalid version.txt format inside templates: %s."), data_str));
unzClose(pkg);
- return;
+ return false;
}
version = data_str;
@@ -237,7 +237,7 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
if (version == String()) {
EditorNode::get_singleton()->show_warning(TTR("No version.txt found inside templates."));
unzClose(pkg);
- return;
+ return false;
}
String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version);
@@ -247,7 +247,7 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
if (err != OK) {
EditorNode::get_singleton()->show_warning(TTR("Error creating path for templates:") + "\n" + template_path);
unzClose(pkg);
- return;
+ return false;
}
memdelete(d);
@@ -310,6 +310,8 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
unzClose(pkg);
_update_template_list();
+
+ return true;
}
void ExportTemplateManager::popup_manager() {
@@ -401,7 +403,15 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int
String path = download_templates->get_download_file();
template_list_state->set_text(TTR("Download Complete."));
template_downloader->hide();
- _install_from_file(path, false);
+ int ret = _install_from_file(path, false);
+ if (ret) {
+ Error err = OS::get_singleton()->move_to_trash(path);
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + path + "\n");
+ }
+ } else {
+ WARN_PRINTS(vformat(TTR("Templates installation failed. The problematic templates archives can be found at '%s'."), path));
+ }
}
} break;
}
diff --git a/editor/export_template_manager.h b/editor/export_template_manager.h
index 54a645c69f..bd43fe5dc5 100644
--- a/editor/export_template_manager.h
+++ b/editor/export_template_manager.h
@@ -70,7 +70,7 @@ class ExportTemplateManager : public ConfirmationDialog {
void _uninstall_template_confirm();
virtual void ok_pressed();
- void _install_from_file(const String &p_file, bool p_use_progress = true);
+ bool _install_from_file(const String &p_file, bool p_use_progress = true);
void _http_download_mirror_completed(int p_status, int p_code, const PoolStringArray &headers, const PoolByteArray &p_data);
void _http_download_templates_completed(int p_status, int p_code, const PoolStringArray &headers, const PoolByteArray &p_data);
diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp
index a218070933..b9e0c7d0fa 100644
--- a/editor/fileserver/editor_file_server.cpp
+++ b/editor/fileserver/editor_file_server.cpp
@@ -78,7 +78,7 @@ void EditorFileServer::_subthread_start(void *s) {
_close_client(cd);
ERR_FAIL_COND(err != OK);
}
- passutf8[passlen] = 0;
+ passutf8.write[passlen] = 0;
String s;
s.parse_utf8(passutf8.ptr());
if (s != cd->efs->password) {
@@ -145,7 +145,7 @@ void EditorFileServer::_subthread_start(void *s) {
_close_client(cd);
ERR_FAIL_COND(err != OK);
}
- fileutf8[namelen] = 0;
+ fileutf8.write[namelen] = 0;
String s;
s.parse_utf8(fileutf8.ptr());
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 37f86cc912..f2c8cde151 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -196,7 +196,8 @@ void FileSystemDock::_notification(int p_what) {
files->connect("item_activated", this, "_select_file");
button_hist_next->connect("pressed", this, "_fw_history");
button_hist_prev->connect("pressed", this, "_bw_history");
- search_box->add_icon_override("right_icon", get_icon("Search", ei));
+ search_box->set_right_icon(get_icon("Search", ei));
+ search_box->set_clear_button_enabled(true);
button_hist_next->set_icon(get_icon("Forward", ei));
button_hist_prev->set_icon(get_icon("Back", ei));
@@ -252,7 +253,8 @@ void FileSystemDock::_notification(int p_what) {
button_hist_next->set_icon(get_icon("Forward", ei));
button_hist_prev->set_icon(get_icon("Back", ei));
- search_box->add_icon_override("right_icon", get_icon("Search", ei));
+ search_box->set_right_icon(get_icon("Search", ei));
+ search_box->set_clear_button_enabled(true);
if (new_mode != display_mode) {
set_display_mode(new_mode);
@@ -1408,7 +1410,7 @@ void FileSystemDock::_resource_created() const {
RES current_res = RES(r);
- editor->save_resource_as(current_res);
+ editor->save_resource_as(current_res, path);
}
void FileSystemDock::_go_to_file_list() {
@@ -1448,7 +1450,7 @@ void FileSystemDock::_dir_rmb_pressed(const Vector2 &p_pos) {
}
folder_options->add_separator();
folder_options->add_item(TTR("New Folder..."), FOLDER_NEW_FOLDER);
- folder_options->add_item(TTR("Show In File Manager"), FOLDER_SHOW_IN_EXPLORER);
+ folder_options->add_item(TTR("Open In File Manager"), FOLDER_SHOW_IN_EXPLORER);
}
folder_options->set_position(tree->get_global_position() + p_pos);
folder_options->popup();
@@ -1757,7 +1759,10 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
file_options->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
file_options->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
file_options->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
- file_options->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER);
+
+ String fpath = files->get_item_metadata(p_item);
+ String item_text = fpath.ends_with("/") ? TTR("Open In File Manager") : TTR("Show In File Manager");
+ file_options->add_item(item_text, FILE_SHOW_IN_EXPLORER);
file_options->set_position(files->get_global_position() + p_pos);
file_options->popup();
@@ -1983,9 +1988,11 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
*/
file_options = memnew(PopupMenu);
+ file_options->set_hide_on_window_lose_focus(true);
add_child(file_options);
folder_options = memnew(PopupMenu);
+ folder_options->set_hide_on_window_lose_focus(true);
add_child(folder_options);
split_box = memnew(VSplitContainer);
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 004a49e2b4..2be1f1644e 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -143,7 +143,7 @@ void FindInFiles::_iterate() {
// Scan folders first so we can build a list of files and have progress info later
- PoolStringArray &folders_to_scan = _folders_stack[_folders_stack.size() - 1];
+ PoolStringArray &folders_to_scan = _folders_stack.write[_folders_stack.size() - 1];
if (folders_to_scan.size() != 0) {
// Scan one folder below
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 2bfd2eb5c3..0efd14e932 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -287,8 +287,10 @@ void GroupDialog::_notification(int p_what) {
add_button->set_icon(get_icon("Forward", "EditorIcons"));
remove_button->set_icon(get_icon("Back", "EditorIcons"));
- add_filter->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
- remove_filter->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ add_filter->set_right_icon(get_icon("Search", "EditorIcons"));
+ add_filter->set_clear_button_enabled(true);
+ remove_filter->set_right_icon(get_icon("Search", "EditorIcons"));
+ remove_filter->set_clear_button_enabled(true);
} break;
}
}
diff --git a/editor/icons/SCsub b/editor/icons/SCsub
index 7f94073e01..31bf8f116a 100644
--- a/editor/icons/SCsub
+++ b/editor/icons/SCsub
@@ -1,96 +1,14 @@
#!/usr/bin/env python
Import('env')
-from compat import StringIO
+from platform_methods import run_in_subprocess
+import editor_icons_builders
-def make_editor_icons_action(target, source, env):
- import os
-
- dst = target[0].srcnode().abspath
- svg_icons = source
-
- icons_string = StringIO()
-
- for f in svg_icons:
-
- fname = str(f)
-
- icons_string.write('\t"')
-
- with open(fname, 'rb') as svgf:
- b = svgf.read(1)
- while(len(b) == 1):
- icons_string.write("\\" + str(hex(ord(b)))[1:])
- b = svgf.read(1)
-
-
- icons_string.write('"')
- if fname != svg_icons[-1]:
- icons_string.write(",")
- icons_string.write('\n')
-
- s = StringIO()
- s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
- s.write("#ifndef _EDITOR_ICONS_H\n")
- s.write("#define _EDITOR_ICONS_H\n")
- s.write("static const int editor_icons_count = {};\n".format(len(svg_icons)))
- s.write("static const char *editor_icons_sources[] = {\n")
- s.write(icons_string.getvalue())
- s.write('};\n\n')
- s.write("static const char *editor_icons_names[] = {\n")
-
- # this is used to store the indices of thumbnail icons
- thumb_medium_indices = [];
- thumb_big_indices = [];
- index = 0
- for f in svg_icons:
-
- fname = str(f)
-
- icon_name = os.path.basename(fname)[5:-4].title().replace("_", "")
- # some special cases
- if icon_name in ['Int', 'Bool', 'Float']:
- icon_name = icon_name.lower()
- if icon_name.endswith("MediumThumb"): # don't know a better way to handle this
- thumb_medium_indices.append(str(index))
- if icon_name.endswith("BigThumb"): # don't know a better way to handle this
- thumb_big_indices.append(str(index))
-
- s.write('\t"{0}"'.format(icon_name))
-
- if fname != svg_icons[-1]:
- s.write(",")
- s.write('\n')
-
- index += 1
-
- s.write('};\n')
-
- if thumb_medium_indices:
- s.write("\n\n")
- s.write("static const int editor_md_thumbs_count = {};\n".format(len(thumb_medium_indices)))
- s.write("static const int editor_md_thumbs_indices[] = {")
- s.write(", ".join(thumb_medium_indices))
- s.write("};\n")
- if thumb_big_indices:
- s.write("\n\n")
- s.write("static const int editor_bg_thumbs_count = {};\n".format(len(thumb_big_indices)))
- s.write("static const int editor_bg_thumbs_indices[] = {")
- s.write(", ".join(thumb_big_indices))
- s.write("};\n")
-
- s.write("#endif\n")
-
- with open(dst, "w") as f:
- f.write(s.getvalue())
-
- s.close()
- icons_string.close()
-
-make_editor_icons_builder = Builder(action=make_editor_icons_action,
+make_editor_icons_builder = Builder(action=run_in_subprocess(editor_icons_builders.make_editor_icons_action),
suffix='.h',
src_suffix='.svg')
+
env['BUILDERS']['MakeEditorIconsBuilder'] = make_editor_icons_builder
env.Alias('editor_icons', [env.MakeEditorIconsBuilder('#editor/editor_icons.gen.h', Glob("*.svg"))])
diff --git a/editor/icons/editor_icons_builders.py b/editor/icons/editor_icons_builders.py
new file mode 100644
index 0000000000..dfd0802ce9
--- /dev/null
+++ b/editor/icons/editor_icons_builders.py
@@ -0,0 +1,96 @@
+"""Functions used to generate source files during build time
+
+All such functions are invoked in a subprocess on Windows to prevent build flakiness.
+
+"""
+import os
+from platform_methods import subprocess_main
+from compat import StringIO
+
+
+def make_editor_icons_action(target, source, env):
+
+ dst = target[0]
+ svg_icons = source
+
+ icons_string = StringIO()
+
+ for f in svg_icons:
+
+ fname = str(f)
+
+ icons_string.write('\t"')
+
+ with open(fname, 'rb') as svgf:
+ b = svgf.read(1)
+ while(len(b) == 1):
+ icons_string.write("\\" + str(hex(ord(b)))[1:])
+ b = svgf.read(1)
+
+
+ icons_string.write('"')
+ if fname != svg_icons[-1]:
+ icons_string.write(",")
+ icons_string.write('\n')
+
+ s = StringIO()
+ s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ s.write("#ifndef _EDITOR_ICONS_H\n")
+ s.write("#define _EDITOR_ICONS_H\n")
+ s.write("static const int editor_icons_count = {};\n".format(len(svg_icons)))
+ s.write("static const char *editor_icons_sources[] = {\n")
+ s.write(icons_string.getvalue())
+ s.write('};\n\n')
+ s.write("static const char *editor_icons_names[] = {\n")
+
+ # this is used to store the indices of thumbnail icons
+ thumb_medium_indices = [];
+ thumb_big_indices = [];
+ index = 0
+ for f in svg_icons:
+
+ fname = str(f)
+
+ icon_name = os.path.basename(fname)[5:-4].title().replace("_", "")
+ # some special cases
+ if icon_name in ['Int', 'Bool', 'Float']:
+ icon_name = icon_name.lower()
+ if icon_name.endswith("MediumThumb"): # don't know a better way to handle this
+ thumb_medium_indices.append(str(index))
+ if icon_name.endswith("BigThumb"): # don't know a better way to handle this
+ thumb_big_indices.append(str(index))
+
+ s.write('\t"{0}"'.format(icon_name))
+
+ if fname != svg_icons[-1]:
+ s.write(",")
+ s.write('\n')
+
+ index += 1
+
+ s.write('};\n')
+
+ if thumb_medium_indices:
+ s.write("\n\n")
+ s.write("static const int editor_md_thumbs_count = {};\n".format(len(thumb_medium_indices)))
+ s.write("static const int editor_md_thumbs_indices[] = {")
+ s.write(", ".join(thumb_medium_indices))
+ s.write("};\n")
+ if thumb_big_indices:
+ s.write("\n\n")
+ s.write("static const int editor_bg_thumbs_count = {};\n".format(len(thumb_big_indices)))
+ s.write("static const int editor_bg_thumbs_indices[] = {")
+ s.write(", ".join(thumb_big_indices))
+ s.write("};\n")
+
+ s.write("#endif\n")
+
+ with open(dst, "w") as f:
+ f.write(s.getvalue())
+
+ s.close()
+ icons_string.close()
+
+
+if __name__ == '__main__':
+ subprocess_main(globals())
diff --git a/editor/icons/icon_add_atlas_tile.svg b/editor/icons/icon_add_atlas_tile.svg
new file mode 100644
index 0000000000..912a0ce2c9
--- /dev/null
+++ b/editor/icons/icon_add_atlas_tile.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6h-2z" fill="#c9cfd4"/>
+</svg>
diff --git a/editor/icons/icon_add_autotile.svg b/editor/icons/icon_add_autotile.svg
new file mode 100644
index 0000000000..2cc34d53b1
--- /dev/null
+++ b/editor/icons/icon_add_autotile.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6h-2z" fill="#4490fc"/>
+</svg>
diff --git a/editor/icons/icon_add_single_tile.svg b/editor/icons/icon_add_single_tile.svg
new file mode 100644
index 0000000000..01af8e0649
--- /dev/null
+++ b/editor/icons/icon_add_single_tile.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6h-2z" fill="#fce844"/>
+</svg>
diff --git a/editor/icons/icon_information_sign.svg b/editor/icons/icon_information_sign.svg
new file mode 100644
index 0000000000..95002b6948
--- /dev/null
+++ b/editor/icons/icon_information_sign.svg
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg8"
+ sodipodi:docname="icon_information_sign.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata14">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs12" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1047"
+ inkscape:window-height="603"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="14.521571"
+ inkscape:cx="12.730205"
+ inkscape:cy="8.6526495"
+ inkscape:window-x="654"
+ inkscape:window-y="156"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg8" />
+ <path
+ style="fill:#ffb65d;fill-opacity:1;fill-rule:evenodd;stroke-width:0.57024062"
+ inkscape:connector-curvature="0"
+ id="path2"
+ d="m 4.5291945,14.892249 h 6.8428865 l 3.421444,-3.421444 V 4.6279186 L 11.372081,1.2064749 H 4.5291945 L 1.1077509,4.6279186 v 6.8428864 z" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.57024062"
+ id="rect829"
+ width="2.6243541"
+ height="6.5062103"
+ x="6.6998501"
+ y="6.3477535" />
+ <ellipse
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.57024062"
+ id="path831"
+ cx="8.0393629"
+ cy="4.2154655"
+ rx="1.3941878"
+ ry="1.3668507" />
+</svg>
diff --git a/editor/icons/icon_texture_3_d.svg b/editor/icons/icon_texture_3_d.svg
new file mode 100644
index 0000000000..dafdc8c68d
--- /dev/null
+++ b/editor/icons/icon_texture_3_d.svg
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg6"
+ sodipodi:docname="icon_texture_3_d.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1853"
+ inkscape:window-height="1016"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="29.5"
+ inkscape:cx="15.226978"
+ inkscape:cy="9.4909723"
+ inkscape:window-x="67"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg6" />
+ <g
+ id="g830"
+ transform="translate(0.35954582,-0.28763666)">
+ <path
+ d="M 2,1 C 1.4477153,1 1,1.4477153 1,2 v 12 c 0,0.552285 0.4477153,1 1,1 h 12 c 0.552285,0 1,-0.447715 1,-1 V 2 C 15,1.4477153 14.552285,1 14,1 Z m 1,2 h 10 v 8 H 3 Z"
+ id="path2"
+ inkscape:connector-curvature="0"
+ style="fill:#e0e0e0;fill-opacity:0.99607999"
+ sodipodi:nodetypes="sssssssssccccc" />
+ </g>
+ <g
+ aria-label="3D"
+ transform="scale(0.9167105,1.0908569)"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.12847996px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:0.20321201"
+ id="text834">
+ <path
+ d="m 5.8175194,8.9717502 q -0.2194689,0 -0.4633233,-0.032514 Q 5.1103417,8.9148508 4.8827442,8.86608 4.6551468,8.8173091 4.4681918,8.7604097 4.2812367,8.7035104 4.1755665,8.6547395 L 4.4112924,7.646808 q 0.2113405,0.089413 0.5364797,0.1950835 0.3332677,0.097542 0.8209765,0.097542 0.5608651,0 0.8209764,-0.2113404 0.2601114,-0.2113405 0.2601114,-0.5689936 0,-0.219469 -0.097542,-0.3657816 Q 6.6628814,6.6388764 6.5003118,6.5494632 6.3377422,6.4519214 6.1101447,6.4194075 5.8906758,6.3787651 5.6386929,6.3787651 H 5.167241 V 5.4033475 h 0.5364797 q 0.1788266,0 0.3413962,-0.032514 0.1706981,-0.032514 0.3007537,-0.1056703 0.1300557,-0.081285 0.203212,-0.2113404 0.081285,-0.1381842 0.081285,-0.3413962 0,-0.1544411 -0.065028,-0.2682398 Q 6.5003118,4.3303881 6.3946415,4.2572318 6.2970998,4.1840755 6.1589156,4.1515616 6.0288599,4.1109192 5.8906758,4.1109192 q -0.3495247,0 -0.6502784,0.1056702 Q 4.9477721,4.3222597 4.7039177,4.4767008 L 4.2731082,3.5906965 Q 4.4031639,3.5094117 4.573862,3.4199984 4.7526886,3.3305851 4.964029,3.2574288 5.1753695,3.1842725 5.4110954,3.1355016 q 0.2438544,-0.048771 0.5120943,-0.048771 0.4958373,0 0.8534904,0.1219272 0.3657816,0.1137987 0.6015075,0.3332677 0.2357259,0.2113405 0.3495246,0.5039657 0.1137987,0.2844968 0.1137987,0.625893 0,0.3332677 -0.186955,0.6502784 -0.186955,0.3088822 -0.5039657,0.4714518 0.4389379,0.1788266 0.6746638,0.5364797 0.2438544,0.3495246 0.2438544,0.8453619 0,0.3901671 -0.1300557,0.7234347 Q 7.808997,8.22393 7.5326287,8.4677844 7.2562604,8.7035104 6.825451,8.8416945 6.40277,8.9717502 5.8175194,8.9717502 Z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.20321201"
+ id="path836" />
+ <path
+ d="m 10.502445,7.817506 q 0.08941,0.00813 0.203212,0.016257 0.121927,0 0.284497,0 0.951032,0 1.406227,-0.4795803 0.463323,-0.4795803 0.463323,-1.3249422 0,-0.8860044 -0.438938,-1.3411992 -0.438938,-0.4551949 -1.38997,-0.4551949 -0.130055,0 -0.26824,0.00813 -0.138184,0 -0.260111,0.016257 z M 14.16839,6.0292405 q 0,0.7315631 -0.227598,1.2761713 -0.227597,0.5446082 -0.650278,0.9022613 -0.414553,0.3576531 -1.01606,0.5364797 -0.601508,0.1788265 -1.349328,0.1788265 -0.341396,0 -0.796591,-0.032514 Q 9.6733402,8.86608 9.2344022,8.7766667 v -5.486724 q 0.438938,-0.081285 0.9103898,-0.1056702 0.47958,-0.032514 0.820976,-0.032514 0.723435,0 1.308686,0.1625696 0.593379,0.1625696 1.01606,0.5120943 0.422681,0.3495246 0.650278,0.8941328 0.227598,0.5446081 0.227598,1.3086853 z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.20321201"
+ id="path838" />
+ </g>
+</svg>
diff --git a/editor/icons/icon_texture_array.svg b/editor/icons/icon_texture_array.svg
new file mode 100644
index 0000000000..8297fc0f5d
--- /dev/null
+++ b/editor/icons/icon_texture_array.svg
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg6"
+ sodipodi:docname="icon_texture_array.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1526"
+ inkscape:window-height="766"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="29.5"
+ inkscape:cx="8.3117238"
+ inkscape:cy="9.4909723"
+ inkscape:window-x="67"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg6" />
+ <g
+ id="g830"
+ transform="translate(0.35954582,-0.28763666)">
+ <path
+ d="M 2,1 C 1.4477153,1 1,1.4477153 1,2 v 12 c 0,0.552285 0.4477153,1 1,1 h 12 c 0.552285,0 1,-0.447715 1,-1 V 2 C 15,1.4477153 14.552285,1 14,1 Z m 1,2 h 10 v 8 H 3 Z"
+ id="path2"
+ inkscape:connector-curvature="0"
+ style="fill:#e0e0e0;fill-opacity:0.99607999"
+ sodipodi:nodetypes="sssssssssccccc" />
+ </g>
+ <g
+ aria-label="[]"
+ transform="matrix(1.6197742,0,0,0.750929,-3.7231532,1.8329569)"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.29580784px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:0.2073952"
+ id="text834">
+ <path
+ d="M 4.7302951,2.4553483 H 6.978459 V 3.4425495 H 5.9082998 V 9.4984892 H 6.978459 V 10.48569 H 4.7302951 Z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.2073952"
+ id="path862"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 10.138643,10.48569 H 7.8904794 V 9.4984892 H 8.9606386 V 3.4425495 H 7.8904794 V 2.4553483 h 2.2481636 z"
+ style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.2073952"
+ id="path864"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index a13f741ee7..22ea5883e8 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -579,12 +579,12 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
.normalized();
}
- tangents[index_arrayr[idx * 3 + 0]] += tangent;
- binormals[index_arrayr[idx * 3 + 0]] += binormal;
- tangents[index_arrayr[idx * 3 + 1]] += tangent;
- binormals[index_arrayr[idx * 3 + 1]] += binormal;
- tangents[index_arrayr[idx * 3 + 2]] += tangent;
- binormals[index_arrayr[idx * 3 + 2]] += binormal;
+ tangents.write[index_arrayr[idx * 3 + 0]] += tangent;
+ binormals.write[index_arrayr[idx * 3 + 0]] += binormal;
+ tangents.write[index_arrayr[idx * 3 + 1]] += tangent;
+ binormals.write[index_arrayr[idx * 3 + 1]] += binormal;
+ tangents.write[index_arrayr[idx * 3 + 2]] += tangent;
+ binormals.write[index_arrayr[idx * 3 + 2]] += binormal;
//print_line(itos(idx)+" tangent: "+tangent);
//print_line(itos(idx)+" binormal: "+binormal);
@@ -800,7 +800,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
total += weights[i].weight;
if (total)
for (int i = 0; i < weights.size(); i++)
- weights[i].weight /= total;
+ weights.write[i].weight /= total;
if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0
//no weights assigned
@@ -987,7 +987,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
vertex_array.resize(vertex_set.size());
for (Set<Collada::Vertex>::Element *F = vertex_set.front(); F; F = F->next()) {
- vertex_array[F->get().idx] = F->get();
+ vertex_array.write[F->get().idx] = F->get();
}
if (has_weights) {
@@ -996,9 +996,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
Transform local_xform = p_local_xform;
for (int i = 0; i < vertex_array.size(); i++) {
- vertex_array[i].vertex = local_xform.xform(vertex_array[i].vertex);
- vertex_array[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
- vertex_array[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
+ vertex_array.write[i].vertex = local_xform.xform(vertex_array[i].vertex);
+ vertex_array.write[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
+ vertex_array.write[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
if (local_xform_mirror) {
//i shouldn't do this? wtf?
//vertex_array[i].normal*=-1.0;
@@ -1061,13 +1061,13 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
//float sum=0.0;
for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
if (l < vertex_array[k].weights.size()) {
- weights[l] = vertex_array[k].weights[l].weight;
- bones[l] = vertex_array[k].weights[l].bone_idx;
+ weights.write[l] = vertex_array[k].weights[l].weight;
+ bones.write[l] = vertex_array[k].weights[l].bone_idx;
//sum += vertex_array[k].weights[l].weight;
} else {
- weights[l] = 0;
- bones[l] = 0;
+ weights.write[l] = 0;
+ bones.write[l] = 0;
}
}
@@ -1286,7 +1286,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
String str = joint_src->sarray[i];
ERR_FAIL_COND_V(!bone_remap_map.has(str), ERR_INVALID_DATA);
- bone_remap[i] = bone_remap_map[str];
+ bone_remap.write[i] = bone_remap_map[str];
}
}
@@ -1506,7 +1506,7 @@ void ColladaImport::_fix_param_animation_tracks() {
const Vector<int> &rt = collada.state.referenced_tracks[track_name];
for (int rti = 0; rti < rt.size(); rti++) {
- Collada::AnimationTrack *at = &collada.state.animation_tracks[rt[rti]];
+ Collada::AnimationTrack *at = &collada.state.animation_tracks.write[rt[rti]];
at->target = E->key();
at->param = "morph/" + collada.state.mesh_name_map[mesh_name];
@@ -1540,7 +1540,7 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_im
for (int i = 0; i < collada.state.animation_tracks.size(); i++) {
- Collada::AnimationTrack &at = collada.state.animation_tracks[i];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[i];
//print_line("CHANNEL: "+at.target+" PARAM: "+at.param);
String node;
@@ -1698,7 +1698,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
if (nm.anim_tracks.size() == 1) {
//use snapshot keys from anim track instead, because this was most likely exported baked
- Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
snapshots.clear();
for (int i = 0; i < at.keys.size(); i++)
snapshots.push_back(at.keys[i].time);
@@ -1723,7 +1723,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
found_anim = true;
- Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
int xform_idx = -1;
for (int j = 0; j < cn->xform_list.size(); j++) {
@@ -1745,18 +1745,18 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Vector<float> data = at.get_value_at_time(snapshots[i]);
ERR_CONTINUE(data.empty());
- Collada::Node::XForm &xf = cn->xform_list[xform_idx];
+ Collada::Node::XForm &xf = cn->xform_list.write[xform_idx];
if (at.component == "ANGLE") {
ERR_CONTINUE(data.size() != 1);
ERR_CONTINUE(xf.op != Collada::Node::XForm::OP_ROTATE);
ERR_CONTINUE(xf.data.size() < 4);
- xf.data[3] = data[0];
+ xf.data.write[3] = data[0];
} else if (at.component == "X" || at.component == "Y" || at.component == "Z") {
int cn = at.component[0] - 'X';
ERR_CONTINUE(cn >= xf.data.size());
ERR_CONTINUE(data.size() > 1);
- xf.data[cn] = data[0];
+ xf.data.write[cn] = data[0];
} else if (data.size() == xf.data.size()) {
xf.data = data;
@@ -1862,7 +1862,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
continue;
}
- Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
+ const Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
// take snapshots
if (!collada.state.scene_map.has(at.target))
@@ -1965,7 +1965,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
if (p_flags & IMPORT_ANIMATION_DETECT_LOOP) {
if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
- state.animations[i]->set_loop(true);
+ state.animations.write[i]->set_loop(true);
}
}
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index f2f4328cd2..906d902b4a 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -203,7 +203,6 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
GLTFNode *node = memnew(GLTFNode);
Dictionary n = nodes[i];
- print_line("node " + itos(i) + ": " + String(Variant(n)));
if (n.has("name")) {
node->name = n["name"];
}
@@ -651,7 +650,7 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
} else {
//fill with zeros, as bufferview is not defined.
for (int i = 0; i < (a.count * component_count); i++) {
- dst_buffer[i] = 0;
+ dst_buffer.write[i] = 0;
}
}
@@ -794,7 +793,7 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state,
ret.resize(ret_size);
{
for (int i = 0; i < ret_size; i++) {
- ret[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
+ ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]);
}
}
return ret;
@@ -808,8 +807,8 @@ Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFSta
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
ret.resize(attribs.size() / 4);
for (int i = 0; i < ret.size(); i++) {
- ret[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
- ret[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
+ ret.write[i][0] = Vector2(attribs[i * 4 + 0], attribs[i * 4 + 1]);
+ ret.write[i][1] = Vector2(attribs[i * 4 + 2], attribs[i * 4 + 3]);
}
return ret;
}
@@ -823,9 +822,9 @@ Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &stat
ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
ret.resize(attribs.size() / 9);
for (int i = 0; i < ret.size(); i++) {
- ret[i].set_axis(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
- ret[i].set_axis(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
- ret[i].set_axis(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
+ ret.write[i].set_axis(0, Vector3(attribs[i * 9 + 0], attribs[i * 9 + 1], attribs[i * 9 + 2]));
+ ret.write[i].set_axis(1, Vector3(attribs[i * 9 + 3], attribs[i * 9 + 4], attribs[i * 9 + 5]));
+ ret.write[i].set_axis(2, Vector3(attribs[i * 9 + 6], attribs[i * 9 + 7], attribs[i * 9 + 8]));
}
return ret;
}
@@ -838,10 +837,10 @@ Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &
ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
ret.resize(attribs.size() / 16);
for (int i = 0; i < ret.size(); i++) {
- ret[i].basis.set_axis(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
- ret[i].basis.set_axis(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
- ret[i].basis.set_axis(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
- ret[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
+ ret.write[i].basis.set_axis(0, Vector3(attribs[i * 16 + 0], attribs[i * 16 + 1], attribs[i * 16 + 2]));
+ ret.write[i].basis.set_axis(1, Vector3(attribs[i * 16 + 4], attribs[i * 16 + 5], attribs[i * 16 + 6]));
+ ret.write[i].basis.set_axis(2, Vector3(attribs[i * 16 + 8], attribs[i * 16 + 9], attribs[i * 16 + 10]));
+ ret.write[i].set_origin(Vector3(attribs[i * 16 + 12], attribs[i * 16 + 13], attribs[i * 16 + 14]));
}
return ret;
}
@@ -1085,7 +1084,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
ERR_FAIL_COND_V(mesh.mesh->get_blend_shape_count() != weights.size(), ERR_PARSE_ERROR);
mesh.blend_weights.resize(weights.size());
for (int j = 0; j < weights.size(); j++) {
- mesh.blend_weights[j] = weights[j];
+ mesh.blend_weights.write[j] = weights[j];
}
}
@@ -1139,7 +1138,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
ERR_FAIL_INDEX_V(bvi, state.buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
- GLTFBufferView &bv = state.buffer_views[bvi];
+ const GLTFBufferView &bv = state.buffer_views[bvi];
int bi = bv.buffer;
ERR_FAIL_INDEX_V(bi, state.buffers.size(), ERR_PARAMETER_RANGE_ERROR);
@@ -1596,7 +1595,7 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
PoolVector<float> weights = _decode_accessor_as_floats(state, output, false);
ERR_FAIL_INDEX_V(state.nodes[node]->mesh, state.meshes.size(), ERR_PARSE_ERROR);
- GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
+ const GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
ERR_FAIL_COND_V(mesh->blend_weights.size() == 0, ERR_PARSE_ERROR);
int wc = mesh->blend_weights.size();
@@ -1611,11 +1610,11 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
Vector<float> wdata;
wdata.resize(wlen);
for (int l = 0; l < wlen; l++) {
- wdata[l] = r[l * wc + k];
+ wdata.write[l] = r[l * wc + k];
}
cf.values = wdata;
- track->weight_tracks[k] = cf;
+ track->weight_tracks.write[k] = cf;
}
} else {
WARN_PRINTS("Invalid path: " + path);
@@ -1657,7 +1656,8 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
if (n->mesh >= 0) {
ERR_FAIL_INDEX(n->mesh, state.meshes.size());
MeshInstance *mi = memnew(MeshInstance);
- GLTFMesh &mesh = state.meshes[n->mesh];
+ print_line("**creating mesh for: " + n->name);
+ GLTFMesh &mesh = state.meshes.write[n->mesh];
mi->set_mesh(mesh.mesh);
if (mesh.mesh->get_name() == "") {
mesh.mesh->set_name(n->name);
@@ -1686,20 +1686,22 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
node->set_name(n->name);
- p_parent->add_child(node);
- node->set_owner(p_owner);
- node->set_transform(n->xform);
-
n->godot_nodes.push_back(node);
if (n->skin >= 0 && Object::cast_to<MeshInstance>(node)) {
MeshInstance *mi = Object::cast_to<MeshInstance>(node);
- //move skeleton around and place it on node, as the node _is_ a skeleton.
+
Skeleton *s = skeletons[n->skin];
- state.paths_to_skeleton[mi] = s;
- //move it later, as skeleton may be moved around first
+ s->add_child(node); //According to spec, mesh should actually act as a child of the skeleton, as it inherits its transform
+ mi->set_skeleton_path(String(".."));
+
+ } else {
+ p_parent->add_child(node);
+ node->set_transform(n->xform);
}
+ node->set_owner(p_owner);
+
#if 0
for (int i = 0; i < n->skeleton_children.size(); i++) {
@@ -1729,6 +1731,10 @@ void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vecto
skeletons[i]->get_parent()->remove_child(skeletons[i]);
p_parent_node->add_child(skeletons[i]);
skeletons[i]->set_owner(owner);
+ //may have meshes as children, set owner in them too
+ for (int j = 0; j < skeletons[i]->get_child_count(); j++) {
+ skeletons[i]->get_child(j)->set_owner(owner);
+ }
}
}
@@ -1744,13 +1750,11 @@ void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vecto
const int parent = gltf_bone_node->parent;
const int parent_index = s->find_bone(state.nodes[parent]->name);
- s->add_bone(bone_name);
const int bone_index = s->find_bone(bone_name);
s->set_bone_parent(bone_index, parent_index);
- s->set_bone_rest(bone_index, state.skins[skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
n->godot_nodes.push_back(s);
- n->joints[i].godot_bone_index = bone_index;
+ n->joints.write[i].godot_bone_index = bone_index;
}
for (int i = 0; i < n->children.size(); i++) {
@@ -1979,8 +1983,9 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
if (node->joints.size()) {
Transform xform;
- xform.basis = Basis(rot);
- xform.basis.scale(scale);
+ //xform.basis = Basis(rot);
+ //xform.basis.scale(scale);
+ xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;
Skeleton *skeleton = skeletons[node->joints[i].skin];
@@ -2061,6 +2066,10 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
if (name == "") {
name = _gen_unique_name(state, "Skeleton");
}
+ for (int j = 0; j < state.skins[i].bones.size(); j++) {
+ s->add_bone(state.nodes[state.skins[i].bones[j].node]->name);
+ s->set_bone_rest(j, state.skins[i].bones[j].inverse_bind.affine_inverse());
+ }
s->set_name(name);
root->add_child(s);
s->set_owner(root);
@@ -2074,12 +2083,6 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
}
}
- for (Map<Node *, Skeleton *>::Element *E = state.paths_to_skeleton.front(); E; E = E->next()) {
- MeshInstance *mi = Object::cast_to<MeshInstance>(E->key());
- ERR_CONTINUE(!mi);
- mi->set_skeleton_path(mi->get_path_to(E->get()));
- }
-
for (int i = 0; i < skeletons.size(); i++) {
skeletons[i]->localize_rests();
}
diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h
index e8f3bdff62..8258ec41fd 100644
--- a/editor/import/editor_scene_importer_gltf.h
+++ b/editor/import/editor_scene_importer_gltf.h
@@ -275,7 +275,6 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<GLTFAnimation> animations;
Map<int, Vector<int> > skeleton_nodes;
- Map<Node *, Skeleton *> paths_to_skeleton;
//Map<int, Vector<int> > skin_users; //cache skin users
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index ec0500361d..cf850eef03 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -119,7 +119,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
if (key != "") {
for (int i = 1; i < line.size(); i++) {
- translations[i - 1]->add_message(key, line[i]);
+ translations.write[i - 1]->add_message(key, line[i]);
}
}
diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp
new file mode 100644
index 0000000000..b6a67c0cd3
--- /dev/null
+++ b/editor/import/resource_importer_image.cpp
@@ -0,0 +1,79 @@
+#include "resource_importer_image.h"
+
+#include "io/image_loader.h"
+#include "io/resource_saver.h"
+#include "os/file_access.h"
+#include "scene/resources/texture.h"
+
+String ResourceImporterImage::get_importer_name() const {
+
+ return "image";
+}
+
+String ResourceImporterImage::get_visible_name() const {
+
+ return "Image";
+}
+void ResourceImporterImage::get_recognized_extensions(List<String> *p_extensions) const {
+
+ ImageLoader::get_recognized_extensions(p_extensions);
+}
+
+String ResourceImporterImage::get_save_extension() const {
+ return "image";
+}
+
+String ResourceImporterImage::get_resource_type() const {
+
+ return "Image";
+}
+
+bool ResourceImporterImage::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterImage::get_preset_count() const {
+ return 0;
+}
+String ResourceImporterImage::get_preset_name(int p_idx) const {
+
+ return String();
+}
+
+void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+}
+
+Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+
+ FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
+ if (!f) {
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ }
+
+ size_t len = f->get_len();
+
+ Vector<uint8_t> data;
+ data.resize(len);
+
+ f->get_buffer(data.ptrw(), len);
+
+ memdelete(f);
+
+ f = FileAccess::open(p_save_path + ".image", FileAccess::WRITE);
+
+ //save the header GDIM
+ const uint8_t header[4] = { 'G', 'D', 'I', 'M' };
+ f->store_buffer(header, 4);
+ //SAVE the extension (so it can be recognized by the loader later
+ f->store_pascal_string(p_source_file.get_extension().to_lower());
+ //SAVE the actual image
+ f->store_buffer(data.ptr(), len);
+
+ memdelete(f);
+
+ return OK;
+}
+
+ResourceImporterImage::ResourceImporterImage() {
+}
diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h
new file mode 100644
index 0000000000..5aadd00a35
--- /dev/null
+++ b/editor/import/resource_importer_image.h
@@ -0,0 +1,27 @@
+#ifndef RESOURCE_IMPORTER_IMAGE_H
+#define RESOURCE_IMPORTER_IMAGE_H
+
+#include "image.h"
+#include "io/resource_import.h"
+
+class ResourceImporterImage : public ResourceImporter {
+ GDCLASS(ResourceImporterImage, ResourceImporter)
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+
+ ResourceImporterImage();
+};
+
+#endif // RESOURCE_IMPORTER_IMAGE_H
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
new file mode 100644
index 0000000000..2f958a6fdd
--- /dev/null
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -0,0 +1,274 @@
+#include "resource_importer_layered_texture.h"
+
+#include "resource_importer_texture.h"
+
+#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
+#include "io/config_file.h"
+#include "io/image_loader.h"
+#include "scene/resources/texture.h"
+
+String ResourceImporterLayeredTexture::get_importer_name() const {
+
+ return is_3d ? "texture_3d" : "texture_array";
+}
+
+String ResourceImporterLayeredTexture::get_visible_name() const {
+
+ return is_3d ? "Texture3D" : "TextureArray";
+}
+void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
+
+ ImageLoader::get_recognized_extensions(p_extensions);
+}
+String ResourceImporterLayeredTexture::get_save_extension() const {
+ return is_3d ? "tex3d" : "texarr";
+}
+
+String ResourceImporterLayeredTexture::get_resource_type() const {
+
+ return is_3d ? "Texture3D" : "TextureArray";
+}
+
+bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterLayeredTexture::get_preset_count() const {
+ return 3;
+}
+String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
+
+ static const char *preset_names[] = {
+ "3D",
+ "2D",
+ "ColorCorrect"
+ };
+
+ return preset_names[p_idx];
+}
+
+void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_COLOR_CORRECT ? 0 : 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable"), p_preset == PRESET_3D ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/horizontal", PROPERTY_HINT_RANGE, "1,256,1"), p_preset == PRESET_COLOR_CORRECT ? 16 : 8));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/vertical", PROPERTY_HINT_RANGE, "1,256,1"), p_preset == PRESET_COLOR_CORRECT ? 1 : 8));
+}
+
+void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags) {
+
+ FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
+ f->store_8('G');
+ f->store_8('D');
+ if (is_3d) {
+ f->store_8('3');
+ } else {
+ f->store_8('A');
+ }
+ f->store_8('T'); //godot streamable texture
+
+ f->store_32(p_images[0]->get_width());
+ f->store_32(p_images[0]->get_height());
+ f->store_32(p_images.size()); //depth
+ f->store_32(p_texture_flags);
+ if (p_compress_mode != COMPRESS_VIDEO_RAM) {
+ //vram needs to do a first compression to tell what the format is, for the rest its ok
+ f->store_32(p_images[0]->get_format());
+ f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+ }
+
+ if ((p_compress_mode == COMPRESS_LOSSLESS) && p_images[0]->get_format() > Image::FORMAT_RGBA8) {
+ p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy
+ }
+
+ for (int i = 0; i < p_images.size(); i++) {
+
+ switch (p_compress_mode) {
+ case COMPRESS_LOSSLESS: {
+
+ Ref<Image> image = p_images[i]->duplicate();
+ if (p_mipmaps) {
+ image->generate_mipmaps();
+ } else {
+ image->clear_mipmaps();
+ }
+
+ int mmc = image->get_mipmap_count() + 1;
+ f->store_32(mmc);
+
+ for (int i = 0; i < mmc; i++) {
+
+ if (i > 0) {
+ image->shrink_x2();
+ }
+
+ PoolVector<uint8_t> data = Image::lossless_packer(image);
+ int data_len = data.size();
+ f->store_32(data_len);
+
+ PoolVector<uint8_t>::Read r = data.read();
+ f->store_buffer(r.ptr(), data_len);
+ }
+
+ } break;
+ case COMPRESS_VIDEO_RAM: {
+
+ Ref<Image> image = p_images[i]->duplicate();
+ image->generate_mipmaps(false);
+
+ Image::CompressSource csource = Image::COMPRESS_SOURCE_LAYERED;
+ image->compress(p_vram_compression, csource, 0.7);
+
+ if (i == 0) {
+ //hack so we can properly tell the format
+ f->store_32(image->get_format());
+ f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+ }
+
+ PoolVector<uint8_t> data = image->get_data();
+ int dl = data.size();
+
+ PoolVector<uint8_t>::Read r = data.read();
+ f->store_buffer(r.ptr(), dl);
+ } break;
+ case COMPRESS_UNCOMPRESSED: {
+
+ Ref<Image> image = p_images[i]->duplicate();
+
+ if (p_mipmaps) {
+ image->generate_mipmaps();
+ } else {
+ image->clear_mipmaps();
+ }
+
+ PoolVector<uint8_t> data = image->get_data();
+ int dl = data.size();
+
+ PoolVector<uint8_t>::Read r = data.read();
+
+ f->store_buffer(r.ptr(), dl);
+
+ } break;
+ }
+ }
+
+ memdelete(f);
+}
+
+Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+
+ int compress_mode = p_options["compress/mode"];
+ int repeat = p_options["flags/repeat"];
+ bool filter = p_options["flags/filter"];
+ bool mipmaps = p_options["flags/mipmaps"];
+ int srgb = p_options["flags/srgb"];
+ int hslices = p_options["slices/horizontal"];
+ int vslices = p_options["slices/vertical"];
+
+ Ref<Image> image;
+ image.instance();
+ Error err = ImageLoader::load_image(p_source_file, image, NULL, false, 1.0);
+ if (err != OK)
+ return err;
+
+ int tex_flags = 0;
+ if (repeat > 0)
+ tex_flags |= Texture::FLAG_REPEAT;
+ if (repeat == 2)
+ tex_flags |= Texture::FLAG_MIRRORED_REPEAT;
+ if (filter)
+ tex_flags |= Texture::FLAG_FILTER;
+ if (mipmaps || compress_mode == COMPRESS_VIDEO_RAM)
+ tex_flags |= Texture::FLAG_MIPMAPS;
+ if (srgb == 1)
+ tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
+
+ Vector<Ref<Image> > slices;
+
+ int slice_w = image->get_width() / hslices;
+ int slice_h = image->get_height() / vslices;
+
+ //optimize
+ if (compress_mode == COMPRESS_VIDEO_RAM) {
+ //if using video ram, optimize
+ if (srgb) {
+ //remove alpha if not needed, so compression is more efficient
+ if (image->get_format() == Image::FORMAT_RGBA8 && !image->detect_alpha()) {
+ image->convert(Image::FORMAT_RGB8);
+ }
+ } else {
+ image->optimize_channels();
+ }
+ }
+
+ for (int i = 0; i < vslices; i++) {
+ for (int j = 0; j < hslices; j++) {
+ int x = slice_w * j;
+ int y = slice_h * i;
+ Ref<Image> slice = image->get_rect(Rect2(x, y, slice_w, slice_h));
+ ERR_CONTINUE(slice.is_null() || slice->empty());
+ if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
+ slice->resize(slice_w, slice_h);
+ }
+ slices.push_back(slice);
+ }
+ }
+
+ String extension = get_save_extension();
+
+ if (compress_mode == COMPRESS_VIDEO_RAM) {
+ //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
+ //Android, GLES 2.x
+
+ bool ok_on_pc = false;
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
+
+ _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps, tex_flags);
+ r_platform_variants->push_back("s3tc");
+ ok_on_pc = true;
+ }
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
+
+ _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps, tex_flags);
+ r_platform_variants->push_back("etc2");
+ }
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
+ _save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps, tex_flags);
+ r_platform_variants->push_back("etc");
+ }
+
+ if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
+
+ _save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps, tex_flags);
+ r_platform_variants->push_back("pvrtc");
+ }
+
+ if (!ok_on_pc) {
+ EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC.");
+ }
+ } else {
+ //import normally
+ _save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags);
+ }
+
+ return OK;
+}
+
+ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = NULL;
+
+ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() {
+
+ singleton = this;
+ is_3d = true;
+}
+
+ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() {
+}
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
new file mode 100644
index 0000000000..ec73b2624d
--- /dev/null
+++ b/editor/import/resource_importer_layered_texture.h
@@ -0,0 +1,57 @@
+#ifndef RESOURCE_IMPORTER_LAYERED_TEXTURE_H
+#define RESOURCE_IMPORTER_LAYERED_TEXTURE_H
+
+#include "image.h"
+#include "io/resource_import.h"
+
+class StreamTexture;
+
+class ResourceImporterLayeredTexture : public ResourceImporter {
+ GDCLASS(ResourceImporterLayeredTexture, ResourceImporter)
+
+ bool is_3d;
+
+protected:
+ static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
+
+ static ResourceImporterLayeredTexture *singleton;
+
+public:
+ static ResourceImporterLayeredTexture *get_singleton() { return singleton; }
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ enum Preset {
+ PRESET_3D,
+ PRESET_2D,
+ PRESET_COLOR_CORRECT,
+ };
+
+ enum CompressMode {
+ COMPRESS_LOSSLESS,
+ COMPRESS_VIDEO_RAM,
+ COMPRESS_UNCOMPRESSED
+ };
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags);
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+
+ void update_imports();
+
+ void set_3d(bool p_3d) { is_3d = p_3d; }
+ ResourceImporterLayeredTexture();
+ ~ResourceImporterLayeredTexture();
+};
+#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index b8dd4a87b7..5babf6419c 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -224,6 +224,13 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p
while (true) {
String l = f->get_line().strip_edges();
+ while (l.length() && l[l.length() - 1] == '\\') {
+ String add = f->get_line().strip_edges();
+ l += add;
+ if (add == String()) {
+ break;
+ }
+ }
if (l.begins_with("v ")) {
//vertex
@@ -264,10 +271,12 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p
face[0] = v[1].split("/");
face[1] = v[2].split("/");
ERR_FAIL_COND_V(face[0].size() == 0, ERR_FILE_CORRUPT);
+
ERR_FAIL_COND_V(face[0].size() != face[1].size(), ERR_FILE_CORRUPT);
for (int i = 2; i < v.size() - 1; i++) {
face[2] = v[i + 1].split("/");
+
ERR_FAIL_COND_V(face[0].size() != face[2].size(), ERR_FILE_CORRUPT);
for (int j = 0; j < 3; j++) {
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index a5ad34f377..b5e3466b12 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -750,7 +750,7 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
Vector<String> strings = p_text.split("\n");
for (int i = 0; i < strings.size(); i++) {
- strings[i] = strings[i].strip_edges();
+ strings.write[i] = strings[i].strip_edges();
}
List<StringName> anim_names;
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index debdeb1c4a..41f5a892eb 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -215,19 +215,19 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
for (int i = 0; i < frames * format_channels; i++) {
// 8 bit samples are UNSIGNED
- data[i] = int8_t(file->get_8() - 128) / 128.f;
+ data.write[i] = int8_t(file->get_8() - 128) / 128.f;
}
} else if (format_bits == 32 && compression_code == 3) {
for (int i = 0; i < frames * format_channels; i++) {
//32 bit IEEE Float
- data[i] = file->get_float();
+ data.write[i] = file->get_float();
}
} else if (format_bits == 16) {
for (int i = 0; i < frames * format_channels; i++) {
//16 bit SIGNED
- data[i] = int16_t(file->get_16()) / 32768.f;
+ data.write[i] = int16_t(file->get_16()) / 32768.f;
}
} else {
for (int i = 0; i < frames * format_channels; i++) {
@@ -241,7 +241,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
}
s <<= (32 - format_bits);
- data[i] = (int32_t(s) >> 16) / 32768.f;
+ data.write[i] = (int32_t(s) >> 16) / 32768.f;
}
}
@@ -335,7 +335,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
float res = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);
- new_data[i * format_channels + c] = res;
+ new_data.write[i * format_channels + c] = res;
// update position and always keep fractional part within ]0...1]
// in order to avoid 32bit floating point precision errors
@@ -374,7 +374,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
float mult = 1.0 / max;
for (int i = 0; i < data.size(); i++) {
- data[i] *= mult;
+ data.write[i] *= mult;
}
}
}
@@ -408,7 +408,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> new_data;
new_data.resize((last - first + 1) * format_channels);
for (int i = first * format_channels; i < (last + 1) * format_channels; i++) {
- new_data[i - first * format_channels] = data[i];
+ new_data.write[i - first * format_channels] = data[i];
}
data = new_data;
@@ -433,7 +433,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> new_data;
new_data.resize(data.size() / 2);
for (int i = 0; i < frames; i++) {
- new_data[i] = (data[i * 2 + 0] + data[i * 2 + 1]) / 2.0;
+ new_data.write[i] = (data[i * 2 + 0] + data[i * 2 + 1]) / 2.0;
}
data = new_data;
@@ -465,8 +465,8 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
right.resize(tframes);
for (int i = 0; i < tframes; i++) {
- left[i] = data[i * 2 + 0];
- right[i] = data[i * 2 + 1];
+ left.write[i] = data[i * 2 + 0];
+ right.write[i] = data[i * 2 + 1];
}
PoolVector<uint8_t> bleft;
@@ -526,119 +526,5 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
return OK;
}
-void ResourceImporterWAV::_compress_ima_adpcm(const Vector<float> &p_data, PoolVector<uint8_t> &dst_data) {
-
- /*p_sample_data->data = (void*)malloc(len);
- xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/
-
- static const int16_t _ima_adpcm_step_table[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
- };
-
- static const int8_t _ima_adpcm_index_table[16] = {
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8
- };
-
- int datalen = p_data.size();
- int datamax = datalen;
- if (datalen & 1)
- datalen++;
-
- dst_data.resize(datalen / 2 + 4);
- PoolVector<uint8_t>::Write w = dst_data.write();
-
- int i, step_idx = 0, prev = 0;
- uint8_t *out = w.ptr();
- //int16_t xm_prev=0;
- const float *in = p_data.ptr();
-
- /* initial value is zero */
- *(out++) = 0;
- *(out++) = 0;
- /* Table index initial value */
- *(out++) = 0;
- /* unused */
- *(out++) = 0;
-
- for (i = 0; i < datalen; i++) {
- int step, diff, vpdiff, mask;
- uint8_t nibble;
- int16_t xm_sample;
-
- if (i >= datamax)
- xm_sample = 0;
- else {
-
- xm_sample = CLAMP(in[i] * 32767.0, -32768, 32767);
- /*
- if (xm_sample==32767 || xm_sample==-32768)
- printf("clippy!\n",xm_sample);
- */
- }
-
- //xm_sample=xm_sample+xm_prev;
- //xm_prev=xm_sample;
-
- diff = (int)xm_sample - prev;
-
- nibble = 0;
- step = _ima_adpcm_step_table[step_idx];
- vpdiff = step >> 3;
- if (diff < 0) {
- nibble = 8;
- diff = -diff;
- }
- mask = 4;
- while (mask) {
-
- if (diff >= step) {
-
- nibble |= mask;
- diff -= step;
- vpdiff += step;
- }
-
- step >>= 1;
- mask >>= 1;
- };
-
- if (nibble & 8)
- prev -= vpdiff;
- else
- prev += vpdiff;
-
- if (prev > 32767) {
- //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev);
- prev = 32767;
- } else if (prev < -32768) {
- //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev);
- prev = -32768;
- }
-
- step_idx += _ima_adpcm_index_table[nibble];
- if (step_idx < 0)
- step_idx = 0;
- else if (step_idx > 88)
- step_idx = 88;
-
- if (i & 1) {
- *out |= nibble << 4;
- out++;
- } else {
- *out = nibble;
- }
- /*dataptr[i]=prev>>8;*/
- }
-}
-
ResourceImporterWAV::ResourceImporterWAV() {
}
diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h
index cfce5a31ee..f78ab09e9b 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -48,7 +48,118 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- void _compress_ima_adpcm(const Vector<float> &p_data, PoolVector<uint8_t> &dst_data);
+ static void _compress_ima_adpcm(const Vector<float> &p_data, PoolVector<uint8_t> &dst_data) {
+ /*p_sample_data->data = (void*)malloc(len);
+ xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/
+
+ static const int16_t _ima_adpcm_step_table[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+ };
+
+ static const int8_t _ima_adpcm_index_table[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+ };
+
+ int datalen = p_data.size();
+ int datamax = datalen;
+ if (datalen & 1)
+ datalen++;
+
+ dst_data.resize(datalen / 2 + 4);
+ PoolVector<uint8_t>::Write w = dst_data.write();
+
+ int i, step_idx = 0, prev = 0;
+ uint8_t *out = w.ptr();
+ //int16_t xm_prev=0;
+ const float *in = p_data.ptr();
+
+ /* initial value is zero */
+ *(out++) = 0;
+ *(out++) = 0;
+ /* Table index initial value */
+ *(out++) = 0;
+ /* unused */
+ *(out++) = 0;
+
+ for (i = 0; i < datalen; i++) {
+ int step, diff, vpdiff, mask;
+ uint8_t nibble;
+ int16_t xm_sample;
+
+ if (i >= datamax)
+ xm_sample = 0;
+ else {
+
+ xm_sample = CLAMP(in[i] * 32767.0, -32768, 32767);
+ /*
+ if (xm_sample==32767 || xm_sample==-32768)
+ printf("clippy!\n",xm_sample);
+ */
+ }
+
+ //xm_sample=xm_sample+xm_prev;
+ //xm_prev=xm_sample;
+
+ diff = (int)xm_sample - prev;
+
+ nibble = 0;
+ step = _ima_adpcm_step_table[step_idx];
+ vpdiff = step >> 3;
+ if (diff < 0) {
+ nibble = 8;
+ diff = -diff;
+ }
+ mask = 4;
+ while (mask) {
+
+ if (diff >= step) {
+
+ nibble |= mask;
+ diff -= step;
+ vpdiff += step;
+ }
+
+ step >>= 1;
+ mask >>= 1;
+ };
+
+ if (nibble & 8)
+ prev -= vpdiff;
+ else
+ prev += vpdiff;
+
+ if (prev > 32767) {
+ //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev);
+ prev = 32767;
+ } else if (prev < -32768) {
+ //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev);
+ prev = -32768;
+ }
+
+ step_idx += _ima_adpcm_index_table[nibble];
+ if (step_idx < 0)
+ step_idx = 0;
+ else if (step_idx > 88)
+ step_idx = 88;
+
+ if (i & 1) {
+ *out |= nibble << 4;
+ out++;
+ } else {
+ *out = nibble;
+ }
+ /*dataptr[i]=prev>>8;*/
+ }
+ }
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 43baabe2f5..615e9df043 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -142,7 +142,7 @@ void InspectorDock::_resource_file_selected(String p_file) {
RES res = ResourceLoader::load(p_file);
if (res.is_null()) {
- warning_dialog->get_ok()->set_text("Ugh");
+ warning_dialog->get_ok()->set_text(TTR("OK"));
warning_dialog->set_text(TTR("Failed to load resource."));
return;
};
@@ -529,7 +529,8 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
search = memnew(LineEdit);
search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search->set_placeholder(TTR("Filter properties"));
- search->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ search->set_right_icon(get_icon("Search", "EditorIcons"));
+ search->set_clear_button_enabled(true);
add_child(search);
warning = memnew(Button);
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 5052b69e24..2d341cdd93 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -345,7 +345,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
- vertices[edited_point.vertex] = edited_point.pos - _get_offset(edited_point.polygon);
+ vertices.write[edited_point.vertex] = edited_point.pos - _get_offset(edited_point.polygon);
undo_redo->create_action(TTR("Edit Poly"));
_action_set_polygon(edited_point.polygon, pre_move_edit, vertices);
@@ -445,7 +445,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
- vertices[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
+ vertices.write[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
_set_polygon(edited_point.polygon, vertices);
}
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 8d17062248..27df60f87a 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -414,7 +414,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
point *= s;
point.y = s.height - point.y;
- points[j] = point;
+ points.write[j] = point;
}
for (int j = 0; j < 3; j++) {
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 23eeef9f20..9ab5436de8 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -1333,7 +1333,7 @@ void AnimationPlayerEditor::_allocate_onion_layers() {
bool is_present = onion.differences_only && i == captures - 1;
// Each capture is a viewport with a canvas item attached that renders a full-size rect with the contents of the main viewport
- onion.captures[i] = VS::get_singleton()->viewport_create();
+ onion.captures.write[i] = VS::get_singleton()->viewport_create();
VS::get_singleton()->viewport_set_usage(onion.captures[i], VS::VIEWPORT_USAGE_2D);
VS::get_singleton()->viewport_set_size(onion.captures[i], capture_size.width, capture_size.height);
VS::get_singleton()->viewport_set_update_mode(onion.captures[i], VS::VIEWPORT_UPDATE_ALWAYS);
@@ -1473,7 +1473,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
float pos = cpos + step_off * anim->get_step();
bool valid = anim->has_loop() || (pos >= 0 && pos <= anim->get_length());
- onion.captures_valid[cidx] = valid;
+ onion.captures_valid.write[cidx] = valid;
if (valid) {
player->seek(pos, true);
get_tree()->flush_transform_notifications(); // Needed for transforms of Spatials
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 04bd5f0cec..ee450333c8 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -679,7 +679,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
Ref<StyleBox> sb = name == selected_node ? style_selected : style;
int strsize = font->get_string_size(name).width;
- NodeRect &nr = node_rects[i];
+ NodeRect &nr = node_rects.write[i];
Vector2 offset = nr.node.position;
int h = nr.node.size.height;
@@ -771,7 +771,7 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
if (idx == -1)
return;
- NodeRect &nr = node_rects[idx];
+ const NodeRect &nr = node_rects[idx];
Vector2 from;
from.x = nr.play.position.x;
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 505dd4ab76..4ed2b051aa 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -197,7 +197,7 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
for (int i = 0; i < preview_images.size(); i++) {
if (preview_images[i].id == p_index) {
- preview_images[i].image = p_image;
+ preview_images.write[i].image = p_image;
if (preview_images[i].button->is_pressed()) {
_preview_click(p_index);
}
@@ -384,14 +384,11 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
return;
}
- progress->set_max(download->get_body_size());
- progress->set_value(download->get_downloaded_bytes());
-
install->set_disabled(false);
+ status->set_text(TTR("Success!"));
+ // Make the progress bar invisible but don't reflow other Controls around it
+ progress->set_modulate(Color(0, 0, 0, 0));
- progress->set_value(download->get_downloaded_bytes());
-
- status->set_text(TTR("Success!") + " (" + String::humanize_size(download->get_downloaded_bytes()) + ")");
set_process(false);
}
@@ -413,25 +410,37 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
- progress->set_max(download->get_body_size());
- progress->set_value(download->get_downloaded_bytes());
+ // Make the progress bar visible again when retrying the download
+ progress->set_modulate(Color(1, 1, 1, 1));
+
+ if (download->get_downloaded_bytes() > 0) {
+ progress->set_max(download->get_body_size());
+ progress->set_value(download->get_downloaded_bytes());
+ }
int cstatus = download->get_http_client_status();
- if (cstatus == HTTPClient::STATUS_BODY)
- status->set_text(TTR("Fetching:") + " " + String::humanize_size(download->get_downloaded_bytes()));
+ if (cstatus == HTTPClient::STATUS_BODY) {
+ status->set_text(vformat(TTR("Downloading (%s / %s)..."), String::humanize_size(download->get_downloaded_bytes()), String::humanize_size(download->get_body_size())));
+ }
if (cstatus != prev_status) {
switch (cstatus) {
case HTTPClient::STATUS_RESOLVING: {
status->set_text(TTR("Resolving..."));
+ progress->set_max(1);
+ progress->set_value(0);
} break;
case HTTPClient::STATUS_CONNECTING: {
status->set_text(TTR("Connecting..."));
+ progress->set_max(1);
+ progress->set_value(0);
} break;
case HTTPClient::STATUS_REQUESTING: {
status->set_text(TTR("Requesting..."));
+ progress->set_max(1);
+ progress->set_value(0);
} break;
default: {}
}
@@ -527,7 +536,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
hb2->add_child(retry);
hb2->add_child(install);
- set_custom_minimum_size(Size2(250, 0));
+ set_custom_minimum_size(Size2(310, 0));
download = memnew(HTTPRequest);
add_child(download);
@@ -554,6 +563,8 @@ void EditorAssetLibrary::_notification(int p_what) {
error_tr->set_texture(get_icon("Error", "EditorIcons"));
reverse->set_icon(get_icon("Sort", "EditorIcons"));
+ filter->set_right_icon(get_icon("Search", "EditorIcons"));
+ filter->set_clear_button_enabled(true);
error_label->raise();
} break;
@@ -604,6 +615,8 @@ void EditorAssetLibrary::_notification(int p_what) {
library_scroll_bg->add_style_override("panel", get_stylebox("bg", "Tree"));
error_tr->set_texture(get_icon("Error", "EditorIcons"));
reverse->set_icon(get_icon("Sort", "EditorIcons"));
+ filter->set_right_icon(get_icon("Search", "EditorIcons"));
+ filter->set_clear_button_enabled(true);
} break;
}
}
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index ddb03d0250..454a5d72f2 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -81,8 +81,8 @@ void AudioStreamEditor::_draw_preview() {
float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
int idx = i;
- lines[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
- lines[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
+ lines.write[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
+ lines.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
}
Vector<Color> color;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 1d20c63969..145a2ef9bb 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -375,33 +375,24 @@ Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_li
// Handles the first element
CanvasItem *canvas_item = p_list.front()->get();
- Rect2 rect;
- if (canvas_item->_edit_use_rect()) {
- rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().position + canvas_item->_edit_get_rect().size / 2), Size2());
- } else {
- rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(Point2()), Size2());
- }
+ Rect2 rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().position + canvas_item->_edit_get_rect().size / 2), Size2());
// Expand with the other ones
for (List<CanvasItem *>::Element *E = p_list.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
Transform2D xform = canvas_item->get_global_transform_with_canvas();
- if (canvas_item->_edit_use_rect()) {
- Rect2 current_rect = canvas_item->_edit_get_rect();
- rect.expand_to(xform.xform(current_rect.position));
- rect.expand_to(xform.xform(current_rect.position + Vector2(current_rect.size.x, 0)));
- rect.expand_to(xform.xform(current_rect.position + current_rect.size));
- rect.expand_to(xform.xform(current_rect.position + Vector2(0, current_rect.size.y)));
- } else {
- rect.expand_to(xform.xform(Point2()));
- }
+ Rect2 current_rect = canvas_item->_edit_get_rect();
+ rect.expand_to(xform.xform(current_rect.position));
+ rect.expand_to(xform.xform(current_rect.position + Vector2(current_rect.size.x, 0)));
+ rect.expand_to(xform.xform(current_rect.position + current_rect.size));
+ rect.expand_to(xform.xform(current_rect.position + Vector2(0, current_rect.size.y)));
}
return rect;
}
-void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
+void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, bool include_locked_nodes) {
if (!p_node)
return;
if (Object::cast_to<Viewport>(p_node))
@@ -409,12 +400,6 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c
const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- /*bool inherited = p_node != get_tree()->get_edited_scene_root() && p_node->get_filename() != "";
- bool editable = !inherited || EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node);
- bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
-
- if (!lock_children && editable) {}*/
-
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
if (canvas_item && !canvas_item->is_set_as_toplevel()) {
_expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, p_parent_xform * canvas_item->get_transform(), p_canvas_xform);
@@ -424,28 +409,17 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c
}
}
- if (canvas_item && canvas_item->is_visible_in_tree() && !canvas_item->has_meta("_edit_lock_")) {
+ if (canvas_item && canvas_item->is_visible_in_tree() && (include_locked_nodes || !canvas_item->has_meta("_edit_lock_"))) {
Transform2D xform = p_parent_xform * p_canvas_xform * canvas_item->get_transform();
- if (canvas_item->_edit_use_rect()) {
- Rect2 rect = canvas_item->_edit_get_rect();
- if (r_first) {
- r_rect = Rect2(xform.xform(rect.position + rect.size / 2), Size2());
- r_first = false;
- }
- if (r_rect.size != Size2()) {
- r_rect.expand_to(xform.xform(rect.position));
- r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0)));
- r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y)));
- r_rect.expand_to(xform.xform(rect.position + rect.size));
- }
- } else {
- if (r_first) {
- r_rect = Rect2(xform.xform(Point2()), Size2());
- r_first = false;
- } else {
- r_rect.expand_to(xform.xform(Point2()));
- }
+ Rect2 rect = canvas_item->_edit_get_rect();
+ if (r_first) {
+ r_rect = Rect2(xform.xform(rect.position + rect.size / 2), Size2());
+ r_first = false;
}
+ r_rect.expand_to(xform.xform(rect.position));
+ r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0)));
+ r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y)));
+ r_rect.expand_to(xform.xform(rect.position + rect.size));
}
}
@@ -533,7 +507,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
r_items.remove(i);
i--;
} else {
- r_items[i].item = canvas_item;
+ r_items.write[i].item = canvas_item;
}
}
}
@@ -4879,7 +4853,7 @@ void CanvasItemEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->get_ok()->set_text(TTR("Ugh"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
accept->popup_centered_minsize();
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index adc4010f39..2c943385ad 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -390,7 +390,7 @@ class CanvasItemEditor : public VBoxContainer {
List<CanvasItem *> _get_edited_canvas_items(bool retreive_locked = false, bool remove_canvas_item_if_parent_in_selection = true);
Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list);
- void _expand_encompassing_rect_using_children(Rect2 &p_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
+ void _expand_encompassing_rect_using_children(Rect2 &p_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D(), bool include_locked_nodes = true);
Rect2 _get_encompassing_rect(const Node *p_node);
Object *_get_editor_data(Object *p_what);
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index e837359d0c..5109379add 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -276,7 +276,7 @@ bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<Inpu
//apply
ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos;
+ poly.write[edited_point] = edited_point_pos;
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node, "set_polygon", poly);
undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index b003664dca..9e052bb027 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -446,8 +446,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
float radius = shape->get_radius();
float height = shape->get_height() / 2;
- handles[0] = Point2(radius, -height);
- handles[1] = Point2(0, -(height + radius));
+ handles.write[0] = Point2(radius, -height);
+ handles.write[1] = Point2(0, -(height + radius));
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -458,7 +458,7 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<CircleShape2D> shape = node->get_shape();
handles.resize(1);
- handles[0] = Point2(shape->get_radius(), 0);
+ handles.write[0] = Point2(shape->get_radius(), 0);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
@@ -476,8 +476,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<LineShape2D> shape = node->get_shape();
handles.resize(2);
- handles[0] = shape->get_normal() * shape->get_d();
- handles[1] = shape->get_normal() * (shape->get_d() + 30.0);
+ handles.write[0] = shape->get_normal() * shape->get_d();
+ handles.write[1] = shape->get_normal() * (shape->get_d() + 30.0);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -488,7 +488,7 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<RayShape2D> shape = node->get_shape();
handles.resize(1);
- handles[0] = Point2(0, shape->get_length());
+ handles.write[0] = Point2(0, shape->get_length());
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
@@ -499,8 +499,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
handles.resize(2);
Vector2 ext = shape->get_extents();
- handles[0] = Point2(ext.x, 0);
- handles[1] = Point2(0, -ext.y);
+ handles.write[0] = Point2(ext.x, 0);
+ handles.write[1] = Point2(0, -ext.y);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -511,8 +511,8 @@ void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Ref<SegmentShape2D> shape = node->get_shape();
handles.resize(2);
- handles[0] = shape->get_a();
- handles[1] = shape->get_b();
+ handles.write[0] = shape->get_a();
+ handles.write[1] = shape->get_b();
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 0d25b3685a..9acbceec92 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -78,7 +78,7 @@ bool EditorTexturePreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Texture");
}
-Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
Ref<Image> img;
Ref<AtlasTexture> atex = p_from;
@@ -138,12 +138,66 @@ EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() {
////////////////////////////////////////////////////////////////////////////
+bool EditorImagePreviewPlugin::handles(const String &p_type) const {
+
+ return p_type == "Image";
+}
+
+Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
+
+ Ref<Image> img = p_from;
+
+ if (img.is_null() || img->empty())
+ return Ref<Image>();
+
+ img = img->duplicate();
+ img->clear_mipmaps();
+
+ int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
+ thumbnail_size *= EDSCALE;
+ if (img->is_compressed()) {
+ if (img->decompress() != OK)
+ return Ref<Image>();
+ } else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
+ img->convert(Image::FORMAT_RGBA8);
+ }
+
+ int width, height;
+ if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
+
+ width = thumbnail_size;
+ height = img->get_height() * thumbnail_size / img->get_width();
+ } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
+
+ height = thumbnail_size;
+ width = img->get_width() * thumbnail_size / img->get_height();
+ } else {
+
+ width = img->get_width();
+ height = img->get_height();
+ }
+
+ img->resize(width, height);
+ post_process_preview(img);
+
+ Ref<ImageTexture> ptex;
+ ptex.instance();
+
+ ptex->create_from_image(img, 0);
+ return ptex;
+}
+
+EditorImagePreviewPlugin::EditorImagePreviewPlugin() {
+}
+
+////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////
bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "BitMap");
}
-Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
Ref<BitMap> bm = p_from;
@@ -215,12 +269,12 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "PackedScene");
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) const {
return generate_from_path(p_from->get_path());
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) const {
String temp_path = EditorSettings::get_singleton()->get_cache_dir();
String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text();
@@ -269,7 +323,7 @@ bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Material"); //any material
}
-Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const {
Ref<Material> material = p_from;
ERR_FAIL_COND_V(material.is_null(), Ref<Texture>());
@@ -281,7 +335,7 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) {
VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
preview_done = false;
- VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+ VS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant());
while (!preview_done) {
OS::get_singleton()->delay_usec(10);
@@ -436,7 +490,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Script");
}
-Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const {
Ref<Script> scr = p_from;
if (scr.is_null())
@@ -559,7 +613,7 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "AudioStream");
}
-Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) const {
Ref<AudioStream> stream = p_from;
ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>());
@@ -657,7 +711,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
}
-Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const {
Ref<Mesh> mesh = p_from;
ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>());
@@ -684,7 +738,7 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) {
VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
preview_done = false;
- VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+ VS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant());
while (!preview_done) {
OS::get_singleton()->delay_usec(10);
@@ -771,16 +825,7 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "DynamicFontData");
}
-Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) {
- if (canvas.is_valid()) {
- VS::get_singleton()->viewport_remove_canvas(viewport, canvas);
- }
-
- canvas = VS::get_singleton()->canvas_create();
- canvas_item = VS::get_singleton()->canvas_item_create();
-
- VS::get_singleton()->viewport_attach_canvas(viewport, canvas);
- VS::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
+Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) const {
Ref<DynamicFontData> SampledFont;
SampledFont.instance();
@@ -809,7 +854,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) {
VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
preview_done = false;
- VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+ VS::get_singleton()->request_frame_drawn_callback(const_cast<EditorFontPreviewPlugin *>(this), "_preview_done", Variant());
while (!preview_done) {
OS::get_singleton()->delay_usec(10);
@@ -829,7 +874,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) {
return ptex;
}
-Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) {
+Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) const {
return generate_from_path(p_from->get_path());
}
@@ -842,6 +887,12 @@ EditorFontPreviewPlugin::EditorFontPreviewPlugin() {
VS::get_singleton()->viewport_set_size(viewport, 128, 128);
VS::get_singleton()->viewport_set_active(viewport, true);
viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
+
+ canvas = VS::get_singleton()->canvas_create();
+ canvas_item = VS::get_singleton()->canvas_item_create();
+
+ VS::get_singleton()->viewport_attach_canvas(viewport, canvas);
+ VS::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
}
EditorFontPreviewPlugin::~EditorFontPreviewPlugin() {
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 140d9f849f..8bd7943383 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -39,16 +39,25 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorTexturePreviewPlugin();
};
+class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator {
+ GDCLASS(EditorImagePreviewPlugin, EditorResourcePreviewGenerator)
+public:
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from) const;
+
+ EditorImagePreviewPlugin();
+};
+
class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorBitmapPreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorBitmapPreviewPlugin();
};
@@ -57,8 +66,8 @@ class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
- virtual Ref<Texture> generate_from_path(const String &p_path);
+ virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path) const;
EditorPackedScenePreviewPlugin();
};
@@ -77,7 +86,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- volatile bool preview_done;
+ mutable volatile bool preview_done;
void _preview_done(const Variant &p_udata);
@@ -86,7 +95,7 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorMaterialPreviewPlugin();
~EditorMaterialPreviewPlugin();
@@ -95,7 +104,7 @@ public:
class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorScriptPreviewPlugin();
};
@@ -103,7 +112,7 @@ public:
class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorAudioStreamPreviewPlugin();
};
@@ -121,7 +130,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- volatile bool preview_done;
+ mutable volatile bool preview_done;
void _preview_done(const Variant &p_udata);
@@ -130,7 +139,7 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate(const RES &p_from) const;
EditorMeshPreviewPlugin();
~EditorMeshPreviewPlugin();
@@ -144,7 +153,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator {
RID viewport_texture;
RID canvas;
RID canvas_item;
- volatile bool preview_done;
+ mutable volatile bool preview_done;
void _preview_done(const Variant &p_udata);
@@ -153,8 +162,8 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from);
- virtual Ref<Texture> generate_from_path(const String &p_path);
+ virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path) const;
EditorFontPreviewPlugin();
~EditorFontPreviewPlugin();
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index a3be10dc33..3351e5918f 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -255,7 +255,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
//apply
ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos;
+ poly.write[edited_point] = edited_point_pos;
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index 6d11079759..c2b17189ef 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -165,12 +165,12 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
if (emode == EMISSION_MODE_SOLID) {
if (capture_colors) {
- valid_colors[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
- valid_colors[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
- valid_colors[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
- valid_colors[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
+ valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
+ valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
+ valid_colors.write[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
+ valid_colors.write[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
}
- valid_positions[vpc++] = Point2(i, j);
+ valid_positions.write[vpc++] = Point2(i, j);
} else {
@@ -189,7 +189,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
}
if (on_border) {
- valid_positions[vpc] = Point2(i, j);
+ valid_positions.write[vpc] = Point2(i, j);
if (emode == EMISSION_MODE_BORDER_DIRECTED) {
Vector2 normal;
@@ -206,14 +206,14 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
}
normal.normalize();
- valid_normals[vpc] = normal;
+ valid_normals.write[vpc] = normal;
}
if (capture_colors) {
- valid_colors[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
- valid_colors[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
- valid_colors[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
- valid_colors[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
+ valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
+ valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
+ valid_colors.write[vpc * 4 + 2] = r[(j * s.width + i) * 4 + 2];
+ valid_colors.write[vpc * 4 + 3] = r[(j * s.width + i) * 4 + 3];
}
vpc++;
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 72a8b55a52..618c70d1a1 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -215,6 +215,10 @@ void PathSpatialGizmo::redraw() {
clear();
+ Ref<SpatialMaterial> path_material = gizmo_plugin->get_material("path_material");
+ Ref<SpatialMaterial> path_thin_material = gizmo_plugin->get_material("path_thin_material");
+ Ref<SpatialMaterial> handles_material = gizmo_plugin->get_material("handles");
+
Ref<Curve3D> c = path->get_curve();
if (c.is_null())
return;
@@ -238,7 +242,7 @@ void PathSpatialGizmo::redraw() {
}
if (v3p.size() > 1) {
- add_lines(v3p, PathEditorPlugin::singleton->path_material);
+ add_lines(v3p, path_material);
add_collision_segments(v3p);
}
@@ -265,13 +269,13 @@ void PathSpatialGizmo::redraw() {
}
if (v3p.size() > 1) {
- add_lines(v3p, PathEditorPlugin::singleton->path_thin_material);
+ add_lines(v3p, path_thin_material);
}
if (handles.size()) {
- add_handles(handles);
+ add_handles(handles, handles_material);
}
if (sec_handles.size()) {
- add_handles(sec_handles, false, true);
+ add_handles(sec_handles, handles_material, false, true);
}
}
}
@@ -282,16 +286,6 @@ PathSpatialGizmo::PathSpatialGizmo(Path *p_path) {
set_spatial_node(p_path);
}
-Ref<SpatialEditorGizmo> PathEditorPlugin::create_spatial_gizmo(Spatial *p_spatial) {
-
- if (Object::cast_to<Path>(p_spatial)) {
-
- return memnew(PathSpatialGizmo(Object::cast_to<Path>(p_spatial)));
- }
-
- return Ref<SpatialEditorGizmo>();
-}
-
bool PathEditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {
if (!path)
@@ -567,21 +561,9 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
mirror_handle_angle = true;
mirror_handle_length = true;
- path_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- path_material->set_albedo(Color(0.5, 0.5, 1.0, 0.8));
- path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- path_material->set_line_width(3);
- path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
-
- path_thin_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- path_thin_material->set_albedo(Color(0.5, 0.5, 1.0, 0.4));
- path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- path_thin_material->set_line_width(1);
- path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
-
- //SpatialEditor::get_singleton()->add_gizmo_plugin(this);
+ Ref<PathSpatialGizmoPlugin> gizmo_plugin;
+ gizmo_plugin.instance();
+ SpatialEditor::get_singleton()->register_gizmo_plugin(gizmo_plugin);
sep = memnew(VSeparator);
sep->hide();
@@ -630,18 +612,53 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
curve_edit->set_pressed(true);
/*
- collision_polygon_editor = memnew( PathEditor(p_node) );
- editor->get_viewport()->add_child(collision_polygon_editor);
+ collision_polygon_editor = memnew( PathEditor(p_node) );
+ editor->get_viewport()->add_child(collision_polygon_editor);
+ collision_polygon_editor->set_margin(MARGIN_LEFT,200);
+ collision_polygon_editor->set_margin(MARGIN_RIGHT,230);
+ collision_polygon_editor->set_margin(MARGIN_TOP,0);
+ collision_polygon_editor->set_margin(MARGIN_BOTTOM,10);
+ collision_polygon_editor->hide();
+ */
+}
- collision_polygon_editor->set_margin(MARGIN_LEFT,200);
- collision_polygon_editor->set_margin(MARGIN_RIGHT,230);
- collision_polygon_editor->set_margin(MARGIN_TOP,0);
- collision_polygon_editor->set_margin(MARGIN_BOTTOM,10);
+PathEditorPlugin::~PathEditorPlugin() {
+}
+
+Ref<EditorSpatialGizmo> PathSpatialGizmoPlugin::create_gizmo(Spatial *p_spatial) {
+ Ref<PathSpatialGizmo> ref;
+ Path *path = Object::cast_to<Path>(p_spatial);
+ if (path) ref = Ref<PathSpatialGizmo>(memnew(PathSpatialGizmo(path)));
- collision_polygon_editor->hide();
- */
+ return ref;
}
-PathEditorPlugin::~PathEditorPlugin() {
+String PathSpatialGizmoPlugin::get_name() const {
+ return "Path";
+}
+
+PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() {
+
+ Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
+
+ Ref<SpatialMaterial> path_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ path_color.a = 0.8;
+ path_material->set_albedo(path_color);
+ path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ path_material->set_line_width(3);
+ path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+
+ Ref<SpatialMaterial> path_thin_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ path_color.a = 0.4;
+ path_thin_material->set_albedo(path_color);
+ path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ path_thin_material->set_line_width(1);
+ path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+
+ add_material("path_material", path_material);
+ add_material("path_thin_material", path_thin_material);
+ create_handle_material("handles");
}
diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h
index 52dfb78b61..61f309e794 100644
--- a/editor/plugins/path_editor_plugin.h
+++ b/editor/plugins/path_editor_plugin.h
@@ -49,10 +49,22 @@ public:
virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
- void redraw();
+ virtual void redraw();
PathSpatialGizmo(Path *p_path = NULL);
};
+class PathSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
+
+ GDCLASS(PathSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
+
+protected:
+ Ref<EditorSpatialGizmo> create_gizmo(Spatial *p_spatial);
+
+public:
+ String get_name() const;
+ PathSpatialGizmoPlugin();
+};
+
class PathEditorPlugin : public EditorPlugin {
GDCLASS(PathEditorPlugin, EditorPlugin);
@@ -88,12 +100,10 @@ public:
Path *get_edited_path() { return path; }
static PathEditorPlugin *singleton;
- Ref<SpatialMaterial> path_material;
- Ref<SpatialMaterial> path_thin_material;
virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
//virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
- virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
+ //virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
virtual String get_name() const { return "Path"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_object);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index a1dc746702..7d72537e32 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -219,6 +219,9 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", this, "_confirmed");
+
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
} break;
}
}
@@ -342,11 +345,11 @@ void ScriptEditor::_save_history() {
if (Object::cast_to<ScriptEditorBase>(n)) {
- history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
- history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+ history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
}
@@ -373,11 +376,11 @@ void ScriptEditor::_go_to_tab(int p_idx) {
if (Object::cast_to<ScriptEditorBase>(n)) {
- history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
- history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+ history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
}
@@ -1876,6 +1879,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
if ((debugger->get_dump_stack_script() != p_resource || debugger->get_debug_with_external_editor()) &&
p_resource->get_path().is_resource_file() &&
+ p_resource->get_class_name() != StringName("VisualScript") &&
bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path");
@@ -2401,26 +2405,25 @@ void ScriptEditor::_make_script_list_context_menu() {
if (se) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save"), FILE_SAVE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save_as"), FILE_SAVE_AS);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_all"), CLOSE_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_other_tabs"), CLOSE_OTHER_TABS);
- context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/copy_path"), FILE_COPY_PATH);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/show_in_file_system"), SHOW_IN_FILE_SYSTEM);
}
-
- Ref<Script> scr = se->get_edited_resource();
- if (scr != NULL) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
- if (!scr.is_null() && scr->is_tool()) {
- context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_all"), CLOSE_ALL);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_other_tabs"), CLOSE_OTHER_TABS);
+ context_menu->add_separator();
+ if (se) {
+ Ref<Script> scr = se->get_edited_resource();
+ if (scr != NULL) {
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
+ if (!scr.is_null() && scr->is_tool()) {
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
+ context_menu->add_separator();
+ }
}
- } else {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/copy_path"), FILE_COPY_PATH);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/show_in_file_system"), SHOW_IN_FILE_SYSTEM);
+ context_menu->add_separator();
}
- context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_move_up"), WINDOW_MOVE_UP);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_move_down"), WINDOW_MOVE_DOWN);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_sort"), WINDOW_SORT);
@@ -2612,11 +2615,11 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
if (Object::cast_to<ScriptEditorBase>(n)) {
- history[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
+ history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
- history[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
+ history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
history_pos = p_new_pos;
@@ -2894,13 +2897,14 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
script_list->set_v_size_flags(SIZE_EXPAND_FILL);
script_split->set_split_offset(140);
_sort_list_on_update = true;
- script_list->connect("gui_input", this, "_script_list_gui_input");
+ script_list->connect("gui_input", this, "_script_list_gui_input", varray(), CONNECT_DEFERRED);
script_list->set_allow_rmb_select(true);
script_list->set_drag_forwarding(this);
context_menu = memnew(PopupMenu);
add_child(context_menu);
context_menu->connect("id_pressed", this, "_menu_option");
+ context_menu->set_hide_on_window_lose_focus(true);
overview_vbox = memnew(VBoxContainer);
overview_vbox->set_custom_minimum_size(Size2(0, 90));
@@ -2955,6 +2959,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu = memnew(MenuButton);
menu_hb->add_child(file_menu);
file_menu->set_text(TTR("File"));
+ file_menu->get_popup()->set_hide_on_window_lose_focus(true);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New")), FILE_NEW);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open")), FILE_OPEN);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
@@ -3004,6 +3009,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
script_search_menu = memnew(MenuButton);
menu_hb->add_child(script_search_menu);
script_search_menu->set_text(TTR("Search"));
+ script_search_menu->get_popup()->set_hide_on_window_lose_focus(true);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F), HELP_SEARCH_FIND);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), HELP_SEARCH_FIND_NEXT);
script_search_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -3012,6 +3018,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
debug_menu = memnew(MenuButton);
menu_hb->add_child(debug_menu);
debug_menu->set_text(TTR("Debug"));
+ debug_menu->get_popup()->set_hide_on_window_lose_focus(true);
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10), DEBUG_NEXT);
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_into", TTR("Step Into"), KEY_F11), DEBUG_STEP);
debug_menu->get_popup()->add_separator();
@@ -3093,7 +3100,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
error_dialog = memnew(AcceptDialog);
add_child(error_dialog);
- error_dialog->get_ok()->set_text(TTR("I see..."));
+ error_dialog->get_ok()->set_text(TTR("OK"));
debugger = memnew(ScriptEditorDebugger(editor));
debugger->connect("goto_script_line", this, "_goto_script_line");
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 165d7e32b9..522ce52234 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -274,6 +274,23 @@ void ScriptTextEditor::_set_theme_for_script() {
}
}
+void ScriptTextEditor::_toggle_warning_pannel(const Ref<InputEvent> &p_event) {
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ warnings_panel->set_visible(!warnings_panel->is_visible());
+ }
+}
+
+void ScriptTextEditor::_warning_clicked(Variant p_line) {
+ if (p_line.get_type() == Variant::INT) {
+ code_editor->get_text_edit()->cursor_set_line(p_line.operator int64_t());
+ } else if (p_line.get_type() == Variant::DICTIONARY) {
+ Dictionary meta = p_line.operator Dictionary();
+ code_editor->get_text_edit()->insert_at("#warning-ignore:" + meta["code"].operator String(), meta["line"].operator int64_t() - 1);
+ _validate_script();
+ }
+}
+
void ScriptTextEditor::reload_text() {
ERR_FAIL_COND(script.is_null());
@@ -421,8 +438,9 @@ void ScriptTextEditor::_validate_script() {
String text = te->get_text();
List<String> fnc;
Set<int> safe_lines;
+ List<ScriptLanguage::Warning> warnings;
- if (!script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc, &safe_lines)) {
+ if (!script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc, &warnings, &safe_lines)) {
String error_text = "error(" + itos(line) + "," + itos(col) + "): " + errortxt;
code_editor->set_error(error_text);
} else {
@@ -442,6 +460,37 @@ void ScriptTextEditor::_validate_script() {
}
}
+ code_editor->get_warning_count_label()->set_text(itos(warnings.size()));
+ warnings_panel->clear();
+ warnings_panel->push_table(3);
+ for (List<ScriptLanguage::Warning>::Element *E = warnings.front(); E; E = E->next()) {
+ ScriptLanguage::Warning w = E->get();
+
+ warnings_panel->push_cell();
+ warnings_panel->push_meta(w.line - 1);
+ warnings_panel->push_color(warnings_panel->get_color("warning_color", "Editor"));
+ warnings_panel->add_text(TTR("Line") + " " + itos(w.line));
+ warnings_panel->add_text(" (" + w.string_code + "):");
+ warnings_panel->pop(); // Color
+ warnings_panel->pop(); // Meta goto
+ warnings_panel->pop(); // Cell
+
+ warnings_panel->push_cell();
+ warnings_panel->add_text(w.message);
+ warnings_panel->pop(); // Cell
+
+ Dictionary ignore_meta;
+ ignore_meta["line"] = w.line;
+ ignore_meta["code"] = w.string_code.to_lower();
+ warnings_panel->push_cell();
+ warnings_panel->push_meta(ignore_meta);
+ warnings_panel->add_text(TTR("(ignore)"));
+ warnings_panel->pop(); // Meta ignore
+ warnings_panel->pop(); // Cell
+ //warnings_panel->add_newline();
+ }
+ warnings_panel->pop(); // Table
+
line--;
bool highlight_safe = EDITOR_DEF("text_editor/highlighting/highlight_type_safe_lines", true);
bool last_is_safe = false;
@@ -967,7 +1016,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
}
} break;
-
case HELP_CONTEXTUAL: {
String text = tx->get_selection_text();
@@ -977,6 +1025,15 @@ void ScriptTextEditor::_edit_option(int p_op) {
emit_signal("request_help_search", text);
}
} break;
+ case LOOKUP_SYMBOL: {
+
+ String text = tx->get_word_under_cursor();
+ if (text == "")
+ text = tx->get_selection_text();
+ if (text != "") {
+ _lookup_symbol(text, tx->cursor_get_line(), tx->cursor_get_column());
+ }
+ } break;
}
}
@@ -1014,6 +1071,8 @@ void ScriptTextEditor::_bind_methods() {
ClassDB::bind_method("_goto_line", &ScriptTextEditor::_goto_line);
ClassDB::bind_method("_lookup_symbol", &ScriptTextEditor::_lookup_symbol);
ClassDB::bind_method("_text_edit_gui_input", &ScriptTextEditor::_text_edit_gui_input);
+ ClassDB::bind_method("_toggle_warning_pannel", &ScriptTextEditor::_toggle_warning_pannel);
+ ClassDB::bind_method("_warning_clicked", &ScriptTextEditor::_warning_clicked);
ClassDB::bind_method("_color_changed", &ScriptTextEditor::_color_changed);
ClassDB::bind_method("get_drag_data_fw", &ScriptTextEditor::get_drag_data_fw);
@@ -1182,19 +1241,13 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_RIGHT) {
-
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
int col, row;
TextEdit *tx = code_editor->get_text_edit();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
Vector2 mpos = mb->get_global_position() - tx->get_global_position();
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
- bool has_color = (tx->get_word_at_pos(mpos) == "Color");
- int fold_state = 0;
- bool can_fold = tx->can_fold(row);
- bool is_folded = tx->is_folded(row);
-
if (tx->is_right_click_moving_caret()) {
if (tx->is_selection_active()) {
@@ -1214,38 +1267,62 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
}
- if (!mb->is_pressed()) {
- if (has_color) {
- String line = tx->get_line(row);
- color_line = row;
- int begin = 0;
- int end = 0;
- bool valid = false;
- for (int i = col; i < line.length(); i++) {
- if (line[i] == '(') {
- begin = i;
- continue;
- } else if (line[i] == ')') {
- end = i + 1;
- valid = true;
- break;
- }
+ String word_at_mouse = tx->get_word_at_pos(mpos);
+ if (word_at_mouse == "")
+ word_at_mouse = tx->get_word_under_cursor();
+ if (word_at_mouse == "")
+ word_at_mouse = tx->get_selection_text();
+
+ bool has_color = (word_at_mouse == "Color");
+ int fold_state = 0;
+ bool foldable = tx->can_fold(row) || tx->is_folded(row);
+ bool open_docs = false;
+ bool goto_definition = false;
+
+ if (word_at_mouse.is_resource_file()) {
+ open_docs = true;
+ } else {
+
+ Node *base = get_tree()->get_edited_scene_root();
+ if (base) {
+ base = _find_node_for_script(base, base, script);
+ }
+ ScriptLanguage::LookupResult result;
+ if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), word_at_mouse, script->get_path().get_base_dir(), base, result) == OK) {
+ open_docs = true;
+ }
+ }
+
+ if (has_color) {
+ String line = tx->get_line(row);
+ color_line = row;
+ int begin = 0;
+ int end = 0;
+ bool valid = false;
+ for (int i = col; i < line.length(); i++) {
+ if (line[i] == '(') {
+ begin = i;
+ continue;
+ } else if (line[i] == ')') {
+ end = i + 1;
+ valid = true;
+ break;
}
- if (valid) {
- color_args = line.substr(begin, end - begin);
- String stripped = color_args.replace(" ", "").replace("(", "").replace(")", "");
- Vector<float> color = stripped.split_floats(",");
- if (color.size() > 2) {
- float alpha = color.size() > 3 ? color[3] : 1.0f;
- color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
- }
- color_panel->set_position(get_global_transform().xform(get_local_mouse_position()));
- } else {
- has_color = false;
+ }
+ if (valid) {
+ color_args = line.substr(begin, end - begin);
+ String stripped = color_args.replace(" ", "").replace("(", "").replace(")", "");
+ Vector<float> color = stripped.split_floats(",");
+ if (color.size() > 2) {
+ float alpha = color.size() > 3 ? color[3] : 1.0f;
+ color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
}
+ color_panel->set_position(get_global_transform().xform(get_local_mouse_position()));
+ } else {
+ has_color = false;
}
- _make_context_menu(tx->is_selection_active(), has_color, can_fold, is_folded);
}
+ _make_context_menu(tx->is_selection_active(), has_color, foldable, open_docs, goto_definition);
}
}
}
@@ -1264,7 +1341,7 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
code_editor->get_text_edit()->set_line(color_line, new_line);
}
-void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded) {
+void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
context_menu->clear();
if (p_selection) {
@@ -1287,13 +1364,17 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
}
- if (p_can_fold || p_is_folded)
+ if (p_foldable)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
- if (p_color) {
+ if (p_color || p_open_docs || p_goto_definition) {
context_menu->add_separator();
- context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
+ if (p_open_docs)
+ context_menu->add_item(TTR("Lookup Symbol"), LOOKUP_SYMBOL);
+ if (p_color)
+ context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
}
+
context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
context_menu->set_size(Vector2(1, 1));
context_menu->popup();
@@ -1303,8 +1384,13 @@ ScriptTextEditor::ScriptTextEditor() {
theme_loaded = false;
+ VSplitContainer *editor_box = memnew(VSplitContainer);
+ add_child(editor_box);
+ editor_box->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ editor_box->set_v_size_flags(SIZE_EXPAND_FILL);
+
code_editor = memnew(CodeTextEditor);
- add_child(code_editor);
+ editor_box->add_child(code_editor);
code_editor->add_constant_override("separation", 0);
code_editor->set_anchors_and_margins_preset(Control::PRESET_WIDE);
code_editor->connect("validate_script", this, "_validate_script");
@@ -1312,7 +1398,20 @@ ScriptTextEditor::ScriptTextEditor() {
code_editor->set_code_complete_func(_code_complete_scripts, this);
code_editor->get_text_edit()->connect("breakpoint_toggled", this, "_breakpoint_toggled");
code_editor->get_text_edit()->connect("symbol_lookup", this, "_lookup_symbol");
- code_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ code_editor->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ warnings_panel = memnew(RichTextLabel);
+ editor_box->add_child(warnings_panel);
+ warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE));
+ warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL);
+ warnings_panel->set_meta_underline(true);
+ warnings_panel->set_selection_enabled(true);
+ warnings_panel->set_focus_mode(FOCUS_CLICK);
+ warnings_panel->hide();
+
+ code_editor->get_warning_label()->connect("gui_input", this, "_toggle_warning_pannel");
+ code_editor->get_warning_count_label()->connect("gui_input", this, "_toggle_warning_pannel");
+ warnings_panel->connect("meta_clicked", this, "_warning_clicked");
update_settings();
@@ -1327,6 +1426,7 @@ ScriptTextEditor::ScriptTextEditor() {
context_menu = memnew(PopupMenu);
add_child(context_menu);
context_menu->connect("id_pressed", this, "_edit_option");
+ context_menu->set_hide_on_window_lose_focus(true);
color_panel = memnew(PopupPanel);
add_child(color_panel);
@@ -1338,6 +1438,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu = memnew(MenuButton);
edit_menu->set_text(TTR("Edit"));
+ edit_menu->get_popup()->set_hide_on_window_lose_focus(true);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -1391,6 +1492,7 @@ ScriptTextEditor::ScriptTextEditor() {
search_menu = memnew(MenuButton);
edit_hb->add_child(search_menu);
search_menu->set_text(TTR("Search"));
+ search_menu->get_popup()->set_hide_on_window_lose_focus(true);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index f0b00a9117..837201a947 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -39,6 +39,7 @@ class ScriptTextEditor : public ScriptEditorBase {
GDCLASS(ScriptTextEditor, ScriptEditorBase);
CodeTextEditor *code_editor;
+ RichTextLabel *warnings_panel;
Ref<Script> script;
@@ -112,6 +113,7 @@ class ScriptTextEditor : public ScriptEditorBase {
DEBUG_GOTO_NEXT_BREAKPOINT,
DEBUG_GOTO_PREV_BREAKPOINT,
HELP_CONTEXTUAL,
+ LOOKUP_SYMBOL,
};
protected:
@@ -123,6 +125,8 @@ protected:
void _code_complete_script(const String &p_code, List<String> *r_options, bool &r_force);
void _load_theme_settings();
void _set_theme_for_script();
+ void _toggle_warning_pannel(const Ref<InputEvent> &p_event);
+ void _warning_clicked(Variant p_line);
void _notification(int p_what);
static void _bind_methods();
@@ -131,7 +135,7 @@ protected:
void _change_syntax_highlighter(int p_idx);
void _edit_option(int p_op);
- void _make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded);
+ void _make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition);
void _text_edit_gui_input(const Ref<InputEvent> &ev);
void _color_changed(const Color &p_color);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 7650cd6ae7..ea1876c27a 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -465,7 +465,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (mb.is_valid()) {
- if (mb->get_button_index() == BUTTON_RIGHT) {
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
int col, row;
TextEdit *tx = shader_editor->get_text_edit();
@@ -491,10 +491,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
tx->cursor_set_column(col);
}
}
-
- if (!mb->is_pressed()) {
- _make_context_menu(tx->is_selection_active());
- }
+ _make_context_menu(tx->is_selection_active());
}
}
}
@@ -546,6 +543,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
context_menu = memnew(PopupMenu);
add_child(context_menu);
context_menu->connect("id_pressed", this, "_menu_option");
+ context_menu->set_hide_on_window_lose_focus(true);
VBoxContainer *main_container = memnew(VBoxContainer);
HBoxContainer *hbc = memnew(HBoxContainer);
@@ -554,6 +552,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
//edit_menu->set_position(Point2(5, -1));
edit_menu->set_text(TTR("Edit"));
+ edit_menu->get_popup()->set_hide_on_window_lose_focus(true);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -578,7 +577,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
search_menu = memnew(MenuButton);
//search_menu->set_position(Point2(38, -1));
search_menu->set_text(TTR("Search"));
-
+ search_menu->get_popup()->set_hide_on_window_lose_focus(true);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp
index 40a696119e..fe7d1df50c 100644
--- a/editor/plugins/skeleton_editor_plugin.cpp
+++ b/editor/plugins/skeleton_editor_plugin.cpp
@@ -68,16 +68,16 @@ void SkeletonEditor::create_physical_skeleton() {
if (parent < 0) {
- bones_infos[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
+ bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
} else {
- bones_infos[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
+ bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
/// create physical bone on parent
if (!bones_infos[parent].physical_bone) {
- bones_infos[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
+ bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
ur->create_action(TTR("Create physical bones"));
ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
diff --git a/editor/plugins/skeleton_ik_editor_plugin.cpp b/editor/plugins/skeleton_ik_editor_plugin.cpp
new file mode 100644
index 0000000000..2d343d3edd
--- /dev/null
+++ b/editor/plugins/skeleton_ik_editor_plugin.cpp
@@ -0,0 +1,110 @@
+/*************************************************************************/
+/* skeleton_ik_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "skeleton_ik_editor_plugin.h"
+
+#include "scene/animation/skeleton_ik.h"
+
+void SkeletonIKEditorPlugin::_play() {
+
+ if (!skeleton_ik)
+ return;
+
+ if (!skeleton_ik->get_parent_skeleton())
+ return;
+
+ if (play_btn->is_pressed()) {
+
+ initial_bone_poses.resize(skeleton_ik->get_parent_skeleton()->get_bone_count());
+ for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) {
+ initial_bone_poses.write[i] = skeleton_ik->get_parent_skeleton()->get_bone_pose(i);
+ }
+
+ skeleton_ik->start();
+ } else {
+ skeleton_ik->stop();
+
+ if (initial_bone_poses.size() != skeleton_ik->get_parent_skeleton()->get_bone_count())
+ return;
+
+ for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) {
+ skeleton_ik->get_parent_skeleton()->set_bone_pose(i, initial_bone_poses[i]);
+ }
+ }
+}
+
+void SkeletonIKEditorPlugin::edit(Object *p_object) {
+
+ if (p_object != skeleton_ik) {
+ if (skeleton_ik) {
+ play_btn->set_pressed(false);
+ _play();
+ }
+ }
+
+ SkeletonIK *s = Object::cast_to<SkeletonIK>(p_object);
+ if (!s)
+ return;
+
+ skeleton_ik = s;
+}
+
+bool SkeletonIKEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("SkeletonIK");
+}
+
+void SkeletonIKEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible)
+ play_btn->show();
+ else
+ play_btn->hide();
+}
+
+void SkeletonIKEditorPlugin::_bind_methods() {
+
+ ClassDB::bind_method("_play", &SkeletonIKEditorPlugin::_play);
+}
+
+SkeletonIKEditorPlugin::SkeletonIKEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ play_btn = memnew(Button);
+ play_btn->set_icon(editor->get_gui_base()->get_icon("Play", "EditorIcons"));
+ play_btn->set_text(TTR("Play IK"));
+ play_btn->set_toggle_mode(true);
+ play_btn->hide();
+ play_btn->connect("pressed", this, "_play");
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, play_btn);
+ skeleton_ik = NULL;
+}
+
+SkeletonIKEditorPlugin::~SkeletonIKEditorPlugin() {}
diff --git a/editor/plugins/skeleton_ik_editor_plugin.h b/editor/plugins/skeleton_ik_editor_plugin.h
new file mode 100644
index 0000000000..e645bea39a
--- /dev/null
+++ b/editor/plugins/skeleton_ik_editor_plugin.h
@@ -0,0 +1,65 @@
+/*************************************************************************/
+/* skeleton_ik_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SKELETON_IK_EDITOR_PLUGIN_H
+#define SKELETON_IK_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+
+class SkeletonIK;
+
+class SkeletonIKEditorPlugin : public EditorPlugin {
+
+ GDCLASS(SkeletonIKEditorPlugin, EditorPlugin);
+
+ SkeletonIK *skeleton_ik;
+
+ Button *play_btn;
+ EditorNode *editor;
+ Vector<Transform> initial_bone_poses;
+
+ void _play();
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_name() const { return "SkeletonIK"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual void make_visible(bool p_visible);
+
+ SkeletonIKEditorPlugin(EditorNode *p_node);
+ ~SkeletonIKEditorPlugin();
+};
+
+#endif // SKELETON_IK_EDITOR_PLUGIN_H
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index f0c874a150..c3d48d498c 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -184,49 +184,6 @@ Transform SpatialEditorViewport::to_camera_transform(const Cursor &p_cursor) con
return camera_transform;
}
-String SpatialEditorGizmo::get_handle_name(int p_idx) const {
-
- if (get_script_instance() && get_script_instance()->has_method("get_handle_name"))
- return get_script_instance()->call("get_handle_name", p_idx);
-
- return "";
-}
-
-Variant SpatialEditorGizmo::get_handle_value(int p_idx) const {
-
- if (get_script_instance() && get_script_instance()->has_method("get_handle_value"))
- return get_script_instance()->call("get_handle_value", p_idx);
-
- return Variant();
-}
-
-void SpatialEditorGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
-
- if (get_script_instance() && get_script_instance()->has_method("set_handle"))
- get_script_instance()->call("set_handle", p_idx, p_camera, p_point);
-}
-
-void SpatialEditorGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
- if (get_script_instance() && get_script_instance()->has_method("commit_handle"))
- get_script_instance()->call("commit_handle", p_idx, p_restore, p_cancel);
-}
-
-bool SpatialEditorGizmo::intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum) {
-
- return false;
-}
-
-bool SpatialEditorGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
-
- return false;
-}
-
-SpatialEditorGizmo::SpatialEditorGizmo() {
-
- selected = false;
-}
-
int SpatialEditorViewport::get_selected_count() const {
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -346,7 +303,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
Vector3 pos = _get_ray_pos(p_pos);
Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario());
- Set<Ref<SpatialEditorGizmo> > found_gizmos;
+ Set<Ref<EditorSpatialGizmo> > found_gizmos;
Node *edited_scene = get_tree()->get_edited_scene_root();
ObjectID closest = 0;
@@ -361,7 +318,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
if (!spat)
continue;
- Ref<SpatialEditorGizmo> seg = spat->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = spat->get_gizmo();
if ((!seg.is_valid()) || found_gizmos.has(seg)) {
continue;
@@ -418,7 +375,7 @@ void SpatialEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_incl
Vector3 pos = _get_ray_pos(p_pos);
Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario());
- Set<Ref<SpatialEditorGizmo> > found_gizmos;
+ Set<Ref<EditorSpatialGizmo> > found_gizmos;
r_includes_current = false;
@@ -429,7 +386,7 @@ void SpatialEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_incl
if (!spat)
continue;
- Ref<SpatialEditorGizmo> seg = spat->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = spat->get_gizmo();
if (!seg.is_valid())
continue;
@@ -559,7 +516,7 @@ void SpatialEditorViewport::_select_region() {
if (selected.find(root_sp) != -1) continue;
- Ref<SpatialEditorGizmo> seg = sp->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = sp->get_gizmo();
if (!seg.is_valid())
continue;
@@ -963,7 +920,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed() && _edit.gizmo.is_valid()) {
//restore
_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, true);
- _edit.gizmo = Ref<SpatialEditorGizmo>();
+ _edit.gizmo = Ref<EditorSpatialGizmo>();
}
if (_edit.mode == TRANSFORM_NONE && b->is_pressed()) {
@@ -1079,7 +1036,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (can_select_gizmos && spatial_editor->get_selected()) {
- Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = spatial_editor->get_selected()->get_gizmo();
if (seg.is_valid()) {
int handle = -1;
Vector3 point;
@@ -1158,7 +1115,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Spatial *spa = Object::cast_to<Spatial>(ObjectDB::get_instance(clicked));
if (spa) {
- Ref<SpatialEditorGizmo> seg = spa->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = spa->get_gizmo();
if (seg.is_valid()) {
_edit.gizmo = seg;
@@ -1175,7 +1132,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (_edit.gizmo.is_valid()) {
_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false);
- _edit.gizmo = Ref<SpatialEditorGizmo>();
+ _edit.gizmo = Ref<EditorSpatialGizmo>();
break;
}
if (clicked) {
@@ -1233,7 +1190,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (spatial_editor->get_selected()) {
- Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = spatial_editor->get_selected()->get_gizmo();
if (seg.is_valid()) {
int selected_handle = -1;
@@ -1928,6 +1885,11 @@ void SpatialEditorViewport::_nav_zoom(Ref<InputEventWithModifiers> p_event, cons
void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
+ if (lock_rotation) {
+ _nav_pan(p_event, p_relative);
+ return;
+ }
+
real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
@@ -2151,6 +2113,21 @@ void SpatialEditorViewport::_notification(int p_what) {
_update_freelook(delta);
+ Node *scene_root = editor->get_scene_tree_dock()->get_editor_data()->get_edited_scene_root();
+ if (previewing_cinema == true && scene_root != NULL) {
+ Camera *cam = scene_root->get_viewport()->get_camera();
+ if (cam != NULL && cam != previewing) {
+ //then switch the viewport's camera to the scene's viewport camera
+ if (previewing != NULL) {
+ previewing->disconnect("tree_exited", this, "_preview_exited_scene");
+ }
+ previewing = cam;
+ previewing->connect("tree_exited", this, "_preview_exited_scene");
+ VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera());
+ surface->update();
+ }
+ }
+
_update_camera(delta);
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -2256,6 +2233,13 @@ void SpatialEditorViewport::_notification(int p_what) {
text += TTR("FPS") + ": " + itos(temp_fps) + " (" + String::num(1000.0f / temp_fps, 2) + " ms)";
fps_label->set_text(text);
}
+
+ bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
+ cinema_label->set_visible(show_cinema);
+ if (show_cinema) {
+ float cinema_half_width = cinema_label->get_size().width / 2.0f;
+ cinema_label->set_anchor_and_margin(MARGIN_LEFT, 0.5f, -cinema_half_width);
+ }
}
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -2268,6 +2252,7 @@ void SpatialEditorViewport::_notification(int p_what) {
surface->connect("focus_exited", this, "_surface_focus_exit");
info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
preview_camera->set_icon(get_icon("Camera", "EditorIcons"));
_init_gizmo_instance(index);
}
@@ -2563,6 +2548,19 @@ void SpatialEditorViewport::_menu_option(int p_option) {
_update_name();
} break;
+ case VIEW_LOCK_ROTATION: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_LOCK_ROTATION);
+ bool current = view_menu->get_popup()->is_item_checked(idx);
+ lock_rotation = !current;
+ view_menu->get_popup()->set_item_checked(idx, !current);
+ if (lock_rotation) {
+ view_menu->set_icon(get_icon("Lock", "EditorIcons"));
+ } else {
+ view_menu->set_icon(Ref<Texture>());
+ }
+
+ } break;
case VIEW_AUDIO_LISTENER: {
int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER);
@@ -2581,6 +2579,22 @@ void SpatialEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(idx, current);
} break;
+ case VIEW_CINEMATIC_PREVIEW: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW);
+ bool current = view_menu->get_popup()->is_item_checked(idx);
+ current = !current;
+ view_menu->get_popup()->set_item_checked(idx, current);
+ previewing_cinema = true;
+ _toggle_cinema_preview(current);
+
+ if (current) {
+ preview_camera->hide();
+ } else {
+ if (previewing != NULL)
+ preview_camera->show();
+ }
+ } break;
case VIEW_GIZMOS: {
int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
@@ -2744,6 +2758,25 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
}
}
+void SpatialEditorViewport::_toggle_cinema_preview(bool p_activate) {
+ previewing_cinema = p_activate;
+ if (!previewing_cinema) {
+ if (previewing != NULL)
+ previewing->disconnect("tree_exited", this, "_preview_exited_scene");
+
+ previewing = NULL;
+ VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), camera->get_camera()); //restore
+ preview_camera->set_pressed(false);
+ if (!preview) {
+ preview_camera->hide();
+ } else {
+ preview_camera->show();
+ }
+ view_menu->show();
+ surface->update();
+ }
+}
+
void SpatialEditorViewport::_selection_result_pressed(int p_result) {
if (selection_results.size() <= p_result)
@@ -2768,7 +2801,7 @@ void SpatialEditorViewport::set_can_preview(Camera *p_preview) {
preview = p_preview;
- if (!preview_camera->is_pressed())
+ if (!preview_camera->is_pressed() && !previewing_cinema)
preview_camera->set_visible(p_preview);
}
@@ -2791,7 +2824,7 @@ void SpatialEditorViewport::update_transform_gizmo_view() {
dd = 0.0001;
float gsize = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
- gizmo_scale = (gsize / Math::abs(dd));
+ gizmo_scale = (gsize / Math::abs(dd)) * MAX(1, EDSCALE) / viewport_container->get_stretch_shrink();
Vector3 scale = Vector3(1, 1, 1) * gizmo_scale;
xform.basis.scale(scale);
@@ -2836,6 +2869,12 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
if (!view_menu->get_popup()->is_item_checked(idx))
_menu_option(display);
}
+ if (p_state.has("lock_rotation")) {
+ lock_rotation = p_state["lock_rotation"];
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_LOCK_ROTATION);
+ view_menu->get_popup()->set_item_checked(idx, lock_rotation);
+ }
if (p_state.has("use_environment")) {
bool env = p_state["use_environment"];
@@ -2883,6 +2922,12 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
int idx = view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION);
view_menu->get_popup()->set_item_checked(idx, half_res);
}
+ if (p_state.has("cinematic_preview")) {
+ previewing_cinema = p_state["cinematic_preview"];
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW);
+ view_menu->get_popup()->set_item_checked(idx, previewing_cinema);
+ }
if (p_state.has("previewing")) {
Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]);
@@ -2921,8 +2966,11 @@ Dictionary SpatialEditorViewport::get_state() const {
d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
d["fps"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS));
d["half_res"] = viewport_container->get_stretch_shrink() > 1;
+ d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
if (previewing)
d["previewing"] = EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing);
+ if (lock_rotation)
+ d["lock_rotation"] = lock_rotation;
return d;
}
@@ -2951,6 +2999,7 @@ void SpatialEditorViewport::_bind_methods() {
void SpatialEditorViewport::reset() {
orthogonal = false;
+ lock_rotation = false;
message_time = 0;
message = "";
last_message = "";
@@ -3007,7 +3056,7 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const
Vector3 world_pos = _get_ray_pos(p_pos);
Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario());
- Set<Ref<SpatialEditorGizmo> > found_gizmos;
+ Set<Ref<EditorSpatialGizmo> > found_gizmos;
float closest_dist = MAX_DISTANCE;
@@ -3021,7 +3070,7 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const
if (!mesh_instance)
continue;
- Ref<SpatialEditorGizmo> seg = mesh_instance->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = mesh_instance->get_gizmo();
if ((!seg.is_valid()) || found_gizmos.has(seg)) {
continue;
@@ -3216,7 +3265,7 @@ void SpatialEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->get_ok()->set_text(TTR("Ugh"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
accept->popup_centered_minsize();
}
@@ -3297,7 +3346,7 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
if (root_node) {
list.push_back(root_node);
} else {
- accept->get_ok()->set_text(TTR("OK :("));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered_minsize();
_remove_preview();
@@ -3305,7 +3354,7 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
}
}
if (list.size() != 1) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
_remove_preview();
@@ -3337,6 +3386,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
clicked = 0;
clicked_includes_current = false;
orthogonal = false;
+ lock_rotation = false;
message_time = 0;
zoom_indicator_delay = 0.0;
@@ -3377,6 +3427,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_radio_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true);
view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_lock_rotation", TTR("Lock View Rotation")), VIEW_LOCK_ROTATION);
+ view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL);
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME);
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW);
@@ -3396,6 +3448,9 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_cinematic_preview", TTR("Cinematic Preview")), VIEW_CINEMATIC_PREVIEW);
+
+ view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_origin"), VIEW_CENTER_TO_ORIGIN);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_selection"), VIEW_CENTER_TO_SELECTION);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_selection_with_view"), VIEW_ALIGN_SELECTION_WITH_VIEW);
@@ -3445,6 +3500,15 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
surface->add_child(fps_label);
fps_label->hide();
+ cinema_label = memnew(Label);
+ cinema_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
+ cinema_label->set_h_grow_direction(GROW_DIRECTION_END);
+ cinema_label->set_align(Label::ALIGN_CENTER);
+ surface->add_child(cinema_label);
+ cinema_label->set_text(TTR("Cinematic Preview"));
+ cinema_label->hide();
+ previewing_cinema = false;
+
accept = NULL;
freelook_active = false;
@@ -3786,10 +3850,6 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
}
}
-int SpatialEditor::get_skeleton_visibility_state() const {
- return view_menu->get_popup()->get_item_state(view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON));
-}
-
void SpatialEditor::update_transform_gizmo() {
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -3942,6 +4002,16 @@ Dictionary SpatialEditor::get_state() const {
d["znear"] = get_znear();
d["zfar"] = get_zfar();
+ Dictionary gizmos_status;
+ for (int i = 0; i < gizmo_plugins.size(); i++) {
+ if (!gizmo_plugins[i]->can_be_hidden()) continue;
+ int state = gizmos_menu->get_item_state(gizmos_menu->get_item_index(i));
+ String name = gizmo_plugins[i]->get_name();
+ gizmos_status[name] = state;
+ }
+
+ d["gizmos_status"] = gizmos_status;
+
return d;
}
void SpatialEditor::set_state(const Dictionary &p_state) {
@@ -4015,6 +4085,39 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
VisualServer::get_singleton()->instance_set_visible(origin_instance, use);
}
}
+
+ if (d.has("gizmos_status")) {
+ Dictionary gizmos_status = d["gizmos_status"];
+ List<Variant> keys;
+ gizmos_status.get_key_list(&keys);
+
+ for (int j = 0; j < gizmo_plugins.size(); ++j) {
+ if (!gizmo_plugins[j]->can_be_hidden()) continue;
+ int state = EditorSpatialGizmoPlugin::ON_TOP;
+ for (uint32_t i = 0; i < keys.size(); i++) {
+ if (gizmo_plugins.write[j]->get_name() == keys[i]) {
+ state = gizmos_status[keys[i]];
+ }
+ }
+
+ const int idx = gizmos_menu->get_item_index(j);
+
+ gizmos_menu->set_item_multistate(idx, state);
+ gizmo_plugins.write[j]->set_state(state);
+
+ switch (state) {
+ case EditorSpatialGizmoPlugin::ON_TOP:
+ gizmos_menu->set_item_icon(idx, gizmos_menu->get_icon("visibility_visible"));
+ break;
+ case EditorSpatialGizmoPlugin::VISIBLE:
+ gizmos_menu->set_item_icon(idx, gizmos_menu->get_icon("visibility_xray"));
+ break;
+ case EditorSpatialGizmoPlugin::HIDDEN:
+ gizmos_menu->set_item_icon(idx, gizmos_menu->get_icon("visibility_hidden"));
+ break;
+ }
+ }
+ }
}
void SpatialEditor::edit(Spatial *p_spatial) {
@@ -4022,7 +4125,7 @@ void SpatialEditor::edit(Spatial *p_spatial) {
if (p_spatial != selected) {
if (selected) {
- Ref<SpatialEditorGizmo> seg = selected->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = selected->get_gizmo();
if (seg.is_valid()) {
seg->set_selected(false);
selected->update_gizmo();
@@ -4034,7 +4137,7 @@ void SpatialEditor::edit(Spatial *p_spatial) {
if (selected) {
- Ref<SpatialEditorGizmo> seg = selected->get_gizmo();
+ Ref<EditorSpatialGizmo> seg = selected->get_gizmo();
if (seg.is_valid()) {
seg->set_selected(true);
selected->update_gizmo();
@@ -4108,6 +4211,30 @@ void SpatialEditor::_menu_item_toggled(bool pressed, int p_option) {
}
}
+void SpatialEditor::_menu_gizmo_toggled(int p_option) {
+
+ const int idx = gizmos_menu->get_item_index(p_option);
+ gizmos_menu->toggle_item_multistate(idx);
+
+ // Change icon
+ const int state = gizmos_menu->get_item_state(idx);
+ switch (state) {
+ case EditorSpatialGizmoPlugin::ON_TOP:
+ gizmos_menu->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_visible"));
+ break;
+ case EditorSpatialGizmoPlugin::VISIBLE:
+ gizmos_menu->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_xray"));
+ break;
+ case EditorSpatialGizmoPlugin::HIDDEN:
+ gizmos_menu->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_hidden"));
+ break;
+ }
+
+ gizmo_plugins.write[p_option]->set_state(state);
+
+ update_all_gizmos();
+}
+
void SpatialEditor::_menu_item_pressed(int p_option) {
switch (p_option) {
@@ -4241,6 +4368,9 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
} break;
+ case MENU_SNAP_TO_FLOOR: {
+ snap_selected_nodes_to_floor();
+ } break;
case MENU_LOCK_SELECTED: {
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -4279,28 +4409,6 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
_refresh_menu_icons();
} break;
- case MENU_VISIBILITY_SKELETON: {
-
- const int idx = view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON);
- view_menu->get_popup()->toggle_item_multistate(idx);
-
- // Change icon
- const int state = view_menu->get_popup()->get_item_state(idx);
- switch (state) {
- case 0:
- view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_hidden"));
- break;
- case 1:
- view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_visible"));
- break;
- case 2:
- view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_xray"));
- break;
- }
-
- update_all_gizmos();
-
- } break;
}
}
@@ -4410,9 +4518,9 @@ void SpatialEditor::_init_indicators() {
nivec * 0.0 + ivec * (GIZMO_ARROW_OFFSET + GIZMO_ARROW_SIZE),
};
- int arrow_sides = 6;
+ int arrow_sides = 16;
- for (int k = 0; k < 6; k++) {
+ for (int k = 0; k < arrow_sides; k++) {
Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
@@ -4496,10 +4604,10 @@ void SpatialEditor::_init_indicators() {
ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
};
- for (int k = 0; k < 32; k++) {
+ for (int k = 0; k < 64; k++) {
- Basis ma(ivec, Math_PI * 2 * float(k) / 32);
- Basis mb(ivec, Math_PI * 2 * float(k + 1) / 32);
+ Basis ma(ivec, Math_PI * 2 * float(k) / 64);
+ Basis mb(ivec, Math_PI * 2 * float(k + 1) / 64);
for (int j = 0; j < 4; j++) {
@@ -4616,6 +4724,26 @@ void SpatialEditor::_init_indicators() {
_generate_selection_box();
}
+struct _GizmoPluginComparator {
+
+ bool operator()(const Ref<EditorSpatialGizmoPlugin> &p_a, const Ref<EditorSpatialGizmoPlugin> &p_b) const {
+ return p_a->get_name() < p_b->get_name();
+ }
+};
+
+void SpatialEditor::_init_gizmos_menu() {
+ _register_all_gizmos();
+
+ gizmo_plugins.sort_custom<_GizmoPluginComparator>();
+
+ for (int i = 0; i < gizmo_plugins.size(); ++i) {
+ if (!gizmo_plugins[i]->can_be_hidden()) continue;
+ String plugin_name = gizmo_plugins[i]->get_name();
+ gizmos_menu->add_multistate_item(TTR(plugin_name), 3, EditorSpatialGizmoPlugin::ON_TOP, i);
+ gizmos_menu->set_item_icon(gizmos_menu->get_item_index(i), gizmos_menu->get_icon("visibility_visible"));
+ }
+}
+
void SpatialEditor::_init_grid() {
PoolVector<Color> grid_colors[3];
@@ -4716,6 +4844,119 @@ void SpatialEditor::_refresh_menu_icons() {
tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
}
+template <typename T>
+Set<T *> _get_child_nodes(Node *parent_node) {
+ Set<T *> nodes = Set<T *>();
+ T *node = Node::cast_to<T>(parent_node);
+ if (node) {
+ nodes.insert(node);
+ }
+
+ for (int i = 0; i < parent_node->get_child_count(); i++) {
+ Node *child_node = parent_node->get_child(i);
+ Set<T *> child_nodes = _get_child_nodes<T>(child_node);
+ for (typename Set<T *>::Element *I = child_nodes.front(); I; I = I->next()) {
+ nodes.insert(I->get());
+ }
+ }
+
+ return nodes;
+}
+
+Set<RID> _get_physics_bodies_rid(Node *node) {
+ Set<RID> rids = Set<RID>();
+ PhysicsBody *pb = Node::cast_to<PhysicsBody>(node);
+ if (pb) {
+ rids.insert(pb->get_rid());
+ }
+ Set<PhysicsBody *> child_nodes = _get_child_nodes<PhysicsBody>(node);
+ for (Set<PhysicsBody *>::Element *I = child_nodes.front(); I; I = I->next()) {
+ rids.insert(I->get()->get_rid());
+ }
+
+ return rids;
+}
+
+void SpatialEditor::snap_selected_nodes_to_floor() {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ Dictionary snap_data;
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Spatial *sp = Object::cast_to<Spatial>(E->get());
+ if (sp) {
+ Vector3 from = Vector3();
+ Vector3 position_offset = Vector3();
+
+ // Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin
+ Set<VisualInstance *> vi = _get_child_nodes<VisualInstance>(sp);
+ Set<CollisionShape *> cs = _get_child_nodes<CollisionShape>(sp);
+
+ if (cs.size()) {
+ AABB aabb = sp->get_global_transform().xform(cs.front()->get()->get_shape()->get_debug_mesh()->get_aabb());
+ for (Set<CollisionShape *>::Element *I = cs.front(); I; I = I->next()) {
+ aabb.merge_with(sp->get_global_transform().xform(I->get()->get_shape()->get_debug_mesh()->get_aabb()));
+ }
+ Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
+ from = aabb.position + size;
+ position_offset.y = from.y - sp->get_global_transform().origin.y;
+ } else if (vi.size()) {
+ AABB aabb = vi.front()->get()->get_transformed_aabb();
+ for (Set<VisualInstance *>::Element *I = vi.front(); I; I = I->next()) {
+ aabb.merge_with(I->get()->get_transformed_aabb());
+ }
+ Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
+ from = aabb.position + size;
+ position_offset.y = from.y - sp->get_global_transform().origin.y;
+ } else {
+ from = sp->get_global_transform().origin;
+ }
+
+ // We add a bit of margin to the from position to avoid it from snapping
+ // when the spatial is already on a floor and there's another floor under
+ // it
+ from = from + Vector3(0.0, 0.1, 0.0);
+
+ Dictionary d;
+
+ d["from"] = from;
+ d["position_offset"] = position_offset;
+ snap_data[sp] = d;
+ }
+ }
+
+ PhysicsDirectSpaceState *ss = get_tree()->get_root()->get_world()->get_direct_space_state();
+ PhysicsDirectSpaceState::RayResult result;
+
+ Array keys = snap_data.keys();
+
+ if (keys.size()) {
+ undo_redo->create_action("Snap Nodes To Floor");
+
+ for (int i = 0; i < keys.size(); i++) {
+ Node *node = keys[i];
+ Spatial *sp = Object::cast_to<Spatial>(node);
+
+ Dictionary d = snap_data[node];
+ Vector3 from = d["from"];
+ Vector3 position_offset = d["position_offset"];
+
+ Vector3 to = from - Vector3(0.0, 10.0, 0.0);
+ Set<RID> excluded = _get_physics_bodies_rid(sp);
+
+ if (ss->intersect_ray(from, to, result, excluded)) {
+ Transform new_transform = sp->get_global_transform();
+ new_transform.origin.y = result.position.y;
+ new_transform.origin = new_transform.origin - position_offset;
+
+ undo_redo->add_do_method(sp, "set_global_transform", new_transform);
+ undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
+ }
+ }
+
+ undo_redo->commit_action();
+ }
+}
+
void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
@@ -4744,6 +4985,8 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event))
_menu_item_pressed(MENU_TOOL_SCALE);
+ else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event))
+ snap_selected_nodes_to_floor();
else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event))
if (are_local_coords_enabled()) {
@@ -4781,7 +5024,6 @@ void SpatialEditor::_notification(int p_what) {
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), get_icon("Panels3", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_icon("Panels3Alt", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_icon("Panels4", "EditorIcons"));
- view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON), view_menu->get_popup()->get_icon("visibility_visible"));
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
@@ -4794,14 +5036,13 @@ void SpatialEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- gizmos = memnew(SpatialEditorGizmos);
+ _init_gizmos_menu();
_init_indicators();
}
if (p_what == NOTIFICATION_EXIT_TREE) {
_finish_indicators();
- memdelete(gizmos);
}
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
tool_button[SpatialEditor::TOOL_MODE_SELECT]->set_icon(get_icon("ToolSelect", "EditorIcons"));
@@ -4860,25 +5101,21 @@ void SpatialEditor::_request_gizmo(Object *p_obj) {
return;
if (editor->get_edited_scene() && (sp == editor->get_edited_scene() || (sp->get_owner() && editor->get_edited_scene()->is_a_parent_of(sp)))) {
- Ref<SpatialEditorGizmo> seg;
+ Ref<EditorSpatialGizmo> seg;
- for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count(); i++) {
+ for (int i = 0; i < gizmo_plugins.size(); ++i) {
+ seg = gizmo_plugins.write[i]->get_gizmo(sp);
- seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp);
- if (seg.is_valid())
- break;
- }
+ if (seg.is_valid()) {
+ sp->set_gizmo(seg);
- if (!seg.is_valid()) {
- seg = gizmos->get_gizmo(sp);
- }
- if (seg.is_valid()) {
- sp->set_gizmo(seg);
- }
+ if (sp == selected) {
+ seg->set_selected(true);
+ selected->update_gizmo();
+ }
- if (seg.is_valid() && sp == selected) {
- seg->set_selected(true);
- selected->update_gizmo();
+ break;
+ }
}
}
}
@@ -4934,11 +5171,35 @@ void SpatialEditor::_node_removed(Node *p_node) {
selected = NULL;
}
+void SpatialEditor::_register_all_gizmos() {
+ register_gizmo_plugin(Ref<CameraSpatialGizmoPlugin>(memnew(CameraSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<LightSpatialGizmoPlugin>(memnew(LightSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<AudioStreamPlayer3DSpatialGizmoPlugin>(memnew(AudioStreamPlayer3DSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<MeshInstanceSpatialGizmoPlugin>(memnew(MeshInstanceSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<SoftBodySpatialGizmoPlugin>(memnew(SoftBodySpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<Sprite3DSpatialGizmoPlugin>(memnew(Sprite3DSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<Position3DSpatialGizmoPlugin>(memnew(Position3DSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<SkeletonSpatialGizmoPlugin>(memnew(SkeletonSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<RayCastSpatialGizmoPlugin>(memnew(RayCastSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
+ register_gizmo_plugin(Ref<ParticlesGizmoPlugin>(memnew(ParticlesGizmoPlugin)));
+ register_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
+ register_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
+ register_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
+ register_gizmo_plugin(Ref<CollisionShapeSpatialGizmoPlugin>(memnew(CollisionShapeSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<CollisionPolygonSpatialGizmoPlugin>(memnew(CollisionPolygonSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<NavigationMeshSpatialGizmoPlugin>(memnew(NavigationMeshSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<JointSpatialGizmoPlugin>(memnew(JointSpatialGizmoPlugin)));
+ register_gizmo_plugin(Ref<PhysicalBoneSpatialGizmoPlugin>(memnew(PhysicalBoneSpatialGizmoPlugin)));
+}
+
void SpatialEditor::_bind_methods() {
ClassDB::bind_method("_unhandled_key_input", &SpatialEditor::_unhandled_key_input);
ClassDB::bind_method("_node_removed", &SpatialEditor::_node_removed);
ClassDB::bind_method("_menu_item_pressed", &SpatialEditor::_menu_item_pressed);
+ ClassDB::bind_method("_menu_gizmo_toggled", &SpatialEditor::_menu_gizmo_toggled);
ClassDB::bind_method("_menu_item_toggled", &SpatialEditor::_menu_item_toggled);
ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action);
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
@@ -5009,7 +5270,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
tool_button[TOOL_MODE_SELECT]->set_flat(true);
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
- button_binds[0] = MENU_TOOL_SELECT;
+ button_binds.write[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
@@ -5017,7 +5278,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
tool_button[TOOL_MODE_MOVE]->set_flat(true);
- button_binds[0] = MENU_TOOL_MOVE;
+ button_binds.write[0] = MENU_TOOL_MOVE;
tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
@@ -5025,7 +5286,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true);
tool_button[TOOL_MODE_ROTATE]->set_flat(true);
- button_binds[0] = MENU_TOOL_ROTATE;
+ button_binds.write[0] = MENU_TOOL_ROTATE;
tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
@@ -5033,7 +5294,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true);
tool_button[TOOL_MODE_SCALE]->set_flat(true);
- button_binds[0] = MENU_TOOL_SCALE;
+ button_binds.write[0] = MENU_TOOL_SCALE;
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
@@ -5041,19 +5302,19 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true);
- button_binds[0] = MENU_TOOL_LIST_SELECT;
+ button_binds.write[0] = MENU_TOOL_LIST_SELECT;
tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
- button_binds[0] = MENU_LOCK_SELECTED;
+ button_binds.write[0] = MENU_LOCK_SELECTED;
tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
- button_binds[0] = MENU_UNLOCK_SELECTED;
+ button_binds.write[0] = MENU_UNLOCK_SELECTED;
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
@@ -5064,7 +5325,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
- button_binds[0] = MENU_TOOL_LOCAL_COORDS;
+ button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
@@ -5074,7 +5335,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
- button_binds[0] = MENU_TOOL_USE_SNAP;
+ button_binds.write[0] = MENU_TOOL_USE_SNAP;
tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
@@ -5103,6 +5364,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W);
ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E);
ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R);
+ ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap To Floor"), KEY_PAGEDOWN);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
@@ -5113,6 +5375,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(transform_menu);
p = transform_menu->get_popup();
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap object to floor")), MENU_SNAP_TO_FLOOR);
p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog...")), MENU_TRANSFORM_DIALOG);
@@ -5137,19 +5400,26 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD + KEY_4), MENU_VIEW_USE_4_VIEWPORTS);
p->add_separator();
+ p->add_submenu_item(TTR("Gizmos"), "GizmosMenu");
+
+ p->add_separator();
+
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
- p->add_separator();
- p->add_multistate_item(TTR("Skeleton Gizmo visibility"), 3, 1, MENU_VISIBILITY_SKELETON);
-
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
p->connect("id_pressed", this, "_menu_item_pressed");
+ gizmos_menu = memnew(PopupMenu);
+ p->add_child(gizmos_menu);
+ gizmos_menu->set_name("GizmosMenu");
+ gizmos_menu->set_hide_on_checkable_item_selection(false);
+ gizmos_menu->connect("id_pressed", this, "_menu_gizmo_toggled");
+
/* REST OF MENU */
palette_split = memnew(HSplitContainer);
@@ -5357,6 +5627,10 @@ void SpatialEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) {
spatial_editor->snap_cursor_to_plane(p_plane);
}
+void SpatialEditor::register_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> ref) {
+ gizmo_plugins.push_back(ref);
+}
+
SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) {
editor = p_node;
@@ -5370,3 +5644,182 @@ SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) {
SpatialEditorPlugin::~SpatialEditorPlugin() {
}
+
+void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) {
+
+ Color instanced_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced");
+
+ Vector<Ref<SpatialMaterial> > mats;
+
+ for (int i = 0; i < 4; i++) {
+ bool selected = i % 2 == 1;
+ bool instanced = i < 2;
+
+ Ref<SpatialMaterial> material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+
+ Color color = instanced ? instanced_color : p_color;
+
+ if (!selected) {
+ color.a *= 0.3;
+ }
+
+ material->set_albedo(color);
+ material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ material->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MIN + 1);
+
+ if (p_use_vertex_color) {
+ material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ }
+
+ if (p_billboard) {
+ material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
+ }
+
+ if (p_on_top && selected) {
+ material->set_on_top_of_alpha();
+ }
+
+ mats.push_back(material);
+ }
+
+ materials[p_name] = mats;
+}
+
+void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top, const Color &p_albedo) {
+
+ Color instanced_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced");
+
+ Vector<Ref<SpatialMaterial> > icons;
+
+ for (int i = 0; i < 4; i++) {
+ bool selected = i % 2 == 1;
+ bool instanced = i < 2;
+
+ Ref<SpatialMaterial> icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+
+ Color color = instanced ? instanced_color : p_albedo;
+
+ if (!selected) {
+ color.a *= 0.3;
+ }
+
+ icon->set_albedo(color);
+
+ icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
+ icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, p_texture);
+ icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true);
+ icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
+ icon->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MIN);
+
+ if (p_on_top && selected) {
+ icon->set_on_top_of_alpha();
+ }
+
+ icons.push_back(icon);
+ }
+
+ materials[p_name] = icons;
+}
+
+void EditorSpatialGizmoPlugin::create_handle_material(const String &p_name, bool p_billboard) {
+ Ref<SpatialMaterial> handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+
+ handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ handle_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
+ Ref<Texture> handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons");
+ handle_material->set_point_size(handle_t->get_width());
+ handle_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle_t);
+ handle_material->set_albedo(Color(1, 1, 1));
+ handle_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ handle_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ handle_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ handle_material->set_on_top_of_alpha();
+ if (p_billboard) {
+ handle_material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
+ handle_material->set_on_top_of_alpha();
+ }
+
+ materials[p_name] = Vector<Ref<SpatialMaterial> >();
+ materials[p_name].push_back(handle_material);
+}
+
+void EditorSpatialGizmoPlugin::add_material(const String &p_name, Ref<SpatialMaterial> p_material) {
+ materials[p_name] = Vector<Ref<SpatialMaterial> >();
+ materials[p_name].push_back(p_material);
+}
+
+Ref<SpatialMaterial> EditorSpatialGizmoPlugin::get_material(const String &p_name, EditorSpatialGizmo *p_gizmo) {
+ ERR_FAIL_COND_V(!materials.has(p_name), Ref<SpatialMaterial>());
+ ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref<SpatialMaterial>());
+
+ if (p_gizmo == NULL) return materials[p_name][0];
+
+ int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0);
+
+ Ref<SpatialMaterial> mat = materials[p_name][index];
+
+ if (current_state == ON_TOP && p_gizmo->is_selected()) {
+ mat->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, true);
+ } else {
+ mat->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, false);
+ }
+
+ return mat;
+}
+
+Ref<EditorSpatialGizmo> EditorSpatialGizmoPlugin::get_gizmo(Spatial *p_spatial) {
+
+ Ref<EditorSpatialGizmo> ref = create_gizmo(p_spatial);
+
+ if (ref.is_null()) return ref;
+
+ ref->set_plugin(this);
+ ref->set_spatial_node(p_spatial);
+ ref->set_hidden(current_state == HIDDEN);
+
+ current_gizmos.push_back(ref.ptr());
+ return ref;
+}
+
+bool EditorSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return false;
+}
+
+Ref<EditorSpatialGizmo> EditorSpatialGizmoPlugin::create_gizmo(Spatial *p_spatial) {
+
+ Ref<EditorSpatialGizmo> ref;
+ if (has_gizmo(p_spatial)) ref.instance();
+ return ref;
+}
+
+bool EditorSpatialGizmoPlugin::can_be_hidden() const {
+ return true;
+}
+
+bool EditorSpatialGizmoPlugin::is_selectable_when_hidden() const {
+ return false;
+}
+
+void EditorSpatialGizmoPlugin::set_state(int p_state) {
+ current_state = p_state;
+ for (int i = 0; i < current_gizmos.size(); ++i) {
+ current_gizmos[i]->set_hidden(current_state == HIDDEN);
+ }
+}
+
+void EditorSpatialGizmoPlugin::unregister_gizmo(EditorSpatialGizmo *p_gizmo) {
+ current_gizmos.erase(p_gizmo);
+}
+
+EditorSpatialGizmoPlugin::EditorSpatialGizmoPlugin() {
+ current_state = ON_TOP;
+}
+
+EditorSpatialGizmoPlugin::~EditorSpatialGizmoPlugin() {
+}
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index af882f6e05..0ebc11e5df 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -43,11 +43,11 @@
class Camera;
class SpatialEditor;
-class SpatialEditorGizmos;
+class EditorSpatialGizmoPlugin;
-class SpatialEditorGizmo : public SpatialGizmo {
+class EditorSpatialGizmo : public SpatialGizmo {
- GDCLASS(SpatialEditorGizmo, SpatialGizmo);
+ GDCLASS(EditorSpatialGizmo, SpatialGizmo);
bool selected;
bool instanced;
@@ -56,15 +56,86 @@ public:
void set_selected(bool p_selected) { selected = p_selected; }
bool is_selected() const { return selected; }
+ struct Instance {
+
+ RID instance;
+ Ref<ArrayMesh> mesh;
+ RID skeleton;
+ bool billboard;
+ bool unscaled;
+ bool can_intersect;
+ bool extra_margin;
+ Instance() {
+
+ billboard = false;
+ unscaled = false;
+ can_intersect = false;
+ extra_margin = false;
+ }
+
+ void create_instance(Spatial *p_base, bool p_hidden = false);
+ };
+
+ Vector<Vector3> collision_segments;
+ Ref<TriangleMesh> collision_mesh;
+
+ struct Handle {
+ Vector3 pos;
+ bool billboard;
+ };
+
+ Vector<Vector3> handles;
+ Vector<Vector3> secondary_handles;
+ float selectable_icon_size = -1.0f;
+ bool billboard_handle;
+
+ bool valid;
+ bool hidden;
+ Spatial *base;
+ Vector<Instance> instances;
+ Spatial *spatial_node;
+ EditorSpatialGizmoPlugin *gizmo_plugin;
+
+ void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Spatial>(p_node)); }
+
+protected:
+ static void _bind_methods();
+
+public:
+ void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false);
+ void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
+ void add_collision_segments(const Vector<Vector3> &p_lines);
+ void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
+ void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1);
+ void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard = false, bool p_secondary = false);
+ void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3());
+
virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
+ virtual Variant get_handle_value(int p_idx);
virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
- virtual bool is_gizmo_handle_highlighted(int idx) const { return false; }
- virtual bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum);
- virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false);
- SpatialEditorGizmo();
+ void set_spatial_node(Spatial *p_node);
+ Spatial *get_spatial_node() const { return spatial_node; }
+ Vector3 get_handle_pos(int p_idx) const;
+ bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum);
+ bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false);
+
+ virtual void clear();
+ virtual void create();
+ virtual void transform();
+ virtual void redraw();
+ virtual void free();
+
+ //TODO remove (?)
+ virtual bool is_editable() const;
+ virtual bool can_draw() const;
+
+ void set_hidden(bool p_hidden);
+ void set_plugin(EditorSpatialGizmoPlugin *p_gizmo);
+
+ EditorSpatialGizmo();
+ ~EditorSpatialGizmo();
};
class SpatialEditorViewport : public Control {
@@ -94,7 +165,9 @@ class SpatialEditorViewport : public Control {
VIEW_DISPLAY_NORMAL,
VIEW_DISPLAY_WIREFRAME,
VIEW_DISPLAY_OVERDRAW,
- VIEW_DISPLAY_SHADELESS
+ VIEW_DISPLAY_SHADELESS,
+ VIEW_LOCK_ROTATION,
+ VIEW_CINEMATIC_PREVIEW
};
public:
@@ -108,7 +181,6 @@ private:
int index;
String name;
void _menu_option(int p_option);
-
Spatial *preview_node;
AABB *preview_bounds;
Vector<String> selected_files;
@@ -132,6 +204,7 @@ private:
Camera *camera;
bool transforming;
bool orthogonal;
+ bool lock_rotation;
float gizmo_scale;
bool freelook_active;
@@ -139,6 +212,7 @@ private:
Label *info_label;
Label *fps_label;
+ Label *cinema_label;
struct _RayResult {
@@ -230,7 +304,7 @@ private:
int edited_gizmo;
Point2 mouse_pos;
bool snap;
- Ref<SpatialEditorGizmo> gizmo;
+ Ref<EditorSpatialGizmo> gizmo;
int gizmo_handle;
Variant gizmo_initial_value;
Vector3 gizmo_initial_pos;
@@ -287,8 +361,11 @@ private:
Camera *previewing;
Camera *preview;
+ bool previewing_cinema;
+
void _preview_exited_scene();
void _toggle_camera_preview(bool);
+ void _toggle_cinema_preview(bool);
void _init_gizmo_instance(int p_idx);
void _finish_gizmo_instances();
void _selection_result_pressed(int);
@@ -403,7 +480,6 @@ public:
TOOL_LOCK_SELECTED,
TOOL_UNLOCK_SELECTED,
TOOL_MAX
-
};
enum ToolOptions {
@@ -484,16 +560,18 @@ private:
MENU_VIEW_USE_4_VIEWPORTS,
MENU_VIEW_ORIGIN,
MENU_VIEW_GRID,
+ MENU_VIEW_GIZMOS_3D_ICONS,
MENU_VIEW_CAMERA_SETTINGS,
MENU_LOCK_SELECTED,
MENU_UNLOCK_SELECTED,
- MENU_VISIBILITY_SKELETON
+ MENU_SNAP_TO_FLOOR
};
Button *tool_button[TOOL_MAX];
Button *tool_option_button[TOOL_OPT_MAX];
MenuButton *transform_menu;
+ PopupMenu *gizmos_menu;
MenuButton *view_menu;
ToolButton *lock_button;
@@ -525,6 +603,7 @@ private:
void _xform_dialog_action();
void _menu_item_pressed(int p_option);
void _menu_item_toggled(bool pressed, int p_option);
+ void _menu_gizmo_toggled(int p_option);
HBoxContainer *hbc_menu;
@@ -533,6 +612,7 @@ private:
void _instance_scene();
void _init_indicators();
+ void _init_gizmos_menu();
void _init_grid();
void _finish_indicators();
void _finish_grid();
@@ -552,7 +632,10 @@ private:
static SpatialEditor *singleton;
void _node_removed(Node *p_node);
- SpatialEditorGizmos *gizmos;
+ Vector<Ref<EditorSpatialGizmoPlugin> > gizmo_plugins;
+
+ void _register_all_gizmos();
+
SpatialEditor();
bool is_any_freelook_active() const;
@@ -592,11 +675,9 @@ public:
Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; }
Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; }
- int get_skeleton_visibility_state() const;
-
void update_transform_gizmo();
void update_all_gizmos();
-
+ void snap_selected_nodes_to_floor();
void select_gizmo_highlight_axis(int p_axis);
void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
@@ -626,6 +707,8 @@ public:
return viewports[p_idx];
}
+ void register_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> ref);
+
Camera *get_camera() { return NULL; }
void edit(Spatial *p_spatial);
void clear();
@@ -662,4 +745,49 @@ public:
~SpatialEditorPlugin();
};
+class EditorSpatialGizmoPlugin : public Resource {
+
+ GDCLASS(EditorSpatialGizmoPlugin, Resource);
+
+public:
+ static const int ON_TOP = 0;
+ static const int VISIBLE = 1;
+ static const int HIDDEN = 2;
+
+private:
+ int current_state;
+ List<EditorSpatialGizmo *> current_gizmos;
+ HashMap<String, Vector<Ref<SpatialMaterial> > > materials;
+
+protected:
+ virtual bool has_gizmo(Spatial *p_spatial);
+ virtual Ref<EditorSpatialGizmo> create_gizmo(Spatial *p_spatial);
+
+public:
+ void create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false);
+ void create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1));
+ void create_handle_material(const String &p_name, bool p_billboard = false);
+ void add_material(const String &p_name, Ref<SpatialMaterial> p_material);
+
+ Ref<SpatialMaterial> get_material(const String &p_name, EditorSpatialGizmo *p_gizmo = NULL);
+
+ virtual String get_name() const = 0;
+ virtual bool can_be_hidden() const;
+ virtual bool is_selectable_when_hidden() const;
+
+ virtual void redraw(EditorSpatialGizmo *p_gizmo) {}
+ virtual String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { return ""; }
+ virtual Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { return Variant(); }
+ virtual void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {}
+ virtual void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) {}
+ virtual bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const { return false; }
+
+ Ref<EditorSpatialGizmo> get_gizmo(Spatial *p_spatial);
+ void set_state(int p_state);
+ void unregister_gizmo(EditorSpatialGizmo *p_gizmo);
+
+ EditorSpatialGizmoPlugin();
+ virtual ~EditorSpatialGizmoPlugin();
+};
+
#endif
diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp
index 66673cca00..9bf1178b58 100644
--- a/editor/plugins/sprite_editor_plugin.cpp
+++ b/editor/plugins/sprite_editor_plugin.cpp
@@ -169,7 +169,7 @@ void SpriteEditor::_update_mesh_data() {
Size2 img_size = Vector2(image->get_width(), image->get_height());
for (int j = 0; j < lines.size(); j++) {
- lines[j] = expand(lines[j], rect, epsilon);
+ lines.write[j] = expand(lines[j], rect, epsilon);
int index_ofs = computed_vertices.size();
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index e4fdd1f251..0419c3d4b1 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -57,8 +57,6 @@ void TextureRegionEditor::_region_draw() {
base_tex = obj_styleBox->get_texture();
else if (atlas_tex.is_valid())
base_tex = atlas_tex->get_atlas();
- else if (tile_set.is_valid() && selected_tile != -1 && tile_set->has_tile(selected_tile))
- base_tex = tile_set->tile_get_texture(selected_tile);
if (base_tex.is_null())
return;
@@ -284,8 +282,6 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
r = obj_styleBox->get_region_rect();
else if (atlas_tex.is_valid())
r = atlas_tex->get_region();
- else if (tile_set.is_valid() && selected_tile != -1)
- r = tile_set->tile_get_region(selected_tile);
rect.expand_to(r.position);
rect.expand_to(r.position + r.size);
}
@@ -302,9 +298,6 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
} else if (atlas_tex.is_valid()) {
undo_redo->add_do_method(atlas_tex.ptr(), "set_region", rect);
undo_redo->add_undo_method(atlas_tex.ptr(), "set_region", atlas_tex->get_region());
- } else if (tile_set.is_valid() && selected_tile != -1) {
- undo_redo->add_do_method(tile_set.ptr(), "tile_set_region", selected_tile, rect);
- undo_redo->add_undo_method(tile_set.ptr(), "tile_set_region", selected_tile, tile_set->tile_get_region(selected_tile));
}
undo_redo->add_do_method(edit_draw, "update");
undo_redo->add_undo_method(edit_draw, "update");
@@ -327,8 +320,6 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
rect_prev = obj_styleBox->get_region_rect();
else if (atlas_tex.is_valid())
rect_prev = atlas_tex->get_region();
- else if (tile_set.is_valid() && selected_tile != -1)
- rect_prev = tile_set->tile_get_region(selected_tile);
for (int i = 0; i < 8; i++) {
Vector2 tuv = endpoints[i];
@@ -372,9 +363,6 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
} else if (obj_styleBox.is_valid()) {
undo_redo->add_do_method(obj_styleBox.ptr(), "set_region_rect", obj_styleBox->get_region_rect());
undo_redo->add_undo_method(obj_styleBox.ptr(), "set_region_rect", rect_prev);
- } else if (tile_set.is_valid()) {
- undo_redo->add_do_method(tile_set.ptr(), "tile_set_region", selected_tile, tile_set->tile_get_region(selected_tile));
- undo_redo->add_undo_method(tile_set.ptr(), "tile_set_region", selected_tile, rect_prev);
}
drag_index = -1;
}
@@ -595,8 +583,6 @@ void TextureRegionEditor::apply_rect(const Rect2 &rect) {
obj_styleBox->set_region_rect(rect);
else if (atlas_tex.is_valid())
atlas_tex->set_region(rect);
- else if (tile_set.is_valid() && selected_tile != -1)
- tile_set->tile_set_region(selected_tile, rect);
}
void TextureRegionEditor::_notification(int p_what) {
@@ -623,12 +609,11 @@ void TextureRegionEditor::_notification(int p_what) {
}
void TextureRegionEditor::_node_removed(Object *p_obj) {
- if (p_obj == node_sprite || p_obj == node_ninepatch || p_obj == obj_styleBox.ptr() || p_obj == atlas_tex.ptr() || p_obj == tile_set.ptr()) {
+ if (p_obj == node_sprite || p_obj == node_ninepatch || p_obj == obj_styleBox.ptr() || p_obj == atlas_tex.ptr()) {
node_ninepatch = NULL;
node_sprite = NULL;
obj_styleBox = Ref<StyleBox>(NULL);
atlas_tex = Ref<AtlasTexture>(NULL);
- tile_set = Ref<TileSet>(NULL);
hide();
}
}
@@ -677,8 +662,6 @@ void TextureRegionEditor::edit(Object *p_obj) {
obj_styleBox->remove_change_receptor(this);
if (atlas_tex.is_valid())
atlas_tex->remove_change_receptor(this);
- if (tile_set.is_valid())
- tile_set->remove_change_receptor(this);
if (p_obj) {
node_sprite = Object::cast_to<Sprite>(p_obj);
node_ninepatch = Object::cast_to<NinePatchRect>(p_obj);
@@ -686,8 +669,6 @@ void TextureRegionEditor::edit(Object *p_obj) {
obj_styleBox = Ref<StyleBoxTexture>(Object::cast_to<StyleBoxTexture>(p_obj));
if (Object::cast_to<AtlasTexture>(p_obj))
atlas_tex = Ref<AtlasTexture>(Object::cast_to<AtlasTexture>(p_obj));
- if (Object::cast_to<TileSet>(p_obj))
- tile_set = Ref<TileSet>(Object::cast_to<TileSet>(p_obj));
p_obj->add_change_receptor(this);
_edit_region();
} else {
@@ -695,7 +676,6 @@ void TextureRegionEditor::edit(Object *p_obj) {
node_ninepatch = NULL;
obj_styleBox = Ref<StyleBoxTexture>(NULL);
atlas_tex = Ref<AtlasTexture>(NULL);
- tile_set = Ref<TileSet>(NULL);
}
edit_draw->update();
if (node_sprite && !node_sprite->is_region()) {
@@ -724,8 +704,6 @@ void TextureRegionEditor::_edit_region() {
texture = obj_styleBox->get_texture();
else if (atlas_tex.is_valid())
texture = atlas_tex->get_atlas();
- else if (tile_set.is_valid() && selected_tile != -1 && tile_set->has_tile(selected_tile))
- texture = tile_set->tile_get_texture(selected_tile);
if (texture.is_null()) {
edit_draw->update();
@@ -794,8 +772,6 @@ void TextureRegionEditor::_edit_region() {
rect = obj_styleBox->get_region_rect();
else if (atlas_tex.is_valid())
rect = atlas_tex->get_region();
- else if (tile_set.is_valid() && selected_tile != -1)
- rect = tile_set->tile_get_region(selected_tile);
edit_draw->update();
}
@@ -814,10 +790,8 @@ TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) {
node_ninepatch = NULL;
obj_styleBox = Ref<StyleBoxTexture>(NULL);
atlas_tex = Ref<AtlasTexture>(NULL);
- tile_set = Ref<TileSet>(NULL);
editor = p_editor;
undo_redo = editor->get_undo_redo();
- selected_tile = -1;
snap_step = Vector2(10, 10);
snap_separation = Vector2(0, 0);
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index eeba1987a6..bd93be9267 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -38,7 +38,6 @@
#include "scene/gui/nine_patch_rect.h"
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
-#include "scene/resources/tile_set.h"
/**
@author Mariano Suligoy
@@ -56,8 +55,6 @@ class TextureRegionEditor : public Control {
};
friend class TextureRegionEditorPlugin;
- friend class TileSetEditor;
- friend class TileSetEditorPlugin;
MenuButton *snap_mode_button;
TextureRect *icon_zoom;
ToolButton *zoom_in;
@@ -91,14 +88,12 @@ class TextureRegionEditor : public Control {
Sprite *node_sprite;
Ref<StyleBoxTexture> obj_styleBox;
Ref<AtlasTexture> atlas_tex;
- Ref<TileSet> tile_set;
Rect2 rect;
Rect2 rect_prev;
float prev_margin;
int edited_margin;
List<Rect2> autoslice_cache;
- int selected_tile;
bool drag;
bool creating;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 484da3b4f3..101dc3037f 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -73,7 +73,8 @@ void TileMapEditor::_notification(int p_what) {
rotate_180->set_icon(get_icon("Rotate180", "EditorIcons"));
rotate_270->set_icon(get_icon("Rotate270", "EditorIcons"));
- search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
PopupMenu *p = options->get_popup();
p->set_item_icon(p->get_item_index(OPTION_PAINTING), get_icon("Edit", "EditorIcons"));
@@ -168,10 +169,11 @@ void TileMapEditor::_menu_option(int p_option) {
}
void TileMapEditor::_palette_selected(int index) {
+ _update_palette();
+}
- if (manual_autotile) {
- _update_palette();
- }
+void TileMapEditor::_palette_multi_selected(int index, bool selected) {
+ _update_palette();
}
void TileMapEditor::_canvas_mouse_enter() {
@@ -196,7 +198,7 @@ Vector<int> TileMapEditor::get_selected_tiles() const {
}
for (int i = items.size() - 1; i >= 0; i--) {
- items[i] = palette->get_item_metadata(items[i]);
+ items.write[i] = palette->get_item_metadata(items[i]);
}
return items;
}
@@ -296,7 +298,7 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p
}
node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose);
- if (manual_autotile) {
+ if (manual_autotile || node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE) {
if (current != -1) {
node->set_cell_autotile_coord(p_pos.x, p_pos.y, position);
}
@@ -317,7 +319,6 @@ void TileMapEditor::_text_entered(const String &p_text) {
}
void TileMapEditor::_text_changed(const String &p_text) {
-
_update_palette();
}
@@ -427,7 +428,7 @@ void TileMapEditor::_update_palette() {
if (tex.is_valid()) {
Rect2 region = tileset->tile_get_region(entries[i].id);
- if (tileset->tile_get_tile_mode(entries[i].id) == TileSet::AUTO_TILE) {
+ if (tileset->tile_get_tile_mode(entries[i].id) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(entries[i].id) == TileSet::ATLAS_TILE) {
int spacing = tileset->autotile_get_spacing(entries[i].id);
region.size = tileset->autotile_get_size(entries[i].id);
region.position += (region.size + Vector2(spacing, spacing)) * tileset->autotile_get_icon_coordinate(entries[i].id);
@@ -450,7 +451,7 @@ void TileMapEditor::_update_palette() {
palette->select(0);
}
- if (manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) {
+ if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) {
const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile);
@@ -676,10 +677,10 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h
Vector2 tile_ofs = node->get_tileset()->tile_get_texture_offset(p_cell);
Rect2 r = node->get_tileset()->tile_get_region(p_cell);
- if (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::AUTO_TILE) {
+ if (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::AUTO_TILE || node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE) {
Vector2 offset;
int selected = manual_palette->get_current();
- if (manual_autotile && selected != -1) {
+ if ((manual_autotile || node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE) && selected != -1) {
offset = manual_palette->get_item_metadata(selected);
} else {
offset = node->get_tileset()->autotile_get_icon_coordinate(p_cell);
@@ -983,7 +984,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
ids.push_back(0);
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- ids[0] = E->get().cell;
+ ids.write[0] = E->get().cell;
_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
_finish_undo();
@@ -1006,7 +1007,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- ids[0] = E->get().cell;
+ ids.write[0] = E->get().cell;
_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
_finish_undo();
@@ -1228,7 +1229,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- tmp_cell[0] = E->get().idx;
+ tmp_cell.write[0] = E->get().idx;
_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
}
@@ -1265,7 +1266,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- tmp_cell[0] = E->get().idx;
+ tmp_cell.write[0] = E->get().idx;
_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
}
@@ -1673,6 +1674,7 @@ void TileMapEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_tileset_settings_changed"), &TileMapEditor::_tileset_settings_changed);
ClassDB::bind_method(D_METHOD("_update_transform_buttons"), &TileMapEditor::_update_transform_buttons);
ClassDB::bind_method(D_METHOD("_palette_selected"), &TileMapEditor::_palette_selected);
+ ClassDB::bind_method(D_METHOD("_palette_multi_selected"), &TileMapEditor::_palette_multi_selected);
ClassDB::bind_method(D_METHOD("_fill_points"), &TileMapEditor::_fill_points);
ClassDB::bind_method(D_METHOD("_erase_points"), &TileMapEditor::_erase_points);
@@ -1750,7 +1752,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
bucket_cache_visited = 0;
invalid_cell.resize(1);
- invalid_cell[0] = TileMap::INVALID_CELL;
+ invalid_cell.write[0] = TileMap::INVALID_CELL;
ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE);
ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F);
@@ -1800,6 +1802,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette->set_max_text_lines(2);
palette->set_select_mode(ItemList::SELECT_MULTI);
palette->connect("item_selected", this, "_palette_selected");
+ palette->connect("multi_selected", this, "_palette_multi_selected");
palette_container->add_child(palette);
// Add autotile override palette
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index b8443ca962..bb76879b02 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -184,6 +184,7 @@ class TileMapEditor : public VBoxContainer {
void _update_palette();
void _menu_option(int p_option);
void _palette_selected(int index);
+ void _palette_multi_selected(int index, bool selected);
void _start_undo(const String &p_action);
void _finish_undo();
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 087c4293f1..8d1db5de8f 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -30,6 +30,8 @@
#include "tile_set_editor_plugin.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/physics_body_2d.h"
#include "scene/2d/sprite.h"
@@ -39,7 +41,9 @@ void TileSetEditor::edit(const Ref<TileSet> &p_tileset) {
tileset = p_tileset;
tileset->add_change_receptor(this);
- update_tile_list();
+ texture_list->clear();
+ texture_map.clear();
+ update_texture_list();
}
void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
@@ -161,75 +165,6 @@ void TileSetEditor::_import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_
_import_node(p_scene, p_library);
}
-void TileSetEditor::_menu_confirm() {
-
- switch (option) {
-
- case MENU_OPTION_MERGE_FROM_SCENE:
- case MENU_OPTION_CREATE_FROM_SCENE: {
-
- EditorNode *en = editor;
- Node *scene = en->get_edited_scene();
- if (!scene)
- break;
-
- _import_scene(scene, tileset, option == MENU_OPTION_MERGE_FROM_SCENE);
-
- } break;
- }
-}
-
-void TileSetEditor::_name_dialog_confirm(const String &name) {
-
- switch (option) {
-
- case MENU_OPTION_REMOVE_ITEM: {
-
- int id = tileset->find_tile_by_name(name);
-
- if (id < 0 && name.is_valid_integer())
- id = name.to_int();
-
- if (tileset->has_tile(id)) {
- tileset->remove_tile(id);
- update_tile_list();
- } else {
- err_dialog->set_text(TTR("Could not find tile:") + " " + name);
- err_dialog->popup_centered(Size2(300, 60));
- }
- } break;
- }
-}
-
-void TileSetEditor::_menu_cbk(int p_option) {
-
- option = p_option;
- switch (p_option) {
-
- case MENU_OPTION_ADD_ITEM: {
- tileset->create_tile(tileset->get_last_unused_tile_id());
- tileset->tile_set_name(tileset->get_last_unused_tile_id() - 1, itos(tileset->get_last_unused_tile_id() - 1));
- update_tile_list();
- } break;
- case MENU_OPTION_REMOVE_ITEM: {
-
- nd->set_title(TTR("Remove Item"));
- nd->set_text(TTR("Item name or ID:"));
- nd->popup_centered(Size2(300, 95));
- } break;
- case MENU_OPTION_CREATE_FROM_SCENE: {
-
- cd->set_text(TTR("Create from scene?"));
- cd->popup_centered(Size2(300, 60));
- } break;
- case MENU_OPTION_MERGE_FROM_SCENE: {
-
- cd->set_text(TTR("Merge from scene?"));
- cd->popup_centered(Size2(300, 60));
- } break;
- }
-}
-
Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bool p_merge) {
_import_scene(p_base_scene, ml, p_merge);
@@ -237,28 +172,36 @@ Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bo
}
void TileSetEditor::_bind_methods() {
-
- ClassDB::bind_method("_menu_cbk", &TileSetEditor::_menu_cbk);
- ClassDB::bind_method("_menu_confirm", &TileSetEditor::_menu_confirm);
- ClassDB::bind_method("_name_dialog_confirm", &TileSetEditor::_name_dialog_confirm);
- ClassDB::bind_method("_on_tile_list_selected", &TileSetEditor::_on_tile_list_selected);
+ ClassDB::bind_method("_on_tileset_toolbar_button_pressed", &TileSetEditor::_on_tileset_toolbar_button_pressed);
+ ClassDB::bind_method("_on_textures_added", &TileSetEditor::_on_textures_added);
+ ClassDB::bind_method("_on_tileset_toolbar_confirm", &TileSetEditor::_on_tileset_toolbar_confirm);
+ ClassDB::bind_method("_on_texture_list_selected", &TileSetEditor::_on_texture_list_selected);
ClassDB::bind_method("_on_edit_mode_changed", &TileSetEditor::_on_edit_mode_changed);
+ ClassDB::bind_method("_on_workspace_mode_changed", &TileSetEditor::_on_workspace_mode_changed);
ClassDB::bind_method("_on_workspace_overlay_draw", &TileSetEditor::_on_workspace_overlay_draw);
+ ClassDB::bind_method("_on_workspace_process", &TileSetEditor::_on_workspace_process);
ClassDB::bind_method("_on_workspace_draw", &TileSetEditor::_on_workspace_draw);
ClassDB::bind_method("_on_workspace_input", &TileSetEditor::_on_workspace_input);
ClassDB::bind_method("_on_tool_clicked", &TileSetEditor::_on_tool_clicked);
ClassDB::bind_method("_on_priority_changed", &TileSetEditor::_on_priority_changed);
ClassDB::bind_method("_on_grid_snap_toggled", &TileSetEditor::_on_grid_snap_toggled);
- ClassDB::bind_method("_set_snap_step_x", &TileSetEditor::_set_snap_step_x);
- ClassDB::bind_method("_set_snap_step_y", &TileSetEditor::_set_snap_step_y);
- ClassDB::bind_method("_set_snap_off_x", &TileSetEditor::_set_snap_off_x);
- ClassDB::bind_method("_set_snap_off_y", &TileSetEditor::_set_snap_off_y);
- ClassDB::bind_method("_set_snap_sep_x", &TileSetEditor::_set_snap_sep_x);
- ClassDB::bind_method("_set_snap_sep_y", &TileSetEditor::_set_snap_sep_y);
+ ClassDB::bind_method("_set_snap_step", &TileSetEditor::_set_snap_step);
+ ClassDB::bind_method("_set_snap_off", &TileSetEditor::_set_snap_off);
+ ClassDB::bind_method("_set_snap_sep", &TileSetEditor::_set_snap_sep);
}
void TileSetEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+
+ tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->set_icon(get_icon("ToolAddNode", "EditorIcons"));
+ tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->set_icon(get_icon("Remove", "EditorIcons"));
+ tileset_toolbar_tools->set_icon(get_icon("Tools", "EditorIcons"));
+
+ tool_workspacemode[WORKSPACE_EDIT]->set_icon(get_icon("Edit", "EditorIcons"));
+ tool_workspacemode[WORKSPACE_CREATE_SINGLE]->set_icon(get_icon("AddSingleTile", "EditorIcons"));
+ tool_workspacemode[WORKSPACE_CREATE_AUTOTILE]->set_icon(get_icon("AddAutotile", "EditorIcons"));
+ tool_workspacemode[WORKSPACE_CREATE_ATLAS]->set_icon(get_icon("AddAtlasTile", "EditorIcons"));
+
tools[TOOL_SELECT]->set_icon(get_icon("ToolSelect", "EditorIcons"));
tools[BITMASK_COPY]->set_icon(get_icon("Duplicate", "EditorIcons"));
tools[BITMASK_PASTE]->set_icon(get_icon("Override", "EditorIcons"));
@@ -266,91 +209,126 @@ void TileSetEditor::_notification(int p_what) {
tools[SHAPE_NEW_POLYGON]->set_icon(get_icon("CollisionPolygon2D", "EditorIcons"));
tools[SHAPE_DELETE]->set_icon(get_icon("Remove", "EditorIcons"));
tools[SHAPE_KEEP_INSIDE_TILE]->set_icon(get_icon("Snap", "EditorIcons"));
- tools[SHAPE_GRID_SNAP]->set_icon(get_icon("SnapGrid", "EditorIcons"));
+ tools[TOOL_GRID_SNAP]->set_icon(get_icon("SnapGrid", "EditorIcons"));
tools[ZOOM_OUT]->set_icon(get_icon("ZoomLess", "EditorIcons"));
tools[ZOOM_1]->set_icon(get_icon("ZoomReset", "EditorIcons"));
tools[ZOOM_IN]->set_icon(get_icon("ZoomMore", "EditorIcons"));
+ tools[VISIBLE_INFO]->set_icon(get_icon("InformationSign", "EditorIcons"));
+
+ tool_editmode[EDITMODE_REGION]->set_icon(get_icon("RegionEdit", "EditorIcons"));
+ tool_editmode[EDITMODE_COLLISION]->set_icon(get_icon("StaticBody2D", "EditorIcons"));
+ tool_editmode[EDITMODE_OCCLUSION]->set_icon(get_icon("LightOccluder2D", "EditorIcons"));
+ tool_editmode[EDITMODE_NAVIGATION]->set_icon(get_icon("Navigation2D", "EditorIcons"));
+ tool_editmode[EDITMODE_BITMASK]->set_icon(get_icon("PackedDataContainer", "EditorIcons"));
+ tool_editmode[EDITMODE_PRIORITY]->set_icon(get_icon("MaterialPreviewLight1", "EditorIcons"));
+ tool_editmode[EDITMODE_ICON]->set_icon(get_icon("LargeTexture", "EditorIcons"));
}
}
-void TileSetEditor::_changed_callback(Object *p_changed, const char *p_prop) {
- if (p_prop == StringName("region")) {
- update_tile_list_icon();
- preview->set_region_rect(tileset->tile_get_region(get_current_tile()));
- } else if (p_prop == StringName("name")) {
- update_tile_list_icon();
- } else if (p_prop == StringName("texture") || p_prop == StringName("modulate") || p_prop == StringName("tile_mode")) {
- _on_tile_list_selected(get_current_tile());
- workspace->update();
- preview->set_texture(tileset->tile_get_texture(get_current_tile()));
- preview->set_modulate(tileset->tile_get_modulate(get_current_tile()));
- preview->set_region_rect(tileset->tile_get_region(get_current_tile()));
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE)
- property_editor->show();
- else
- property_editor->hide();
- texture_region_editor->_edit_region();
- update_tile_list_icon();
- } else if (p_prop == StringName("autotile")) {
- workspace->update();
- }
-}
+TileSetEditor::TileSetEditor(EditorNode *p_editor) {
-void TileSetEditor::initialize_bottom_editor() {
+ editor = p_editor;
+ set_name("Tile Set Bottom Editor");
- //Side Panel
- side_panel = memnew(Control);
- side_panel->set_name("Tile Set");
+ HSplitContainer *split = memnew(HSplitContainer);
+ split->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_MINSIZE, 10);
+ add_child(split);
- VSplitContainer *split = memnew(VSplitContainer);
- side_panel->add_child(split);
- split->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ VBoxContainer *left_container = memnew(VBoxContainer);
+ split->add_child(left_container);
- tile_list = memnew(ItemList);
- tile_list->set_v_size_flags(SIZE_EXPAND_FILL);
- tile_list->set_h_size_flags(SIZE_EXPAND_FILL);
- tile_list->set_custom_minimum_size(Size2(10, 200));
- tile_list->connect("item_selected", this, "_on_tile_list_selected");
- split->add_child(tile_list);
+ texture_list = memnew(ItemList);
+ left_container->add_child(texture_list);
+ texture_list->set_v_size_flags(SIZE_EXPAND_FILL);
+ texture_list->set_custom_minimum_size(Size2(200, 0));
+ texture_list->connect("item_selected", this, "_on_texture_list_selected");
- property_editor = memnew(PropertyEditor);
- property_editor->set_v_size_flags(SIZE_EXPAND_FILL);
- property_editor->set_h_size_flags(SIZE_EXPAND_FILL);
- property_editor->set_custom_minimum_size(Size2(10, 70));
- split->add_child(property_editor);
+ HBoxContainer *tileset_toolbar_container = memnew(HBoxContainer);
+ left_container->add_child(tileset_toolbar_container);
- helper = memnew(TileSetEditorHelper(this));
- property_editor->call_deferred("edit", helper);
- helper->add_change_receptor(this);
+ tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE] = memnew(ToolButton);
+ Vector<Variant> p;
+ p.push_back((int)TOOL_TILESET_ADD_TEXTURE);
+ tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->connect("pressed", this, "_on_tileset_toolbar_button_pressed", p);
+ tileset_toolbar_container->add_child(tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]);
+ tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->set_tooltip(TTR("Add Texture(s) to TileSet"));
+
+ tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE] = memnew(ToolButton);
+ p = Vector<Variant>();
+ p.push_back((int)TOOL_TILESET_REMOVE_TEXTURE);
+ tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->connect("pressed", this, "_on_tileset_toolbar_button_pressed", p);
+ tileset_toolbar_container->add_child(tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]);
+ tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->set_tooltip(TTR("Remove current Texture from TileSet"));
+
+ Control *toolbar_separator = memnew(Control);
+ toolbar_separator->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ tileset_toolbar_container->add_child(toolbar_separator);
+
+ tileset_toolbar_tools = memnew(MenuButton);
+ tileset_toolbar_tools->set_text("Tools");
+ p = Vector<Variant>();
+ p.push_back((int)TOOL_TILESET_CREATE_SCENE);
+ tileset_toolbar_tools->get_popup()->add_item(TTR("Create from Scene"), TOOL_TILESET_CREATE_SCENE);
+ p = Vector<Variant>();
+ p.push_back((int)TOOL_TILESET_MERGE_SCENE);
+ tileset_toolbar_tools->get_popup()->add_item(TTR("Merge from Scene"), TOOL_TILESET_MERGE_SCENE);
- //Editor
- //Bottom Panel
- bottom_panel = memnew(Control);
- bottom_panel->set_name("Tile Set Bottom Editor");
+ tileset_toolbar_tools->get_popup()->connect("id_pressed", this, "_on_tileset_toolbar_button_pressed");
+ tileset_toolbar_container->add_child(tileset_toolbar_tools);
+
+ //---------------
+ VBoxContainer *right_container = memnew(VBoxContainer);
+ right_container->set_v_size_flags(SIZE_EXPAND_FILL);
+ split->add_child(right_container);
dragging_point = -1;
creating_shape = false;
snap_step = Vector2(32, 32);
+ snap_offset = WORKSPACE_MARGIN;
- bottom_panel->set_custom_minimum_size(Size2(0, 150));
+ set_custom_minimum_size(Size2(0, 150));
VBoxContainer *main_vb = memnew(VBoxContainer);
- bottom_panel->add_child(main_vb);
- main_vb->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ right_container->add_child(main_vb);
+ main_vb->set_v_size_flags(SIZE_EXPAND_FILL);
HBoxContainer *tool_hb = memnew(HBoxContainer);
Ref<ButtonGroup> g(memnew(ButtonGroup));
- String label[EDITMODE_MAX] = { "Collision", "Occlusion", "Navigation", "Bitmask", "Priority", "Icon" };
+ String workspace_label[WORKSPACE_MODE_MAX] = { "Edit", "New Single Tile", "New Autotile", "New Atlas" };
+
+ for (int i = 0; i < (int)WORKSPACE_MODE_MAX; i++) {
+ tool_workspacemode[i] = memnew(Button);
+ tool_workspacemode[i]->set_text(workspace_label[i]);
+ tool_workspacemode[i]->set_toggle_mode(true);
+ tool_workspacemode[i]->set_button_group(g);
+ Vector<Variant> p;
+ p.push_back(i);
+ tool_workspacemode[i]->connect("pressed", this, "_on_workspace_mode_changed", p);
+ tool_hb->add_child(tool_workspacemode[i]);
+ }
+ tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
+ workspace_mode = WORKSPACE_EDIT;
+
+ main_vb->add_child(tool_hb);
+ main_vb->add_child(memnew(HSeparator));
+
+ tool_hb = memnew(HBoxContainer);
+ Control *spacer = memnew(Control);
+ spacer->set_custom_minimum_size(Size2(30, 0));
+ tool_hb->add_child(spacer);
+
+ g = Ref<ButtonGroup>(memnew(ButtonGroup));
+ String label[EDITMODE_MAX] = { "Region", "Collision", "Occlusion", "Navigation", "Bitmask", "Priority", "Icon" };
for (int i = 0; i < (int)EDITMODE_MAX; i++) {
tool_editmode[i] = memnew(Button);
tool_editmode[i]->set_text(label[i]);
tool_editmode[i]->set_toggle_mode(true);
tool_editmode[i]->set_button_group(g);
- Vector<Variant> args;
- args.push_back(i);
- tool_editmode[i]->connect("pressed", this, "_on_edit_mode_changed", args);
+ Vector<Variant> p;
+ p.push_back(i);
+ tool_editmode[i]->connect("pressed", this, "_on_edit_mode_changed", p);
tool_hb->add_child(tool_editmode[i]);
}
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
@@ -360,127 +338,52 @@ void TileSetEditor::initialize_bottom_editor() {
main_vb->add_child(memnew(HSeparator));
toolbar = memnew(HBoxContainer);
- for (int i = 0; i < (int)TOOLBAR_MAX; i++) {
- tool_containers[i] = memnew(HBoxContainer);
- toolbar->add_child(tool_containers[i]);
- tool_containers[i]->hide();
- }
-
Ref<ButtonGroup> tg(memnew(ButtonGroup));
- Vector<Variant> p;
+ p = Vector<Variant>();
tools[TOOL_SELECT] = memnew(ToolButton);
- tool_containers[TOOLBAR_DUMMY]->add_child(tools[TOOL_SELECT]);
+ toolbar->add_child(tools[TOOL_SELECT]);
tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to use as icon, this will be also used on invalid autotile bindings."));
tools[TOOL_SELECT]->set_toggle_mode(true);
tools[TOOL_SELECT]->set_button_group(tg);
tools[TOOL_SELECT]->set_pressed(true);
p.push_back((int)TOOL_SELECT);
tools[TOOL_SELECT]->connect("pressed", this, "_on_tool_clicked", p);
- tool_containers[TOOLBAR_DUMMY]->show();
tools[BITMASK_COPY] = memnew(ToolButton);
p.push_back((int)BITMASK_COPY);
tools[BITMASK_COPY]->connect("pressed", this, "_on_tool_clicked", p);
- tool_containers[TOOLBAR_BITMASK]->add_child(tools[BITMASK_COPY]);
+ toolbar->add_child(tools[BITMASK_COPY]);
tools[BITMASK_PASTE] = memnew(ToolButton);
p = Vector<Variant>();
p.push_back((int)BITMASK_PASTE);
tools[BITMASK_PASTE]->connect("pressed", this, "_on_tool_clicked", p);
- tool_containers[TOOLBAR_BITMASK]->add_child(tools[BITMASK_PASTE]);
+ toolbar->add_child(tools[BITMASK_PASTE]);
tools[BITMASK_CLEAR] = memnew(ToolButton);
p = Vector<Variant>();
p.push_back((int)BITMASK_CLEAR);
tools[BITMASK_CLEAR]->connect("pressed", this, "_on_tool_clicked", p);
- tool_containers[TOOLBAR_BITMASK]->add_child(tools[BITMASK_CLEAR]);
+ toolbar->add_child(tools[BITMASK_CLEAR]);
tools[SHAPE_NEW_POLYGON] = memnew(ToolButton);
- tool_containers[TOOLBAR_SHAPE]->add_child(tools[SHAPE_NEW_POLYGON]);
+ toolbar->add_child(tools[SHAPE_NEW_POLYGON]);
tools[SHAPE_NEW_POLYGON]->set_toggle_mode(true);
tools[SHAPE_NEW_POLYGON]->set_button_group(tg);
- tool_containers[TOOLBAR_SHAPE]->add_child(memnew(VSeparator));
+ toolbar->add_child(memnew(VSeparator));
tools[SHAPE_DELETE] = memnew(ToolButton);
p = Vector<Variant>();
p.push_back((int)SHAPE_DELETE);
tools[SHAPE_DELETE]->connect("pressed", this, "_on_tool_clicked", p);
- tool_containers[TOOLBAR_SHAPE]->add_child(tools[SHAPE_DELETE]);
- tool_containers[TOOLBAR_SHAPE]->add_child(memnew(VSeparator));
+ toolbar->add_child(tools[SHAPE_DELETE]);
+ toolbar->add_child(memnew(VSeparator));
tools[SHAPE_KEEP_INSIDE_TILE] = memnew(ToolButton);
tools[SHAPE_KEEP_INSIDE_TILE]->set_toggle_mode(true);
tools[SHAPE_KEEP_INSIDE_TILE]->set_pressed(true);
- tool_containers[TOOLBAR_SHAPE]->add_child(tools[SHAPE_KEEP_INSIDE_TILE]);
- tools[SHAPE_GRID_SNAP] = memnew(ToolButton);
- tools[SHAPE_GRID_SNAP]->set_toggle_mode(true);
- tools[SHAPE_GRID_SNAP]->connect("toggled", this, "_on_grid_snap_toggled");
- tool_containers[TOOLBAR_SHAPE]->add_child(tools[SHAPE_GRID_SNAP]);
-
- hb_grid = memnew(HBoxContainer);
- tool_containers[TOOLBAR_SHAPE]->add_child(hb_grid);
-
- hb_grid->add_child(memnew(VSeparator));
- hb_grid->add_child(memnew(Label(TTR("Offset:"))));
-
- sb_off_x = memnew(SpinBox);
- sb_off_x->set_min(-256);
- sb_off_x->set_max(256);
- sb_off_x->set_step(1);
- sb_off_x->set_value(snap_offset.x);
- sb_off_x->set_suffix("px");
- sb_off_x->connect("value_changed", this, "_set_snap_off_x");
- hb_grid->add_child(sb_off_x);
-
- sb_off_y = memnew(SpinBox);
- sb_off_y->set_min(-256);
- sb_off_y->set_max(256);
- sb_off_y->set_step(1);
- sb_off_y->set_value(snap_offset.y);
- sb_off_y->set_suffix("px");
- sb_off_y->connect("value_changed", this, "_set_snap_off_y");
- hb_grid->add_child(sb_off_y);
-
- hb_grid->add_child(memnew(VSeparator));
- hb_grid->add_child(memnew(Label(TTR("Step:"))));
-
- sb_step_x = memnew(SpinBox);
- sb_step_x->set_min(-256);
- sb_step_x->set_max(256);
- sb_step_x->set_step(1);
- sb_step_x->set_value(snap_step.x);
- sb_step_x->set_suffix("px");
- sb_step_x->connect("value_changed", this, "_set_snap_step_x");
- hb_grid->add_child(sb_step_x);
-
- sb_step_y = memnew(SpinBox);
- sb_step_y->set_min(-256);
- sb_step_y->set_max(256);
- sb_step_y->set_step(1);
- sb_step_y->set_value(snap_step.y);
- sb_step_y->set_suffix("px");
- sb_step_y->connect("value_changed", this, "_set_snap_step_y");
- hb_grid->add_child(sb_step_y);
-
- hb_grid->add_child(memnew(VSeparator));
- hb_grid->add_child(memnew(Label(TTR("Separation:"))));
-
- sb_sep_x = memnew(SpinBox);
- sb_sep_x->set_min(0);
- sb_sep_x->set_max(256);
- sb_sep_x->set_step(1);
- sb_sep_x->set_value(snap_separation.x);
- sb_sep_x->set_suffix("px");
- sb_sep_x->connect("value_changed", this, "_set_snap_sep_x");
- hb_grid->add_child(sb_sep_x);
-
- sb_sep_y = memnew(SpinBox);
- sb_sep_y->set_min(0);
- sb_sep_y->set_max(256);
- sb_sep_y->set_step(1);
- sb_sep_y->set_value(snap_separation.y);
- sb_sep_y->set_suffix("px");
- sb_sep_y->connect("value_changed", this, "_set_snap_sep_y");
- hb_grid->add_child(sb_sep_y);
-
- hb_grid->hide();
+ toolbar->add_child(tools[SHAPE_KEEP_INSIDE_TILE]);
+ tools[TOOL_GRID_SNAP] = memnew(ToolButton);
+ tools[TOOL_GRID_SNAP]->set_toggle_mode(true);
+ tools[TOOL_GRID_SNAP]->connect("toggled", this, "_on_grid_snap_toggled");
+ toolbar->add_child(tools[TOOL_GRID_SNAP]);
spin_priority = memnew(SpinBox);
spin_priority->set_min(1);
@@ -491,8 +394,6 @@ void TileSetEditor::initialize_bottom_editor() {
spin_priority->hide();
toolbar->add_child(spin_priority);
- tool_containers[TOOLBAR_SHAPE]->show();
-
Control *separator = memnew(Control);
separator->set_h_size_flags(SIZE_EXPAND_FILL);
toolbar->add_child(separator);
@@ -502,22 +403,31 @@ void TileSetEditor::initialize_bottom_editor() {
p.push_back((int)ZOOM_OUT);
tools[ZOOM_OUT]->connect("pressed", this, "_on_tool_clicked", p);
toolbar->add_child(tools[ZOOM_OUT]);
+ tools[ZOOM_OUT]->set_tooltip(TTR("Zoom Out"));
tools[ZOOM_1] = memnew(ToolButton);
p = Vector<Variant>();
p.push_back((int)ZOOM_1);
tools[ZOOM_1]->connect("pressed", this, "_on_tool_clicked", p);
toolbar->add_child(tools[ZOOM_1]);
+ tools[ZOOM_1]->set_tooltip(TTR("Reset Zoom"));
tools[ZOOM_IN] = memnew(ToolButton);
p = Vector<Variant>();
p.push_back((int)ZOOM_IN);
tools[ZOOM_IN]->connect("pressed", this, "_on_tool_clicked", p);
toolbar->add_child(tools[ZOOM_IN]);
+ tools[ZOOM_IN]->set_tooltip(TTR("Zoom In"));
+
+ tools[VISIBLE_INFO] = memnew(ToolButton);
+ tools[VISIBLE_INFO]->set_toggle_mode(true);
+ tools[VISIBLE_INFO]->set_tooltip(TTR("Display tile's names (hold Alt Key)"));
+ toolbar->add_child(tools[VISIBLE_INFO]);
main_vb->add_child(toolbar);
scroll = memnew(ScrollContainer);
main_vb->add_child(scroll);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
+ scroll->set_clip_contents(true);
workspace_container = memnew(Control);
scroll->add_child(workspace_container);
@@ -527,6 +437,7 @@ void TileSetEditor::initialize_bottom_editor() {
workspace_container->add_child(workspace_overlay);
workspace = memnew(Control);
+ workspace->set_focus_mode(FOCUS_ALL);
workspace->connect("draw", this, "_on_workspace_draw");
workspace->connect("gui_input", this, "_on_workspace_input");
workspace->set_draw_behind_parent(true);
@@ -536,39 +447,35 @@ void TileSetEditor::initialize_bottom_editor() {
workspace->add_child(preview);
preview->set_centered(false);
preview->set_draw_behind_parent(true);
- preview->set_region(true);
-}
+ preview->set_position(WORKSPACE_MARGIN);
-TileSetEditor::TileSetEditor(EditorNode *p_editor) {
-
- menu = memnew(MenuButton);
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(menu);
- menu->hide();
- menu->set_text(TTR("Tile Set"));
- menu->get_popup()->add_item(TTR("Add Item"), MENU_OPTION_ADD_ITEM);
- menu->get_popup()->add_item(TTR("Remove Item"), MENU_OPTION_REMOVE_ITEM);
- menu->get_popup()->add_separator();
- menu->get_popup()->add_item(TTR("Create from Scene"), MENU_OPTION_CREATE_FROM_SCENE);
- menu->get_popup()->add_item(TTR("Merge from Scene"), MENU_OPTION_MERGE_FROM_SCENE);
- menu->get_popup()->connect("id_pressed", this, "_menu_cbk");
- editor = p_editor;
+ //---------------
cd = memnew(ConfirmationDialog);
add_child(cd);
- cd->get_ok()->connect("pressed", this, "_menu_confirm");
-
- nd = memnew(EditorNameDialog);
- add_child(nd);
- nd->set_hide_on_ok(true);
- nd->get_line_edit()->set_margin(MARGIN_TOP, 28);
- nd->connect("name_confirmed", this, "_name_dialog_confirm");
+ cd->connect("confirmed", this, "_on_tileset_toolbar_confirm");
+ //---------------
err_dialog = memnew(AcceptDialog);
add_child(err_dialog);
- err_dialog->set_title(TTR("Error"));
- draw_handles = false;
+ //---------------
+ texture_dialog = memnew(EditorFileDialog);
+ texture_dialog->set_access(EditorFileDialog::ACCESS_RESOURCES);
+ texture_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILES);
+ texture_dialog->clear_filters();
+ List<String> extensions;
+
+ ResourceLoader::get_recognized_extensions_for_type("Texture", &extensions);
+ for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
- initialize_bottom_editor();
+ texture_dialog->add_filter("*." + E->get() + " ; " + E->get().to_upper());
+ }
+ add_child(texture_dialog);
+ texture_dialog->connect("files_selected", this, "_on_textures_added");
+
+ //---------------
+ helper = memnew(TilesetEditorContext(this));
+ tile_names_opacity = 0;
}
TileSetEditor::~TileSetEditor() {
@@ -576,57 +483,166 @@ TileSetEditor::~TileSetEditor() {
memdelete(helper);
}
-void TileSetEditor::_on_tile_list_selected(int p_index) {
- if (get_current_tile() >= 0) {
+void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
+ option = p_index;
+ switch (option) {
+ case TOOL_TILESET_ADD_TEXTURE: {
+ texture_dialog->popup_centered_ratio();
+ } break;
+ case TOOL_TILESET_REMOVE_TEXTURE: {
+ if (get_current_texture().is_valid()) {
+ cd->set_text(TTR("Remove Selected Textue and ALL TILES wich uses it?"));
+ cd->popup_centered(Size2(300, 60));
+ } else {
+ err_dialog->set_text(TTR("You haven't selected a texture to remove."));
+ err_dialog->popup_centered(Size2(300, 60));
+ }
+ } break;
+ case TOOL_TILESET_CREATE_SCENE: {
+
+ cd->set_text(TTR("Create from scene?"));
+ cd->popup_centered(Size2(300, 60));
+ } break;
+ case TOOL_TILESET_MERGE_SCENE: {
+
+ cd->set_text(TTR("Merge from scene?"));
+ cd->popup_centered(Size2(300, 60));
+ } break;
+ }
+}
+
+void TileSetEditor::_on_tileset_toolbar_confirm() {
+ switch (option) {
+ case TOOL_TILESET_REMOVE_TEXTURE: {
+ RID current_rid = get_current_texture()->get_rid();
+ List<int> ids;
+ tileset->get_tile_list(&ids);
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ if (tileset->tile_get_texture(E->get())->get_rid() == current_rid) {
+ tileset->remove_tile(E->get());
+ }
+ }
+ texture_list->remove_item(texture_list->find_metadata(current_rid));
+ texture_map.erase(current_rid);
+ _on_texture_list_selected(-1);
+ } break;
+ case TOOL_TILESET_MERGE_SCENE:
+ case TOOL_TILESET_CREATE_SCENE: {
+
+ EditorNode *en = editor;
+ Node *scene = en->get_edited_scene();
+ if (!scene)
+ break;
+ _import_scene(scene, tileset, option == TOOL_TILESET_MERGE_SCENE);
+
+ edit(tileset);
+ } break;
+ }
+}
+
+void TileSetEditor::_on_texture_list_selected(int p_index) {
+ if (get_current_texture().is_valid()) {
current_item_index = p_index;
- preview->set_texture(tileset->tile_get_texture(get_current_tile()));
- preview->set_modulate(tileset->tile_get_modulate(get_current_tile()));
- preview->set_region_rect(tileset->tile_get_region(get_current_tile()));
- workspace->set_custom_minimum_size(tileset->tile_get_region(get_current_tile()).size);
+ preview->set_texture(get_current_texture());
+ workspace->set_custom_minimum_size(get_current_texture()->get_size() + WORKSPACE_MARGIN * 2);
+ workspace_container->set_custom_minimum_size(get_current_texture()->get_size() + WORKSPACE_MARGIN * 2);
+ workspace_overlay->set_custom_minimum_size(get_current_texture()->get_size() + WORKSPACE_MARGIN * 2);
update_workspace_tile_mode();
} else {
current_item_index = -1;
preview->set_texture(NULL);
workspace->set_custom_minimum_size(Size2i());
+ update_workspace_tile_mode();
}
- texture_region_editor->selected_tile = get_current_tile();
- texture_region_editor->_edit_region();
- helper->selected_tile = get_current_tile();
- helper->_change_notify("");
+ set_current_tile(-1);
workspace->update();
}
+void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
+ int invalid_count = 0;
+ for (int i = 0; i < p_paths.size(); i++) {
+ Ref<Texture> t = Ref<Texture>(ResourceLoader::load(p_paths[i]));
+ if (texture_map.has(t->get_rid())) {
+ invalid_count++;
+ } else {
+ texture_list->add_item(t->get_path().get_file());
+ texture_map.insert(t->get_rid(), t);
+ texture_list->set_item_metadata(texture_list->get_item_count() - 1, t->get_rid());
+ }
+ }
+ update_texture_list_icon();
+ texture_list->select(texture_list->get_item_count() - 1);
+ _on_texture_list_selected(texture_list->get_item_count() - 1);
+ if (invalid_count > 0) {
+ err_dialog->set_text(String::num(invalid_count, 0) + TTR(" file(s) was not added because was already on the list."));
+ err_dialog->popup_centered(Size2(300, 60));
+ }
+}
+
void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
edit_mode = (EditMode)p_edit_mode;
switch (edit_mode) {
+ case EDITMODE_REGION: {
+ tools[TOOL_SELECT]->show();
+ tools[BITMASK_COPY]->hide();
+ tools[BITMASK_PASTE]->hide();
+ tools[BITMASK_CLEAR]->hide();
+ tools[SHAPE_NEW_POLYGON]->hide();
+ if (workspace_mode == WORKSPACE_EDIT)
+ tools[SHAPE_DELETE]->show();
+ else
+ tools[SHAPE_DELETE]->hide();
+ tools[SHAPE_KEEP_INSIDE_TILE]->hide();
+ tools[TOOL_GRID_SNAP]->show();
+
+ tools[TOOL_SELECT]->set_pressed(true);
+ tools[TOOL_SELECT]->set_tooltip(TTR("Drag handles to edit Rect.\nClick on another Tile to edit it."));
+ spin_priority->hide();
+ } break;
case EDITMODE_BITMASK: {
- tool_containers[TOOLBAR_DUMMY]->show();
- tool_containers[TOOLBAR_BITMASK]->show();
- tool_containers[TOOLBAR_SHAPE]->hide();
+ tools[TOOL_SELECT]->show();
+ tools[BITMASK_COPY]->show();
+ tools[BITMASK_PASTE]->show();
+ tools[BITMASK_CLEAR]->show();
+ tools[SHAPE_NEW_POLYGON]->hide();
+ tools[SHAPE_DELETE]->hide();
+ tools[SHAPE_KEEP_INSIDE_TILE]->hide();
+ tools[TOOL_GRID_SNAP]->hide();
+
tools[TOOL_SELECT]->set_pressed(true);
- tools[TOOL_SELECT]->set_tooltip(TTR("LMB: set bit on.\nRMB: set bit off."));
+ tools[TOOL_SELECT]->set_tooltip(TTR("LMB: set bit on.\nRMB: set bit off.\nClick on another Tile to edit it."));
spin_priority->hide();
} break;
case EDITMODE_COLLISION:
case EDITMODE_NAVIGATION:
case EDITMODE_OCCLUSION: {
- tool_containers[TOOLBAR_DUMMY]->show();
- tool_containers[TOOLBAR_BITMASK]->hide();
- tool_containers[TOOLBAR_SHAPE]->show();
- tools[TOOL_SELECT]->set_tooltip(TTR("Select current edited sub-tile."));
+ tools[TOOL_SELECT]->show();
+ tools[BITMASK_COPY]->hide();
+ tools[BITMASK_PASTE]->hide();
+ tools[BITMASK_CLEAR]->hide();
+ tools[SHAPE_NEW_POLYGON]->show();
+ tools[SHAPE_DELETE]->show();
+ tools[SHAPE_KEEP_INSIDE_TILE]->show();
+ tools[TOOL_GRID_SNAP]->show();
+
+ tools[TOOL_SELECT]->set_tooltip(TTR("Select current edited sub-tile.\nClick on another Tile to edit it."));
spin_priority->hide();
-
select_coord(edited_shape_coord);
} break;
default: {
- tool_containers[TOOLBAR_DUMMY]->show();
- tool_containers[TOOLBAR_BITMASK]->hide();
- tool_containers[TOOLBAR_SHAPE]->hide();
+ tools[TOOL_SELECT]->show();
+ tools[BITMASK_COPY]->hide();
+ tools[BITMASK_PASTE]->hide();
+ tools[BITMASK_CLEAR]->hide();
+ tools[SHAPE_NEW_POLYGON]->hide();
+ tools[SHAPE_DELETE]->hide();
+ tools[SHAPE_KEEP_INSIDE_TILE]->hide();
+ tools[TOOL_GRID_SNAP]->show();
if (edit_mode == EDITMODE_ICON) {
- tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to use as icon, this will be also used on invalid autotile bindings."));
+ tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to use as icon, this will be also used on invalid autotile bindings.\nClick on another Tile to edit it."));
spin_priority->hide();
} else {
- tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to change its priority."));
+ tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to change its priority.\nClick on another Tile to edit it."));
spin_priority->show();
}
} break;
@@ -634,25 +650,52 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
workspace->update();
}
+void TileSetEditor::_on_workspace_mode_changed(int p_workspace_mode) {
+ workspace_mode = (WorkspaceMode)p_workspace_mode;
+ if (p_workspace_mode == WORKSPACE_EDIT) {
+ update_workspace_tile_mode();
+ } else {
+ for (int i = 0; i < EDITMODE_MAX; i++) {
+ tool_editmode[i]->hide();
+ }
+ tool_editmode[EDITMODE_REGION]->show();
+ tool_editmode[EDITMODE_REGION]->set_pressed(true);
+ _on_edit_mode_changed(EDITMODE_REGION);
+ }
+}
+
void TileSetEditor::_on_workspace_draw() {
- if (get_current_tile() >= 0 && !tileset.is_null()) {
+ const Color COLOR_AUTOTILE = Color(0.266373, 0.565288, 0.988281);
+ const Color COLOR_SINGLE = Color(0.988281, 0.909323, 0.266373);
+ const Color COLOR_ATLAS = Color(0.78653, 0.812835, 0.832031);
+
+ if (tileset.is_null())
+ return;
+ if (!get_current_texture().is_valid())
+ return;
+
+ draw_highlight_current_tile();
+
+ draw_grid_snap();
+ if (get_current_tile() >= 0) {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->autotile_get_size(get_current_tile());
Rect2i region = tileset->tile_get_region(get_current_tile());
- Color c(0.347214, 0.722656, 0.617063);
switch (edit_mode) {
case EDITMODE_ICON: {
Vector2 coord = tileset->autotile_get_icon_coordinate(get_current_tile());
- draw_highlight_tile(coord);
+ draw_highlight_subtile(coord);
} break;
case EDITMODE_BITMASK: {
- c = Color(1, 0, 0, 0.5);
+ Color c(1, 0, 0, 0.5);
for (float x = 0; x < region.size.x / (spacing + size.x); x++) {
for (float y = 0; y < region.size.y / (spacing + size.y); y++) {
Vector2 coord(x, y);
Point2 anchor(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
+ anchor += WORKSPACE_MARGIN;
+ anchor += region.position;
uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
if (mask & TileSet::BIND_TOPLEFT) {
@@ -702,9 +745,9 @@ void TileSetEditor::_on_workspace_draw() {
case EDITMODE_COLLISION:
case EDITMODE_OCCLUSION:
case EDITMODE_NAVIGATION: {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
Vector2 coord = edited_shape_coord;
- draw_highlight_tile(coord);
+ draw_highlight_subtile(coord);
}
draw_polygon_shapes();
draw_grid_snap();
@@ -723,89 +766,334 @@ void TileSetEditor::_on_workspace_draw() {
}
}
spin_priority->set_suffix(" / " + String::num(total, 0));
- draw_highlight_tile(edited_shape_coord, queue_others);
+ draw_highlight_subtile(edited_shape_coord, queue_others);
} break;
}
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
- float j = -size.x; //make sure to draw at 0
- while (j < region.size.x) {
- j += size.x;
- if (spacing <= 0) {
- workspace->draw_line(Point2(j, 0), Point2(j, region.size.y), c);
- } else {
- workspace->draw_rect(Rect2(Point2(j, 0), Size2(spacing, region.size.y)), c);
- }
- j += spacing;
- }
- j = -size.y; //make sure to draw at 0
- while (j < region.size.y) {
- j += size.y;
- if (spacing <= 0) {
- workspace->draw_line(Point2(0, j), Point2(region.size.x, j), c);
- } else {
- workspace->draw_rect(Rect2(Point2(0, j), Size2(region.size.x, spacing)), c);
- }
- j += spacing;
+ draw_tile_subdivision(get_current_tile(), Color(0.347214, 0.722656, 0.617063));
+ }
+
+ RID current_texture_rid = get_current_texture()->get_rid();
+ List<int> *tiles = new List<int>();
+ tileset->get_tile_list(tiles);
+ for (List<int>::Element *E = tiles->front(); E; E = E->next()) {
+ int t_id = E->get();
+ if (tileset->tile_get_texture(t_id)->get_rid() == current_texture_rid && (t_id != get_current_tile() || edit_mode != EDITMODE_REGION)) {
+ Rect2i region = tileset->tile_get_region(t_id);
+ region.position += WORKSPACE_MARGIN;
+ Color c;
+ if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE)
+ c = COLOR_SINGLE;
+ else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE)
+ c = COLOR_AUTOTILE;
+ else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
+ c = COLOR_ATLAS;
+ draw_tile_subdivision(t_id, Color(0.347214, 0.722656, 0.617063, 0.5));
+ workspace->draw_rect(region, c, false);
+ }
+ }
+ if (edit_mode == EDITMODE_REGION) {
+ if (workspace_mode != WORKSPACE_EDIT) {
+ Rect2i region = edited_region;
+ Color c;
+ if (workspace_mode == WORKSPACE_CREATE_SINGLE)
+ c = COLOR_SINGLE;
+ else if (workspace_mode == WORKSPACE_CREATE_AUTOTILE)
+ c = COLOR_AUTOTILE;
+ else if (workspace_mode == WORKSPACE_CREATE_ATLAS)
+ c = COLOR_ATLAS;
+ workspace->draw_rect(region, c, false);
+ draw_edited_region_subdivision();
+ } else {
+ int t_id = get_current_tile();
+ Rect2i region;
+ if (draw_edited_region)
+ region = edited_region;
+ else {
+ region = tileset->tile_get_region(t_id);
+ region.position += WORKSPACE_MARGIN;
}
+ Color c;
+ if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE)
+ c = COLOR_SINGLE;
+ else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE)
+ c = COLOR_AUTOTILE;
+ else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
+ c = COLOR_ATLAS;
+ if (draw_edited_region)
+ draw_edited_region_subdivision();
+ else
+ draw_tile_subdivision(t_id, Color(0.347214, 0.722656, 0.617063, 1));
+ workspace->draw_rect(region, c, false);
}
}
workspace_overlay->update();
}
+void TileSetEditor::_on_workspace_process() {
+ float a = tile_names_opacity;
+ if (Input::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
+ a += get_tree()->get_idle_process_time() * 2;
+ } else {
+ a -= get_tree()->get_idle_process_time() * 2;
+ }
+
+ a = CLAMP(a, 0, 1);
+ if (a != tile_names_opacity)
+ workspace_overlay->update();
+ tile_names_opacity = a;
+}
+
void TileSetEditor::_on_workspace_overlay_draw() {
+ if (!tileset.is_valid())
+ return;
+ if (!get_current_texture().is_valid())
+ return;
+
+ const Color COLOR_AUTOTILE = Color(0.266373, 0.565288, 0.988281);
+ const Color COLOR_SINGLE = Color(0.988281, 0.909323, 0.266373);
+ const Color COLOR_ATLAS = Color(0.78653, 0.812835, 0.832031);
+
+ if (tile_names_opacity > 0) {
+ RID current_texture_rid = get_current_texture()->get_rid();
+ List<int> *tiles = new List<int>();
+ tileset->get_tile_list(tiles);
+ for (List<int>::Element *E = tiles->front(); E; E = E->next()) {
+ int t_id = E->get();
+ if (tileset->tile_get_texture(t_id)->get_rid() == current_texture_rid) {
+ Rect2i region = tileset->tile_get_region(t_id);
+ region.position += WORKSPACE_MARGIN;
+ region.position *= workspace->get_scale().x;
+ Color c;
+ if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE)
+ c = COLOR_SINGLE;
+ else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE)
+ c = COLOR_AUTOTILE;
+ else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
+ c = COLOR_ATLAS;
+ c.a = tile_names_opacity;
+ Ref<Font> font = get_font("font", "Label");
+ region.set_size(font->get_string_size(tileset->tile_get_name(t_id)));
+ workspace_overlay->draw_rect(region, c);
+ region.position.y += region.size.y - 2;
+ c = Color(0.1, 0.1, 0.1, tile_names_opacity);
+ workspace_overlay->draw_string(font, region.position, tileset->tile_get_name(t_id), c);
+ }
+ }
+ }
+
int t_id = get_current_tile();
- if (t_id < 0 || !draw_handles)
+ if (t_id < 0)
return;
Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
-
- for (int i = 0; i < current_shape.size(); i++) {
- workspace_overlay->draw_texture(handle, current_shape[i] * workspace->get_scale().x - handle->get_size() * 0.5);
+ if (draw_handles) {
+ for (int i = 0; i < current_shape.size(); i++) {
+ workspace_overlay->draw_texture(handle, current_shape[i] * workspace->get_scale().x - handle->get_size() * 0.5);
+ }
}
}
#define MIN_DISTANCE_SQUARED 6
void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
+ if (tileset.is_null())
+ return;
+ if (!get_current_texture().is_valid())
+ return;
- if (get_current_tile() >= 0 && !tileset.is_null()) {
- Ref<InputEventMouseButton> mb = p_ie;
- Ref<InputEventMouseMotion> mm = p_ie;
+ static bool dragging;
+ static bool erasing;
+ draw_edited_region = false;
- static bool dragging;
- static bool erasing;
+ Rect2 current_tile_region = Rect2();
+ if (get_current_tile() >= 0) {
+ current_tile_region = tileset->tile_get_region(get_current_tile());
+ }
+ current_tile_region.position += WORKSPACE_MARGIN;
+
+ Ref<InputEventMouseButton> mb = p_ie;
+ Ref<InputEventMouseMotion> mm = p_ie;
+
+ if (mb.is_valid()) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (!current_tile_region.has_point(mb->get_position())) {
+ List<int> *tiles = new List<int>();
+ tileset->get_tile_list(tiles);
+ for (List<int>::Element *E = tiles->front(); E; E = E->next()) {
+ int t_id = E->get();
+ if (get_current_texture()->get_rid() == tileset->tile_get_texture(t_id)->get_rid()) {
+ Rect2 r = tileset->tile_get_region(t_id);
+ r.position += WORKSPACE_MARGIN;
+ if (r.has_point(mb->get_position())) {
+ set_current_tile(t_id);
+ workspace->update();
+ workspace_overlay->update();
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ // Drag Middle Mouse
+ if (mm.is_valid()) {
+ if (mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
+ Vector2 dragged(mm->get_relative().x, mm->get_relative().y);
+ scroll->set_h_scroll(scroll->get_h_scroll() - dragged.x * workspace->get_scale().x);
+ scroll->set_v_scroll(scroll->get_v_scroll() - dragged.y * workspace->get_scale().x);
+ }
+ }
- int spacing = tileset->autotile_get_spacing(get_current_tile());
- Vector2 size = tileset->autotile_get_size(get_current_tile());
- switch (edit_mode) {
- case EDITMODE_ICON: {
- if (mb.is_valid()) {
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
- Vector2 coord((int)(mb->get_position().x / (spacing + size.x)), (int)(mb->get_position().y / (spacing + size.y)));
- tileset->autotile_set_icon_coordinate(get_current_tile(), coord);
- Rect2 region = tileset->tile_get_region(get_current_tile());
- region.size = size;
- coord.x *= (spacing + size.x);
- coord.y *= (spacing + size.y);
- region.position += coord;
- tile_list->set_item_icon_region(current_item_index, region);
- workspace->update();
+ if (edit_mode == EDITMODE_REGION) {
+ if (mb.is_valid()) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (get_current_tile() >= 0 || workspace_mode != WORKSPACE_EDIT) {
+ dragging = true;
+ region_from = mb->get_position();
+ edited_region = Rect2(region_from, Size2());
+ workspace->update();
+ workspace_overlay->update();
+ return;
+ }
+ } else if (dragging && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
+ dragging = false;
+ edited_region = Rect2();
+ workspace->update();
+ workspace_overlay->update();
+ return;
+ } else if (dragging && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ dragging = false;
+ update_edited_region(mb->get_position());
+ edited_region.position -= WORKSPACE_MARGIN;
+ if (!edited_region.has_no_area()) {
+ if (get_current_tile() >= 0 && workspace_mode == WORKSPACE_EDIT) {
+ tileset->tile_set_region(get_current_tile(), edited_region);
+ } else {
+ int t_id = tileset->get_last_unused_tile_id();
+ tileset->create_tile(t_id);
+ tileset->tile_set_texture(t_id, get_current_texture());
+ tileset->tile_set_region(t_id, edited_region);
+ tileset->tile_set_name(t_id, get_current_texture()->get_path().get_file() + " " + String::num(t_id, 0));
+ if (workspace_mode != WORKSPACE_CREATE_SINGLE) {
+ tileset->autotile_set_size(t_id, snap_step);
+ tileset->autotile_set_spacing(t_id, snap_separation.x);
+ tileset->tile_set_tile_mode(t_id, workspace_mode == WORKSPACE_CREATE_AUTOTILE ? TileSet::AUTO_TILE : TileSet::ATLAS_TILE);
+ }
+ set_current_tile(t_id);
+ tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
+ _on_workspace_mode_changed(WORKSPACE_EDIT);
}
}
- } break;
- case EDITMODE_BITMASK: {
- if (mb.is_valid()) {
- if (mb->is_pressed()) {
- if (dragging) {
- return;
+ workspace->update();
+ workspace_overlay->update();
+ return;
+ }
+ } else if (mm.is_valid()) {
+ if (dragging) {
+ update_edited_region(mm->get_position());
+ draw_edited_region = true;
+ workspace->update();
+ workspace_overlay->update();
+ return;
+ }
+ }
+ }
+ if (workspace_mode == WORKSPACE_EDIT) {
+
+ if (get_current_tile() >= 0) {
+ int spacing = tileset->autotile_get_spacing(get_current_tile());
+ Vector2 size = tileset->autotile_get_size(get_current_tile());
+ switch (edit_mode) {
+ case EDITMODE_ICON: {
+ if (mb.is_valid()) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && current_tile_region.has_point(mb->get_position())) {
+ Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
+ tileset->autotile_set_icon_coordinate(get_current_tile(), coord);
+ Rect2 region = tileset->tile_get_region(get_current_tile());
+ region.size = size;
+ coord.x *= (spacing + size.x);
+ coord.y *= (spacing + size.y);
+ region.position += coord;
+ workspace->update();
+ }
+ }
+ } break;
+ case EDITMODE_BITMASK: {
+ if (mb.is_valid()) {
+ if (mb->is_pressed()) {
+ if (dragging) {
+ return;
+ }
+ if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) {
+ dragging = true;
+ erasing = (mb->get_button_index() == BUTTON_RIGHT);
+ Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
+ Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
+ pos = mb->get_position() - (pos + current_tile_region.position);
+ uint16_t bit = 0;
+ if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
+ if (pos.x < size.x / 2) {
+ if (pos.y < size.y / 2) {
+ bit = TileSet::BIND_TOPLEFT;
+ } else {
+ bit = TileSet::BIND_BOTTOMLEFT;
+ }
+ } else {
+ if (pos.y < size.y / 2) {
+ bit = TileSet::BIND_TOPRIGHT;
+ } else {
+ bit = TileSet::BIND_BOTTOMRIGHT;
+ }
+ }
+ } else {
+ if (pos.x < size.x / 3) {
+ if (pos.y < size.y / 3) {
+ bit = TileSet::BIND_TOPLEFT;
+ } else if (pos.y > (size.y / 3) * 2) {
+ bit = TileSet::BIND_BOTTOMLEFT;
+ } else {
+ bit = TileSet::BIND_LEFT;
+ }
+ } else if (pos.x > (size.x / 3) * 2) {
+ if (pos.y < size.y / 3) {
+ bit = TileSet::BIND_TOPRIGHT;
+ } else if (pos.y > (size.y / 3) * 2) {
+ bit = TileSet::BIND_BOTTOMRIGHT;
+ } else {
+ bit = TileSet::BIND_RIGHT;
+ }
+ } else {
+ if (pos.y < size.y / 3) {
+ bit = TileSet::BIND_TOP;
+ } else if (pos.y > (size.y / 3) * 2) {
+ bit = TileSet::BIND_BOTTOM;
+ } else {
+ bit = TileSet::BIND_CENTER;
+ }
+ }
+ }
+ uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+ if (erasing) {
+ mask &= ~bit;
+ } else {
+ mask |= bit;
+ }
+ tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
+ workspace->update();
+ }
+ } else {
+ if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) {
+ dragging = false;
+ erasing = false;
+ }
}
- if (mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) {
- dragging = true;
- erasing = (mb->get_button_index() == BUTTON_RIGHT);
- Vector2 coord((int)(mb->get_position().x / (spacing + size.x)), (int)(mb->get_position().y / (spacing + size.y)));
+ }
+ if (mm.is_valid()) {
+ if (dragging && current_tile_region.has_point(mm->get_position())) {
+ Vector2 coord((int)((mm->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mm->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
- pos = mb->get_position() - pos;
+ pos = mm->get_position() - (pos + current_tile_region.position);
uint16_t bit = 0;
if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
if (pos.x < size.x / 2) {
@@ -857,269 +1145,198 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
workspace->update();
}
- } else {
- if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) {
- dragging = false;
- erasing = false;
- }
}
- }
- if (mm.is_valid()) {
- if (dragging) {
- Vector2 coord((int)(mm->get_position().x / (spacing + size.x)), (int)(mm->get_position().y / (spacing + size.y)));
- Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
- pos = mm->get_position() - pos;
- uint16_t bit = 0;
- if (tileset->autotile_get_bitmask_mode(get_current_tile()) == TileSet::BITMASK_2X2) {
- if (pos.x < size.x / 2) {
- if (pos.y < size.y / 2) {
- bit = TileSet::BIND_TOPLEFT;
- } else {
- bit = TileSet::BIND_BOTTOMLEFT;
- }
- } else {
- if (pos.y < size.y / 2) {
- bit = TileSet::BIND_TOPRIGHT;
- } else {
- bit = TileSet::BIND_BOTTOMRIGHT;
- }
- }
- } else {
- if (pos.x < size.x / 3) {
- if (pos.y < size.y / 3) {
- bit = TileSet::BIND_TOPLEFT;
- } else if (pos.y > (size.y / 3) * 2) {
- bit = TileSet::BIND_BOTTOMLEFT;
- } else {
- bit = TileSet::BIND_LEFT;
- }
- } else if (pos.x > (size.x / 3) * 2) {
- if (pos.y < size.y / 3) {
- bit = TileSet::BIND_TOPRIGHT;
- } else if (pos.y > (size.y / 3) * 2) {
- bit = TileSet::BIND_BOTTOMRIGHT;
- } else {
- bit = TileSet::BIND_RIGHT;
- }
- } else {
- if (pos.y < size.y / 3) {
- bit = TileSet::BIND_TOP;
- } else if (pos.y > (size.y / 3) * 2) {
- bit = TileSet::BIND_BOTTOM;
- } else {
- bit = TileSet::BIND_CENTER;
- }
- }
- }
- uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
- if (erasing) {
- mask &= ~bit;
- } else {
- mask |= bit;
- }
- tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
- workspace->update();
+ } break;
+ case EDITMODE_COLLISION:
+ case EDITMODE_OCCLUSION:
+ case EDITMODE_NAVIGATION:
+ case EDITMODE_PRIORITY: {
+ Vector2 shape_anchor = Vector2(0, 0);
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ shape_anchor = edited_shape_coord;
+ shape_anchor.x *= (size.x + spacing);
+ shape_anchor.y *= (size.y + spacing);
}
- }
- } break;
- case EDITMODE_COLLISION:
- case EDITMODE_OCCLUSION:
- case EDITMODE_NAVIGATION:
- case EDITMODE_PRIORITY: {
- Vector2 shape_anchor = Vector2(0, 0);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
- shape_anchor = edited_shape_coord;
- shape_anchor.x *= (size.x + spacing);
- shape_anchor.y *= (size.y + spacing);
- }
- if (tools[TOOL_SELECT]->is_pressed()) {
- if (mb.is_valid()) {
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
- if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) {
- for (int i = 0; i < current_shape.size(); i++) {
- if ((current_shape[i] - mb->get_position()).length_squared() <= MIN_DISTANCE_SQUARED) {
- dragging_point = i;
- workspace->update();
- return;
+ shape_anchor += current_tile_region.position;
+ if (tools[TOOL_SELECT]->is_pressed()) {
+ if (mb.is_valid()) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) {
+ for (int i = 0; i < current_shape.size(); i++) {
+ if ((current_shape[i] - mb->get_position()).length_squared() <= MIN_DISTANCE_SQUARED) {
+ dragging_point = i;
+ workspace->update();
+ return;
+ }
}
}
- }
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
- Vector2 coord((int)(mb->get_position().x / (spacing + size.x)), (int)(mb->get_position().y / (spacing + size.y)));
- if (edited_shape_coord != coord) {
- edited_shape_coord = coord;
- edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord);
- edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord);
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
- bool found_collision_shape = false;
- for (int i = 0; i < sd.size(); i++) {
- if (sd[i].autotile_coord == coord) {
- edited_collision_shape = sd[i].shape;
- found_collision_shape = true;
- break;
+ if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) && current_tile_region.has_point(mb->get_position())) {
+ Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
+ if (edited_shape_coord != coord) {
+ edited_shape_coord = coord;
+ edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord);
+ edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord);
+ Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
+ bool found_collision_shape = false;
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].autotile_coord == coord) {
+ edited_collision_shape = sd[i].shape;
+ found_collision_shape = true;
+ break;
+ }
}
+ if (!found_collision_shape)
+ edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
+ select_coord(edited_shape_coord);
}
- if (!found_collision_shape)
- edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
- select_coord(edited_shape_coord);
}
- }
- workspace->update();
- } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
- if (edit_mode == EDITMODE_COLLISION) {
- if (dragging_point >= 0) {
- dragging_point = -1;
+ workspace->update();
+ } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (edit_mode == EDITMODE_COLLISION) {
+ if (dragging_point >= 0) {
+ dragging_point = -1;
- Vector<Vector2> points;
+ Vector<Vector2> points;
- for (int i = 0; i < current_shape.size(); i++) {
- Vector2 p = current_shape[i];
- if (tools[SHAPE_GRID_SNAP]->is_pressed() || tools[SHAPE_KEEP_INSIDE_TILE]->is_pressed()) {
- p = snap_point(p);
+ for (int i = 0; i < current_shape.size(); i++) {
+ Vector2 p = current_shape[i];
+ if (tools[TOOL_GRID_SNAP]->is_pressed() || tools[SHAPE_KEEP_INSIDE_TILE]->is_pressed()) {
+ p = snap_point(p);
+ }
+ points.push_back(p - shape_anchor);
}
- points.push_back(p - shape_anchor);
- }
- edited_collision_shape->set_points(points);
+ edited_collision_shape->set_points(points);
- workspace->update();
- }
- } else if (edit_mode == EDITMODE_OCCLUSION) {
- if (dragging_point >= 0) {
- dragging_point = -1;
-
- PoolVector<Vector2> polygon;
- polygon.resize(current_shape.size());
- PoolVector<Vector2>::Write w = polygon.write();
-
- for (int i = 0; i < current_shape.size(); i++) {
- w[i] = current_shape[i] - shape_anchor;
+ workspace->update();
}
+ } else if (edit_mode == EDITMODE_OCCLUSION) {
+ if (dragging_point >= 0) {
+ dragging_point = -1;
- w = PoolVector<Vector2>::Write();
- edited_occlusion_shape->set_polygon(polygon);
+ PoolVector<Vector2> polygon;
+ polygon.resize(current_shape.size());
+ PoolVector<Vector2>::Write w = polygon.write();
- workspace->update();
- }
- } else if (edit_mode == EDITMODE_NAVIGATION) {
- if (dragging_point >= 0) {
- dragging_point = -1;
+ for (int i = 0; i < current_shape.size(); i++) {
+ w[i] = current_shape[i] - shape_anchor;
+ }
- PoolVector<Vector2> polygon;
- Vector<int> indices;
- polygon.resize(current_shape.size());
- PoolVector<Vector2>::Write w = polygon.write();
+ w = PoolVector<Vector2>::Write();
+ edited_occlusion_shape->set_polygon(polygon);
- for (int i = 0; i < current_shape.size(); i++) {
- w[i] = current_shape[i] - shape_anchor;
- indices.push_back(i);
+ workspace->update();
}
+ } else if (edit_mode == EDITMODE_NAVIGATION) {
+ if (dragging_point >= 0) {
+ dragging_point = -1;
+
+ PoolVector<Vector2> polygon;
+ Vector<int> indices;
+ polygon.resize(current_shape.size());
+ PoolVector<Vector2>::Write w = polygon.write();
+
+ for (int i = 0; i < current_shape.size(); i++) {
+ w[i] = current_shape[i] - shape_anchor;
+ indices.push_back(i);
+ }
- w = PoolVector<Vector2>::Write();
- edited_navigation_shape->set_vertices(polygon);
- edited_navigation_shape->add_polygon(indices);
-
- workspace->update();
- }
- }
- }
- } else if (mm.is_valid()) {
- if (dragging_point >= 0) {
- current_shape.set(dragging_point, snap_point(mm->get_position()));
- workspace->update();
- }
- }
- } else if (tools[SHAPE_NEW_POLYGON]->is_pressed()) {
+ w = PoolVector<Vector2>::Write();
+ edited_navigation_shape->set_vertices(polygon);
+ edited_navigation_shape->add_polygon(indices);
- if (mb.is_valid()) {
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
- Vector2 pos = mb->get_position();
- pos = snap_point(pos);
- if (creating_shape) {
- if (current_shape.size() > 0) {
- if ((pos - current_shape[0]).length_squared() <= MIN_DISTANCE_SQUARED) {
- if (current_shape.size() > 2) {
- close_shape(shape_anchor);
- workspace->update();
- return;
- }
+ workspace->update();
}
}
- current_shape.push_back(pos);
+ }
+ } else if (mm.is_valid()) {
+ if (dragging_point >= 0) {
+ current_shape.set(dragging_point, snap_point(mm->get_position()));
workspace->update();
- } else {
- int t_id = get_current_tile();
- if (t_id >= 0) {
- if (edit_mode == EDITMODE_COLLISION) {
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(t_id);
- for (int i = 0; i < sd.size(); i++) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || sd[i].autotile_coord == edited_shape_coord) {
- Ref<ConvexPolygonShape2D> shape = sd[i].shape;
-
- if (!shape.is_null()) {
- sd.remove(i);
- tileset->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape = Ref<Shape2D>();
- workspace->update();
- }
- break;
+ }
+ }
+ } else if (tools[SHAPE_NEW_POLYGON]->is_pressed()) {
+
+ if (mb.is_valid()) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ Vector2 pos = mb->get_position();
+ pos = snap_point(pos);
+ if (creating_shape) {
+ if (current_shape.size() > 0) {
+ if ((pos - current_shape[0]).length_squared() <= MIN_DISTANCE_SQUARED) {
+ if (current_shape.size() > 2) {
+ close_shape(shape_anchor);
+ workspace->update();
+ return;
}
}
- } else if (edit_mode == EDITMODE_OCCLUSION) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
- Map<Vector2, Ref<OccluderPolygon2D> > map = tileset->autotile_get_light_oclusion_map(t_id);
- for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = map.front(); E; E = E->next()) {
- if (E->key() == edited_shape_coord) {
- tileset->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+ }
+ current_shape.push_back(pos);
+ workspace->update();
+ } else {
+ int t_id = get_current_tile();
+ if (t_id >= 0) {
+ if (edit_mode == EDITMODE_COLLISION) {
+ Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(t_id);
+ for (int i = 0; i < sd.size(); i++) {
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || sd[i].autotile_coord == edited_shape_coord) {
+ Ref<ConvexPolygonShape2D> shape = sd[i].shape;
+
+ if (!shape.is_null()) {
+ sd.remove(i);
+ tileset->tile_set_shapes(get_current_tile(), sd);
+ edited_collision_shape = Ref<Shape2D>();
+ workspace->update();
+ }
break;
}
}
- } else
- tileset->tile_set_light_occluder(t_id, Ref<OccluderPolygon2D>());
+ } else if (edit_mode == EDITMODE_OCCLUSION) {
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ Map<Vector2, Ref<OccluderPolygon2D> > map = tileset->autotile_get_light_oclusion_map(t_id);
+ for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = map.front(); E; E = E->next()) {
+ if (E->key() == edited_shape_coord) {
+ tileset->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+ break;
+ }
+ }
+ } else
+ tileset->tile_set_light_occluder(t_id, Ref<OccluderPolygon2D>());
- edited_occlusion_shape = Ref<OccluderPolygon2D>();
- workspace->update();
- } else if (edit_mode == EDITMODE_NAVIGATION) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
- Map<Vector2, Ref<NavigationPolygon> > map = tileset->autotile_get_navigation_map(t_id);
- for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) {
- if (E->key() == edited_shape_coord) {
- tileset->autotile_set_navigation_polygon(t_id, Ref<NavigationPolygon>(), edited_shape_coord);
- break;
+ edited_occlusion_shape = Ref<OccluderPolygon2D>();
+ workspace->update();
+ } else if (edit_mode == EDITMODE_NAVIGATION) {
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ Map<Vector2, Ref<NavigationPolygon> > map = tileset->autotile_get_navigation_map(t_id);
+ for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) {
+ if (E->key() == edited_shape_coord) {
+ tileset->autotile_set_navigation_polygon(t_id, Ref<NavigationPolygon>(), edited_shape_coord);
+ break;
+ }
}
- }
- } else
- tileset->tile_set_navigation_polygon(t_id, Ref<NavigationPolygon>());
- edited_navigation_shape = Ref<NavigationPolygon>();
- workspace->update();
+ } else
+ tileset->tile_set_navigation_polygon(t_id, Ref<NavigationPolygon>());
+ edited_navigation_shape = Ref<NavigationPolygon>();
+ workspace->update();
+ }
}
- }
- creating_shape = true;
- current_shape.resize(0);
- current_shape.push_back(snap_point(pos));
+ creating_shape = true;
+ current_shape.resize(0);
+ current_shape.push_back(snap_point(pos));
+ }
+ } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT && current_shape.size() > 2) {
+ if (creating_shape) {
+ close_shape(shape_anchor);
+ }
}
- } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT && current_shape.size() > 2) {
+ } else if (mm.is_valid()) {
if (creating_shape) {
- close_shape(shape_anchor);
+ workspace->update();
}
}
- } else if (mm.is_valid()) {
- if (creating_shape) {
- workspace->update();
- }
}
- }
- } break;
- }
-
- //Drag Middle Mouse
- if (mm.is_valid()) {
- if (mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
-
- Vector2 dragged(mm->get_relative().x, mm->get_relative().y);
- scroll->set_h_scroll(scroll->get_h_scroll() - dragged.x * workspace->get_scale().x);
- scroll->set_v_scroll(scroll->get_v_scroll() - dragged.y * workspace->get_scale().x);
+ } break;
}
}
}
@@ -1144,6 +1361,16 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
workspace->update();
} else {
switch (edit_mode) {
+ case EDITMODE_REGION: {
+ if (workspace_mode == WORKSPACE_EDIT && get_current_tile() >= 0) {
+ tileset->remove_tile(get_current_tile());
+ workspace->update();
+ workspace_overlay->update();
+ }
+ tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
+ workspace_mode = WORKSPACE_EDIT;
+ update_workspace_tile_mode();
+ } break;
case EDITMODE_COLLISION: {
if (!edited_collision_shape.is_null()) {
Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
@@ -1186,22 +1413,22 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
if (scale > 0.1) {
scale /= 2;
workspace->set_scale(Vector2(scale, scale));
- workspace_container->set_custom_minimum_size(preview->get_region_rect().size * scale);
- workspace_overlay->set_custom_minimum_size(preview->get_region_rect().size * scale);
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
}
} else if (p_tool == ZOOM_1) {
workspace->set_scale(Vector2(1, 1));
- workspace_container->set_custom_minimum_size(preview->get_region_rect().size);
- workspace_overlay->set_custom_minimum_size(preview->get_region_rect().size);
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size);
} else if (p_tool == ZOOM_IN) {
float scale = workspace->get_scale().x;
scale *= 2;
workspace->set_scale(Vector2(scale, scale));
- workspace_container->set_custom_minimum_size(preview->get_region_rect().size * scale);
- workspace_overlay->set_custom_minimum_size(preview->get_region_rect().size * scale);
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
} else if (p_tool == TOOL_SELECT) {
if (creating_shape) {
- //Cancel Creation
+ // Cancel Creation
creating_shape = false;
current_shape.resize(0);
workspace->update();
@@ -1215,66 +1442,140 @@ void TileSetEditor::_on_priority_changed(float val) {
}
void TileSetEditor::_on_grid_snap_toggled(bool p_val) {
- if (p_val)
- hb_grid->show();
- else
- hb_grid->hide();
+ helper->set_snap_options_visible(p_val);
workspace->update();
}
-void TileSetEditor::_set_snap_step_x(float p_val) {
- snap_step.x = p_val;
+void TileSetEditor::_set_snap_step(Vector2 p_val) {
+ snap_step.x = CLAMP(p_val.x, 0, 256);
+ snap_step.y = CLAMP(p_val.y, 0, 256);
workspace->update();
}
-void TileSetEditor::_set_snap_step_y(float p_val) {
- snap_step.y = p_val;
+void TileSetEditor::_set_snap_off(Vector2 p_val) {
+ snap_offset.x = CLAMP(p_val.x, 0, 256 + WORKSPACE_MARGIN.x);
+ snap_offset.y = CLAMP(p_val.y, 0, 256 + WORKSPACE_MARGIN.y);
workspace->update();
}
-void TileSetEditor::_set_snap_off_x(float p_val) {
- snap_offset.x = p_val;
+void TileSetEditor::_set_snap_sep(Vector2 p_val) {
+ snap_separation.x = CLAMP(p_val.x, 0, 256);
+ snap_separation.y = CLAMP(p_val.y, 0, 256);
workspace->update();
}
-void TileSetEditor::_set_snap_off_y(float p_val) {
- snap_offset.y = p_val;
- workspace->update();
-}
-void TileSetEditor::_set_snap_sep_x(float p_val) {
- snap_separation.x = p_val;
- workspace->update();
-}
+void TileSetEditor::draw_highlight_current_tile() {
-void TileSetEditor::_set_snap_sep_y(float p_val) {
- snap_separation.y = p_val;
- workspace->update();
+ if (get_current_tile() >= 0) {
+ Rect2 region = tileset->tile_get_region(get_current_tile());
+ region.position += WORKSPACE_MARGIN;
+ workspace->draw_rect(Rect2(0, 0, workspace->get_rect().size.x, region.position.y), Color(0.3, 0.3, 0.3, 0.3));
+ workspace->draw_rect(Rect2(0, region.position.y, region.position.x, region.size.y), Color(0.3, 0.3, 0.3, 0.3));
+ workspace->draw_rect(Rect2(region.position.x + region.size.x, region.position.y, workspace->get_rect().size.x - region.position.x - region.size.x, region.size.y), Color(0.3, 0.3, 0.3, 0.3));
+ workspace->draw_rect(Rect2(0, region.position.y + region.size.y, workspace->get_rect().size.x, workspace->get_rect().size.y - region.size.y - region.position.y), Color(0.3, 0.3, 0.3, 0.3));
+ } else {
+ workspace->draw_rect(Rect2(Point2(0, 0), workspace->get_rect().size), Color(0.3, 0.3, 0.3, 0.3));
+ }
}
-void TileSetEditor::draw_highlight_tile(Vector2 coord, const Vector<Vector2> &other_highlighted) {
+void TileSetEditor::draw_highlight_subtile(Vector2 coord, const Vector<Vector2> &other_highlighted) {
Vector2 size = tileset->autotile_get_size(get_current_tile());
int spacing = tileset->autotile_get_spacing(get_current_tile());
Rect2 region = tileset->tile_get_region(get_current_tile());
coord.x *= (size.x + spacing);
coord.y *= (size.y + spacing);
- workspace->draw_rect(Rect2(0, 0, region.size.x, coord.y), Color(0.5, 0.5, 0.5, 0.5));
- workspace->draw_rect(Rect2(0, coord.y, coord.x, size.y), Color(0.5, 0.5, 0.5, 0.5));
- workspace->draw_rect(Rect2(coord.x + size.x, coord.y, region.size.x - coord.x - size.x, size.y), Color(0.5, 0.5, 0.5, 0.5));
- workspace->draw_rect(Rect2(0, coord.y + size.y, region.size.x, region.size.y - size.y - coord.y), Color(0.5, 0.5, 0.5, 0.5));
+ coord += region.position;
+ coord += WORKSPACE_MARGIN;
+ workspace->draw_rect(Rect2(0, 0, workspace->get_rect().size.x, coord.y), Color(0.3, 0.3, 0.3, 0.3));
+ workspace->draw_rect(Rect2(0, coord.y, coord.x, size.y), Color(0.3, 0.3, 0.3, 0.3));
+ workspace->draw_rect(Rect2(coord.x + size.x, coord.y, workspace->get_rect().size.x - coord.x - size.x, size.y), Color(0.3, 0.3, 0.3, 0.3));
+ workspace->draw_rect(Rect2(0, coord.y + size.y, workspace->get_rect().size.x, workspace->get_rect().size.y - size.y - coord.y), Color(0.3, 0.3, 0.3, 0.3));
coord += Vector2(1, 1) / workspace->get_scale().x;
workspace->draw_rect(Rect2(coord, size - Vector2(2, 2) / workspace->get_scale().x), Color(1, 0, 0), false);
for (int i = 0; i < other_highlighted.size(); i++) {
coord = other_highlighted[i];
coord.x *= (size.x + spacing);
coord.y *= (size.y + spacing);
+ coord += region.position;
+ coord += WORKSPACE_MARGIN;
coord += Vector2(1, 1) / workspace->get_scale().x;
- workspace->draw_rect(Rect2(coord, size - Vector2(2, 2) / workspace->get_scale().x), Color(1, 0, 0), false);
+ workspace->draw_rect(Rect2(coord, size - Vector2(2, 2) / workspace->get_scale().x), Color(1, 0.5, 0.5), false);
+ }
+}
+
+void TileSetEditor::draw_tile_subdivision(int p_id, Color p_color) const {
+ Color c = p_color;
+ if (tileset->tile_get_tile_mode(p_id) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(p_id) == TileSet::ATLAS_TILE) {
+ Rect2 region = tileset->tile_get_region(p_id);
+ Size2 size = tileset->autotile_get_size(p_id);
+ int spacing = tileset->autotile_get_spacing(p_id);
+ float j = 0;
+ while (j < region.size.x) {
+ j += size.x;
+ if (spacing <= 0) {
+ workspace->draw_line(region.position + WORKSPACE_MARGIN + Point2(j, 0), region.position + WORKSPACE_MARGIN + Point2(j, region.size.y), c);
+ } else {
+ workspace->draw_rect(Rect2(region.position + WORKSPACE_MARGIN + Point2(j, 0), Size2(spacing, region.size.y)), c);
+ }
+ j += spacing;
+ }
+ j = 0;
+ while (j < region.size.y) {
+ j += size.y;
+ if (spacing <= 0) {
+ workspace->draw_line(region.position + WORKSPACE_MARGIN + Point2(0, j), region.position + WORKSPACE_MARGIN + Point2(region.size.x, j), c);
+ } else {
+ workspace->draw_rect(Rect2(region.position + WORKSPACE_MARGIN + Point2(0, j), Size2(region.size.x, spacing)), c);
+ }
+ j += spacing;
+ }
+ }
+}
+
+void TileSetEditor::draw_edited_region_subdivision() const {
+ Color c = Color(0.347214, 0.722656, 0.617063, 1);
+ Rect2 region = edited_region;
+ Size2 size;
+ int spacing;
+ bool draw;
+ if (workspace_mode == WORKSPACE_EDIT) {
+ int p_id = get_current_tile();
+ size = tileset->autotile_get_size(p_id);
+ spacing = tileset->autotile_get_spacing(p_id);
+ draw = tileset->tile_get_tile_mode(p_id) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(p_id) == TileSet::ATLAS_TILE;
+ } else {
+ size = snap_step;
+ spacing = snap_separation.x;
+ draw = workspace_mode != WORKSPACE_CREATE_SINGLE;
+ }
+ if (draw) {
+
+ float j = 0;
+ while (j < region.size.x) {
+ j += size.x;
+ if (spacing <= 0) {
+ workspace->draw_line(region.position + Point2(j, 0), region.position + Point2(j, region.size.y), c);
+ } else {
+ workspace->draw_rect(Rect2(region.position + Point2(j, 0), Size2(spacing, region.size.y)), c);
+ }
+ j += spacing;
+ }
+ j = 0;
+ while (j < region.size.y) {
+ j += size.y;
+ if (spacing <= 0) {
+ workspace->draw_line(region.position + Point2(0, j), region.position + Point2(region.size.x, j), c);
+ } else {
+ workspace->draw_rect(Rect2(region.position + Point2(0, j), Size2(region.size.x, spacing)), c);
+ }
+ j += spacing;
+ }
}
}
void TileSetEditor::draw_grid_snap() {
- if (tools[SHAPE_GRID_SNAP]->is_pressed()) {
+ if (tools[TOOL_GRID_SNAP]->is_pressed()) {
Color grid_color = Color(0.39, 0, 1, 0.2f);
Size2 s = workspace->get_size();
@@ -1328,7 +1629,7 @@ void TileSetEditor::draw_polygon_shapes() {
for (int i = 0; i < sd.size(); i++) {
Vector2 coord = Vector2(0, 0);
Vector2 anchor = Vector2(0, 0);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
coord = sd[i].autotile_coord;
anchor = tileset->autotile_get_size(t_id);
anchor.x += tileset->autotile_get_spacing(t_id);
@@ -1336,6 +1637,8 @@ void TileSetEditor::draw_polygon_shapes() {
anchor.x *= coord.x;
anchor.y *= coord.y;
}
+ anchor += WORKSPACE_MARGIN;
+ anchor += tileset->tile_get_region(t_id).position;
Ref<ConvexPolygonShape2D> shape = sd[i].shape;
if (shape.is_valid()) {
Color c_bg;
@@ -1407,6 +1710,8 @@ void TileSetEditor::draw_polygon_shapes() {
anchor.y += tileset->autotile_get_spacing(t_id);
anchor.x *= coord.x;
anchor.y *= coord.y;
+ anchor += WORKSPACE_MARGIN;
+ anchor += tileset->tile_get_region(t_id).position;
Ref<OccluderPolygon2D> shape = E->value();
if (shape.is_valid()) {
Color c_bg;
@@ -1483,6 +1788,8 @@ void TileSetEditor::draw_polygon_shapes() {
anchor.y += tileset->autotile_get_spacing(t_id);
anchor.x *= coord.x;
anchor.y *= coord.y;
+ anchor += WORKSPACE_MARGIN;
+ anchor += tileset->tile_get_region(t_id).position;
Ref<NavigationPolygon> shape = E->value();
if (shape.is_valid()) {
Color c_bg;
@@ -1558,10 +1865,10 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
shape->set_points(segments);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE)
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
tileset->tile_add_shape(get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
else
- tileset->tile_set_shape(get_current_tile(), 0, shape);
+ tileset->tile_add_shape(get_current_tile(), shape, Transform2D());
edited_collision_shape = shape;
}
@@ -1582,7 +1889,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
w = PoolVector<Vector2>::Write();
shape->set_polygon(polygon);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE)
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
tileset->autotile_set_light_occluder(get_current_tile(), shape, edited_shape_coord);
else
tileset->tile_set_light_occluder(get_current_tile(), shape);
@@ -1606,7 +1913,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
shape->set_vertices(polygon);
shape->add_polygon(indices);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE)
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
tileset->autotile_set_navigation_polygon(get_current_tile(), shape, edited_shape_coord);
else
tileset->tile_set_navigation_polygon(get_current_tile(), shape);
@@ -1619,6 +1926,8 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
void TileSetEditor::select_coord(const Vector2 &coord) {
current_shape = PoolVector2Array();
+ Rect2 current_tile_region = tileset->tile_get_region(get_current_tile());
+ current_tile_region.position += WORKSPACE_MARGIN;
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0))
edited_collision_shape = tileset->tile_get_shape(get_current_tile(), 0);
@@ -1631,14 +1940,14 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
current_shape.resize(0);
if (edited_collision_shape.is_valid()) {
for (int i = 0; i < edited_collision_shape->get_points().size(); i++) {
- current_shape.push_back(edited_collision_shape->get_points()[i]);
+ current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position);
}
}
} else if (edit_mode == EDITMODE_OCCLUSION) {
current_shape.resize(0);
if (edited_occlusion_shape.is_valid()) {
for (int i = 0; i < edited_occlusion_shape->get_polygon().size(); i++) {
- current_shape.push_back(edited_occlusion_shape->get_polygon()[i]);
+ current_shape.push_back(edited_occlusion_shape->get_polygon()[i] + current_tile_region.position);
}
}
} else if (edit_mode == EDITMODE_NAVIGATION) {
@@ -1647,7 +1956,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
if (edited_navigation_shape->get_polygon_count() > 0) {
PoolVector<Vector2> vertices = edited_navigation_shape->get_vertices();
for (int i = 0; i < edited_navigation_shape->get_polygon(0).size(); i++) {
- current_shape.push_back(vertices[edited_navigation_shape->get_polygon(0)[i]]);
+ current_shape.push_back(vertices[edited_navigation_shape->get_polygon(0)[i]] + current_tile_region.position);
}
}
}
@@ -1658,6 +1967,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
Vector2 shape_anchor = coord;
shape_anchor.x *= (size.x + spacing);
shape_anchor.y *= (size.y + spacing);
+ shape_anchor += current_tile_region.position;
if (edit_mode == EDITMODE_COLLISION) {
current_shape.resize(0);
if (edited_collision_shape.is_valid()) {
@@ -1684,6 +1994,9 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
}
}
}
+ workspace->update();
+ workspace_container->update();
+ helper->_change_notify("");
}
Vector2 TileSetEditor::snap_point(const Vector2 &point) {
@@ -1694,11 +2007,13 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
Vector2 anchor = coord;
anchor.x *= (tile_size.x + spacing);
anchor.y *= (tile_size.y + spacing);
+ anchor += tileset->tile_get_region(get_current_tile()).position;
+ anchor += WORKSPACE_MARGIN;
Rect2 region(anchor, tile_size);
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE)
- region.position = Point2(0, 0);
+ region.position = tileset->tile_get_region(get_current_tile()).position + WORKSPACE_MARGIN;
- if (tools[SHAPE_GRID_SNAP]->is_pressed()) {
+ if (tools[TOOL_GRID_SNAP]->is_pressed()) {
p.x = Math::snap_scalar_seperation(snap_offset.x, snap_step.x, p.x, snap_separation.x);
p.y = Math::snap_scalar_seperation(snap_offset.y, snap_step.y, p.y, snap_separation.y);
}
@@ -1715,211 +2030,332 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
return p;
}
-void TileSetEditor::update_tile_list() {
- int selected_tile = get_current_tile();
-
- if (selected_tile < 0)
- selected_tile = 0;
+void TileSetEditor::update_texture_list() {
+ Ref<Texture> selected_texture = get_current_texture();
helper->set_tileset(tileset);
- tile_list->clear();
List<int> ids;
tileset->get_tile_list(&ids);
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
- tile_list->add_item(tileset->tile_get_name(E->get()));
- tile_list->set_item_metadata(tile_list->get_item_count() - 1, E->get());
- tile_list->set_item_icon(tile_list->get_item_count() - 1, tileset->tile_get_texture(E->get()));
- Rect2 region = tileset->tile_get_region(E->get());
- if (tileset->tile_get_tile_mode(E->get()) == TileSet::AUTO_TILE) {
- region.size = tileset->autotile_get_size(E->get());
- Vector2 pos = tileset->autotile_get_icon_coordinate(E->get());
- pos.x *= (tileset->autotile_get_spacing(E->get()) + region.size.x);
- pos.y *= (tileset->autotile_get_spacing(E->get()) + region.size.y);
- region.position += pos;
+ if (!texture_map.has(tileset->tile_get_texture(E->get())->get_rid())) {
+ texture_list->add_item(tileset->tile_get_texture(E->get())->get_path().get_file());
+ texture_map.insert(tileset->tile_get_texture(E->get())->get_rid(), tileset->tile_get_texture(E->get()));
+ texture_list->set_item_metadata(texture_list->get_item_count() - 1, tileset->tile_get_texture(E->get())->get_rid());
}
- tile_list->set_item_icon_region(tile_list->get_item_count() - 1, region);
- tile_list->set_item_icon_modulate(tile_list->get_item_count() - 1, tileset->tile_get_modulate(E->get()));
}
- if (tile_list->get_item_count() > 0 && selected_tile < tile_list->get_item_count()) {
- tile_list->select(selected_tile);
- _on_tile_list_selected(selected_tile);
+ if (texture_list->get_item_count() > 0 && selected_texture.is_valid()) {
+ texture_list->select(texture_list->find_metadata(selected_texture->get_rid()));
+ if (texture_list->get_selected_items().size() > 0)
+ _on_texture_list_selected(texture_list->get_selected_items()[0]);
+ } else if (get_current_texture().is_valid()) {
+ _on_texture_list_selected(texture_list->find_metadata(get_current_texture()->get_rid()));
+ } else {
+ _on_texture_list_selected(-1);
}
+ update_texture_list_icon();
helper->_change_notify("");
}
-void TileSetEditor::update_tile_list_icon() {
- List<int> ids;
- tileset->get_tile_list(&ids);
- int current_idx = 0;
- for (List<int>::Element *E = ids.front(); E; E = E->next()) {
- if (current_idx >= tile_list->get_item_count())
- break;
-
- Rect2 region = tileset->tile_get_region(E->get());
- if (tileset->tile_get_tile_mode(E->get()) == TileSet::AUTO_TILE) {
- region.size = tileset->autotile_get_size(E->get());
- Vector2 pos = tileset->autotile_get_icon_coordinate(E->get());
- pos.x *= (tileset->autotile_get_spacing(E->get()) + region.size.x);
- pos.y *= (tileset->autotile_get_spacing(E->get()) + region.size.y);
- region.position += pos;
- }
- tile_list->set_item_metadata(current_idx, E->get());
- tile_list->set_item_icon(current_idx, tileset->tile_get_texture(E->get()));
- tile_list->set_item_icon_region(current_idx, region);
- tile_list->set_item_icon_modulate(current_idx, tileset->tile_get_modulate(E->get()));
- tile_list->set_item_text(current_idx, tileset->tile_get_name(E->get()));
- current_idx += 1;
+void TileSetEditor::update_texture_list_icon() {
+
+ for (int current_idx = 0; current_idx < texture_list->get_item_count(); current_idx++) {
+ RID rid = texture_list->get_item_metadata(current_idx);
+ texture_list->set_item_icon(current_idx, texture_map[rid]);
+ texture_list->set_item_icon_region(current_idx, Rect2(0, 0, 150, 100));
}
- tile_list->update();
+ texture_list->update();
}
void TileSetEditor::update_workspace_tile_mode() {
- if (get_current_tile() < 0)
+
+ if (workspace_mode != WORKSPACE_EDIT) {
+ for (int i = 0; i < EDITMODE_MAX; i++) {
+ tool_editmode[i]->hide();
+ }
+ tool_editmode[EDITMODE_REGION]->show();
+ tool_editmode[EDITMODE_REGION]->set_pressed(true);
+ _on_edit_mode_changed(EDITMODE_REGION);
+ return;
+ }
+
+ if (get_current_tile() < 0) {
+ for (int i = 0; i < EDITMODE_MAX; i++) {
+ tool_editmode[i]->hide();
+ }
+ for (int i = 0; i < ZOOM_OUT; i++) {
+ tools[i]->hide();
+ }
return;
+ }
+
+ for (int i = 0; i < EDITMODE_MAX; i++) {
+ tool_editmode[i]->show();
+ }
+
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
if (tool_editmode[EDITMODE_ICON]->is_pressed() || tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed()) {
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
- _on_edit_mode_changed(EDITMODE_COLLISION);
- } else {
- select_coord(Vector2(0, 0));
+ edit_mode = EDITMODE_COLLISION;
}
+ select_coord(Vector2(0, 0));
tool_editmode[EDITMODE_ICON]->hide();
tool_editmode[EDITMODE_BITMASK]->hide();
tool_editmode[EDITMODE_PRIORITY]->hide();
- property_editor->hide();
+ } else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ if (edit_mode == EDITMODE_ICON)
+ select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
+ else
+ select_coord(edited_shape_coord);
+ } else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ if (tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed()) {
+ tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
+ edit_mode = EDITMODE_COLLISION;
+ }
+ if (edit_mode == EDITMODE_ICON)
+ select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
+ else
+ select_coord(edited_shape_coord);
+
+ tool_editmode[EDITMODE_BITMASK]->hide();
+ tool_editmode[EDITMODE_PRIORITY]->hide();
+ }
+ _on_edit_mode_changed(edit_mode);
+}
+
+void TileSetEditor::update_edited_region(const Vector2 &end_point) {
+ edited_region = Rect2(region_from, Size2());
+ if (tools[TOOL_GRID_SNAP]->is_pressed()) {
+ Vector2 grid_coord;
+ grid_coord.x = Math::floor((region_from.x - snap_offset.x) / (snap_step.x + snap_separation.x));
+ grid_coord.y = Math::floor((region_from.y - snap_offset.y) / (snap_step.y + snap_separation.y));
+ grid_coord.x *= (snap_step.x + snap_separation.x);
+ grid_coord.y *= (snap_step.y + snap_separation.y);
+ grid_coord += snap_offset;
+ edited_region.expand_to(grid_coord);
+ grid_coord += snap_step;
+ edited_region.expand_to(grid_coord);
+ grid_coord.x = Math::floor((end_point.x - snap_offset.x) / (snap_step.x + snap_separation.x));
+ grid_coord.y = Math::floor((end_point.y - snap_offset.y) / (snap_step.y + snap_separation.y));
+ grid_coord.x *= (snap_step.x + snap_separation.x);
+ grid_coord.y *= (snap_step.y + snap_separation.y);
+ grid_coord += snap_offset;
+ edited_region.expand_to(grid_coord);
+ grid_coord += snap_step;
+ if (grid_coord.x < end_point.x)
+ grid_coord.x += snap_separation.x;
+ if (grid_coord.y < end_point.y)
+ grid_coord.y += snap_separation.y;
+ edited_region.expand_to(grid_coord);
} else {
- tool_editmode[EDITMODE_ICON]->show();
- tool_editmode[EDITMODE_BITMASK]->show();
- tool_editmode[EDITMODE_PRIORITY]->show();
- property_editor->show();
+ edited_region.expand_to(end_point);
}
}
-int TileSetEditor::get_current_tile() {
- if (tile_list->get_selected_items().size() == 0)
- return -1;
+int TileSetEditor::get_current_tile() const {
+ return current_tile;
+}
+
+void TileSetEditor::set_current_tile(int p_id) {
+ if (current_tile != p_id) {
+ current_tile = p_id;
+ helper->_change_notify("");
+ select_coord(Vector2(0, 0));
+ update_workspace_tile_mode();
+ }
+}
+
+Ref<Texture> TileSetEditor::get_current_texture() {
+ if (texture_list->get_selected_items().size() == 0)
+ return Ref<Texture>();
else
- return tile_list->get_item_metadata(tile_list->get_selected_items()[0]);
+ return texture_map[texture_list->get_item_metadata(texture_list->get_selected_items()[0])];
}
-void TileSetEditorHelper::set_tileset(const Ref<TileSet> &p_tileset) {
+void TilesetEditorContext::set_tileset(const Ref<TileSet> &p_tileset) {
tileset = p_tileset;
}
-bool TileSetEditorHelper::_set(const StringName &p_name, const Variant &p_value) {
+void TilesetEditorContext::set_snap_options_visible(bool p_visible) {
+ snap_options_visible = p_visible;
+ _change_notify("");
+}
- if (selected_tile < 0 || tileset.is_null())
- return false;
+bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name.operator String();
- bool v = false;
- if (name == "bitmask_mode") {
- tileset->set(String::num(selected_tile, 0) + "/autotile/bitmask_mode", p_value, &v);
- } else if (name.left(7) == "layout/") {
- tileset->set(String::num(selected_tile, 0) + "/autotile" + name.right(6), p_value, &v);
- }
- if (v) {
- tileset->_change_notify("autotile");
+
+ if (name == "options_offset") {
+ Vector2 snap = p_value;
+ tileset_editor->_set_snap_off(snap + WORKSPACE_MARGIN);
+ return true;
+ } else if (name == "options_step") {
+ Vector2 snap = p_value;
+ tileset_editor->_set_snap_step(snap);
+ return true;
+ } else if (name == "options_separation") {
+ Vector2 snap = p_value;
+ tileset_editor->_set_snap_sep(snap);
+ return true;
+ } else if (p_name.operator String().left(5) == "tile_") {
+ String name = p_name.operator String().right(5);
+ bool v = false;
+
+ if (tileset_editor->get_current_tile() < 0 || tileset.is_null())
+ return false;
+
+ if (name == "autotile_bitmask_mode") {
+ tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/bitmask_mode", p_value, &v);
+ } else if (name == "subtile_size") {
+ tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/tile_size", p_value, &v);
+ } else if (name == "subtile_spacing") {
+ tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/spacing", p_value, &v);
+ } else {
+ tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/" + name, p_value, &v);
+ }
+ if (v) {
+ tileset->_change_notify("");
+ tileset_editor->workspace->update();
+ tileset_editor->workspace_overlay->update();
+ }
+ return v;
}
- return v;
-}
-bool TileSetEditorHelper::_get(const StringName &p_name, Variant &r_ret) const {
+ tileset_editor->err_dialog->set_text(TTR("This property can't be changed."));
+ tileset_editor->err_dialog->popup_centered(Size2(300, 60));
+ return false;
+}
- if (selected_tile < 0 || tileset.is_null())
- return false;
- if (!tileset->has_tile(selected_tile))
- return false;
+bool TilesetEditorContext::_get(const StringName &p_name, Variant &r_ret) const {
String name = p_name.operator String();
bool v = false;
- if (name == "bitmask_mode") {
- r_ret = tileset->get(String::num(selected_tile, 0) + "/autotile/bitmask_mode", &v);
- } else if (name.left(7) == "layout/") {
- r_ret = tileset->get(String::num(selected_tile, 0) + "/autotile" + name.right(6), &v);
+
+ if (name == "options_offset") {
+ r_ret = tileset_editor->snap_offset - WORKSPACE_MARGIN;
+ v = true;
+ } else if (name == "options_step") {
+ r_ret = tileset_editor->snap_step;
+ v = true;
+ } else if (name == "options_separation") {
+ r_ret = tileset_editor->snap_separation;
+ v = true;
+ } else if (name.left(5) == "tile_") {
+ name = name.right(5);
+
+ if (tileset_editor->get_current_tile() < 0 || tileset.is_null())
+ return false;
+ if (!tileset->has_tile(tileset_editor->get_current_tile()))
+ return false;
+
+ if (name == "autotile_bitmask_mode") {
+ r_ret = tileset->get(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/bitmask_mode", &v);
+ } else if (name == "subtile_size") {
+ r_ret = tileset->get(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/tile_size", &v);
+ } else if (name == "subtile_spacing") {
+ r_ret = tileset->get(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/spacing", &v);
+ } else {
+ r_ret = tileset->get(String::num(tileset_editor->get_current_tile(), 0) + "/" + name, &v);
+ }
+ return v;
+ } else if (name == "selected_collision") {
+ r_ret = tileset_editor->edited_collision_shape;
+ v = true;
+ } else if (name == "selected_navigation") {
+ r_ret = tileset_editor->edited_navigation_shape;
+ v = true;
+ } else if (name == "selected_occlusion") {
+ r_ret = tileset_editor->edited_occlusion_shape;
+ v = true;
}
return v;
}
-void TileSetEditorHelper::_get_property_list(List<PropertyInfo> *p_list) const {
-
- if (selected_tile < 0 || tileset.is_null())
- return;
+void TilesetEditorContext::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::INT, "bitmask_mode", PROPERTY_HINT_ENUM, "2x2,3x3 (minimal),3x3"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "layout/tile_size"));
- p_list->push_back(PropertyInfo(Variant::INT, "layout/spacing", PROPERTY_HINT_RANGE, "0,256,1"));
+ if (snap_options_visible) {
+ p_list->push_back(PropertyInfo(Variant::NIL, "Snap Options", PROPERTY_HINT_NONE, "options_", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "options_offset"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "options_step"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "options_separation"));
+ }
+ if (tileset_editor->get_current_tile() >= 0 && !tileset.is_null()) {
+ int id = tileset_editor->get_current_tile();
+ p_list->push_back(PropertyInfo(Variant::NIL, "Selected Tile", PROPERTY_HINT_NONE, "tile_", PROPERTY_USAGE_GROUP));
+ p_list->push_back(PropertyInfo(Variant::STRING, "tile_name"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "tile_normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_tex_offset"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "tile_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"));
+ p_list->push_back(PropertyInfo(Variant::COLOR, "tile_modulate"));
+ p_list->push_back(PropertyInfo(Variant::INT, "tile_tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE,ATLAS_TILE"));
+ if (tileset->tile_get_tile_mode(id) == TileSet::AUTO_TILE) {
+ p_list->push_back(PropertyInfo(Variant::INT, "tile_autotile_bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3 (minimal),3X3"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_subtile_size"));
+ p_list->push_back(PropertyInfo(Variant::INT, "tile_subtile_spacing", PROPERTY_HINT_RANGE, "0, 256, 1"));
+ } else if (tileset->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) {
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_subtile_size"));
+ p_list->push_back(PropertyInfo(Variant::INT, "tile_subtile_spacing", PROPERTY_HINT_RANGE, "0, 256, 1"));
+ }
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_occluder_offset"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_navigation_offset"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_shape_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::INT, "tile_z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"));
+ }
+ if (tileset_editor->edit_mode == TileSetEditor::EDITMODE_COLLISION && tileset_editor->edited_collision_shape.is_valid()) {
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "selected_collision", PROPERTY_HINT_RESOURCE_TYPE, tileset_editor->edited_collision_shape->get_class()));
+ }
+ if (tileset_editor->edit_mode == TileSetEditor::EDITMODE_NAVIGATION && tileset_editor->edited_navigation_shape.is_valid()) {
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "selected_navigation", PROPERTY_HINT_RESOURCE_TYPE, tileset_editor->edited_navigation_shape->get_class()));
+ }
+ if (tileset_editor->edit_mode == TileSetEditor::EDITMODE_OCCLUSION && tileset_editor->edited_occlusion_shape.is_valid()) {
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "selected_occlusion", PROPERTY_HINT_RESOURCE_TYPE, tileset_editor->edited_occlusion_shape->get_class()));
+ }
}
-TileSetEditorHelper::TileSetEditorHelper(TileSetEditor *p_tileset_editor) {
-
+TilesetEditorContext::TilesetEditorContext(TileSetEditor *p_tileset_editor) {
tileset_editor = p_tileset_editor;
- selected_tile = -1;
}
void TileSetEditorPlugin::edit(Object *p_node) {
if (Object::cast_to<TileSet>(p_node)) {
tileset_editor->edit(Object::cast_to<TileSet>(p_node));
- tileset_editor->show();
- tileset_editor->texture_region_editor->edit(p_node);
- } else
- tileset_editor->hide();
+ editor->get_inspector()->edit(tileset_editor->helper);
+ }
}
bool TileSetEditorPlugin::handles(Object *p_node) const {
- return p_node->is_class("TileSet");
+ return p_node->is_class("TileSet") ||
+ p_node->is_class("TilesetEditorContext");
}
void TileSetEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
- tileset_editor->show();
- tileset_editor->menu->show();
tileset_editor_button->show();
- tileset_editor->side_panel->show();
if (tileset_editor_button->is_pressed()) {
- tileset_editor->bottom_panel->show();
+ tileset_editor->show();
}
- texture_region_button->show();
- if (texture_region_button->is_pressed())
- tileset_editor->texture_region_editor->show();
+ get_tree()->connect("idle_frame", tileset_editor, "_on_workspace_process");
} else {
tileset_editor->hide();
- tileset_editor->menu->hide();
- tileset_editor->side_panel->hide();
- tileset_editor->bottom_panel->hide();
tileset_editor_button->hide();
- texture_region_button->hide();
- tileset_editor->texture_region_editor->hide();
+ get_tree()->disconnect("idle_frame", tileset_editor, "_on_workspace_process");
}
}
TileSetEditorPlugin::TileSetEditorPlugin(EditorNode *p_node) {
-
+ editor = p_node;
tileset_editor = memnew(TileSetEditor(p_node));
- add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, tileset_editor);
- tileset_editor->set_anchors_and_margins_preset(Control::PRESET_TOP_WIDE);
- tileset_editor->set_end(Point2(0, 22));
- tileset_editor->hide();
-
- tileset_editor->texture_region_editor = memnew(TextureRegionEditor(p_node));
- texture_region_button = p_node->add_bottom_panel_item(TTR("Texture Region"), tileset_editor->texture_region_editor);
- texture_region_button->set_tooltip(TTR("Texture Region Editor"));
-
- tileset_editor->texture_region_editor->set_custom_minimum_size(Size2(0, 200));
- tileset_editor->texture_region_editor->hide();
- texture_region_button->hide();
+ tileset_editor_button =
+ p_node->add_bottom_panel_item(TTR("Tile Set"), tileset_editor);
+ tileset_editor_button->set_tooltip(TTR("Tile Set Editor"));
- add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE, tileset_editor->side_panel);
- tileset_editor->side_panel->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- tileset_editor->side_panel->set_custom_minimum_size(Size2(200, 0));
- tileset_editor->side_panel->hide();
- tileset_editor_button = p_node->add_bottom_panel_item(TTR("Tile Set"), tileset_editor->bottom_panel);
+ tileset_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
+ tileset_editor->hide();
tileset_editor_button->hide();
}
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 4894d641a3..0c175e718c 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -33,21 +33,38 @@
#include "editor/editor_name_dialog.h"
#include "editor/editor_node.h"
-#include "editor/plugins/texture_region_editor_plugin.h"
#include "scene/2d/sprite.h"
#include "scene/resources/convex_polygon_shape_2d.h"
#include "scene/resources/tile_set.h"
-class TileSetEditorHelper;
+#define WORKSPACE_MARGIN Vector2(10, 10)
+class TilesetEditorContext;
-class TileSetEditor : public Control {
+class TileSetEditor : public Panel {
friend class TileSetEditorPlugin;
- friend class TextureRegionEditor;
+ friend class TilesetEditorContext;
- GDCLASS(TileSetEditor, Control);
+ GDCLASS(TileSetEditor, Panel)
+
+ enum TextureToolButtons {
+ TOOL_TILESET_ADD_TEXTURE,
+ TOOL_TILESET_REMOVE_TEXTURE,
+ TOOL_TILESET_CREATE_SCENE,
+ TOOL_TILESET_MERGE_SCENE,
+ TOOL_TILESET_MAX
+ };
+
+ enum WorkspaceMode {
+ WORKSPACE_EDIT,
+ WORKSPACE_CREATE_SINGLE,
+ WORKSPACE_CREATE_AUTOTILE,
+ WORKSPACE_CREATE_ATLAS,
+ WORKSPACE_MODE_MAX
+ };
enum EditMode {
+ EDITMODE_REGION,
EDITMODE_COLLISION,
EDITMODE_OCCLUSION,
EDITMODE_NAVIGATION,
@@ -57,13 +74,6 @@ class TileSetEditor : public Control {
EDITMODE_MAX
};
- enum TileSetToolbar {
- TOOLBAR_DUMMY,
- TOOLBAR_BITMASK,
- TOOLBAR_SHAPE,
- TOOLBAR_MAX
- };
-
enum TileSetTools {
TOOL_SELECT,
BITMASK_COPY,
@@ -71,17 +81,42 @@ class TileSetEditor : public Control {
BITMASK_CLEAR,
SHAPE_NEW_POLYGON,
SHAPE_DELETE,
- SHAPE_CREATE_FROM_BITMASK,
- SHAPE_CREATE_FROM_NOT_BITMASK,
SHAPE_KEEP_INSIDE_TILE,
- SHAPE_GRID_SNAP,
+ TOOL_GRID_SNAP,
ZOOM_OUT,
ZOOM_1,
ZOOM_IN,
+ VISIBLE_INFO,
TOOL_MAX
};
Ref<TileSet> tileset;
+ TilesetEditorContext *helper;
+ EditorNode *editor;
+
+ ConfirmationDialog *cd;
+ AcceptDialog *err_dialog;
+ EditorFileDialog *texture_dialog;
+
+ ItemList *texture_list;
+ int option;
+ ToolButton *tileset_toolbar_buttons[TOOL_TILESET_MAX];
+ MenuButton *tileset_toolbar_tools;
+ Map<RID, Ref<Texture> > texture_map;
+
+ bool creating_shape;
+ int dragging_point;
+ float tile_names_opacity;
+ Vector2 region_from;
+ Rect2 edited_region;
+ bool draw_edited_region;
+ Vector2 edited_shape_coord;
+ PoolVector2Array current_shape;
+ Map<Vector2, uint16_t> bitmask_map_copy;
+
+ Vector2 snap_step;
+ Vector2 snap_offset;
+ Vector2 snap_separation;
Ref<ConvexPolygonShape2D> edited_collision_shape;
Ref<OccluderPolygon2D> edited_occlusion_shape;
@@ -94,55 +129,19 @@ class TileSetEditor : public Control {
bool draw_handles;
Control *workspace_overlay;
Control *workspace;
+ Button *tool_workspacemode[WORKSPACE_MODE_MAX];
Button *tool_editmode[EDITMODE_MAX];
- HBoxContainer *tool_containers[TOOLBAR_MAX];
HBoxContainer *toolbar;
- HBoxContainer *hb_grid;
ToolButton *tools[TOOL_MAX];
SpinBox *spin_priority;
- SpinBox *sb_step_y;
- SpinBox *sb_step_x;
- SpinBox *sb_off_y;
- SpinBox *sb_off_x;
- SpinBox *sb_sep_y;
- SpinBox *sb_sep_x;
+ WorkspaceMode workspace_mode;
EditMode edit_mode;
+ int current_tile;
- Vector2 snap_step;
- Vector2 snap_offset;
- Vector2 snap_separation;
+ void update_texture_list();
+ void update_texture_list_icon();
- bool creating_shape;
- int dragging_point;
- Vector2 edited_shape_coord;
- PoolVector2Array current_shape;
- Map<Vector2, uint16_t> bitmask_map_copy;
-
- EditorNode *editor;
- TextureRegionEditor *texture_region_editor;
- Control *bottom_panel;
- Control *side_panel;
- ItemList *tile_list;
- PropertyEditor *property_editor;
- TileSetEditorHelper *helper;
-
- MenuButton *menu;
- ConfirmationDialog *cd;
- EditorNameDialog *nd;
- AcceptDialog *err_dialog;
-
- enum {
-
- MENU_OPTION_ADD_ITEM,
- MENU_OPTION_REMOVE_ITEM,
- MENU_OPTION_CREATE_FROM_SCENE,
- MENU_OPTION_MERGE_FROM_SCENE
- };
-
- int option;
- void _menu_cbk(int p_option);
- void _menu_confirm();
- void _name_dialog_confirm(const String &name);
+ Ref<Texture> get_current_texture();
static void _import_node(Node *p_node, Ref<TileSet> p_library);
static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge);
@@ -150,7 +149,6 @@ class TileSetEditor : public Control {
protected:
static void _bind_methods();
void _notification(int p_what);
- virtual void _changed_callback(Object *p_changed, const char *p_prop);
public:
void edit(const Ref<TileSet> &p_tileset);
@@ -160,53 +158,61 @@ public:
~TileSetEditor();
private:
- void _on_tile_list_selected(int p_index);
+ void _on_tileset_toolbar_button_pressed(int p_index);
+ void _on_tileset_toolbar_confirm();
+ void _on_texture_list_selected(int p_index);
+ void _on_textures_added(const PoolStringArray &p_paths);
void _on_edit_mode_changed(int p_edit_mode);
+ void _on_workspace_mode_changed(int p_workspace_mode);
void _on_workspace_overlay_draw();
void _on_workspace_draw();
+ void _on_workspace_process();
void _on_workspace_input(const Ref<InputEvent> &p_ie);
void _on_tool_clicked(int p_tool);
void _on_priority_changed(float val);
void _on_grid_snap_toggled(bool p_val);
- void _set_snap_step_x(float p_val);
- void _set_snap_step_y(float p_val);
- void _set_snap_off_x(float p_val);
- void _set_snap_off_y(float p_val);
- void _set_snap_sep_x(float p_val);
- void _set_snap_sep_y(float p_val);
-
- void initialize_bottom_editor();
- void draw_highlight_tile(Vector2 coord, const Vector<Vector2> &other_highlighted = Vector<Vector2>());
+ void _set_snap_step(Vector2 p_val);
+ void _set_snap_off(Vector2 p_val);
+ void _set_snap_sep(Vector2 p_val);
+
+ void draw_highlight_current_tile();
+ void draw_highlight_subtile(Vector2 coord, const Vector<Vector2> &other_highlighted = Vector<Vector2>());
+ void draw_tile_subdivision(int p_id, Color p_color) const;
+ void draw_edited_region_subdivision() const;
void draw_grid_snap();
void draw_polygon_shapes();
void close_shape(const Vector2 &shape_anchor);
void select_coord(const Vector2 &coord);
Vector2 snap_point(const Vector2 &point);
- void update_tile_list();
- void update_tile_list_icon();
void update_workspace_tile_mode();
+ void update_edited_region(const Vector2 &end_point);
- int get_current_tile();
+ int get_current_tile() const;
+ void set_current_tile(int p_id);
};
-class TileSetEditorHelper : public Object {
+class TilesetEditorContext : public Object {
friend class TileSetEditor;
- GDCLASS(TileSetEditorHelper, Object);
+ GDCLASS(TilesetEditorContext, Object);
Ref<TileSet> tileset;
TileSetEditor *tileset_editor;
- int selected_tile;
+ bool snap_options_visible;
public:
void set_tileset(const Ref<TileSet> &p_tileset);
+private:
+ void set_snap_options_visible(bool p_visible);
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
- TileSetEditorHelper(TileSetEditor *p_tileset_editor);
+public:
+ TilesetEditorContext(TileSetEditor *p_tileset_editor);
};
class TileSetEditorPlugin : public EditorPlugin {
@@ -214,11 +220,9 @@ class TileSetEditorPlugin : public EditorPlugin {
GDCLASS(TileSetEditorPlugin, EditorPlugin);
TileSetEditor *tileset_editor;
+ Button *tileset_editor_button;
EditorNode *editor;
- ToolButton *tileset_editor_button;
- ToolButton *texture_region_button;
-
public:
virtual String get_name() const { return "TileSet"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index b9b8b07a2e..63e89b78ea 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -119,6 +119,9 @@ void VisualShaderEditor::_update_graph() {
if (updating)
return;
+ if (visual_shader.is_null())
+ return;
+
graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE);
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
@@ -190,7 +193,7 @@ void VisualShaderEditor::_update_graph() {
}
for (int i = 0; i < plugins.size(); i++) {
- custom_editor = plugins[i]->create_editor(vsnode);
+ custom_editor = plugins.write[i]->create_editor(vsnode);
if (custom_editor) {
break;
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index af7c4bb379..aad9258ed9 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -915,12 +915,6 @@ void ProjectManager::_update_project_buttons() {
CanvasItem *item = Object::cast_to<CanvasItem>(scroll_children->get_child(i));
item->update();
-
- Button *show = Object::cast_to<Button>(item->get_node(NodePath("project/path_box/show")));
- if (show) {
- String current = item->get_meta("name");
- show->set_visible(selected_list.has(current));
- }
}
bool empty_selection = selected_list.empty();
@@ -1316,7 +1310,6 @@ void ProjectManager::_load_recent_projects() {
path_hb->add_child(show);
show->connect("pressed", this, "_show_project", varray(path));
show->set_tooltip(TTR("Show In File Manager"));
- show->set_visible(false);
Label *fpath = memnew(Label(path));
fpath->set_name("path");
@@ -1757,6 +1750,8 @@ ProjectManager::ProjectManager() {
editor_set_scale(custom_display_scale);
} break;
}
+
+ OS::get_singleton()->set_window_size(OS::get_singleton()->get_window_size() * MAX(1, EDSCALE));
}
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
@@ -1781,8 +1776,7 @@ ProjectManager::ProjectManager() {
vb->add_constant_override("separation", 15 * EDSCALE);
String cp;
- cp.push_back(0xA9);
- cp.push_back(0);
+ cp += 0xA9;
OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2018 Juan Linietsky, Ariel Manzur & Godot Contributors");
HBoxContainer *top_hb = memnew(HBoxContainer);
@@ -1825,7 +1819,7 @@ ProjectManager::ProjectManager() {
project_filter = memnew(ProjectListFilter);
search_box->add_child(project_filter);
project_filter->connect("filter_changed", this, "_load_recent_projects");
- project_filter->set_custom_minimum_size(Size2(250, 10));
+ project_filter->set_custom_minimum_size(Size2(280, 10) * EDSCALE);
search_tree_vb->add_child(search_box);
PanelContainer *pc = memnew(PanelContainer);
@@ -2023,18 +2017,6 @@ void ProjectListFilter::_setup_filters() {
filter_option->add_item(TTR("Path"));
}
-void ProjectListFilter::_command(int p_command) {
- switch (p_command) {
-
- case CMD_CLEAR_FILTER: {
- if (search_box->get_text() != "") {
- search_box->clear();
- emit_signal("filter_changed");
- }
- } break;
- }
-}
-
void ProjectListFilter::_search_text_changed(const String &p_newtext) {
emit_signal("filter_changed");
}
@@ -2057,13 +2039,14 @@ void ProjectListFilter::_filter_option_selected(int p_idx) {
void ProjectListFilter::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE)
- clear_search_button->set_icon(get_icon("Close", "EditorIcons"));
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
+ }
}
void ProjectListFilter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_command"), &ProjectListFilter::_command);
ClassDB::bind_method(D_METHOD("_search_text_changed"), &ProjectListFilter::_search_text_changed);
ClassDB::bind_method(D_METHOD("_filter_option_selected"), &ProjectListFilter::_filter_option_selected);
@@ -2088,8 +2071,4 @@ ProjectListFilter::ProjectListFilter() {
search_box->connect("text_changed", this, "_search_text_changed");
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(search_box);
-
- clear_search_button = memnew(ToolButton);
- clear_search_button->connect("pressed", this, "_command", make_binds(CMD_CLEAR_FILTER));
- add_child(clear_search_button);
}
diff --git a/editor/project_manager.h b/editor/project_manager.h
index a9d23b1f71..ad21e00b0d 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -128,13 +128,8 @@ class ProjectListFilter : public HBoxContainer {
private:
friend class ProjectManager;
- enum Command {
- CMD_CLEAR_FILTER,
- };
-
OptionButton *filter_option;
LineEdit *search_box;
- ToolButton *clear_search_button;
enum FilterOption {
FILTER_NAME,
@@ -142,7 +137,6 @@ private:
};
FilterOption _current_filter;
- void _command(int p_command);
void _search_text_changed(const String &p_newtext);
void _setup_filters();
void _filter_option_selected(int p_idx);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index e6ae2d64e7..ea697f5da2 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -81,7 +81,8 @@ void ProjectSettingsEditor::_notification(int p_what) {
globals_editor->edit(ProjectSettings::get_singleton());
search_button->set_icon(get_icon("Search", "EditorIcons"));
- clear_button->set_icon(get_icon("Close", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
action_add_error->add_color_override("font_color", get_color("error_color", "Editor"));
@@ -119,7 +120,8 @@ void ProjectSettingsEditor::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
search_button->set_icon(get_icon("Search", "EditorIcons"));
- clear_button->set_icon(get_icon("Close", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
action_add_error->add_color_override("font_color", get_color("error_color", "Editor"));
popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY), get_icon("Keyboard", "EditorIcons"));
popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_BUTTON), get_icon("JoyButton", "EditorIcons"));
@@ -213,10 +215,8 @@ void ProjectSettingsEditor::_action_edited() {
undo_redo->create_action(TTR("Change Action deadzone"));
undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, new_action);
- undo_redo->add_do_method(this, "_update_actions");
undo_redo->add_do_method(this, "_settings_changed");
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_action);
- undo_redo->add_undo_method(this, "_update_actions");
undo_redo->add_undo_method(this, "_settings_changed");
undo_redo->commit_action();
}
@@ -1462,7 +1462,7 @@ void ProjectSettingsEditor::_update_translations() {
t->set_editable(0, true);
t->set_tooltip(0, l);
t->set_checked(0, l_filter.has(l));
- translation_filter_treeitems[i] = t;
+ translation_filter_treeitems.write[i] = t;
}
} else {
for (int i = 0; i < s; i++) {
@@ -1502,7 +1502,7 @@ void ProjectSettingsEditor::_update_translations() {
if (langnames.length() > 0)
langnames += ",";
langnames += names[i];
- translation_locales_idxs_remap[l_idx] = i;
+ translation_locales_idxs_remap.write[l_idx] = i;
l_idx++;
}
}
@@ -1591,15 +1591,6 @@ void ProjectSettingsEditor::_toggle_search_bar(bool p_pressed) {
}
}
-void ProjectSettingsEditor::_clear_search_box() {
-
- if (search_box->get_text() == "")
- return;
-
- search_box->clear();
- globals_editor->get_inspector()->update_tree();
-}
-
void ProjectSettingsEditor::set_plugins_page() {
tab_container->set_current_tab(plugin_settings->get_index());
@@ -1662,7 +1653,6 @@ void ProjectSettingsEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_translation_filter_option_changed"), &ProjectSettingsEditor::_translation_filter_option_changed);
ClassDB::bind_method(D_METHOD("_translation_filter_mode_changed"), &ProjectSettingsEditor::_translation_filter_mode_changed);
- ClassDB::bind_method(D_METHOD("_clear_search_box"), &ProjectSettingsEditor::_clear_search_box);
ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettingsEditor::_toggle_search_bar);
ClassDB::bind_method(D_METHOD("_copy_to_platform_about_to_show"), &ProjectSettingsEditor::_copy_to_platform_about_to_show);
@@ -1753,10 +1743,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_bar->add_child(search_box);
- clear_button = memnew(ToolButton);
- search_bar->add_child(clear_button);
- clear_button->connect("pressed", this, "_clear_search_box");
-
globals_editor = memnew(SectionedInspector);
props_base->add_child(globals_editor);
globals_editor->get_inspector()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo());
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index 3b74ae1909..b738c4ae20 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -69,7 +69,6 @@ class ProjectSettingsEditor : public AcceptDialog {
HBoxContainer *search_bar;
Button *search_button;
LineEdit *search_box;
- ToolButton *clear_button;
HBoxContainer *add_prop_bar;
AcceptDialog *message;
@@ -158,7 +157,6 @@ class ProjectSettingsEditor : public AcceptDialog {
void _translation_filter_mode_changed(int p_mode);
void _toggle_search_bar(bool p_pressed);
- void _clear_search_box();
void _copy_to_platform_about_to_show();
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 576227344b..b370a711e3 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -90,7 +90,7 @@ bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) co
return false;
}
-Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) {
+Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const {
if (get_script_instance())
return get_script_instance()->call("_convert", p_resource);
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 56743822d2..7d8fa22f3f 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -64,7 +64,7 @@ protected:
public:
virtual String converts_to() const;
virtual bool handles(const Ref<Resource> &p_resource) const;
- virtual Ref<Resource> convert(const Ref<Resource> &p_resource);
+ virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
};
class CustomPropertyEditor : public Popup {
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 26dd931321..d2101f1e00 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -195,7 +195,7 @@ Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<Strin
Vector<float> scores;
scores.resize(list.size());
for (int i = 0; i < list.size(); i++)
- scores[i] = _path_cmp(search_text, list[i].first);
+ scores.write[i] = _path_cmp(search_text, list[i].first);
while (list.size() > 0) {
@@ -258,6 +258,9 @@ void EditorQuickOpen::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
connect("confirmed", this, "_confirmed");
+
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
}
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 8d38bf39b5..d17bcef92b 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -119,7 +119,7 @@ void SceneTreeDock::instance(const String &p_file) {
if (!edited_scene) {
current_option = -1;
- accept->get_ok()->set_text(TTR("OK :("));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered_minsize();
return;
@@ -164,7 +164,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]);
if (!sdata.is_valid()) {
current_option = -1;
- accept->get_ok()->set_text(TTR("Ugh"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error loading scene from %s"), p_files[i]));
accept->popup_centered_minsize();
error = true;
@@ -174,7 +174,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
current_option = -1;
- accept->get_ok()->set_text(TTR("Ugh"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), p_files[i]));
accept->popup_centered_minsize();
error = true;
@@ -233,7 +233,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
if (!sdata.is_valid()) {
- accept->get_ok()->set_text(TTR("Ugh"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error loading scene from %s"), p_file));
accept->popup_centered_minsize();
return;
@@ -241,7 +241,7 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
- accept->get_ok()->set_text(TTR("Ugh"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), p_file));
accept->popup_centered_minsize();
return;
@@ -349,21 +349,33 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
Ref<Script> existing = selected->get_script();
- if (existing.is_valid())
- editor->push_item(existing.ptr());
- else {
- String path = selected->get_filename();
- if (path == "") {
- String root_path = editor_data->get_edited_scene_root()->get_filename();
- if (root_path == "") {
- path = "res://" + selected->get_name();
- } else {
- path = root_path.get_base_dir() + "/" + selected->get_name();
+
+ String path = selected->get_filename();
+ if (path == "") {
+ String root_path = editor_data->get_edited_scene_root()->get_filename();
+ if (root_path == "") {
+ path = "res://" + selected->get_name();
+ } else {
+ path = root_path.get_base_dir() + "/" + selected->get_name();
+ }
+ }
+
+ String inherits = selected->get_class();
+ if (existing.is_valid()) {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptLanguage *l = ScriptServer::get_language(i);
+ if (l->get_type() == existing->get_class()) {
+ if (EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) {
+ String name = l->get_global_class_name(existing->get_path(), NULL);
+ inherits = editor->get_editor_data().script_class_get_base(name);
+ } else if (l->can_inherit_from_file()) {
+ inherits = "\"" + existing->get_path() + "\"";
+ }
}
}
- script_create_dialog->config(selected->get_class(), path);
- script_create_dialog->popup_centered();
}
+ script_create_dialog->config(inherits, path);
+ script_create_dialog->popup_centered();
} break;
case TOOL_CLEAR_SCRIPT: {
@@ -401,7 +413,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (scene_tree->get_selected() == edited_scene) {
current_option = -1;
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
@@ -462,7 +474,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (editor_selection->is_selected(edited_scene)) {
current_option = -1;
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
@@ -532,7 +544,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (editor_selection->is_selected(edited_scene)) {
current_option = -1;
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered_minsize();
break;
@@ -619,7 +631,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *scene = editor_data->get_edited_scene_root();
if (!scene) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done without a scene."));
accept->popup_centered_minsize();
break;
@@ -628,7 +640,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.size() != 1) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
break;
@@ -637,14 +649,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *tocopy = selection.front()->get();
if (tocopy == scene) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can not perform with the root node."));
accept->popup_centered_minsize();
break;
}
if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_filename() != "") {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation can't be done on instanced scenes."));
accept->popup_centered_minsize();
break;
@@ -785,13 +797,38 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_CREATE_2D_SCENE:
case TOOL_CREATE_3D_SCENE:
- case TOOL_CREATE_USER_INTERFACE: {
+ case TOOL_CREATE_USER_INTERFACE:
+ case TOOL_CREATE_FAVORITE: {
Node *new_node;
- switch (p_tool) {
- case TOOL_CREATE_2D_SCENE: new_node = memnew(Node2D); break;
- case TOOL_CREATE_3D_SCENE: new_node = memnew(Spatial); break;
- case TOOL_CREATE_USER_INTERFACE: new_node = memnew(Control); break;
+
+ if (TOOL_CREATE_FAVORITE == p_tool) {
+ String name = selected_favorite_root.get_slicec(' ', 0);
+ if (ScriptServer::is_global_class(name)) {
+ new_node = Object::cast_to<Node>(ClassDB::instance(ScriptServer::get_global_class_base(name)));
+ Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(name), "Script");
+ if (new_node && script.is_valid()) {
+ new_node->set_script(script.get_ref_ptr());
+ new_node->set_name(name);
+ }
+ } else {
+ new_node = Object::cast_to<Node>(ClassDB::instance(selected_favorite_root));
+ }
+ if (!new_node) {
+ ERR_EXPLAIN("Creating root from favorite '" + selected_favorite_root + "' failed. Creating 'Node' instead.");
+ new_node = memnew(Node);
+ }
+ } else {
+ switch (p_tool) {
+ case TOOL_CREATE_2D_SCENE: new_node = memnew(Node2D); break;
+ case TOOL_CREATE_3D_SCENE: new_node = memnew(Spatial); break;
+ case TOOL_CREATE_USER_INTERFACE: {
+ Control *node = memnew(Control);
+ node->set_anchors_and_margins_preset(PRESET_WIDE); //more useful for resizable UIs.
+ new_node = node;
+
+ } break;
+ }
}
editor_data->get_undo_redo().create_action("New Scene Root");
@@ -845,39 +882,67 @@ void SceneTreeDock::_notification(int p_what) {
button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
button_clear_script->set_icon(get_icon("ScriptRemove", "EditorIcons"));
- filter->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ filter->set_right_icon(get_icon("Search", "EditorIcons"));
+ filter->set_clear_button_enabled(true);
EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed");
- create_root_dialog->add_child(memnew(Label(TTR("Create Root Node:"))));
+ // create_root_dialog
+ HBoxContainer *top_row = memnew(HBoxContainer);
+ top_row->set_name("NodeShortcutsTopRow");
+ top_row->set_h_size_flags(SIZE_EXPAND_FILL);
+ top_row->add_child(memnew(Label(TTR("Create Root Node:"))));
+ top_row->add_spacer();
- Button *button_2d = memnew(Button);
- create_root_dialog->add_child(button_2d);
+ ToolButton *node_shortcuts_toggle = memnew(ToolButton);
+ node_shortcuts_toggle->set_name("NodeShortcutsToggle");
+ node_shortcuts_toggle->set_icon(get_icon("Favorites", "EditorIcons"));
+ node_shortcuts_toggle->set_toggle_mode(true);
+ node_shortcuts_toggle->set_pressed(EDITOR_GET("_use_favorites_root_selection"));
+ node_shortcuts_toggle->set_anchors_and_margins_preset(Control::PRESET_CENTER_RIGHT);
+ node_shortcuts_toggle->connect("pressed", this, "_update_create_root_dialog");
+ top_row->add_child(node_shortcuts_toggle);
+
+ create_root_dialog->add_child(top_row);
+
+ VBoxContainer *node_shortcuts = memnew(VBoxContainer);
+ node_shortcuts->set_name("NodeShortcuts");
+
+ VBoxContainer *beginner_node_shortcuts = memnew(VBoxContainer);
+ beginner_node_shortcuts->set_name("BeginnerNodeShortcuts");
+ node_shortcuts->add_child(beginner_node_shortcuts);
+ Button *button_2d = memnew(Button);
+ beginner_node_shortcuts->add_child(button_2d);
button_2d->set_text(TTR("2D Scene"));
button_2d->set_icon(get_icon("Node2D", "EditorIcons"));
button_2d->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_2D_SCENE, false));
Button *button_3d = memnew(Button);
- create_root_dialog->add_child(button_3d);
+ beginner_node_shortcuts->add_child(button_3d);
button_3d->set_text(TTR("3D Scene"));
button_3d->set_icon(get_icon("Spatial", "EditorIcons"));
button_3d->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_3D_SCENE, false));
Button *button_ui = memnew(Button);
- create_root_dialog->add_child(button_ui);
+ beginner_node_shortcuts->add_child(button_ui);
button_ui->set_text(TTR("User Interface"));
button_ui->set_icon(get_icon("Control", "EditorIcons"));
button_ui->connect("pressed", this, "_tool_selected", make_binds(TOOL_CREATE_USER_INTERFACE, false));
+ VBoxContainer *favorite_node_shortcuts = memnew(VBoxContainer);
+ favorite_node_shortcuts->set_name("FavoriteNodeShortcuts");
+ node_shortcuts->add_child(favorite_node_shortcuts);
+
Button *button_custom = memnew(Button);
- create_root_dialog->add_child(button_custom);
+ node_shortcuts->add_child(button_custom);
button_custom->set_text(TTR("Custom Node"));
button_custom->set_icon(get_icon("Add", "EditorIcons"));
button_custom->connect("pressed", this, "_tool_selected", make_binds(TOOL_NEW, false));
- create_root_dialog->add_spacer();
-
+ node_shortcuts->add_spacer();
+ create_root_dialog->add_child(node_shortcuts);
+ _update_create_root_dialog();
} break;
case NOTIFICATION_ENTER_TREE: {
@@ -893,7 +958,8 @@ void SceneTreeDock::_notification(int p_what) {
button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
button_clear_script->set_icon(get_icon("ScriptRemove", "EditorIcons"));
- filter->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
+ filter->set_right_icon(get_icon("Search", "EditorIcons"));
+ filter->set_clear_button_enabled(true);
} break;
case NOTIFICATION_PROCESS: {
@@ -1232,7 +1298,7 @@ bool SceneTreeDock::_validate_no_foreign() {
if (E->get() != edited_scene && E->get()->get_owner() != edited_scene) {
- accept->get_ok()->set_text(TTR("Makes Sense!"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can't operate on nodes from a foreign scene!"));
accept->popup_centered_minsize();
return false;
@@ -1240,7 +1306,7 @@ bool SceneTreeDock::_validate_no_foreign() {
if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) {
- accept->get_ok()->set_text(TTR("Makes Sense!"));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
accept->popup_centered_minsize();
return false;
@@ -1426,13 +1492,9 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
}
- editor_data->get_undo_redo().add_do_method(editor, "push_item", p_script.operator->());
- editor_data->get_undo_redo().add_undo_method(editor, "push_item", (Script *)NULL);
-
- editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
- editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
-
editor_data->get_undo_redo().commit_action();
+
+ editor->push_item(p_script.operator->());
}
void SceneTreeDock::_delete_confirm() {
@@ -1521,16 +1583,9 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_update_script_button() {
if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) {
- if (EditorNode::get_singleton()->get_editor_selection()->get_selection().front()->key()->get_script().is_null()) {
- button_create_script->show();
- button_clear_script->hide();
- } else {
- button_create_script->hide();
- button_clear_script->show();
- }
+ button_create_script->show();
} else {
button_create_script->hide();
- button_clear_script->hide();
}
}
@@ -1731,7 +1786,7 @@ void SceneTreeDock::_new_scene_from(String p_file) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.size() != 1) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
return;
@@ -1749,7 +1804,7 @@ void SceneTreeDock::_new_scene_from(String p_file) {
memdelete(copy);
if (err != OK) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied."));
accept->popup_centered_minsize();
return;
@@ -1761,14 +1816,14 @@ void SceneTreeDock::_new_scene_from(String p_file) {
err = ResourceSaver::save(p_file, sdata, flg);
if (err != OK) {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Error saving scene."));
accept->popup_centered_minsize();
return;
}
_replace_with_branch_scene(p_file, base);
} else {
- accept->get_ok()->set_text(TTR("I see..."));
+ accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("Error duplicating scene to save it."));
accept->popup_centered_minsize();
return;
@@ -1984,6 +2039,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (selection.size() == 1) {
+ Node *selected = selection[0];
+
subresources.clear();
menu_subresources->clear();
menu_subresources->set_size(Size2(1, 1));
@@ -1994,18 +2051,23 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
menu->add_separator();
+
menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
- menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ Ref<Script> existing = selected->get_script();
+ if (existing.is_valid()) {
+ menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ }
menu->add_separator();
menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
- menu->add_separator();
- menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
- menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
- menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
- menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
-
+ if (scene_tree->get_selected() != edited_scene) {
+ menu->add_separator();
+ menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
+ menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
+ menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
+ menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
+ }
if (selection.size() == 1) {
menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
@@ -2135,6 +2197,67 @@ void SceneTreeDock::_local_tree_selected() {
edit_local->set_pressed(true);
}
+void SceneTreeDock::_update_create_root_dialog() {
+
+ BaseButton *toggle = Object::cast_to<BaseButton>(create_root_dialog->get_node(String("NodeShortcutsTopRow/NodeShortcutsToggle")));
+ Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcuts"));
+
+ if (!toggle || !node_shortcuts)
+ return;
+
+ Control *beginner_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("BeginnerNodeShortcuts")));
+ Control *favorite_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("FavoriteNodeShortcuts")));
+
+ if (!beginner_nodes || !favorite_nodes)
+ return;
+
+ EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", toggle->is_pressed());
+ EditorSettings::get_singleton()->save();
+ if (toggle->is_pressed()) {
+
+ for (int i = 0; i < favorite_nodes->get_child_count(); i++) {
+ favorite_nodes->get_child(i)->queue_delete();
+ }
+
+ FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites.Node"), FileAccess::READ);
+
+ if (f) {
+
+ while (!f->eof_reached()) {
+ String l = f->get_line().strip_edges();
+
+ if (l != String()) {
+ Button *button = memnew(Button);
+ favorite_nodes->add_child(button);
+ button->set_text(TTR(l));
+ String name = l.get_slicec(' ', 0);
+ if (ScriptServer::is_global_class(name))
+ name = ScriptServer::get_global_class_base(name);
+ button->set_icon(get_icon(name, "EditorIcons"));
+ button->connect("pressed", this, "_favorite_root_selected", make_binds(l));
+ }
+ }
+
+ memdelete(f);
+ }
+
+ if (!favorite_nodes->is_visible_in_tree()) {
+ favorite_nodes->show();
+ beginner_nodes->hide();
+ }
+ } else {
+ if (!beginner_nodes->is_visible_in_tree()) {
+ beginner_nodes->show();
+ favorite_nodes->hide();
+ }
+ }
+}
+
+void SceneTreeDock::_favorite_root_selected(const String &p_class) {
+ selected_favorite_root = p_class;
+ _tool_selected(TOOL_CREATE_FAVORITE, false);
+}
+
void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_tool_selected"), &SceneTreeDock::_tool_selected, DEFVAL(false));
@@ -2163,6 +2286,8 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_remote_tree_selected"), &SceneTreeDock::_remote_tree_selected);
ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected);
ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button);
+ ClassDB::bind_method(D_METHOD("_favorite_root_selected"), &SceneTreeDock::_favorite_root_selected);
+ ClassDB::bind_method(D_METHOD("_update_create_root_dialog"), &SceneTreeDock::_update_create_root_dialog);
ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance);
@@ -2288,6 +2413,8 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
create_dialog->set_base_type("Node");
add_child(create_dialog);
create_dialog->connect("create", this, "_create");
+ create_dialog->connect("favorites_updated", this, "_update_create_root_dialog");
+ EditorFileSystem::get_singleton()->connect("script_classes_updated", create_dialog, "_save_and_update_favorite_list");
rename_dialog = memnew(RenameDialog(scene_tree, &editor_data->get_undo_redo()));
add_child(rename_dialog);
@@ -2324,6 +2451,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
menu = memnew(PopupMenu);
add_child(menu);
menu->connect("id_pressed", this, "_tool_selected");
+ menu->set_hide_on_window_lose_focus(true);
menu_subresources = memnew(PopupMenu);
menu_subresources->set_name("Sub-Resources");
menu_subresources->connect("id_pressed", this, "_tool_selected");
@@ -2333,11 +2461,12 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
clear_inherit_confirm = memnew(ConfirmationDialog);
clear_inherit_confirm->set_text(TTR("Clear Inheritance? (No Undo!)"));
- clear_inherit_confirm->get_ok()->set_text(TTR("Clear!"));
+ clear_inherit_confirm->get_ok()->set_text(TTR("Clear"));
add_child(clear_inherit_confirm);
set_process_input(true);
set_process(true);
EDITOR_DEF("interface/editors/show_scene_tree_root_selection", true);
+ EDITOR_DEF("_use_favorites_root_selection", false);
}
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 57f4759747..34a7c98d11 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -86,6 +86,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_CREATE_2D_SCENE,
TOOL_CREATE_3D_SCENE,
TOOL_CREATE_USER_INTERFACE,
+ TOOL_CREATE_FAVORITE,
};
@@ -141,6 +142,7 @@ class SceneTreeDock : public VBoxContainer {
EditorNode *editor;
VBoxContainer *create_root_dialog;
+ String selected_favorite_root;
void _add_children_to_popup(Object *p_obj, int p_depth);
@@ -201,6 +203,9 @@ class SceneTreeDock : public VBoxContainer {
void _remote_tree_selected();
void _local_tree_selected();
+ void _update_create_root_dialog();
+ void _favorite_root_selected(const String &p_class);
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 9ce0e973f7..bd661ade53 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -658,7 +658,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
Vector<float> p;
p.resize(arr.size());
for (int i = 0; i < arr.size(); i++) {
- p[i] = arr[i];
+ p.write[i] = arr[i];
if (i < perf_items.size()) {
float v = p[i];
@@ -693,7 +693,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
perf_items[i]->set_text(1, vs);
perf_items[i]->set_tooltip(1, tt);
if (p[i] > perf_max[i])
- perf_max[i] = p[i];
+ perf_max.write[i] = p[i];
}
}
perf_history.push_front(p);
@@ -807,7 +807,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
item.signature = "categ::" + name + "::" + item.name;
item.name = item.name.capitalize();
c.total_time += item.total;
- c.items[i / 2] = item;
+ c.items.write[i / 2] = item;
}
metric.categories.push_back(c);
}
@@ -844,7 +844,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
item.calls = calls;
item.self = self;
item.total = total;
- funcs.items[i] = item;
+ funcs.items.write[i] = item;
}
metric.categories.push_back(funcs);
@@ -1193,12 +1193,12 @@ void ScriptEditorDebugger::start() {
perf_history.clear();
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
- perf_max[i] = 0;
+ perf_max.write[i] = 0;
}
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
if (server->listen(remote_port) != OK) {
- EditorNode::get_log()->add_message(String("Error listening on port ") + itos(remote_port), true);
+ EditorNode::get_log()->add_message(String("Error listening on port ") + itos(remote_port), EditorLog::MSG_TYPE_ERROR);
return;
}
@@ -2076,7 +2076,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
it->set_selectable(1, false);
it->set_text(0, name.capitalize());
perf_items.push_back(it);
- perf_max[i] = 0;
+ perf_max.write[i] = 0;
}
}
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index fe379703e5..4ebba73cb3 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -114,22 +114,6 @@ void EditorSettingsDialog::popup_edit_settings() {
_focus_current_search_box();
}
-void EditorSettingsDialog::_clear_search_box() {
-
- if (search_box->get_text() == "")
- return;
-
- search_box->clear();
- inspector->get_inspector()->update_tree();
-}
-
-void EditorSettingsDialog::_clear_shortcut_search_box() {
- if (shortcut_search_box->get_text() == "")
- return;
-
- shortcut_search_box->clear();
-}
-
void EditorSettingsDialog::_filter_shortcuts(const String &p_filter) {
shortcut_filter = p_filter;
_update_shortcuts();
@@ -198,10 +182,10 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
void EditorSettingsDialog::_update_icons() {
- search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
- shortcut_search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
- clear_button->set_icon(get_icon("Close", "EditorIcons"));
- shortcut_clear_button->set_icon(get_icon("Close", "EditorIcons"));
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
+ shortcut_search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ shortcut_search_box->set_clear_button_enabled(true);
restart_close_button->set_icon(get_icon("Close", "EditorIcons"));
restart_container->add_style_override("panel", get_stylebox("bg", "Tree"));
@@ -411,8 +395,6 @@ void EditorSettingsDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_settings_save"), &EditorSettingsDialog::_settings_save);
ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed);
ClassDB::bind_method(D_METHOD("_settings_property_edited"), &EditorSettingsDialog::_settings_property_edited);
- ClassDB::bind_method(D_METHOD("_clear_search_box"), &EditorSettingsDialog::_clear_search_box);
- ClassDB::bind_method(D_METHOD("_clear_shortcut_search_box"), &EditorSettingsDialog::_clear_shortcut_search_box);
ClassDB::bind_method(D_METHOD("_shortcut_button_pressed"), &EditorSettingsDialog::_shortcut_button_pressed);
ClassDB::bind_method(D_METHOD("_filter_shortcuts"), &EditorSettingsDialog::_filter_shortcuts);
ClassDB::bind_method(D_METHOD("_update_shortcuts"), &EditorSettingsDialog::_update_shortcuts);
@@ -451,10 +433,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hbc->add_child(search_box);
- clear_button = memnew(ToolButton);
- hbc->add_child(clear_button);
- clear_button->connect("pressed", this, "_clear_search_box");
-
inspector = memnew(SectionedInspector);
//inspector->hide_top_label();
inspector->get_inspector()->set_use_filter(true);
@@ -500,10 +478,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
hbc->add_child(shortcut_search_box);
shortcut_search_box->connect("text_changed", this, "_filter_shortcuts");
- shortcut_clear_button = memnew(ToolButton);
- hbc->add_child(shortcut_clear_button);
- shortcut_clear_button->connect("pressed", this, "_clear_shortcut_search_box");
-
shortcuts = memnew(Tree);
tab_shortcuts->add_child(shortcuts, true);
shortcuts->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h
index 6cf2eb6bdf..37d32e401d 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/settings_config_dialog.h
@@ -52,8 +52,6 @@ class EditorSettingsDialog : public AcceptDialog {
LineEdit *search_box;
LineEdit *shortcut_search_box;
- ToolButton *clear_button;
- ToolButton *shortcut_clear_button;
SectionedInspector *inspector;
Timer *timer;
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 35544f711b..64fdc778d0 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -47,7 +47,10 @@
// Keep small children away from this file.
// It's so ugly it will eat them alive
-#define HANDLE_HALF_SIZE 0.05
+// The previous comment is kept only for historical reasons.
+// No children will be harmed by the viewing of this file... hopefully.
+
+#define HANDLE_HALF_SIZE 9.5
bool EditorSpatialGizmo::can_draw() const {
return is_editable();
@@ -85,11 +88,37 @@ void EditorSpatialGizmo::clear() {
void EditorSpatialGizmo::redraw() {
- if (get_script_instance() && get_script_instance()->has_method("redraw"))
- get_script_instance()->call("redraw");
+ ERR_FAIL_COND(!gizmo_plugin);
+ gizmo_plugin->redraw(this);
+}
+
+String EditorSpatialGizmo::get_handle_name(int p_idx) const {
+ ERR_FAIL_COND_V(!gizmo_plugin, "");
+ return gizmo_plugin->get_handle_name(this, p_idx);
+}
+
+Variant EditorSpatialGizmo::get_handle_value(int p_idx) {
+ ERR_FAIL_COND_V(!gizmo_plugin, Variant());
+ return gizmo_plugin->get_handle_value(this, p_idx);
+}
+
+void EditorSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
+ ERR_FAIL_COND(!gizmo_plugin);
+ return gizmo_plugin->set_handle(this, p_idx, p_camera, p_point);
+}
+
+void EditorSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+ ERR_FAIL_COND(!gizmo_plugin);
+ return gizmo_plugin->commit_handle(this, p_idx, p_restore, p_cancel);
+}
+
+void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) {
+
+ ERR_FAIL_NULL(p_node);
+ spatial_node = p_node;
}
-void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
+void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base, bool p_hidden) {
instance = VS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world()->get_scenario());
VS::get_singleton()->instance_attach_object_instance_id(instance, p_base->get_instance_id());
@@ -98,7 +127,8 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
if (extra_margin)
VS::get_singleton()->instance_set_extra_visibility_margin(instance, 1);
VS::get_singleton()->instance_geometry_set_cast_shadows_setting(instance, VS::SHADOW_CASTING_SETTING_OFF);
- VS::get_singleton()->instance_set_layer_mask(instance, 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26
+ int layer = p_hidden ? 0 : 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER;
+ VS::get_singleton()->instance_set_layer_mask(instance, layer); //gizmos are 26
}
void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const RID &p_skeleton) {
@@ -110,7 +140,7 @@ void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard
ins.mesh = p_mesh;
ins.skeleton = p_skeleton;
if (valid) {
- ins.create_instance(spatial_node);
+ ins.create_instance(spatial_node, hidden);
VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
}
@@ -159,7 +189,7 @@ void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mat
ins.billboard = p_billboard;
ins.mesh = mesh;
if (valid) {
- ins.create_instance(spatial_node);
+ ins.create_instance(spatial_node, hidden);
VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
}
@@ -210,7 +240,7 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
ins.unscaled = true;
ins.billboard = true;
if (valid) {
- ins.create_instance(spatial_node);
+ ins.create_instance(spatial_node, hidden);
VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
}
@@ -229,11 +259,11 @@ void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines)
collision_segments.resize(from + p_lines.size());
for (int i = 0; i < p_lines.size(); i++) {
- collision_segments[from + i] = p_lines[i];
+ collision_segments.write[from + i] = p_lines[i];
}
}
-void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_billboard, bool p_secondary) {
+void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard, bool p_secondary) {
billboard_handle = p_billboard;
@@ -257,7 +287,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
for (int i = 0; i < p_handles.size(); i++) {
Color col(1, 1, 1, 1);
- if (is_gizmo_handle_highlighted(i))
+ if (gizmo_plugin->is_gizmo_handle_highlighted(this, i))
col = Color(0, 0, 1, 0.9);
if (SpatialEditor::get_singleton()->get_over_gizmo_handle() != i)
@@ -268,10 +298,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
}
a[VS::ARRAY_COLOR] = colors;
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, a);
- if (p_billboard)
- mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material_billboard);
- else
- mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material);
+ mesh->surface_set_material(0, p_material);
if (p_billboard) {
float md = 0;
@@ -288,7 +315,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
ins.billboard = p_billboard;
ins.extra_margin = true;
if (valid) {
- ins.create_instance(spatial_node);
+ ins.create_instance(spatial_node, hidden);
VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
}
instances.push_back(ins);
@@ -296,14 +323,14 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
int chs = handles.size();
handles.resize(chs + p_handles.size());
for (int i = 0; i < p_handles.size(); i++) {
- handles[i + chs] = p_handles[i];
+ handles.write[i + chs] = p_handles[i];
}
} else {
int chs = secondary_handles.size();
secondary_handles.resize(chs + p_handles.size());
for (int i = 0; i < p_handles.size(); i++) {
- secondary_handles[i + chs] = p_handles[i];
+ secondary_handles.write[i + chs] = p_handles[i];
}
}
}
@@ -330,17 +357,13 @@ void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size
add_mesh(m);
}
-void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) {
-
- ERR_FAIL_NULL(p_node);
- spatial_node = p_node;
-}
-
bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum) {
ERR_FAIL_COND_V(!spatial_node, false);
ERR_FAIL_COND_V(!valid, false);
+ if (hidden && !gizmo_plugin->is_selectable_when_hidden()) return false;
+
if (selectable_icon_size > 0.0f) {
Vector3 origin = spatial_node->get_global_transform().get_origin();
@@ -413,7 +436,9 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point,
ERR_FAIL_COND_V(!spatial_node, false);
ERR_FAIL_COND_V(!valid, false);
- if (r_gizmo_handle) {
+ if (hidden && !gizmo_plugin->is_selectable_when_hidden()) return false;
+
+ if (r_gizmo_handle && !hidden) {
Transform t = spatial_node->get_global_transform();
t.orthonormalize();
@@ -428,7 +453,8 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point,
Vector3 hpos = t.xform(secondary_handles[i]);
Vector2 p = p_camera->unproject_position(hpos);
- if (p.distance_to(p_point) < SpatialEditorGizmos::singleton->handle_t->get_width() * 0.6) {
+
+ if (p.distance_to(p_point) < HANDLE_HALF_SIZE) {
real_t dp = p_camera->get_transform().origin.distance_to(hpos);
if (dp < min_d) {
@@ -453,7 +479,8 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point,
Vector3 hpos = t.xform(handles[i]);
Vector2 p = p_camera->unproject_position(hpos);
- if (p.distance_to(p_point) < SpatialEditorGizmos::singleton->handle_t->get_width() * 0.6) {
+
+ if (p.distance_to(p_point) < HANDLE_HALF_SIZE) {
real_t dp = p_camera->get_transform().origin.distance_to(hpos);
if (dp < min_d) {
@@ -504,6 +531,8 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point,
rect.set_position(center - rect.get_size() / 2.0);
if (rect.has_point(p_point)) {
+ r_pos = t.origin;
+ r_normal = -p_camera->project_ray_normal(p_point);
return true;
}
@@ -597,7 +626,7 @@ void EditorSpatialGizmo::create() {
for (int i = 0; i < instances.size(); i++) {
- instances[i].create_instance(spatial_node);
+ instances.write[i].create_instance(spatial_node, hidden);
}
transform();
@@ -621,99 +650,24 @@ void EditorSpatialGizmo::free() {
if (instances[i].instance.is_valid())
VS::get_singleton()->free(instances[i].instance);
- instances[i].instance = RID();
+ instances.write[i].instance = RID();
}
+ clear();
+
valid = false;
}
-Ref<SpatialMaterial> EditorSpatialGizmo::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) {
-
- String name = p_name;
-
- if (!is_editable()) {
- name += "@readonly";
- } else if (is_selected()) {
- name += "@selected";
- }
-
- if (SpatialEditorGizmos::singleton->material_cache.has(name)) {
- return SpatialEditorGizmos::singleton->material_cache[name];
- }
-
- Color color = p_color;
-
- if (!is_editable()) {
- color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced");
- }
- if (!is_selected()) {
- color.a *= 0.3;
- }
-
- Ref<SpatialMaterial> line_material;
- line_material.instance();
- line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- if (p_use_vertex_color) {
- line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- }
-
- if (p_billboard) {
- line_material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
+void EditorSpatialGizmo::set_hidden(bool p_hidden) {
+ hidden = p_hidden;
+ int layer = hidden ? 0 : 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER;
+ for (int i = 0; i < instances.size(); ++i) {
+ VS::get_singleton()->instance_set_layer_mask(instances[i].instance, layer);
}
-
- if (p_on_top && is_selected()) {
- line_material->set_on_top_of_alpha();
- }
-
- line_material->set_albedo(color);
-
- SpatialEditorGizmos::singleton->material_cache[name] = line_material;
-
- return line_material;
}
-Ref<SpatialMaterial> EditorSpatialGizmo::create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top, const Color &p_albedo) {
-
- String name = p_name;
-
- if (!is_editable()) {
- name += "@readonly";
- } else if (is_selected()) {
- name += "@selected";
- }
-
- if (SpatialEditorGizmos::singleton->material_cache.has(name)) {
- return SpatialEditorGizmos::singleton->material_cache[name];
- }
-
- Color color = p_albedo;
-
- if (!is_editable()) {
- color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced");
- } else if (!is_selected()) {
- color.a *= 0.3;
- }
-
- Ref<SpatialMaterial> icon;
- icon.instance();
- icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
- icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- icon->set_albedo(color);
- icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, p_texture);
- icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true);
- icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
-
- if (p_on_top && is_selected()) {
- icon->set_on_top_of_alpha();
- }
-
- SpatialEditorGizmos::singleton->material_cache[name] = icon;
-
- return icon;
+void EditorSpatialGizmo::set_plugin(EditorSpatialGizmoPlugin *p_plugin) {
+ gizmo_plugin = p_plugin;
}
void EditorSpatialGizmo::_bind_methods() {
@@ -726,6 +680,7 @@ void EditorSpatialGizmo::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_handles", "handles", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node);
ClassDB::bind_method(D_METHOD("clear"), &EditorSpatialGizmo::clear);
+ ClassDB::bind_method(D_METHOD("set_hidden", "hidden"), &EditorSpatialGizmo::set_hidden);
BIND_VMETHOD(MethodInfo("redraw"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "get_handle_name", PropertyInfo(Variant::INT, "index")));
@@ -743,12 +698,17 @@ void EditorSpatialGizmo::_bind_methods() {
EditorSpatialGizmo::EditorSpatialGizmo() {
valid = false;
billboard_handle = false;
+ hidden = false;
base = NULL;
+ selected = false;
+ instanced = false;
spatial_node = NULL;
+ gizmo_plugin = NULL;
}
EditorSpatialGizmo::~EditorSpatialGizmo() {
+ if (gizmo_plugin != NULL) gizmo_plugin->unregister_gizmo(this);
clear();
}
@@ -761,7 +721,30 @@ Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const {
//// light gizmo
-String LightSpatialGizmo::get_handle_name(int p_idx) const {
+LightSpatialGizmoPlugin::LightSpatialGizmoPlugin() {
+
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2));
+
+ create_material("lines", gizmo_color);
+ create_material("lines_billboard", gizmo_color, true);
+
+ create_icon_material("light_directional_icon", SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
+ create_icon_material("light_omni_icon", SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
+ create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpotLight", "EditorIcons"));
+
+ create_handle_material("handles");
+ create_handle_material("handles_billboard", true);
+}
+
+bool LightSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Light>(p_spatial) != NULL;
+}
+
+String LightSpatialGizmoPlugin::get_name() const {
+ return "Lights";
+}
+
+String LightSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
if (p_idx == 0)
return "Radius";
@@ -769,8 +752,9 @@ String LightSpatialGizmo::get_handle_name(int p_idx) const {
return "Aperture";
}
-Variant LightSpatialGizmo::get_handle_value(int p_idx) const {
+Variant LightSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ Light *light = Object::cast_to<Light>(p_gizmo->get_spatial_node());
if (p_idx == 0)
return light->get_param(Light::PARAM_RANGE);
if (p_idx == 1)
@@ -808,8 +792,9 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec
return a * 180.0 / Math_PI;
}
-void LightSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
+void LightSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+ Light *light = Object::cast_to<Light>(p_gizmo->get_spatial_node());
Transform gt = light->get_global_transform();
gt.orthonormalize();
Transform gi = gt.affine_inverse();
@@ -848,8 +833,9 @@ void LightSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_
}
}
-void LightSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+void LightSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+ Light *light = Object::cast_to<Light>(p_gizmo->get_spatial_node());
if (p_cancel) {
light->set_param(p_idx == 0 ? Light::PARAM_RANGE : Light::PARAM_SPOT_ANGLE, p_restore);
@@ -871,14 +857,16 @@ void LightSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool
}
}
-void LightSpatialGizmo::redraw() {
+void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ Light *light = Object::cast_to<Light>(p_gizmo->get_spatial_node());
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/light");
+ p_gizmo->clear();
if (Object::cast_to<DirectionalLight>(light)) {
- Ref<Material> material = create_material("light_directional_material", gizmo_color);
- Ref<Material> icon = create_icon_material("light_directional_icon", SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
+ Ref<Material> material = get_material("lines", p_gizmo);
+ Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
const int arrow_points = 7;
const float arrow_length = 1.5;
@@ -909,16 +897,15 @@ void LightSpatialGizmo::redraw() {
}
}
- add_lines(lines, material);
- add_collision_segments(lines);
- add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
}
if (Object::cast_to<OmniLight>(light)) {
- Ref<Material> material = create_material("light_omni_material", gizmo_color, true);
- Ref<Material> icon = create_icon_material("light_omni_icon", SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
- clear();
+ Ref<Material> material = get_material("lines_billboard", p_gizmo);
+ Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
OmniLight *on = Object::cast_to<OmniLight>(light);
@@ -941,29 +928,27 @@ void LightSpatialGizmo::redraw() {
points.push_back(Vector3(b.x, b.y, 0));
}
- add_lines(points, material, true);
- add_collision_segments(points);
+ p_gizmo->add_lines(points, material, true);
+ p_gizmo->add_collision_segments(points);
- add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
Vector<Vector3> handles;
handles.push_back(Vector3(r, 0, 0));
- add_handles(handles, true);
+ p_gizmo->add_handles(handles, get_material("handles_billboard"), true);
}
if (Object::cast_to<SpotLight>(light)) {
- Ref<Material> material = create_material("light_spot_material", gizmo_color);
- Ref<Material> icon = create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpotLight", "EditorIcons"));
-
- clear();
+ Ref<Material> material = get_material("lines", p_gizmo);
+ Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
Vector<Vector3> points;
- SpotLight *on = Object::cast_to<SpotLight>(light);
+ SpotLight *sl = Object::cast_to<SpotLight>(light);
- float r = on->get_param(Light::PARAM_RANGE);
- float w = r * Math::sin(Math::deg2rad(on->get_param(Light::PARAM_SPOT_ANGLE)));
- float d = r * Math::cos(Math::deg2rad(on->get_param(Light::PARAM_SPOT_ANGLE)));
+ float r = sl->get_param(Light::PARAM_RANGE);
+ float w = r * Math::sin(Math::deg2rad(sl->get_param(Light::PARAM_SPOT_ANGLE)));
+ float d = r * Math::cos(Math::deg2rad(sl->get_param(Light::PARAM_SPOT_ANGLE)));
for (int i = 0; i < 360; i++) {
@@ -985,7 +970,7 @@ void LightSpatialGizmo::redraw() {
points.push_back(Vector3(0, 0, -r));
points.push_back(Vector3());
- add_lines(points, material);
+ p_gizmo->add_lines(points, material);
Vector<Vector3> handles;
handles.push_back(Vector3(0, 0, -r));
@@ -1017,33 +1002,45 @@ void LightSpatialGizmo::redraw() {
collision_segments.push_back(Vector3(0, 0, -r));
collision_segments.push_back(Vector3());
- add_handles(handles);
- add_collision_segments(collision_segments);
- add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_handles(handles, get_material("handles"));
+ p_gizmo->add_collision_segments(collision_segments);
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
}
}
-LightSpatialGizmo::LightSpatialGizmo(Light *p_light) {
+//////
+
+//// player gizmo
+AudioStreamPlayer3DSpatialGizmoPlugin::AudioStreamPlayer3DSpatialGizmoPlugin() {
+
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
- light = p_light;
- set_spatial_node(p_light);
+ create_icon_material("stream_player_3d_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons"));
+ create_material("stream_player_3d_material", gizmo_color);
+ create_handle_material("handles");
}
-//////
+bool AudioStreamPlayer3DSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<AudioStreamPlayer3D>(p_spatial) != NULL;
+}
-//// player gizmo
+String AudioStreamPlayer3DSpatialGizmoPlugin::get_name() const {
+ return "AudioStreamPlayer3D";
+}
-String AudioStreamPlayer3DSpatialGizmo::get_handle_name(int p_idx) const {
+String AudioStreamPlayer3DSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
return "Emission Radius";
}
-Variant AudioStreamPlayer3DSpatialGizmo::get_handle_value(int p_idx) const {
-
+Variant AudioStreamPlayer3DSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
return player->get_emission_angle();
}
-void AudioStreamPlayer3DSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
+void AudioStreamPlayer3DSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
Transform gt = player->get_global_transform();
gt.orthonormalize();
@@ -1081,7 +1078,9 @@ void AudioStreamPlayer3DSpatialGizmo::set_handle(int p_idx, Camera *p_camera, co
}
}
-void AudioStreamPlayer3DSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+void AudioStreamPlayer3DSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -1097,16 +1096,17 @@ void AudioStreamPlayer3DSpatialGizmo::commit_handle(int p_idx, const Variant &p_
}
}
-void AudioStreamPlayer3DSpatialGizmo::redraw() {
+void AudioStreamPlayer3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
- clear();
+ AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
- Ref<Material> icon = create_icon_material("stream_player_3d_material", SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons"));
+ Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);
if (player->is_emission_angle_enabled()) {
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/stream_player_3d");
- Ref<Material> material = create_material("stream_player_3d_material", gizmo_color);
+ Ref<Material> material = get_material("stream_player_3d_material", p_gizmo);
float pc = player->get_emission_angle();
@@ -1124,8 +1124,8 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() {
Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
- points[i * 2 + 0] = from;
- points[i * 2 + 1] = to;
+ points.write[i * 2 + 0] = from;
+ points.write[i * 2 + 1] = to;
}
for (int i = 0; i < 4; i++) {
@@ -1134,31 +1134,44 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() {
Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
- points[200 + i * 2 + 0] = from;
- points[200 + i * 2 + 1] = Vector3();
+ points.write[200 + i * 2 + 0] = from;
+ points.write[200 + i * 2 + 1] = Vector3();
}
- add_lines(points, material);
- add_collision_segments(points);
+ p_gizmo->add_lines(points, material);
+ p_gizmo->add_collision_segments(points);
Vector<Vector3> handles;
float ha = Math::deg2rad(player->get_emission_angle());
handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
- add_handles(handles);
+ p_gizmo->add_handles(handles, get_material("handles"));
}
- add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
}
-AudioStreamPlayer3DSpatialGizmo::AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player) {
+//////
+
+CameraSpatialGizmoPlugin::CameraSpatialGizmoPlugin() {
+
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8));
- player = p_player;
- set_spatial_node(p_player);
+ create_material("camera_material", gizmo_color);
+ create_icon_material("camera_icon", SpatialEditor::get_singleton()->get_icon("GizmoCamera", "EditorIcons"));
+ create_handle_material("handles");
}
-//////
+bool CameraSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Camera>(p_spatial) != NULL;
+}
+
+String CameraSpatialGizmoPlugin::get_name() const {
+ return "Camera";
+}
-String CameraSpatialGizmo::get_handle_name(int p_idx) const {
+String CameraSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ Camera *camera = Object::cast_to<Camera>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
return "FOV";
@@ -1166,7 +1179,10 @@ String CameraSpatialGizmo::get_handle_name(int p_idx) const {
return "Size";
}
}
-Variant CameraSpatialGizmo::get_handle_value(int p_idx) const {
+
+Variant CameraSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ Camera *camera = Object::cast_to<Camera>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
return camera->get_fov();
@@ -1175,7 +1191,10 @@ Variant CameraSpatialGizmo::get_handle_value(int p_idx) const {
return camera->get_size();
}
}
-void CameraSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+void CameraSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ Camera *camera = Object::cast_to<Camera>(p_gizmo->get_spatial_node());
Transform gt = camera->get_global_transform();
gt.orthonormalize();
@@ -1201,7 +1220,10 @@ void CameraSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p
camera->set("size", d);
}
}
-void CameraSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+
+void CameraSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ Camera *camera = Object::cast_to<Camera>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
@@ -1231,16 +1253,17 @@ void CameraSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool
}
}
-void CameraSpatialGizmo::redraw() {
+void CameraSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
- clear();
+ Camera *camera = Object::cast_to<Camera>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Vector<Vector3> lines;
Vector<Vector3> handles;
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/camera");
- Ref<Material> material = create_material("camera_material", gizmo_color);
- Ref<Material> icon = create_icon_material("camera_icon", SpatialEditor::get_singleton()->get_icon("GizmoCamera", "EditorIcons"));
+ Ref<Material> material = get_material("camera_material", p_gizmo);
+ Ref<Material> icon = get_material("camera_icon", p_gizmo);
switch (camera->get_projection()) {
@@ -1310,71 +1333,81 @@ void CameraSpatialGizmo::redraw() {
} break;
}
- add_lines(lines, material);
- add_collision_segments(lines);
- add_unscaled_billboard(icon, 0.05);
- add_handles(handles);
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_handles(handles, get_material("handles"));
}
-CameraSpatialGizmo::CameraSpatialGizmo(Camera *p_camera) {
+//////
- camera = p_camera;
- set_spatial_node(camera);
+MeshInstanceSpatialGizmoPlugin::MeshInstanceSpatialGizmoPlugin() {
}
-//////
+bool MeshInstanceSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<MeshInstance>(p_spatial) != NULL && Object::cast_to<SoftBody>(p_spatial) == NULL;
+}
-bool MeshInstanceSpatialGizmo::can_draw() const {
- return true; //mesh can always draw (even though nothing is displayed)
+String MeshInstanceSpatialGizmoPlugin::get_name() const {
+ return "MeshInstance";
}
-void MeshInstanceSpatialGizmo::redraw() {
- clear();
+bool MeshInstanceSpatialGizmoPlugin::can_be_hidden() const {
+ return false;
+}
+
+void MeshInstanceSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ MeshInstance *mesh = Object::cast_to<MeshInstance>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Ref<Mesh> m = mesh->get_mesh();
+
if (!m.is_valid())
return; //none
Ref<TriangleMesh> tm = m->generate_triangle_mesh();
if (tm.is_valid()) {
- add_collision_triangles(tm);
+ p_gizmo->add_collision_triangles(tm);
}
}
-MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) {
+/////
+Sprite3DSpatialGizmoPlugin::Sprite3DSpatialGizmoPlugin() {
+}
- mesh = p_mesh;
- set_spatial_node(p_mesh);
+bool Sprite3DSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Sprite3D>(p_spatial) != NULL;
}
-/////
+String Sprite3DSpatialGizmoPlugin::get_name() const {
+ return "Sprite3D";
+}
-bool Sprite3DSpatialGizmo::can_draw() const {
- return true;
+bool Sprite3DSpatialGizmoPlugin::can_be_hidden() const {
+ return false;
}
-void Sprite3DSpatialGizmo::redraw() {
- clear();
+void Sprite3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ Sprite3D *sprite = Object::cast_to<Sprite3D>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Ref<TriangleMesh> tm = sprite->generate_triangle_mesh();
if (tm.is_valid()) {
- add_collision_triangles(tm);
+ p_gizmo->add_collision_triangles(tm);
}
}
-Sprite3DSpatialGizmo::Sprite3DSpatialGizmo(SpriteBase3D *p_sprite) {
-
- sprite = p_sprite;
- set_spatial_node(p_sprite);
-}
-
///
-void Position3DSpatialGizmo::redraw() {
+Position3DSpatialGizmoPlugin::Position3DSpatialGizmoPlugin() {
+ pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ cursor_points = Vector<Vector3>();
- clear();
- add_mesh(SpatialEditorGizmos::singleton->pos3d_mesh);
- Vector<Vector3> cursor_points;
+ PoolVector<Color> cursor_colors;
float cs = 0.25;
cursor_points.push_back(Vector3(+cs, 0, 0));
cursor_points.push_back(Vector3(-cs, 0, 0));
@@ -1382,51 +1415,65 @@ void Position3DSpatialGizmo::redraw() {
cursor_points.push_back(Vector3(0, -cs, 0));
cursor_points.push_back(Vector3(0, 0, +cs));
cursor_points.push_back(Vector3(0, 0, -cs));
- add_collision_segments(cursor_points);
+ cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
+ cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
+ cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
+ cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
+ cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
+ cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
+
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_line_width(3);
+ Array d;
+ d.resize(VS::ARRAY_MAX);
+ d[Mesh::ARRAY_VERTEX] = cursor_points;
+ d[Mesh::ARRAY_COLOR] = cursor_colors;
+ pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
+ pos3d_mesh->surface_set_material(0, mat);
}
-Position3DSpatialGizmo::Position3DSpatialGizmo(Position3D *p_p3d) {
+bool Position3DSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Position3D>(p_spatial) != NULL;
+}
+
+String Position3DSpatialGizmoPlugin::get_name() const {
+ return "Position3D";
+}
+
+void Position3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
- p3d = p_p3d;
- set_spatial_node(p3d);
+ p_gizmo->clear();
+ p_gizmo->add_mesh(pos3d_mesh);
+ p_gizmo->add_collision_segments(cursor_points);
}
/////
-void SkeletonSpatialGizmo::redraw() {
+SkeletonSpatialGizmoPlugin::SkeletonSpatialGizmoPlugin() {
- clear();
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
+ create_material("skeleton_material", gizmo_color);
+}
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton");
- Ref<Material> material = create_material("skeleton_material", gizmo_color);
- SpatialMaterial *sm = Object::cast_to<SpatialMaterial>(material.ptr());
-
- { // Reset
- Color c(sm->get_albedo());
- c.a = 1;
- sm->set_albedo(c);
- }
- if (sm) {
- switch (SpatialEditor::get_singleton()->get_skeleton_visibility_state()) {
- case 0: {
- // Hidden
- Color c(sm->get_albedo());
- c.a = 0;
- sm->set_albedo(c);
- sm->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- } break;
- case 1:
- // Visible
- sm->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, false);
- sm->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MIN);
- sm->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, false);
- break;
- case 2:
- // x-ray
- sm->set_on_top_of_alpha();
- break;
- }
- }
+bool SkeletonSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Skeleton>(p_spatial) != NULL;
+}
+
+String SkeletonSpatialGizmoPlugin::get_name() const {
+ return "Skeleton";
+}
+
+void SkeletonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ Skeleton *skel = Object::cast_to<Skeleton>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
+
+ Ref<Material> material = get_material("skeleton_material", p_gizmo);
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
@@ -1441,23 +1488,25 @@ void SkeletonSpatialGizmo::redraw() {
weights.resize(4);
for (int i = 0; i < 4; i++) {
- bones[i] = 0;
- weights[i] = 0;
+ bones.write[i] = 0;
+ weights.write[i] = 0;
}
- weights[0] = 1;
+ weights.write[0] = 1;
AABB aabb;
Color bonecolor = Color(1.0, 0.4, 0.4, 0.3);
Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
- for (int i = 0; i < skel->get_bone_count(); i++) {
+ for (int i_bone = 0; i_bone < skel->get_bone_count(); i_bone++) {
+
+ int i = skel->get_process_order(i_bone);
int parent = skel->get_bone_parent(i);
if (parent >= 0) {
- grests[i] = grests[parent] * skel->get_bone_rest(i);
+ grests.write[i] = grests[parent] * skel->get_bone_rest(i);
Vector3 v0 = grests[parent].origin;
Vector3 v1 = grests[i].origin;
@@ -1480,7 +1529,7 @@ void SkeletonSpatialGizmo::redraw() {
int pointidx = 0;
for (int j = 0; j < 3; j++) {
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(rootcolor);
@@ -1508,7 +1557,7 @@ void SkeletonSpatialGizmo::redraw() {
Vector3 point = v0 + d * dist * 0.2;
point += axis * dist * 0.1;
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
@@ -1518,12 +1567,12 @@ void SkeletonSpatialGizmo::redraw() {
surface_tool->add_color(bonecolor);
surface_tool->add_vertex(point);
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
surface_tool->add_vertex(point);
- bones[0] = i;
+ bones.write[0] = i;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
@@ -1535,7 +1584,7 @@ void SkeletonSpatialGizmo::redraw() {
SWAP(points[1], points[2]);
for (int j = 0; j < 4; j++) {
- bones[0] = parent;
+ bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
surface_tool->add_color(bonecolor);
@@ -1560,8 +1609,8 @@ void SkeletonSpatialGizmo::redraw() {
*/
} else {
- grests[i] = skel->get_bone_rest(i);
- bones[0] = i;
+ grests.write[i] = skel->get_bone_rest(i);
+ bones.write[0] = i;
}
/*
Transform t = grests[i];
@@ -1604,24 +1653,28 @@ void SkeletonSpatialGizmo::redraw() {
}
Ref<ArrayMesh> m = surface_tool->commit();
- add_mesh(m, false, skel->get_skeleton());
+ p_gizmo->add_mesh(m, false, skel->get_skeleton());
}
-SkeletonSpatialGizmo::SkeletonSpatialGizmo(Skeleton *p_skel) {
+////
+
+PhysicalBoneSpatialGizmoPlugin::PhysicalBoneSpatialGizmoPlugin() {
+ create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
+}
- skel = p_skel;
- set_spatial_node(p_skel);
+bool PhysicalBoneSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<PhysicalBone>(p_spatial) != NULL;
}
-PhysicalBoneSpatialGizmo::PhysicalBoneSpatialGizmo(PhysicalBone *p_pb) :
- EditorSpatialGizmo(),
- physical_bone(p_pb) {
- set_spatial_node(p_pb);
+String PhysicalBoneSpatialGizmoPlugin::get_name() const {
+ return "PhysicalBones";
}
-void PhysicalBoneSpatialGizmo::redraw() {
+void PhysicalBoneSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
- clear();
+ p_gizmo->clear();
+
+ PhysicalBone *physical_bone = Object::cast_to<PhysicalBone>(p_gizmo->get_spatial_node());
if (!physical_bone)
return;
@@ -1635,26 +1688,25 @@ void PhysicalBoneSpatialGizmo::redraw() {
switch (physical_bone->get_joint_type()) {
case PhysicalBone::JOINT_TYPE_PIN: {
- PinJointSpatialGizmo::CreateGizmo(physical_bone->get_joint_offset(), points);
+ JointSpatialGizmoPlugin::CreatePinJointGizmo(physical_bone->get_joint_offset(), points);
} break;
case PhysicalBone::JOINT_TYPE_CONE: {
const PhysicalBone::ConeJointData *cjd(static_cast<const PhysicalBone::ConeJointData *>(physical_bone->get_joint_data()));
- ConeTwistJointSpatialGizmo::CreateGizmo(
+ JointSpatialGizmoPlugin::CreateConeTwistJointGizmo(
physical_bone->get_joint_offset(),
physical_bone->get_global_transform() * physical_bone->get_joint_offset(),
pb ? pb->get_global_transform() : Transform(),
pbp ? pbp->get_global_transform() : Transform(),
cjd->swing_span,
cjd->twist_span,
- points,
pb ? &points : NULL,
pbp ? &points : NULL);
} break;
case PhysicalBone::JOINT_TYPE_HINGE: {
const PhysicalBone::HingeJointData *hjd(static_cast<const PhysicalBone::HingeJointData *>(physical_bone->get_joint_data()));
- HingeJointSpatialGizmo::CreateGizmo(
+ JointSpatialGizmoPlugin::CreateHingeJointGizmo(
physical_bone->get_joint_offset(),
physical_bone->get_global_transform() * physical_bone->get_joint_offset(),
pb ? pb->get_global_transform() : Transform(),
@@ -1669,7 +1721,7 @@ void PhysicalBoneSpatialGizmo::redraw() {
case PhysicalBone::JOINT_TYPE_SLIDER: {
const PhysicalBone::SliderJointData *sjd(static_cast<const PhysicalBone::SliderJointData *>(physical_bone->get_joint_data()));
- SliderJointSpatialGizmo::CreateGizmo(
+ JointSpatialGizmoPlugin::CreateSliderJointGizmo(
physical_bone->get_joint_offset(),
physical_bone->get_global_transform() * physical_bone->get_joint_offset(),
pb ? pb->get_global_transform() : Transform(),
@@ -1685,7 +1737,7 @@ void PhysicalBoneSpatialGizmo::redraw() {
case PhysicalBone::JOINT_TYPE_6DOF: {
const PhysicalBone::SixDOFJointData *sdofjd(static_cast<const PhysicalBone::SixDOFJointData *>(physical_bone->get_joint_data()));
- Generic6DOFJointSpatialGizmo::CreateGizmo(
+ JointSpatialGizmoPlugin::CreateGeneric6DOFJointGizmo(
physical_bone->get_joint_offset(),
physical_bone->get_global_transform() * physical_bone->get_joint_offset(),
@@ -1721,14 +1773,15 @@ void PhysicalBoneSpatialGizmo::redraw() {
return;
}
- Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
+ Ref<Material> material = get_material("joint_material", p_gizmo);
- add_collision_segments(points);
- add_lines(points, material);
+ p_gizmo->add_collision_segments(points);
+ p_gizmo->add_lines(points, material);
}
// FIXME: Kept as reference for reimplementation in 3.1+
#if 0
+
void RoomSpatialGizmo::redraw() {
clear();
@@ -1745,41 +1798,41 @@ void RoomSpatialGizmo::redraw() {
for (int i = 0; i < fc; i++) {
- Vector3 fn = r[i].get_plane().normal;
+ Vector3 fn = r[i].get_plane().normal;
- for (int j = 0; j < 3; j++) {
+ for (int j = 0; j < 3; j++) {
- _EdgeKey ek;
- ek.from = r[i].vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
- ek.to = r[i].vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
- if (ek.from < ek.to)
- SWAP(ek.from, ek.to);
+ _EdgeKey ek;
+ ek.from = r[i].vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
+ ek.to = r[i].vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
+ if (ek.from < ek.to)
+ SWAP(ek.from, ek.to);
- Map<_EdgeKey, Vector3>::Element *E = edge_map.find(ek);
+ Map<_EdgeKey, Vector3>::Element *E = edge_map.find(ek);
- if (E) {
+ if (E) {
- if (E->get().dot(fn) > 0.9) {
+ if (E->get().dot(fn) > 0.9) {
- E->get() = Vector3();
- }
+ E->get() = Vector3();
+ }
- } else {
+ } else {
- edge_map[ek] = fn;
- }
+ edge_map[ek] = fn;
+ }
+ }
}
- }
for (Map<_EdgeKey, Vector3>::Element *E = edge_map.front(); E; E = E->next()) {
- if (E->get() != Vector3()) {
- lines.push_back(E->key().from);
- lines.push_back(E->key().to);
+ if (E->get() != Vector3()) {
+ lines.push_back(E->key().from);
+ lines.push_back(E->key().to);
+ }
}
- }
- add_lines(lines, SpatialEditorGizmos::singleton->room_material);
+ add_lines(lines, EditorSpatialGizmos::singleton->room_material);
add_collision_segments(lines);
}
@@ -1797,31 +1850,31 @@ void PortalSpatialGizmo::redraw() {
Vector<Point2> points = portal->get_shape();
if (points.size() == 0) {
- return;
- }
+ return;
+ }
Vector<Vector3> lines;
Vector3 center;
for (int i = 0; i < points.size(); i++) {
- Vector3 f;
- f.x = points[i].x;
- f.y = points[i].y;
- Vector3 fn;
- fn.x = points[(i + 1) % points.size()].x;
- fn.y = points[(i + 1) % points.size()].y;
- center += f;
+ Vector3 f;
+ f.x = points[i].x;
+ f.y = points[i].y;
+ Vector3 fn;
+ fn.x = points[(i + 1) % points.size()].x;
+ fn.y = points[(i + 1) % points.size()].y;
+ center += f;
- lines.push_back(f);
- lines.push_back(fn);
- }
+ lines.push_back(f);
+ lines.push_back(fn);
+ }
center /= points.size();
lines.push_back(center);
lines.push_back(center + Vector3(0, 0, 1));
- add_lines(lines, SpatialEditorGizmos::singleton->portal_material);
+ add_lines(lines, EditorSpatialGizmos::singleton->portal_material);
add_collision_segments(lines);
}
@@ -1834,33 +1887,58 @@ PortalSpatialGizmo::PortalSpatialGizmo(Portal *p_portal) {
#endif
/////
-void RayCastSpatialGizmo::redraw() {
+RayCastSpatialGizmoPlugin::RayCastSpatialGizmoPlugin() {
- clear();
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ create_material("shape_material", gizmo_color);
+}
+
+bool RayCastSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<RayCast>(p_spatial) != NULL;
+}
+
+String RayCastSpatialGizmoPlugin::get_name() const {
+ return "RayCast";
+}
+
+void RayCastSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ RayCast *raycast = Object::cast_to<RayCast>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Vector<Vector3> lines;
lines.push_back(Vector3());
lines.push_back(raycast->get_cast_to());
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
- Ref<Material> material = create_material("shape_material", gizmo_color);
+ Ref<SpatialMaterial> material = get_material("shape_material", p_gizmo);
- add_lines(lines, material);
- add_collision_segments(lines);
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
}
-RayCastSpatialGizmo::RayCastSpatialGizmo(RayCast *p_raycast) {
+/////
+
+VehicleWheelSpatialGizmoPlugin::VehicleWheelSpatialGizmoPlugin() {
- set_spatial_node(p_raycast);
- raycast = p_raycast;
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ create_material("shape_material", gizmo_color);
}
-/////
+bool VehicleWheelSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<VehicleWheel>(p_spatial) != NULL;
+}
-void VehicleWheelSpatialGizmo::redraw() {
+String VehicleWheelSpatialGizmoPlugin::get_name() const {
+ return "VehicleWheel";
+}
- clear();
+void VehicleWheelSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ VehicleWheel *car_wheel = Object::cast_to<VehicleWheel>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Vector<Vector3> points;
@@ -1904,23 +1982,36 @@ void VehicleWheelSpatialGizmo::redraw() {
points.push_back(Vector3(0, -r, r * 2));
points.push_back(Vector3(-r * 2 * 0.2, -r, r * 2 * 0.8));
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
- Ref<Material> material = create_material("shape_material", gizmo_color);
+ Ref<Material> material = get_material("shape_material", p_gizmo);
- add_lines(points, material);
- add_collision_segments(points);
+ p_gizmo->add_lines(points, material);
+ p_gizmo->add_collision_segments(points);
}
-VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel) {
+///////////
- set_spatial_node(p_car_wheel);
- car_wheel = p_car_wheel;
+SoftBodySpatialGizmoPlugin::SoftBodySpatialGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ create_material("shape_material", gizmo_color);
+ create_handle_material("handles");
}
-///////////
+bool SoftBodySpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<SoftBody>(p_spatial) != NULL;
+}
-void SoftBodySpatialGizmo::redraw() {
- clear();
+String SoftBodySpatialGizmoPlugin::get_name() const {
+ return "SoftBody";
+}
+
+bool SoftBodySpatialGizmoPlugin::is_selectable_when_hidden() const {
+ return true;
+}
+
+void SoftBodySpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+ SoftBody *soft_body = Object::cast_to<SoftBody>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
if (!soft_body || soft_body->get_mesh().is_null()) {
return;
@@ -1936,84 +2027,840 @@ void SoftBodySpatialGizmo::redraw() {
return;
}
+ Ref<TriangleMesh> tm = soft_body->get_mesh()->generate_triangle_mesh();
+
Vector<Vector3> points;
soft_body->get_mesh()->generate_debug_mesh_indices(points);
-
soft_body->get_mesh()->clear_cache();
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
- Ref<Material> material = create_material("shape_material", gizmo_color);
+ Ref<Material> material = get_material("shape_material", p_gizmo);
- add_lines(lines, material);
- add_collision_segments(lines);
- add_handles(points);
-}
-
-bool SoftBodySpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
- return EditorSpatialGizmo::intersect_ray(p_camera, p_point, r_pos, r_normal, r_gizmo_handle, p_sec_first);
-
- /* Perform a shape cast but doesn't work with softbody
- PhysicsDirectSpaceState *space_state = PhysicsServer::get_singleton()->space_get_direct_state(SceneTree::get_singleton()->get_root()->get_world()->get_space());
- if (!physics_sphere_shape.is_valid()) {
- physics_sphere_shape = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE);
- real_t radius = 0.02;
- PhysicsServer::get_singleton()->shape_set_data(physics_sphere_shape, radius);
- }
-
- Vector3 sphere_motion(p_camera->project_ray_normal(p_point));
- real_t closest_safe;
- real_t closest_unsafe;
- PhysicsDirectSpaceState::ShapeRestInfo result;
- bool collided = space_state->cast_motion(
- physics_sphere_shape,
- p_camera->get_transform(),
- sphere_motion * Vector3(1000, 1000, 1000),
- 0.f,
- closest_safe,
- closest_unsafe,
- Set<RID>(),
- 0xFFFFFFFF,
- 0xFFFFFFFF,
- &result);
-
- if (collided) {
-
- if (result.collider_id == soft_body->get_instance_id()) {
- print_line("Collided");
- } else {
- print_line("Collided but with wrong object: " + itos(result.collider_id));
- }
- } else {
- print_line("Not collided, motion: x: " + rtos(sphere_motion[0]) + " y: " + rtos(sphere_motion[1]) + " z: " + rtos(sphere_motion[2]));
- }
- return false;
- */
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+ p_gizmo->add_handles(points, get_material("handles"));
+ p_gizmo->add_collision_triangles(tm);
+}
+
+String SoftBodySpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ return "SoftBody pin point";
+}
+
+Variant SoftBodySpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ SoftBody *soft_body = Object::cast_to<SoftBody>(p_gizmo->get_spatial_node());
+ return Variant(soft_body->is_point_pinned(p_idx));
}
-void SoftBodySpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+void SoftBodySpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+ SoftBody *soft_body = Object::cast_to<SoftBody>(p_gizmo->get_spatial_node());
soft_body->pin_point_toggle(p_idx);
- redraw();
}
-bool SoftBodySpatialGizmo::is_gizmo_handle_highlighted(int idx) const {
+bool SoftBodySpatialGizmoPlugin::is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const {
+ SoftBody *soft_body = Object::cast_to<SoftBody>(p_gizmo->get_spatial_node());
return soft_body->is_point_pinned(idx);
}
-SoftBodySpatialGizmo::SoftBodySpatialGizmo(SoftBody *p_soft_physics_body) :
- EditorSpatialGizmo(),
- soft_body(p_soft_physics_body) {
- set_spatial_node(p_soft_physics_body);
+///////////
+
+VisibilityNotifierGizmoPlugin::VisibilityNotifierGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/visibility_notifier", Color(0.8, 0.5, 0.7));
+ create_material("visibility_notifier_material", gizmo_color);
+ gizmo_color.a = 0.1;
+ create_material("visibility_notifier_solid_material", gizmo_color);
+ create_handle_material("handles");
}
-SoftBodySpatialGizmo::~SoftBodySpatialGizmo() {
- //if (!physics_sphere_shape.is_valid()) {
- // PhysicsServer::get_singleton()->free(physics_sphere_shape);
- //}
+bool VisibilityNotifierGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<VisibilityNotifier>(p_spatial) != NULL;
}
-///////////
+String VisibilityNotifierGizmoPlugin::get_name() const {
+ return "VisibilityNotifier";
+}
+
+String VisibilityNotifierGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ switch (p_idx) {
+ case 0: return "Size X";
+ case 1: return "Size Y";
+ case 2: return "Size Z";
+ case 3: return "Pos X";
+ case 4: return "Pos Y";
+ case 5: return "Pos Z";
+ }
+
+ return "";
+}
+
+Variant VisibilityNotifierGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ VisibilityNotifier *notifier = Object::cast_to<VisibilityNotifier>(p_gizmo->get_spatial_node());
+ return notifier->get_aabb();
+}
+void VisibilityNotifierGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ VisibilityNotifier *notifier = Object::cast_to<VisibilityNotifier>(p_gizmo->get_spatial_node());
+
+ Transform gt = notifier->get_global_transform();
+
+ Transform gi = gt.affine_inverse();
+
+ bool move = p_idx >= 3;
+ p_idx = p_idx % 3;
+
+ AABB aabb = notifier->get_aabb();
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
+
+ Vector3 ofs = aabb.position + aabb.size * 0.5;
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ if (move) {
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
+
+ float d = ra[p_idx];
+
+ aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
+ notifier->set_aabb(aabb);
+
+ } else {
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
+
+ float d = ra[p_idx] - ofs[p_idx];
+ if (d < 0.001)
+ d = 0.001;
+ //resize
+ aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
+ aabb.size[p_idx] = d * 2;
+ notifier->set_aabb(aabb);
+ }
+}
+
+void VisibilityNotifierGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ VisibilityNotifier *notifier = Object::cast_to<VisibilityNotifier>(p_gizmo->get_spatial_node());
+
+ if (p_cancel) {
+ notifier->set_aabb(p_restore);
+ return;
+ }
+
+ UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Notifier AABB"));
+ ur->add_do_method(notifier, "set_aabb", notifier->get_aabb());
+ ur->add_undo_method(notifier, "set_aabb", p_restore);
+ ur->commit_action();
+}
+
+void VisibilityNotifierGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ VisibilityNotifier *notifier = Object::cast_to<VisibilityNotifier>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
+
+ Vector<Vector3> lines;
+ AABB aabb = notifier->get_aabb();
+
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
+
+ Vector<Vector3> handles;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
+ ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
+ handles.push_back(ax);
+ }
+
+ Vector3 center = aabb.position + aabb.size * 0.5;
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = 1.0;
+ handles.push_back(center + ax);
+ lines.push_back(center);
+ lines.push_back(center + ax);
+ }
+
+ Ref<Material> material = get_material("visibility_notifier_material", p_gizmo);
+
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+
+ if (p_gizmo->is_selected()) {
+ Ref<Material> solid_material = get_material("visibility_notifier_solid_material", p_gizmo);
+ p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0);
+ }
+
+ p_gizmo->add_handles(handles, get_material("handles"));
+}
+
+////
+
+ParticlesGizmoPlugin::ParticlesGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
+ create_material("particles_material", gizmo_color);
+ gizmo_color.a = 0.1;
+ create_material("particles_solid_material", gizmo_color);
+ create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoParticles", "EditorIcons"));
+ create_handle_material("handles");
+}
+
+bool ParticlesGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Particles>(p_spatial) != NULL;
+}
+
+String ParticlesGizmoPlugin::get_name() const {
+ return "Particles";
+}
+
+bool ParticlesGizmoPlugin::is_selectable_when_hidden() const {
+ return true;
+}
+
+String ParticlesGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ switch (p_idx) {
+ case 0: return "Size X";
+ case 1: return "Size Y";
+ case 2: return "Size Z";
+ case 3: return "Pos X";
+ case 4: return "Pos Y";
+ case 5: return "Pos Z";
+ }
+
+ return "";
+}
+Variant ParticlesGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ Particles *particles = Object::cast_to<Particles>(p_gizmo->get_spatial_node());
+ return particles->get_visibility_aabb();
+}
+void ParticlesGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ Particles *particles = Object::cast_to<Particles>(p_gizmo->get_spatial_node());
+
+ Transform gt = particles->get_global_transform();
+ //gt.orthonormalize();
+ Transform gi = gt.affine_inverse();
+
+ bool move = p_idx >= 3;
+ p_idx = p_idx % 3;
+
+ AABB aabb = particles->get_visibility_aabb();
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
+
+ Vector3 ofs = aabb.position + aabb.size * 0.5;
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ if (move) {
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
+
+ float d = ra[p_idx];
+
+ aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
+ particles->set_visibility_aabb(aabb);
+
+ } else {
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
+
+ float d = ra[p_idx] - ofs[p_idx];
+ if (d < 0.001)
+ d = 0.001;
+ //resize
+ aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
+ aabb.size[p_idx] = d * 2;
+ particles->set_visibility_aabb(aabb);
+ }
+}
+
+void ParticlesGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ Particles *particles = Object::cast_to<Particles>(p_gizmo->get_spatial_node());
+
+ if (p_cancel) {
+ particles->set_visibility_aabb(p_restore);
+ return;
+ }
+
+ UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Particles AABB"));
+ ur->add_do_method(particles, "set_custom_aabb", particles->get_visibility_aabb());
+ ur->add_undo_method(particles, "set_custom_aabb", p_restore);
+ ur->commit_action();
+}
+
+void ParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ Particles *particles = Object::cast_to<Particles>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
+
+ Vector<Vector3> lines;
+ AABB aabb = particles->get_visibility_aabb();
+
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
+
+ Vector<Vector3> handles;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
+ ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
+ handles.push_back(ax);
+ }
+
+ Vector3 center = aabb.position + aabb.size * 0.5;
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = 1.0;
+ handles.push_back(center + ax);
+ lines.push_back(center);
+ lines.push_back(center + ax);
+ }
+
+ Ref<Material> material = get_material("particles_material", p_gizmo);
+ Ref<Material> icon = get_material("particles_icon", p_gizmo);
+
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+
+ if (p_gizmo->is_selected()) {
+ Ref<Material> solid_material = get_material("particles_solid_material", p_gizmo);
+ p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0);
+ }
+
+ p_gizmo->add_handles(handles, get_material("handles"));
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
+}
+////
+
+ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5));
+
+ create_material("reflection_probe_material", gizmo_color);
+
+ gizmo_color.a = 0.5;
+ create_material("reflection_internal_material", gizmo_color);
+
+ gizmo_color.a = 0.1;
+ create_material("reflection_probe_solid_material", gizmo_color);
+
+ create_icon_material("reflection_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoReflectionProbe", "EditorIcons"));
+ create_handle_material("handles");
+}
+
+bool ReflectionProbeGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<ReflectionProbe>(p_spatial) != NULL;
+}
+
+String ReflectionProbeGizmoPlugin::get_name() const {
+ return "ReflectionProbe";
+}
+
+String ReflectionProbeGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ switch (p_idx) {
+ case 0: return "Extents X";
+ case 1: return "Extents Y";
+ case 2: return "Extents Z";
+ case 3: return "Origin X";
+ case 4: return "Origin Y";
+ case 5: return "Origin Z";
+ }
+
+ return "";
+}
+Variant ReflectionProbeGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
+ return AABB(probe->get_extents(), probe->get_origin_offset());
+}
+void ReflectionProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
+ Transform gt = probe->get_global_transform();
+
+ Transform gi = gt.affine_inverse();
+
+ if (p_idx < 3) {
+ Vector3 extents = probe->get_extents();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
+ float d = ra[p_idx];
+ if (d < 0.001)
+ d = 0.001;
+
+ extents[p_idx] = d;
+ probe->set_extents(extents);
+ } else {
+
+ p_idx -= 3;
+
+ Vector3 origin = probe->get_origin_offset();
+ origin[p_idx] = 0;
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb);
+ float d = ra[p_idx];
+ d += 0.25;
+
+ origin[p_idx] = d;
+ probe->set_origin_offset(origin);
+ }
+}
+
+void ReflectionProbeGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
+
+ AABB restore = p_restore;
+
+ if (p_cancel) {
+ probe->set_extents(restore.position);
+ probe->set_origin_offset(restore.size);
+ return;
+ }
+
+ UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Probe Extents"));
+ ur->add_do_method(probe, "set_extents", probe->get_extents());
+ ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset());
+ ur->add_undo_method(probe, "set_extents", restore.position);
+ ur->add_undo_method(probe, "set_origin_offset", restore.size);
+ ur->commit_action();
+}
+
+void ReflectionProbeGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
+
+ Vector<Vector3> lines;
+ Vector<Vector3> internal_lines;
+ Vector3 extents = probe->get_extents();
+
+ AABB aabb;
+ aabb.position = -extents;
+ aabb.size = extents * 2;
+
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ Vector3 ep = aabb.get_endpoint(i);
+ internal_lines.push_back(probe->get_origin_offset());
+ internal_lines.push_back(ep);
+ }
+
+ Vector<Vector3> handles;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ handles.push_back(ax);
+ }
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 orig_handle = probe->get_origin_offset();
+ orig_handle[i] -= 0.25;
+ lines.push_back(orig_handle);
+ handles.push_back(orig_handle);
+
+ orig_handle[i] += 0.5;
+ lines.push_back(orig_handle);
+ }
+
+ Ref<Material> material = get_material("reflection_probe_material", p_gizmo);
+ Ref<Material> material_internal = get_material("reflection_internal_material", p_gizmo);
+ Ref<Material> icon = get_material("reflection_probe_icon", p_gizmo);
+
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_lines(internal_lines, material_internal);
+
+ if (p_gizmo->is_selected()) {
+ Ref<Material> solid_material = get_material("reflection_probe_solid_material", p_gizmo);
+ p_gizmo->add_solid_box(solid_material, probe->get_extents() * 2.0);
+ }
+
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_collision_segments(lines);
+ p_gizmo->add_handles(handles, get_material("handles"));
+}
+
+GIProbeGizmoPlugin::GIProbeGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6));
+
+ create_material("gi_probe_material", gizmo_color);
+
+ gizmo_color.a = 0.5;
+ create_material("gi_probe_internal_material", gizmo_color);
+
+ gizmo_color.a = 0.1;
+ create_material("gi_probe_solid_material", gizmo_color);
+
+ create_icon_material("gi_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons"));
+ create_handle_material("handles");
+}
+
+bool GIProbeGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<GIProbe>(p_spatial) != NULL;
+}
+
+String GIProbeGizmoPlugin::get_name() const {
+ return "GIProbe";
+}
+
+String GIProbeGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ switch (p_idx) {
+ case 0: return "Extents X";
+ case 1: return "Extents Y";
+ case 2: return "Extents Z";
+ }
+
+ return "";
+}
+Variant GIProbeGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
+ return probe->get_extents();
+}
+void GIProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
+
+ Transform gt = probe->get_global_transform();
+ //gt.orthonormalize();
+ Transform gi = gt.affine_inverse();
+
+ Vector3 extents = probe->get_extents();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
+ float d = ra[p_idx];
+ if (d < 0.001)
+ d = 0.001;
+
+ extents[p_idx] = d;
+ probe->set_extents(extents);
+}
+
+void GIProbeGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
+
+ Vector3 restore = p_restore;
+
+ if (p_cancel) {
+ probe->set_extents(restore);
+ return;
+ }
+
+ UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Probe Extents"));
+ ur->add_do_method(probe, "set_extents", probe->get_extents());
+ ur->add_undo_method(probe, "set_extents", restore);
+ ur->commit_action();
+}
+
+void GIProbeGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
+
+ Ref<Material> material = get_material("gi_probe_material", p_gizmo);
+ Ref<Material> icon = get_material("gi_probe_icon", p_gizmo);
+ Ref<Material> material_internal = get_material("gi_probe_internal_material", p_gizmo);
+
+ p_gizmo->clear();
+
+ Vector<Vector3> lines;
+ Vector3 extents = probe->get_extents();
+
+ static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 };
+
+ AABB aabb = AABB(-extents, extents * 2);
+ int subdiv = subdivs[probe->get_subdiv()];
+ float cell_size = aabb.get_longest_axis_size() / subdiv;
+
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
+
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+
+ lines.clear();
+
+ for (int i = 1; i < subdiv; i++) {
+
+ for (int j = 0; j < 3; j++) {
+
+ if (cell_size * i > aabb.size[j]) {
+ continue;
+ }
+
+ Vector2 dir;
+ dir[j] = 1.0;
+ Vector2 ta, tb;
+ int j_n1 = (j + 1) % 3;
+ int j_n2 = (j + 2) % 3;
+ ta[j_n1] = 1.0;
+ tb[j_n2] = 1.0;
+
+ for (int k = 0; k < 4; k++) {
+
+ Vector3 from = aabb.position, to = aabb.position;
+ from[j] += cell_size * i;
+ to[j] += cell_size * i;
+
+ if (k & 1) {
+ to[j_n1] += aabb.size[j_n1];
+ } else {
+
+ to[j_n2] += aabb.size[j_n2];
+ }
+
+ if (k & 2) {
+ from[j_n1] += aabb.size[j_n1];
+ from[j_n2] += aabb.size[j_n2];
+ }
+
+ lines.push_back(from);
+ lines.push_back(to);
+ }
+ }
+ }
+
+ p_gizmo->add_lines(lines, material_internal);
+
+ Vector<Vector3> handles;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ handles.push_back(ax);
+ }
+
+ if (p_gizmo->is_selected()) {
+ Ref<Material> solid_material = get_material("gi_probe_solid_material", p_gizmo);
+ p_gizmo->add_solid_box(solid_material, aabb.get_size());
+ }
+
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_handles(handles, get_material("handles"));
+}
+
+////
+
+BakedIndirectLightGizmoPlugin::BakedIndirectLightGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/baked_indirect_light", Color(0.5, 0.6, 1));
+
+ create_material("baked_indirect_light_material", gizmo_color);
+
+ gizmo_color.a = 0.1;
+ create_material("baked_indirect_light_internal_material", gizmo_color);
+
+ create_icon_material("baked_indirect_light_icon", SpatialEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons"));
+ create_handle_material("handles");
+}
+
+String BakedIndirectLightGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ switch (p_idx) {
+ case 0: return "Extents X";
+ case 1: return "Extents Y";
+ case 2: return "Extents Z";
+ }
+
+ return "";
+}
+Variant BakedIndirectLightGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+ return baker->get_extents();
+}
+void BakedIndirectLightGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+
+ Transform gt = baker->get_global_transform();
+ //gt.orthonormalize();
+ Transform gi = gt.affine_inverse();
+
+ Vector3 extents = baker->get_extents();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+
+ Vector3 axis;
+ axis[p_idx] = 1.0;
+
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
+ float d = ra[p_idx];
+ if (d < 0.001)
+ d = 0.001;
+
+ extents[p_idx] = d;
+ baker->set_extents(extents);
+}
+
+void BakedIndirectLightGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+
+ Vector3 restore = p_restore;
+
+ if (p_cancel) {
+ baker->set_extents(restore);
+ return;
+ }
+
+ UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Probe Extents"));
+ ur->add_do_method(baker, "set_extents", baker->get_extents());
+ ur->add_undo_method(baker, "set_extents", restore);
+ ur->commit_action();
+}
+
+bool BakedIndirectLightGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<BakedLightmap>(p_spatial) != NULL;
+}
+
+String BakedIndirectLightGizmoPlugin::get_name() const {
+ return "BakedLightmap";
+}
+
+void BakedIndirectLightGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+
+ Ref<Material> material = get_material("baked_indirect_light_material", p_gizmo);
+ Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo);
+ Ref<Material> material_internal = get_material("baked_indirect_light_internal_material", p_gizmo);
+
+ p_gizmo->clear();
+
+ Vector<Vector3> lines;
+ Vector3 extents = baker->get_extents();
+
+ AABB aabb = AABB(-extents, extents * 2);
+
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
+
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+
+ Vector<Vector3> handles;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ handles.push_back(ax);
+ }
+
+ if (p_gizmo->is_selected()) {
+ p_gizmo->add_solid_box(material_internal, aabb.get_size());
+ }
+
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_handles(handles, get_material("handles"));
+}
+
+////
+
+CollisionShapeSpatialGizmoPlugin::CollisionShapeSpatialGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ create_material("shape_material", gizmo_color);
+ create_handle_material("handles");
+}
+
+bool CollisionShapeSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<CollisionShape>(p_spatial) != NULL;
+}
+
+String CollisionShapeSpatialGizmoPlugin::get_name() const {
+ return "CollisionShape";
+}
-String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const {
+String CollisionShapeSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ const CollisionShape *cs = Object::cast_to<CollisionShape>(p_gizmo->get_spatial_node());
Ref<Shape> s = cs->get_shape();
if (s.is_null())
@@ -2046,7 +2893,10 @@ String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const {
return "";
}
-Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const {
+
+Variant CollisionShapeSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+
+ CollisionShape *cs = Object::cast_to<CollisionShape>(p_gizmo->get_spatial_node());
Ref<Shape> s = cs->get_shape();
if (s.is_null())
@@ -2084,7 +2934,10 @@ Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const {
return Variant();
}
-void CollisionShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
+void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ CollisionShape *cs = Object::cast_to<CollisionShape>(p_gizmo->get_spatial_node());
+
Ref<Shape> s = cs->get_shape();
if (s.is_null())
return;
@@ -2175,7 +3028,10 @@ void CollisionShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const P
cs->set_height(d * 2.0);
}
}
-void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+void CollisionShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ CollisionShape *cs = Object::cast_to<CollisionShape>(p_gizmo->get_spatial_node());
+
Ref<Shape> s = cs->get_shape();
if (s.is_null())
return;
@@ -2252,7 +3108,11 @@ void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_resto
ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
ur->add_undo_method(ss.ptr(), "set_radius", p_restore);
} else {
- ur->create_action(TTR("Change Cylinder Shape Height"));
+ ur->create_action(
+ ///
+
+ ////////
+ TTR("Change Cylinder Shape Height"));
ur->add_do_method(ss.ptr(), "set_height", ss->get_height());
ur->add_undo_method(ss.ptr(), "set_height", p_restore);
}
@@ -2275,16 +3135,18 @@ void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_resto
ur->commit_action();
}
}
-void CollisionShapeSpatialGizmo::redraw() {
+void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
- clear();
+ CollisionShape *cs = Object::cast_to<CollisionShape>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Ref<Shape> s = cs->get_shape();
if (s.is_null())
return;
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
- Ref<Material> material = create_material("shape_material", gizmo_color);
+ Ref<Material> material = get_material("shape_material", p_gizmo);
+ Ref<Material> handles_material = get_material("handles");
if (Object::cast_to<SphereShape>(*s)) {
@@ -2325,11 +3187,11 @@ void CollisionShapeSpatialGizmo::redraw() {
collision_segments.push_back(Vector3(b.x, b.y, 0));
}
- add_lines(points, material);
- add_collision_segments(collision_segments);
+ p_gizmo->add_lines(points, material);
+ p_gizmo->add_collision_segments(collision_segments);
Vector<Vector3> handles;
handles.push_back(Vector3(r, 0, 0));
- add_handles(handles);
+ p_gizmo->add_handles(handles, handles_material);
}
if (Object::cast_to<BoxShape>(*s)) {
@@ -2356,9 +3218,9 @@ void CollisionShapeSpatialGizmo::redraw() {
handles.push_back(ax);
}
- add_lines(lines, material);
- add_collision_segments(lines);
- add_handles(handles);
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
+ p_gizmo->add_handles(handles, handles_material);
}
if (Object::cast_to<CapsuleShape>(*s)) {
@@ -2397,7 +3259,7 @@ void CollisionShapeSpatialGizmo::redraw() {
points.push_back(Vector3(b.y, 0, b.x) + dud);
}
- add_lines(points, material);
+ p_gizmo->add_lines(points, material);
Vector<Vector3> collision_segments;
@@ -2428,12 +3290,12 @@ void CollisionShapeSpatialGizmo::redraw() {
collision_segments.push_back(Vector3(b.y, 0, b.x) + dud);
}
- add_collision_segments(collision_segments);
+ p_gizmo->add_collision_segments(collision_segments);
Vector<Vector3> handles;
handles.push_back(Vector3(cs->get_radius(), 0, 0));
handles.push_back(Vector3(0, 0, cs->get_height() * 0.5 + cs->get_radius()));
- add_handles(handles);
+ p_gizmo->add_handles(handles, handles_material);
}
if (Object::cast_to<CylinderShape>(*s)) {
@@ -2465,7 +3327,7 @@ void CollisionShapeSpatialGizmo::redraw() {
}
}
- add_lines(points, material);
+ p_gizmo->add_lines(points, material);
Vector<Vector3> collision_segments;
@@ -2489,12 +3351,12 @@ void CollisionShapeSpatialGizmo::redraw() {
}
}
- add_collision_segments(collision_segments);
+ p_gizmo->add_collision_segments(collision_segments);
Vector<Vector3> handles;
handles.push_back(Vector3(cs->get_radius(), 0, 0));
handles.push_back(Vector3(0, cs->get_height() * 0.5, 0));
- add_handles(handles);
+ p_gizmo->add_handles(handles, handles_material);
}
if (Object::cast_to<PlaneShape>(*s)) {
@@ -2524,8 +3386,8 @@ void CollisionShapeSpatialGizmo::redraw() {
points.push_back(p.normal * p.d);
points.push_back(p.normal * p.d + p.normal * 3);
- add_lines(points, material);
- add_collision_segments(points);
+ p_gizmo->add_lines(points, material);
+ p_gizmo->add_collision_segments(points);
}
if (Object::cast_to<ConvexPolygonShape>(*s)) {
@@ -2542,12 +3404,12 @@ void CollisionShapeSpatialGizmo::redraw() {
Vector<Vector3> points;
points.resize(md.edges.size() * 2);
for (int i = 0; i < md.edges.size(); i++) {
- points[i * 2 + 0] = md.vertices[md.edges[i].a];
- points[i * 2 + 1] = md.vertices[md.edges[i].b];
+ points.write[i * 2 + 0] = md.vertices[md.edges[i].a];
+ points.write[i * 2 + 1] = md.vertices[md.edges[i].b];
}
- add_lines(points, material);
- add_collision_segments(points);
+ p_gizmo->add_lines(points, material);
+ p_gizmo->add_collision_segments(points);
}
}
}
@@ -2559,24 +3421,34 @@ void CollisionShapeSpatialGizmo::redraw() {
Vector<Vector3> points;
points.push_back(Vector3());
points.push_back(Vector3(0, 0, rs->get_length()));
- add_lines(points, material);
- add_collision_segments(points);
+ p_gizmo->add_lines(points, material);
+ p_gizmo->add_collision_segments(points);
Vector<Vector3> handles;
handles.push_back(Vector3(0, 0, rs->get_length()));
- add_handles(handles);
+ p_gizmo->add_handles(handles, handles_material);
}
}
-CollisionShapeSpatialGizmo::CollisionShapeSpatialGizmo(CollisionShape *p_cs) {
- cs = p_cs;
- set_spatial_node(p_cs);
+/////
+
+CollisionPolygonSpatialGizmoPlugin::CollisionPolygonSpatialGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ create_material("shape_material", gizmo_color);
}
-/////
+bool CollisionPolygonSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<CollisionPolygon>(p_spatial) != NULL;
+}
-void CollisionPolygonSpatialGizmo::redraw() {
+String CollisionPolygonSpatialGizmoPlugin::get_name() const {
+ return "CollisionPolygon";
+}
- clear();
+void CollisionPolygonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+
+ CollisionPolygon *polygon = Object::cast_to<CollisionPolygon>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
Vector<Vector2> points = polygon->get_polygon();
float depth = polygon->get_depth() * 0.5;
@@ -2593,695 +3465,39 @@ void CollisionPolygonSpatialGizmo::redraw() {
lines.push_back(Vector3(points[i].x, points[i].y, -depth));
}
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
- Ref<Material> material = create_material("shape_material", gizmo_color);
-
- add_lines(lines, material);
- add_collision_segments(lines);
-}
-
-CollisionPolygonSpatialGizmo::CollisionPolygonSpatialGizmo(CollisionPolygon *p_polygon) {
-
- set_spatial_node(p_polygon);
- polygon = p_polygon;
-}
-///
-
-String VisibilityNotifierGizmo::get_handle_name(int p_idx) const {
-
- switch (p_idx) {
- case 0: return "X";
- case 1: return "Y";
- case 2: return "Z";
- }
-
- return "";
-}
-Variant VisibilityNotifierGizmo::get_handle_value(int p_idx) const {
-
- return notifier->get_aabb();
-}
-void VisibilityNotifierGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
-
- Transform gt = notifier->get_global_transform();
- //gt.orthonormalize();
- Transform gi = gt.affine_inverse();
-
- AABB aabb = notifier->get_aabb();
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
- Vector3 ofs = aabb.position + aabb.size * 0.5;
-
- Vector3 axis;
- axis[p_idx] = 1.0;
-
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
- float d = ra[p_idx];
- if (d < 0.001)
- d = 0.001;
-
- aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
- aabb.size[p_idx] = d * 2;
- notifier->set_aabb(aabb);
-}
-
-void VisibilityNotifierGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
- if (p_cancel) {
- notifier->set_aabb(p_restore);
- return;
- }
-
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Notifier Extents"));
- ur->add_do_method(notifier, "set_aabb", notifier->get_aabb());
- ur->add_undo_method(notifier, "set_aabb", p_restore);
- ur->commit_action();
-}
-
-void VisibilityNotifierGizmo::redraw() {
-
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/visibility_notifier");
- Ref<Material> material = create_material("visibility_notifier_material", gizmo_color);
-
- clear();
-
- Vector<Vector3> lines;
- AABB aabb = notifier->get_aabb();
-
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
-
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
-
- add_lines(lines, material);
- //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
- add_collision_segments(lines);
- add_handles(handles);
-}
-VisibilityNotifierGizmo::VisibilityNotifierGizmo(VisibilityNotifier *p_notifier) {
-
- notifier = p_notifier;
- set_spatial_node(p_notifier);
-}
-
-////////
-
-///
-
-String ParticlesGizmo::get_handle_name(int p_idx) const {
-
- switch (p_idx) {
- case 0: return "Size X";
- case 1: return "Size Y";
- case 2: return "Size Z";
- case 3: return "Pos X";
- case 4: return "Pos Y";
- case 5: return "Pos Z";
- }
-
- return "";
-}
-Variant ParticlesGizmo::get_handle_value(int p_idx) const {
-
- return particles->get_visibility_aabb();
-}
-void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
-
- Transform gt = particles->get_global_transform();
- //gt.orthonormalize();
- Transform gi = gt.affine_inverse();
-
- bool move = p_idx >= 3;
- p_idx = p_idx % 3;
-
- AABB aabb = particles->get_visibility_aabb();
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
-
- Vector3 ofs = aabb.position + aabb.size * 0.5;
-
- Vector3 axis;
- axis[p_idx] = 1.0;
-
- if (move) {
-
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
-
- float d = ra[p_idx];
-
- aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
- particles->set_visibility_aabb(aabb);
-
- } else {
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
-
- float d = ra[p_idx] - ofs[p_idx];
- if (d < 0.001)
- d = 0.001;
- //resize
- aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
- aabb.size[p_idx] = d * 2;
- particles->set_visibility_aabb(aabb);
- }
-}
-
-void ParticlesGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
- if (p_cancel) {
- particles->set_visibility_aabb(p_restore);
- return;
- }
-
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Particles AABB"));
- ur->add_do_method(particles, "set_custom_aabb", particles->get_visibility_aabb());
- ur->add_undo_method(particles, "set_custom_aabb", p_restore);
- ur->commit_action();
-}
-
-void ParticlesGizmo::redraw() {
-
- clear();
-
- Vector<Vector3> lines;
- AABB aabb = particles->get_visibility_aabb();
-
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
-
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
- ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
- handles.push_back(ax);
- }
-
- Vector3 center = aabb.position + aabb.size * 0.5;
- for (int i = 0; i < 3; i++) {
-
- Vector3 ax;
- ax[i] = 1.0;
- handles.push_back(center + ax);
- lines.push_back(center);
- lines.push_back(center + ax);
- }
-
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/particles");
- Ref<Material> material = create_material("particles_material", gizmo_color);
- Ref<Material> icon = create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoParticles", "EditorIcons"));
-
- add_lines(lines, material);
- add_collision_segments(lines);
-
- if (is_selected()) {
-
- gizmo_color.a = 0.1;
- Ref<Material> solid_material = create_material("particles_solid_material", gizmo_color);
- add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0);
- }
-
- //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
+ Ref<Material> material = get_material("shape_material", p_gizmo);
- add_handles(handles);
- add_unscaled_billboard(icon, 0.05);
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_collision_segments(lines);
}
-ParticlesGizmo::ParticlesGizmo(Particles *p_particles) {
- particles = p_particles;
- set_spatial_node(p_particles);
-}
-
-////////
-
-///
-
-String ReflectionProbeGizmo::get_handle_name(int p_idx) const {
-
- switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
- case 3: return "Origin X";
- case 4: return "Origin Y";
- case 5: return "Origin Z";
- }
-
- return "";
-}
-Variant ReflectionProbeGizmo::get_handle_value(int p_idx) const {
-
- return AABB(probe->get_extents(), probe->get_origin_offset());
-}
-void ReflectionProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
-
- Transform gt = probe->get_global_transform();
- //gt.orthonormalize();
- Transform gi = gt.affine_inverse();
-
- if (p_idx < 3) {
- Vector3 extents = probe->get_extents();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_idx] = 1.0;
-
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_idx];
- if (d < 0.001)
- d = 0.001;
-
- extents[p_idx] = d;
- probe->set_extents(extents);
- } else {
-
- p_idx -= 3;
-
- Vector3 origin = probe->get_origin_offset();
- origin[p_idx] = 0;
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_idx] = 1.0;
-
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_idx];
- d += 0.25;
-
- origin[p_idx] = d;
- probe->set_origin_offset(origin);
- }
-}
-
-void ReflectionProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
- AABB restore = p_restore;
-
- if (p_cancel) {
- probe->set_extents(restore.position);
- probe->set_origin_offset(restore.size);
- return;
- }
-
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Probe Extents"));
- ur->add_do_method(probe, "set_extents", probe->get_extents());
- ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset());
- ur->add_undo_method(probe, "set_extents", restore.position);
- ur->add_undo_method(probe, "set_origin_offset", restore.size);
- ur->commit_action();
-}
-
-void ReflectionProbeGizmo::redraw() {
-
- clear();
-
- Vector<Vector3> lines;
- Vector<Vector3> internal_lines;
- Vector3 extents = probe->get_extents();
-
- AABB aabb;
- aabb.position = -extents;
- aabb.size = extents * 2;
-
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
-
- for (int i = 0; i < 8; i++) {
- Vector3 ep = aabb.get_endpoint(i);
- internal_lines.push_back(probe->get_origin_offset());
- internal_lines.push_back(ep);
- }
-
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 orig_handle = probe->get_origin_offset();
- orig_handle[i] -= 0.25;
- lines.push_back(orig_handle);
- handles.push_back(orig_handle);
-
- orig_handle[i] += 0.5;
- lines.push_back(orig_handle);
- }
-
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/reflection_probe");
- Ref<Material> material = create_material("reflection_probe_material", gizmo_color);
- Ref<Material> icon = create_icon_material("reflection_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoReflectionProbe", "EditorIcons"));
-
- Color gizmo_color_internal = gizmo_color;
- gizmo_color_internal.a = 0.5;
- Ref<Material> material_internal = create_material("reflection_internal_material", gizmo_color_internal);
-
- add_lines(lines, material);
- add_lines(internal_lines, material_internal);
-
- if (is_selected()) {
-
- gizmo_color.a = 0.1;
- Ref<Material> solid_material = create_material("reflection_probe_solid_material", gizmo_color);
- add_solid_box(solid_material, probe->get_extents() * 2.0);
- }
-
- //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
- add_unscaled_billboard(icon, 0.05);
- add_collision_segments(lines);
- add_handles(handles);
-}
-ReflectionProbeGizmo::ReflectionProbeGizmo(ReflectionProbe *p_probe) {
-
- probe = p_probe;
- set_spatial_node(p_probe);
-}
-
-////////
-
-///
-
-String GIProbeGizmo::get_handle_name(int p_idx) const {
-
- switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
- }
-
- return "";
-}
-Variant GIProbeGizmo::get_handle_value(int p_idx) const {
-
- return probe->get_extents();
-}
-void GIProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
-
- Transform gt = probe->get_global_transform();
- //gt.orthonormalize();
- Transform gi = gt.affine_inverse();
-
- Vector3 extents = probe->get_extents();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_idx] = 1.0;
-
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_idx];
- if (d < 0.001)
- d = 0.001;
-
- extents[p_idx] = d;
- probe->set_extents(extents);
-}
-
-void GIProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
- Vector3 restore = p_restore;
-
- if (p_cancel) {
- probe->set_extents(restore);
- return;
- }
-
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Probe Extents"));
- ur->add_do_method(probe, "set_extents", probe->get_extents());
- ur->add_undo_method(probe, "set_extents", restore);
- ur->commit_action();
-}
-
-void GIProbeGizmo::redraw() {
-
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/gi_probe");
- Ref<Material> material = create_material("gi_probe_material", gizmo_color);
- Ref<Material> icon = create_icon_material("gi_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons"));
- Color gizmo_color_internal = gizmo_color;
- gizmo_color_internal.a = 0.1;
- Ref<Material> material_internal = create_material("gi_probe_internal_material", gizmo_color_internal);
-
- clear();
-
- Vector<Vector3> lines;
- Vector3 extents = probe->get_extents();
-
- static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 };
-
- AABB aabb = AABB(-extents, extents * 2);
- int subdiv = subdivs[probe->get_subdiv()];
- float cell_size = aabb.get_longest_axis_size() / subdiv;
-
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
-
- add_lines(lines, material);
- add_collision_segments(lines);
-
- lines.clear();
-
- for (int i = 1; i < subdiv; i++) {
-
- for (int j = 0; j < 3; j++) {
-
- if (cell_size * i > aabb.size[j]) {
- continue;
- }
-
- Vector2 dir;
- dir[j] = 1.0;
- Vector2 ta, tb;
- int j_n1 = (j + 1) % 3;
- int j_n2 = (j + 2) % 3;
- ta[j_n1] = 1.0;
- tb[j_n2] = 1.0;
-
- for (int k = 0; k < 4; k++) {
-
- Vector3 from = aabb.position, to = aabb.position;
- from[j] += cell_size * i;
- to[j] += cell_size * i;
-
- if (k & 1) {
- to[j_n1] += aabb.size[j_n1];
- } else {
-
- to[j_n2] += aabb.size[j_n2];
- }
-
- if (k & 2) {
- from[j_n1] += aabb.size[j_n1];
- from[j_n2] += aabb.size[j_n2];
- }
-
- lines.push_back(from);
- lines.push_back(to);
- }
- }
- }
-
- add_lines(lines, material_internal);
-
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
-
- if (is_selected()) {
-
- gizmo_color.a = 0.1;
- Ref<Material> solid_material = create_material("gi_probe_solid_material", gizmo_color);
- add_solid_box(solid_material, aabb.get_size());
- }
-
- add_unscaled_billboard(icon, 0.05);
- add_handles(handles);
-}
-GIProbeGizmo::GIProbeGizmo(GIProbe *p_probe) {
-
- probe = p_probe;
- set_spatial_node(p_probe);
-}
-
-////////
-////////
-
-///
-
-String BakedIndirectLightGizmo::get_handle_name(int p_idx) const {
-
- switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
- }
-
- return "";
-}
-Variant BakedIndirectLightGizmo::get_handle_value(int p_idx) const {
-
- return baker->get_extents();
-}
-void BakedIndirectLightGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
-
- Transform gt = baker->get_global_transform();
- //gt.orthonormalize();
- Transform gi = gt.affine_inverse();
-
- Vector3 extents = baker->get_extents();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_idx] = 1.0;
-
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_idx];
- if (d < 0.001)
- d = 0.001;
+////
- extents[p_idx] = d;
- baker->set_extents(extents);
+NavigationMeshSpatialGizmoPlugin::NavigationMeshSpatialGizmoPlugin() {
+ create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge", Color(0.5, 1, 1)));
+ create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled", Color(0.7, 0.7, 0.7)));
+ create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid", Color(0.5, 1, 1, 0.4)));
+ create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled", Color(0.7, 0.7, 0.7, 0.4)));
}
-void BakedIndirectLightGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
- Vector3 restore = p_restore;
-
- if (p_cancel) {
- baker->set_extents(restore);
- return;
- }
-
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Probe Extents"));
- ur->add_do_method(baker, "set_extents", baker->get_extents());
- ur->add_undo_method(baker, "set_extents", restore);
- ur->commit_action();
+bool NavigationMeshSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<NavigationMeshInstance>(p_spatial) != NULL;
}
-void BakedIndirectLightGizmo::redraw() {
-
- Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/baked_indirect_light");
- Ref<Material> material = create_material("baked_indirect_light_material", gizmo_color);
- Ref<Material> icon = create_icon_material("baked_indirect_light_icon", SpatialEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons"));
- Color gizmo_color_internal = gizmo_color;
- gizmo_color_internal.a = 0.1;
- Ref<Material> material_internal = create_material("baked_indirect_light_internal_material", gizmo_color_internal);
-
- clear();
-
- Vector<Vector3> lines;
- Vector3 extents = baker->get_extents();
-
- AABB aabb = AABB(-extents, extents * 2);
-
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
-
- add_lines(lines, material);
- add_collision_segments(lines);
-
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
-
- if (is_selected()) {
-
- gizmo_color.a = 0.1;
- Ref<Material> solid_material = create_material("baked_indirect_light_solid_material", gizmo_color);
- add_solid_box(solid_material, aabb.get_size());
- }
-
- add_unscaled_billboard(icon, 0.05);
- add_handles(handles);
+String NavigationMeshSpatialGizmoPlugin::get_name() const {
+ return "NavigationMeshInstance";
}
-BakedIndirectLightGizmo::BakedIndirectLightGizmo(BakedLightmap *p_baker) {
- baker = p_baker;
- set_spatial_node(p_baker);
-}
+void NavigationMeshSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
-////////
-void NavigationMeshSpatialGizmo::redraw() {
+ NavigationMeshInstance *navmesh = Object::cast_to<NavigationMeshInstance>(p_gizmo->get_spatial_node());
- Ref<Material> edge_material = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_edge"));
- Ref<Material> edge_material_disabled = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled"));
- Ref<Material> solid_material = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_solid"));
- Ref<Material> solid_material_disabled = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled"));
+ Ref<Material> edge_material = get_material("navigation_material", p_gizmo);
+ Ref<Material> edge_material_disabled = get_material("navigation_material", p_gizmo);
+ Ref<Material> solid_material = get_material("navigation_material", p_gizmo);
+ Ref<Material> solid_material_disabled = get_material("navigation_material", p_gizmo);
- clear();
+ p_gizmo->clear();
Ref<NavigationMesh> navmeshie = navmesh->get_navigation_mesh();
if (navmeshie.is_null())
return;
@@ -3353,28 +3569,19 @@ void NavigationMeshSpatialGizmo::redraw() {
tmesh->create(tmeshfaces);
if (lines.size())
- add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled);
- add_collision_triangles(tmesh);
+ p_gizmo->add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled);
+ p_gizmo->add_collision_triangles(tmesh);
Ref<ArrayMesh> m = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
a[0] = tmeshfaces;
m->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a);
m->surface_set_material(0, navmesh->is_enabled() ? solid_material : solid_material_disabled);
- add_mesh(m);
- add_collision_segments(lines);
-}
-
-NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh) {
-
- set_spatial_node(p_navmesh);
- navmesh = p_navmesh;
+ p_gizmo->add_mesh(m);
+ p_gizmo->add_collision_segments(lines);
}
//////
-///
-///
-///
#define BODY_A_RADIUS 0.25
#define BODY_B_RADIUS 0.27
@@ -3625,38 +3832,169 @@ void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base
}
}
-void PinJointSpatialGizmo::CreateGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points) {
- float cs = 0.25;
+////
- r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin);
- r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin);
- r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin);
- r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin);
- r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin);
- r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin);
+JointSpatialGizmoPlugin::JointSpatialGizmoPlugin() {
+ create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
+ create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1)));
+ create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1)));
}
-void PinJointSpatialGizmo::redraw() {
+bool JointSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<Joint>(p_spatial) != NULL;
+}
- clear();
- Vector<Vector3> cursor_points;
- CreateGizmo(Transform(), cursor_points);
- add_collision_segments(cursor_points);
+String JointSpatialGizmoPlugin::get_name() const {
+ return "Joints";
+}
- Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
+void JointSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+ Joint *joint = Object::cast_to<Joint>(p_gizmo->get_spatial_node());
- add_lines(cursor_points, material);
-}
+ p_gizmo->clear();
-PinJointSpatialGizmo::PinJointSpatialGizmo(PinJoint *p_p3d) {
+ const Spatial *node_body_a = Object::cast_to<Spatial>(joint->get_node(joint->get_node_a()));
+ const Spatial *node_body_b = Object::cast_to<Spatial>(joint->get_node(joint->get_node_b()));
- p3d = p_p3d;
- set_spatial_node(p3d);
-}
+ Ref<Material> common_material = get_material("joint_material", p_gizmo);
+ Ref<Material> body_a_material = get_material("joint_body_a_material", p_gizmo);
+ Ref<Material> body_b_material = get_material("joint_body_b_material", p_gizmo);
-////
+ Vector<Vector3> points;
+ Vector<Vector3> body_a_points;
+ Vector<Vector3> body_b_points;
-void HingeJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
+ if (Object::cast_to<PinJoint>(joint)) {
+ CreatePinJointGizmo(Transform(), points);
+ p_gizmo->add_collision_segments(points);
+ p_gizmo->add_lines(points, common_material);
+ }
+
+ HingeJoint *hinge = Object::cast_to<HingeJoint>(joint);
+ if (hinge) {
+
+ CreateHingeJointGizmo(
+ Transform(),
+ hinge->get_global_transform(),
+ node_body_a ? node_body_a->get_global_transform() : Transform(),
+ node_body_b ? node_body_b->get_global_transform() : Transform(),
+ hinge->get_param(HingeJoint::PARAM_LIMIT_LOWER),
+ hinge->get_param(HingeJoint::PARAM_LIMIT_UPPER),
+ hinge->get_flag(HingeJoint::FLAG_USE_LIMIT),
+ points,
+ node_body_a ? &body_a_points : NULL,
+ node_body_b ? &body_b_points : NULL);
+
+ p_gizmo->add_collision_segments(points);
+ p_gizmo->add_collision_segments(body_a_points);
+ p_gizmo->add_collision_segments(body_b_points);
+
+ p_gizmo->add_lines(points, common_material);
+ p_gizmo->add_lines(body_a_points, body_a_material);
+ p_gizmo->add_lines(body_b_points, body_b_material);
+ }
+
+ SliderJoint *slider = Object::cast_to<SliderJoint>(joint);
+ if (slider) {
+
+ CreateSliderJointGizmo(
+ Transform(),
+ slider->get_global_transform(),
+ node_body_a ? node_body_a->get_global_transform() : Transform(),
+ node_body_b ? node_body_b->get_global_transform() : Transform(),
+ slider->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER),
+ slider->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER),
+ slider->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER),
+ slider->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER),
+ points,
+ node_body_a ? &body_a_points : NULL,
+ node_body_b ? &body_b_points : NULL);
+
+ p_gizmo->add_collision_segments(points);
+ p_gizmo->add_collision_segments(body_a_points);
+ p_gizmo->add_collision_segments(body_b_points);
+
+ p_gizmo->add_lines(points, common_material);
+ p_gizmo->add_lines(body_a_points, body_a_material);
+ p_gizmo->add_lines(body_b_points, body_b_material);
+ }
+
+ ConeTwistJoint *cone = Object::cast_to<ConeTwistJoint>(joint);
+ if (cone) {
+
+ CreateConeTwistJointGizmo(
+ Transform(),
+ cone->get_global_transform(),
+ node_body_a ? node_body_a->get_global_transform() : Transform(),
+ node_body_b ? node_body_b->get_global_transform() : Transform(),
+ cone->get_param(ConeTwistJoint::PARAM_SWING_SPAN),
+ cone->get_param(ConeTwistJoint::PARAM_TWIST_SPAN),
+ node_body_a ? &body_a_points : NULL,
+ node_body_b ? &body_b_points : NULL);
+
+ p_gizmo->add_collision_segments(body_a_points);
+ p_gizmo->add_collision_segments(body_b_points);
+
+ p_gizmo->add_lines(body_a_points, body_a_material);
+ p_gizmo->add_lines(body_b_points, body_b_material);
+ }
+
+ Generic6DOFJoint *gen = Object::cast_to<Generic6DOFJoint>(joint);
+ if (gen) {
+
+ CreateGeneric6DOFJointGizmo(
+ Transform(),
+ gen->get_global_transform(),
+ node_body_a ? node_body_a->get_global_transform() : Transform(),
+ node_body_b ? node_body_b->get_global_transform() : Transform(),
+
+ gen->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT),
+ gen->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT),
+ gen->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT),
+ gen->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT),
+ gen->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT),
+ gen->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT),
+
+ gen->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT),
+ gen->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT),
+ gen->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT),
+ gen->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT),
+ gen->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT),
+ gen->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT),
+
+ gen->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT),
+ gen->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT),
+ gen->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT),
+ gen->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT),
+ gen->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT),
+ gen->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT),
+
+ points,
+ node_body_a ? &body_a_points : NULL,
+ node_body_a ? &body_b_points : NULL);
+
+ p_gizmo->add_collision_segments(points);
+ p_gizmo->add_collision_segments(body_a_points);
+ p_gizmo->add_collision_segments(body_b_points);
+
+ p_gizmo->add_lines(points, common_material);
+ p_gizmo->add_lines(body_a_points, body_a_material);
+ p_gizmo->add_lines(body_b_points, body_b_material);
+ }
+}
+
+void JointSpatialGizmoPlugin::CreatePinJointGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points) {
+ float cs = 0.25;
+
+ r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin);
+ r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin);
+ r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin);
+ r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin);
+ r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin);
+ r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin);
+}
+
+void JointSpatialGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin);
r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin);
@@ -3688,52 +4026,7 @@ void HingeJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transf
}
}
-void HingeJointSpatialGizmo::redraw() {
-
- const Spatial *node_body_a = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_a()));
- const Spatial *node_body_b = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_b()));
-
- Vector<Vector3> points;
- Vector<Vector3> body_a_points;
- Vector<Vector3> body_b_points;
- CreateGizmo(
- Transform(),
- p3d->get_global_transform(),
- node_body_a ? node_body_a->get_global_transform() : Transform(),
- node_body_b ? node_body_b->get_global_transform() : Transform(),
- p3d->get_param(HingeJoint::PARAM_LIMIT_LOWER),
- p3d->get_param(HingeJoint::PARAM_LIMIT_UPPER),
- p3d->get_flag(HingeJoint::FLAG_USE_LIMIT),
- points,
- node_body_a ? &body_a_points : NULL,
- node_body_b ? &body_b_points : NULL);
-
- clear();
-
- Ref<Material> common_material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
- Ref<Material> body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a"));
- Ref<Material> body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b"));
-
- add_collision_segments(points);
- add_collision_segments(body_a_points);
- add_collision_segments(body_b_points);
-
- add_lines(points, common_material);
- add_lines(body_a_points, body_a_material);
- add_lines(body_b_points, body_b_material);
-}
-
-HingeJointSpatialGizmo::HingeJointSpatialGizmo(HingeJoint *p_p3d) {
-
- p3d = p_p3d;
- set_spatial_node(p3d);
-}
-
-///////
-///
-////
-
-void SliderJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
+void JointSpatialGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
p_linear_limit_lower = -p_linear_limit_lower;
p_linear_limit_upper = -p_linear_limit_upper;
@@ -3793,53 +4086,7 @@ void SliderJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Trans
true);
}
-void SliderJointSpatialGizmo::redraw() {
-
- const Spatial *node_body_a = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_a()));
- const Spatial *node_body_b = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_b()));
-
- clear();
- Vector<Vector3> cursor_points;
- Vector<Vector3> body_a_points;
- Vector<Vector3> body_b_points;
-
- CreateGizmo(
- Transform(),
- p3d->get_global_transform(),
- node_body_a ? node_body_a->get_global_transform() : Transform(),
- node_body_b ? node_body_b->get_global_transform() : Transform(),
- p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER),
- p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER),
- p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER),
- p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER),
- cursor_points,
- node_body_a ? &body_a_points : NULL,
- node_body_b ? &body_b_points : NULL);
-
- Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
- Ref<Material> body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a"));
- Ref<Material> body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b"));
-
- add_collision_segments(cursor_points);
- add_collision_segments(body_a_points);
- add_collision_segments(body_b_points);
-
- add_lines(cursor_points, material);
- add_lines(body_a_points, body_a_material);
- add_lines(body_b_points, body_b_material);
-}
-
-SliderJointSpatialGizmo::SliderJointSpatialGizmo(SliderJoint *p_p3d) {
-
- p3d = p_p3d;
- set_spatial_node(p3d);
-}
-
-///////
-///
-////
-
-void ConeTwistJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
+void JointSpatialGizmoPlugin::CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
if (r_body_a_points)
JointGizmosDrawer::draw_cone(
@@ -3858,51 +4105,7 @@ void ConeTwistJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Tr
*r_body_b_points);
}
-void ConeTwistJointSpatialGizmo::redraw() {
-
- const Spatial *node_body_a = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_a()));
- const Spatial *node_body_b = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_b()));
-
- clear();
- Vector<Vector3> points;
- Vector<Vector3> body_a_points;
- Vector<Vector3> body_b_points;
-
- CreateGizmo(
- Transform(),
- p3d->get_global_transform(),
- node_body_a ? node_body_a->get_global_transform() : Transform(),
- node_body_b ? node_body_b->get_global_transform() : Transform(),
- p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN),
- p3d->get_param(ConeTwistJoint::PARAM_TWIST_SPAN),
- points,
- node_body_a ? &body_a_points : NULL,
- node_body_b ? &body_b_points : NULL);
-
- Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
- Ref<Material> body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a"));
- Ref<Material> body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b"));
-
- add_collision_segments(points);
- add_collision_segments(body_a_points);
- add_collision_segments(body_b_points);
-
- add_lines(points, material);
- add_lines(body_a_points, body_a_material);
- add_lines(body_b_points, body_b_material);
-}
-
-ConeTwistJointSpatialGizmo::ConeTwistJointSpatialGizmo(ConeTwistJoint *p_p3d) {
-
- p3d = p_p3d;
- set_spatial_node(p3d);
-}
-
-///////
-///
-////
-
-void Generic6DOFJointSpatialGizmo::CreateGizmo(
+void JointSpatialGizmoPlugin::CreateGeneric6DOFJointGizmo(
const Transform &p_offset,
const Transform &p_trs_joint,
const Transform &p_trs_body_a,
@@ -4051,510 +4254,3 @@ void Generic6DOFJointSpatialGizmo::CreateGizmo(
#undef ADD_VTX
}
-
-void Generic6DOFJointSpatialGizmo::redraw() {
-
- const Spatial *node_body_a = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_a()));
- const Spatial *node_body_b = Object::cast_to<Spatial>(p3d->get_node(p3d->get_node_b()));
-
- clear();
- Vector<Vector3> cursor_points;
- Vector<Vector3> body_a_points;
- Vector<Vector3> body_b_points;
-
- CreateGizmo(
- Transform(),
- p3d->get_global_transform(),
- node_body_a ? node_body_a->get_global_transform() : Transform(),
- node_body_b ? node_body_b->get_global_transform() : Transform(),
-
- p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT),
- p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT),
- p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT),
- p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT),
- p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT),
- p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT),
-
- p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT),
- p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT),
- p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT),
- p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT),
- p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT),
- p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT),
-
- p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT),
- p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT),
- p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT),
- p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT),
- p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT),
- p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT),
-
- cursor_points,
- node_body_a ? &body_a_points : NULL,
- node_body_a ? &body_b_points : NULL);
-
- Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
- Ref<Material> body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a"));
- Ref<Material> body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b"));
-
- add_collision_segments(cursor_points);
- add_collision_segments(body_a_points);
- add_collision_segments(body_b_points);
-
- add_lines(cursor_points, material);
- add_lines(body_a_points, body_a_material);
- add_lines(body_b_points, body_b_material);
-}
-
-Generic6DOFJointSpatialGizmo::Generic6DOFJointSpatialGizmo(Generic6DOFJoint *p_p3d) {
-
- p3d = p_p3d;
- set_spatial_node(p3d);
-}
-
-///////
-///
-////
-
-SpatialEditorGizmos *SpatialEditorGizmos::singleton = NULL;
-
-Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
-
- if (Object::cast_to<Light>(p_spatial)) {
-
- Ref<LightSpatialGizmo> lsg = memnew(LightSpatialGizmo(Object::cast_to<Light>(p_spatial)));
- return lsg;
- }
-
- if (Object::cast_to<Camera>(p_spatial)) {
-
- Ref<CameraSpatialGizmo> lsg = memnew(CameraSpatialGizmo(Object::cast_to<Camera>(p_spatial)));
- return lsg;
- }
-
- if (Object::cast_to<Skeleton>(p_spatial)) {
-
- Ref<SkeletonSpatialGizmo> lsg = memnew(SkeletonSpatialGizmo(Object::cast_to<Skeleton>(p_spatial)));
- return lsg;
- }
-
- if (Object::cast_to<PhysicalBone>(p_spatial)) {
-
- Ref<PhysicalBoneSpatialGizmo> pbsg = memnew(PhysicalBoneSpatialGizmo(Object::cast_to<PhysicalBone>(p_spatial)));
- return pbsg;
- }
-
- if (Object::cast_to<Position3D>(p_spatial)) {
-
- Ref<Position3DSpatialGizmo> lsg = memnew(Position3DSpatialGizmo(Object::cast_to<Position3D>(p_spatial)));
- return lsg;
- }
-
- if (Object::cast_to<SoftBody>(p_spatial)) {
-
- Ref<SoftBodySpatialGizmo> misg = memnew(SoftBodySpatialGizmo(Object::cast_to<SoftBody>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<MeshInstance>(p_spatial)) {
-
- Ref<MeshInstanceSpatialGizmo> misg = memnew(MeshInstanceSpatialGizmo(Object::cast_to<MeshInstance>(p_spatial)));
- return misg;
- }
-
- /*if (Object::cast_to<Room>(p_spatial)) {
-
- Ref<RoomSpatialGizmo> misg = memnew(RoomSpatialGizmo(Object::cast_to<Room>(p_spatial)));
- return misg;
- }*/
-
- if (Object::cast_to<NavigationMeshInstance>(p_spatial)) {
-
- Ref<NavigationMeshSpatialGizmo> misg = memnew(NavigationMeshSpatialGizmo(Object::cast_to<NavigationMeshInstance>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<RayCast>(p_spatial)) {
-
- Ref<RayCastSpatialGizmo> misg = memnew(RayCastSpatialGizmo(Object::cast_to<RayCast>(p_spatial)));
- return misg;
- }
- /*
- if (Object::cast_to<Portal>(p_spatial)) {
-
- Ref<PortalSpatialGizmo> misg = memnew(PortalSpatialGizmo(Object::cast_to<Portal>(p_spatial)));
- return misg;
- }
-*/
-
- if (Object::cast_to<CollisionShape>(p_spatial)) {
-
- Ref<CollisionShapeSpatialGizmo> misg = memnew(CollisionShapeSpatialGizmo(Object::cast_to<CollisionShape>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<VisibilityNotifier>(p_spatial)) {
-
- Ref<VisibilityNotifierGizmo> misg = memnew(VisibilityNotifierGizmo(Object::cast_to<VisibilityNotifier>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<Particles>(p_spatial)) {
-
- Ref<ParticlesGizmo> misg = memnew(ParticlesGizmo(Object::cast_to<Particles>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<ReflectionProbe>(p_spatial)) {
-
- Ref<ReflectionProbeGizmo> misg = memnew(ReflectionProbeGizmo(Object::cast_to<ReflectionProbe>(p_spatial)));
- return misg;
- }
- if (Object::cast_to<GIProbe>(p_spatial)) {
-
- Ref<GIProbeGizmo> misg = memnew(GIProbeGizmo(Object::cast_to<GIProbe>(p_spatial)));
- return misg;
- }
- if (Object::cast_to<BakedLightmap>(p_spatial)) {
-
- Ref<BakedIndirectLightGizmo> misg = memnew(BakedIndirectLightGizmo(Object::cast_to<BakedLightmap>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<VehicleWheel>(p_spatial)) {
-
- Ref<VehicleWheelSpatialGizmo> misg = memnew(VehicleWheelSpatialGizmo(Object::cast_to<VehicleWheel>(p_spatial)));
- return misg;
- }
- if (Object::cast_to<PinJoint>(p_spatial)) {
-
- Ref<PinJointSpatialGizmo> misg = memnew(PinJointSpatialGizmo(Object::cast_to<PinJoint>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<HingeJoint>(p_spatial)) {
-
- Ref<HingeJointSpatialGizmo> misg = memnew(HingeJointSpatialGizmo(Object::cast_to<HingeJoint>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<SliderJoint>(p_spatial)) {
-
- Ref<SliderJointSpatialGizmo> misg = memnew(SliderJointSpatialGizmo(Object::cast_to<SliderJoint>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<ConeTwistJoint>(p_spatial)) {
-
- Ref<ConeTwistJointSpatialGizmo> misg = memnew(ConeTwistJointSpatialGizmo(Object::cast_to<ConeTwistJoint>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<Generic6DOFJoint>(p_spatial)) {
-
- Ref<Generic6DOFJointSpatialGizmo> misg = memnew(Generic6DOFJointSpatialGizmo(Object::cast_to<Generic6DOFJoint>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<CollisionPolygon>(p_spatial)) {
-
- Ref<CollisionPolygonSpatialGizmo> misg = memnew(CollisionPolygonSpatialGizmo(Object::cast_to<CollisionPolygon>(p_spatial)));
- return misg;
- }
-
- if (Object::cast_to<AudioStreamPlayer3D>(p_spatial)) {
-
- Ref<AudioStreamPlayer3DSpatialGizmo> misg = memnew(AudioStreamPlayer3DSpatialGizmo(Object::cast_to<AudioStreamPlayer3D>(p_spatial)));
- return misg;
- }
-
- return Ref<SpatialEditorGizmo>();
-}
-
-SpatialEditorGizmos::SpatialEditorGizmos() {
-
- singleton = this;
-
- handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- handle_material->set_on_top_of_alpha();
- handle_material->set_albedo(Color(0.8, 0.8, 0.8));
- handle_material_billboard = handle_material->duplicate();
- handle_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
-
- handle2_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- handle2_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- handle2_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
- handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons");
- handle2_material->set_point_size(handle_t->get_width());
- handle2_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle_t);
- handle2_material->set_albedo(Color(1, 1, 1));
- handle2_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- handle2_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- handle2_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- handle2_material->set_on_top_of_alpha();
- handle2_material_billboard = handle2_material->duplicate();
- handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
- handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
- handle2_material_billboard->set_on_top_of_alpha();
-
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/visibility_notifier", Color(0.8, 0.5, 0.7));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/baked_indirect_light", Color(0.5, 0.6, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge", Color(0.5, 1, 1));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled", Color(0.7, 0.7, 0.7));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid", Color(0.5, 1, 1, 0.4));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled", Color(0.7, 0.7, 0.7, 0.4));
- EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5));
-
-#if 0
- light_material = create_line_material(Color(1, 1, 0.2));
- light_material_omni = create_line_material(Color(1, 1, 0.2));
- light_material_omni->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
-
- light_material_omni_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- light_material_omni_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- light_material_omni_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- light_material_omni_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
- light_material_omni_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- light_material_omni_icon->set_albedo(Color(1, 1, 1, 0.9));
- light_material_omni_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
- light_material_omni_icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true);
- light_material_omni_icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
-
- light_material_directional_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- light_material_directional_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- light_material_directional_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- light_material_directional_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
- light_material_directional_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- light_material_directional_icon->set_albedo(Color(1, 1, 1, 0.9));
- light_material_directional_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
- light_material_directional_icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
- light_material_directional_icon->set_depth_scale(1);
-
- camera_material = create_line_material(Color(1.0, 0.5, 1.0));
-
- navmesh_edge_material = create_line_material(Color(0.1, 0.8, 1.0));
- navmesh_solid_material = create_solid_material(Color(0.1, 0.8, 1.0, 0.4));
- navmesh_edge_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
- navmesh_edge_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
- navmesh_solid_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
-
- navmesh_edge_material_disabled = create_line_material(Color(1.0, 0.8, 0.1));
- navmesh_solid_material_disabled = create_solid_material(Color(1.0, 0.8, 0.1, 0.4));
- navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
- navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
- navmesh_solid_material_disabled->set_cull_mode(SpatialMaterial::CULL_DISABLED);
-
- skeleton_material = create_line_material(Color(0.6, 1.0, 0.3));
- skeleton_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- skeleton_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- skeleton_material->set_on_top_of_alpha();
- skeleton_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
-
- //position 3D Shared mesh
-
- pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- {
-
- PoolVector<Vector3> cursor_points;
- PoolVector<Color> cursor_colors;
- float cs = 0.25;
- cursor_points.push_back(Vector3(+cs, 0, 0));
- cursor_points.push_back(Vector3(-cs, 0, 0));
- cursor_points.push_back(Vector3(0, +cs, 0));
- cursor_points.push_back(Vector3(0, -cs, 0));
- cursor_points.push_back(Vector3(0, 0, +cs));
- cursor_points.push_back(Vector3(0, 0, -cs));
- cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
- cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
- cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
-
- Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
- mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_line_width(3);
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[Mesh::ARRAY_VERTEX] = cursor_points;
- d[Mesh::ARRAY_COLOR] = cursor_colors;
- pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
- pos3d_mesh->surface_set_material(0, mat);
- }
-
- listener_line_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- {
-
- PoolVector<Vector3> cursor_points;
- PoolVector<Color> cursor_colors;
- cursor_points.push_back(Vector3(0, 0, 0));
- cursor_points.push_back(Vector3(0, 0, -1.0));
- cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
-
- Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
- mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_line_width(3);
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[Mesh::ARRAY_VERTEX] = cursor_points;
- d[Mesh::ARRAY_COLOR] = cursor_colors;
- listener_line_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
- listener_line_mesh->surface_set_material(0, mat);
- }
-
- room_material = create_line_material(Color(1.0, 0.6, 0.9));
- portal_material = create_line_material(Color(1.0, 0.8, 0.6));
- raycast_material = create_line_material(Color(1.0, 0.8, 0.6));
- car_wheel_material = create_line_material(Color(0.6, 0.8, 1.0));
- visibility_notifier_material = create_line_material(Color(1.0, 0.5, 1.0));
- particles_material = create_line_material(Color(1.0, 1.0, 0.5));
- reflection_probe_material = create_line_material(Color(0.5, 1.0, 0.7));
- reflection_probe_material_internal = create_line_material(Color(0.3, 0.8, 0.5, 0.15));
- gi_probe_material = create_line_material(Color(0.7, 1.0, 0.5));
- gi_probe_material_internal = create_line_material(Color(0.5, 0.8, 0.3, 0.1));
- joint_material = create_line_material(Color(0.6, 0.8, 1.0));
-
- stream_player_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- stream_player_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- stream_player_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- stream_player_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
- stream_player_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- stream_player_icon->set_albedo(Color(1, 1, 1, 0.9));
- stream_player_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer", "EditorIcons"));
-
- visibility_notifier_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- visibility_notifier_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- visibility_notifier_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- visibility_notifier_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
- visibility_notifier_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- visibility_notifier_icon->set_albedo(Color(1, 1, 1, 0.9));
- visibility_notifier_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("Visible", "EditorIcons"));
-
- listener_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- listener_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- listener_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- listener_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
- listener_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- listener_icon->set_albedo(Color(1, 1, 1, 0.9));
- listener_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons"));
-
- {
-
- PoolVector<Vector3> vertices;
-
-#undef ADD_VTX
-#define ADD_VTX(m_idx) \
- vertices.push_back(face_points[m_idx]);
-
- for (int i = 0; i < 6; i++) {
-
- Vector3 face_points[4];
-
- for (int j = 0; j < 4; j++) {
-
- float v[3];
- v[0] = 1.0;
- v[1] = 1 - 2 * ((j >> 1) & 1);
- v[2] = v[1] * (1 - 2 * (j & 1));
-
- for (int k = 0; k < 3; k++) {
-
- if (i < 3)
- face_points[j][(i + k) % 3] = v[k];
- else
- face_points[3 - j][(i + k) % 3] = -v[k];
- }
- }
- //tri 1
- ADD_VTX(0);
- ADD_VTX(1);
- ADD_VTX(2);
- //tri 2
- ADD_VTX(2);
- ADD_VTX(3);
- ADD_VTX(0);
- }
-
- test_cube_tm = Ref<TriangleMesh>(memnew(TriangleMesh));
- test_cube_tm->create(vertices);
- }
-
- shape_material = create_line_material(Color(0.2, 1, 1.0));
-#endif
-
- pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- {
-
- PoolVector<Vector3> cursor_points;
- PoolVector<Color> cursor_colors;
- float cs = 0.25;
- cursor_points.push_back(Vector3(+cs, 0, 0));
- cursor_points.push_back(Vector3(-cs, 0, 0));
- cursor_points.push_back(Vector3(0, +cs, 0));
- cursor_points.push_back(Vector3(0, -cs, 0));
- cursor_points.push_back(Vector3(0, 0, +cs));
- cursor_points.push_back(Vector3(0, 0, -cs));
- cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
- cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
- cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
-
- Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
- mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_line_width(3);
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[Mesh::ARRAY_VERTEX] = cursor_points;
- d[Mesh::ARRAY_COLOR] = cursor_colors;
- pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
- pos3d_mesh->surface_set_material(0, mat);
- }
-
- listener_line_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- {
-
- PoolVector<Vector3> cursor_points;
- PoolVector<Color> cursor_colors;
- cursor_points.push_back(Vector3(0, 0, 0));
- cursor_points.push_back(Vector3(0, 0, -1.0));
- cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
- cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
-
- Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
- mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_line_width(3);
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[Mesh::ARRAY_VERTEX] = cursor_points;
- d[Mesh::ARRAY_COLOR] = cursor_colors;
- listener_line_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
- listener_line_mesh->surface_set_material(0, mat);
- }
-}
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index 198d028516..877590b91d 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -55,187 +55,120 @@
class Camera;
-class EditorSpatialGizmo : public SpatialEditorGizmo {
+class LightSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- GDCLASS(EditorSpatialGizmo, SpatialGizmo);
+ GDCLASS(LightSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
- struct Instance {
-
- RID instance;
- Ref<ArrayMesh> mesh;
- RID skeleton;
- bool billboard;
- bool unscaled;
- bool can_intersect;
- bool extra_margin;
- Instance() {
-
- billboard = false;
- unscaled = false;
- can_intersect = false;
- extra_margin = false;
- }
-
- void create_instance(Spatial *p_base);
- };
-
- Vector<Vector3> collision_segments;
- Ref<TriangleMesh> collision_mesh;
-
- struct Handle {
- Vector3 pos;
- bool billboard;
- };
-
- Vector<Vector3> handles;
- Vector<Vector3> secondary_handles;
- float selectable_icon_size = -1.0f;
- bool billboard_handle;
+public:
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
- bool valid;
- Spatial *base;
- Vector<Instance> instances;
- Spatial *spatial_node;
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Spatial>(p_node)); }
+ LightSpatialGizmoPlugin();
+};
-protected:
- void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false);
- void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
- void add_collision_segments(const Vector<Vector3> &p_lines);
- void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
- void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1);
- void add_handles(const Vector<Vector3> &p_handles, bool p_billboard = false, bool p_secondary = false);
- void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3());
+class AudioStreamPlayer3DSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- void set_spatial_node(Spatial *p_node);
- const Spatial *get_spatial_node() const { return spatial_node; }
+ GDCLASS(AudioStreamPlayer3DSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
- static void _bind_methods();
+public:
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
- Ref<SpatialMaterial> create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false);
- Ref<SpatialMaterial> create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1));
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+ void redraw(EditorSpatialGizmo *p_gizmo);
-public:
- virtual Vector3 get_handle_pos(int p_idx) const;
- virtual bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum);
- virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false);
-
- void clear();
- void create();
- void transform();
- virtual void redraw();
- void free();
- virtual bool is_editable() const;
- virtual bool can_draw() const;
-
- EditorSpatialGizmo();
- ~EditorSpatialGizmo();
+ AudioStreamPlayer3DSpatialGizmoPlugin();
};
-class LightSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(LightSpatialGizmo, EditorSpatialGizmo);
+class CameraSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- Light *light;
+ GDCLASS(CameraSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
- void redraw();
- LightSpatialGizmo(Light *p_light = NULL);
-};
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+ void redraw(EditorSpatialGizmo *p_gizmo);
-class AudioStreamPlayer3DSpatialGizmo : public EditorSpatialGizmo {
+ CameraSpatialGizmoPlugin();
+};
- GDCLASS(AudioStreamPlayer3DSpatialGizmo, EditorSpatialGizmo);
+class MeshInstanceSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- AudioStreamPlayer3D *player;
+ GDCLASS(MeshInstanceSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ bool can_be_hidden() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player = NULL);
+ MeshInstanceSpatialGizmoPlugin();
};
-class CameraSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(CameraSpatialGizmo, EditorSpatialGizmo);
+class Sprite3DSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- Camera *camera;
+ GDCLASS(Sprite3DSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ bool can_be_hidden() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- CameraSpatialGizmo(Camera *p_camera = NULL);
+ Sprite3DSpatialGizmoPlugin();
};
-class MeshInstanceSpatialGizmo : public EditorSpatialGizmo {
+class Position3DSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- GDCLASS(MeshInstanceSpatialGizmo, EditorSpatialGizmo);
+ GDCLASS(Position3DSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
- MeshInstance *mesh;
+ Ref<ArrayMesh> pos3d_mesh;
+ Vector<Vector3> cursor_points;
public:
- virtual bool can_draw() const;
- void redraw();
- MeshInstanceSpatialGizmo(MeshInstance *p_mesh = NULL);
-};
-
-class Sprite3DSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(Sprite3DSpatialGizmo, EditorSpatialGizmo);
-
- SpriteBase3D *sprite;
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
-public:
- virtual bool can_draw() const;
- void redraw();
- Sprite3DSpatialGizmo(SpriteBase3D *p_sprite = NULL);
+ Position3DSpatialGizmoPlugin();
};
-class Position3DSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(Position3DSpatialGizmo, EditorSpatialGizmo);
+class SkeletonSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- Position3D *p3d;
+ GDCLASS(SkeletonSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- void redraw();
- Position3DSpatialGizmo(Position3D *p_p3d = NULL);
-};
-
-class SkeletonSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(SkeletonSpatialGizmo, EditorSpatialGizmo);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- Skeleton *skel;
-
-public:
- void redraw();
- SkeletonSpatialGizmo(Skeleton *p_skel = NULL);
+ SkeletonSpatialGizmoPlugin();
};
-class PhysicalBoneSpatialGizmo : public EditorSpatialGizmo {
- GDCLASS(PhysicalBoneSpatialGizmo, EditorSpatialGizmo);
+class PhysicalBoneSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- PhysicalBone *physical_bone;
+ GDCLASS(PhysicalBoneSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- //virtual Transform get_global_gizmo_transform();
- virtual void redraw();
- PhysicalBoneSpatialGizmo(PhysicalBone *p_pb = NULL);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+
+ PhysicalBoneSpatialGizmoPlugin();
};
#if 0
@@ -251,154 +184,166 @@ public:
};
#endif
-class VisibilityNotifierGizmo : public EditorSpatialGizmo {
-
- GDCLASS(VisibilityNotifierGizmo, EditorSpatialGizmo);
+class RayCastSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- VisibilityNotifier *notifier;
+ GDCLASS(RayCastSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- VisibilityNotifierGizmo(VisibilityNotifier *p_notifier = NULL);
+ RayCastSpatialGizmoPlugin();
};
-class ParticlesGizmo : public EditorSpatialGizmo {
-
- GDCLASS(ParticlesGizmo, EditorSpatialGizmo);
+class VehicleWheelSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- Particles *particles;
+ GDCLASS(VehicleWheelSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- ParticlesGizmo(Particles *p_particles = NULL);
+ VehicleWheelSpatialGizmoPlugin();
};
-class ReflectionProbeGizmo : public EditorSpatialGizmo {
-
- GDCLASS(ReflectionProbeGizmo, EditorSpatialGizmo);
+class SoftBodySpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- ReflectionProbe *probe;
+ GDCLASS(SoftBodySpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ bool is_selectable_when_hidden() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- ReflectionProbeGizmo(ReflectionProbe *p_probe = NULL);
-};
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel);
+ bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const;
-class GIProbeGizmo : public EditorSpatialGizmo {
+ SoftBodySpatialGizmoPlugin();
+};
- GDCLASS(GIProbeGizmo, EditorSpatialGizmo);
+class VisibilityNotifierGizmoPlugin : public EditorSpatialGizmoPlugin {
- GIProbe *probe;
+ GDCLASS(VisibilityNotifierGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- GIProbeGizmo(GIProbe *p_probe = NULL);
-};
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
-class BakedIndirectLightGizmo : public EditorSpatialGizmo {
+ VisibilityNotifierGizmoPlugin();
+};
- GDCLASS(BakedIndirectLightGizmo, EditorSpatialGizmo);
+class ParticlesGizmoPlugin : public EditorSpatialGizmoPlugin {
- BakedLightmap *baker;
+ GDCLASS(ParticlesGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ bool is_selectable_when_hidden() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- void redraw();
- BakedIndirectLightGizmo(BakedLightmap *p_baker = NULL);
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+
+ ParticlesGizmoPlugin();
};
-class SoftBodySpatialGizmo : public EditorSpatialGizmo {
- GDCLASS(SoftBodySpatialGizmo, EditorSpatialGizmo);
+class ReflectionProbeGizmoPlugin : public EditorSpatialGizmoPlugin {
- class SoftBody *soft_body;
- //RID physics_sphere_shape; // Used for raycast that doesn't work, in this moment, with softbody
+ GDCLASS(ReflectionProbeGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- void redraw();
- virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
- virtual bool is_gizmo_handle_highlighted(int idx) const;
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
- SoftBodySpatialGizmo(SoftBody *p_soft_physics_body = NULL);
- ~SoftBodySpatialGizmo();
+ ReflectionProbeGizmoPlugin();
};
-class CollisionShapeSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(CollisionShapeSpatialGizmo, EditorSpatialGizmo);
+class GIProbeGizmoPlugin : public EditorSpatialGizmoPlugin {
- CollisionShape *cs;
+ GDCLASS(GIProbeGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
- void redraw();
- CollisionShapeSpatialGizmo(CollisionShape *p_cs = NULL);
-};
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
-class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo {
+ GIProbeGizmoPlugin();
+};
- GDCLASS(CollisionPolygonSpatialGizmo, EditorSpatialGizmo);
+class BakedIndirectLightGizmoPlugin : public EditorSpatialGizmoPlugin {
- CollisionPolygon *polygon;
+ GDCLASS(BakedIndirectLightGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- void redraw();
- CollisionPolygonSpatialGizmo(CollisionPolygon *p_polygon = NULL);
-};
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
-class RayCastSpatialGizmo : public EditorSpatialGizmo {
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+
+ BakedIndirectLightGizmoPlugin();
+};
- GDCLASS(RayCastSpatialGizmo, EditorSpatialGizmo);
+class CollisionShapeSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- RayCast *raycast;
+ GDCLASS(CollisionShapeSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- void redraw();
- RayCastSpatialGizmo(RayCast *p_raycast = NULL);
-};
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+
+ String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
-class VehicleWheelSpatialGizmo : public EditorSpatialGizmo {
+ CollisionShapeSpatialGizmoPlugin();
+};
- GDCLASS(VehicleWheelSpatialGizmo, EditorSpatialGizmo);
+class CollisionPolygonSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- VehicleWheel *car_wheel;
+ GDCLASS(CollisionPolygonSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- void redraw();
- VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel = NULL);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+
+ CollisionPolygonSpatialGizmoPlugin();
};
-class NavigationMeshSpatialGizmo : public EditorSpatialGizmo {
+class NavigationMeshSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- GDCLASS(NavigationMeshSpatialGizmo, EditorSpatialGizmo);
+ GDCLASS(NavigationMeshSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
struct _EdgeKey {
@@ -408,11 +353,12 @@ class NavigationMeshSpatialGizmo : public EditorSpatialGizmo {
bool operator<(const _EdgeKey &p_with) const { return from == p_with.from ? to < p_with.to : from < p_with.from; }
};
- NavigationMeshInstance *navmesh;
-
public:
- void redraw();
- NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh = NULL);
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+
+ NavigationMeshSpatialGizmoPlugin();
};
class JointGizmosDrawer {
@@ -421,7 +367,7 @@ public:
static Basis look_body_toward(Vector3::Axis p_axis, const Transform &joint_transform, const Transform &body_transform);
static Basis look_body_toward_x(const Transform &p_joint_transform, const Transform &p_body_transform);
static Basis look_body_toward_y(const Transform &p_joint_transform, const Transform &p_body_transform);
- /// Special function just used for physics joints, it that returns a basis constrained toward Joint Z axis
+ /// Special function just used for physics joints, it returns a basis constrained toward Joint Z axis
/// with axis X and Y that are looking toward the body and oriented toward up
static Basis look_body_toward_z(const Transform &p_joint_transform, const Transform &p_body_transform);
@@ -430,66 +376,20 @@ public:
static void draw_cone(const Transform &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points);
};
-class PinJointSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(PinJointSpatialGizmo, EditorSpatialGizmo);
-
- PinJoint *p3d;
-
-public:
- static void CreateGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points);
-
- void redraw();
- PinJointSpatialGizmo(PinJoint *p_p3d = NULL);
-};
-
-class HingeJointSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(HingeJointSpatialGizmo, EditorSpatialGizmo);
-
- HingeJoint *p3d;
-
-public:
- static void CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points);
-
- void redraw();
- HingeJointSpatialGizmo(HingeJoint *p_p3d = NULL);
-};
-
-class SliderJointSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(SliderJointSpatialGizmo, EditorSpatialGizmo);
-
- SliderJoint *p3d;
-
-public:
- static void CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points);
-
- void redraw();
- SliderJointSpatialGizmo(SliderJoint *p_p3d = NULL);
-};
-
-class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(ConeTwistJointSpatialGizmo, EditorSpatialGizmo);
+class JointSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
- ConeTwistJoint *p3d;
+ GDCLASS(JointSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
public:
- static void CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points);
-
- void redraw();
- ConeTwistJointSpatialGizmo(ConeTwistJoint *p_p3d = NULL);
-};
-
-class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(Generic6DOFJointSpatialGizmo, EditorSpatialGizmo);
-
- Generic6DOFJoint *p3d;
-
-public:
- static void CreateGizmo(
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+
+ static void CreatePinJointGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points);
+ static void CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points);
+ static void CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points);
+ static void CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points);
+ static void CreateGeneric6DOFJointGizmo(
const Transform &p_offset,
const Transform &p_trs_joint,
const Transform &p_trs_body_a,
@@ -516,26 +416,7 @@ public:
Vector<Vector3> *r_body_a_points,
Vector<Vector3> *r_body_b_points);
- void redraw();
- Generic6DOFJointSpatialGizmo(Generic6DOFJoint *p_p3d = NULL);
+ JointSpatialGizmoPlugin();
};
-class SpatialEditorGizmos {
-
-public:
- HashMap<String, Ref<SpatialMaterial> > material_cache;
-
- Ref<SpatialMaterial> handle2_material;
- Ref<SpatialMaterial> handle2_material_billboard;
- Ref<SpatialMaterial> handle_material;
- Ref<SpatialMaterial> handle_material_billboard;
- Ref<Texture> handle_t;
- Ref<ArrayMesh> pos3d_mesh;
- Ref<ArrayMesh> listener_line_mesh;
- static SpatialEditorGizmos *singleton;
-
- Ref<SpatialEditorGizmo> get_gizmo(Spatial *p_spatial);
-
- SpatialEditorGizmos();
-};
#endif // SPATIAL_EDITOR_GIZMOS_H
diff --git a/editor/translations/af.po b/editor/translations/af.po
index c5853bbb2f..d4c8bc26f4 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -7328,6 +7328,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index ccf2b97d9a..1535ccafb6 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Adel <dragonhunter250@gmail.com>, 2018.
# athomield <athomield@hotmail.com>, 2017.
# Basil Al-Khateeb <basil.y.alkhateeb@gmail.com>, 2017.
@@ -15,13 +14,12 @@
# omar anwar aglan <omar.aglan91@yahoo.com>, 2017-2018.
# OWs Tetra <owstetra@gmail.com>, 2017.
# Rached Noureddine <rached.noureddine@gmail.com>, 2018.
-# Rex_sa <asd1234567890m@gmail.com>, 2017.
+# Rex_sa <asd1234567890m@gmail.com>, 2017, 2018.
# Wajdi Feki <wajdi.feki@gmail.com>, 2017.
-#
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-28 18:34+0000\n"
+"PO-Revision-Date: 2018-07-15 19:34+0000\n"
"Last-Translator: Rached Noureddine <rached.noureddine@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
@@ -30,7 +28,7 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -4331,11 +4329,11 @@ msgstr "ولد رؤية AABB"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
-msgstr ""
+msgstr "إزالة نقطة من المنحنى"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Out-Control from Curve"
-msgstr ""
+msgstr "أزل Out-Control من المنحنى"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove In-Control from Curve"
@@ -7392,6 +7390,11 @@ msgstr "بناء المشروع"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "إظهار الملفات"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
@@ -8076,7 +8079,7 @@ msgstr ""
#: scene/resources/dynamic_font.cpp
msgid "Invalid font size."
-msgstr ""
+msgstr "حجم الخط غير صالح"
#~ msgid "Next"
#~ msgstr "التالي"
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 9f366b3d2f..71b9216b46 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -7383,6 +7383,11 @@ msgstr "Проект"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Преглед на файловете"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 3d00e3450c..aa36beefb6 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -7773,6 +7773,11 @@ msgstr "নতুন প্রকল্প"
msgid "Warnings"
msgstr "সতর্কতা"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "ফাইল"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index d2bffb0f84..085241296e 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -7438,6 +7438,11 @@ msgstr "Munta el Projecte"
msgid "Warnings"
msgstr "Avisos"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Visualitza Fitxers"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Final de la traça de la pila d'excepció interna"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 1066bbad94..b4cf176796 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -7372,6 +7372,11 @@ msgstr "Sestavit projekt"
msgid "Warnings"
msgstr "Varování"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Zobrazit soubory"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/da.po b/editor/translations/da.po
index 3b5854334a..fcfdb6d249 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -7445,6 +7445,11 @@ msgstr "Projekt"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vis filer"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/de.po b/editor/translations/de.po
index d5d63f654b..c61d78e37e 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -27,12 +27,15 @@
# Tim Schellenberg <smwleod@gmail.com>, 2017.
# Timo Schwarzer <account@timoschwarzer.com>, 2016-2018.
# viernullvier <hannes.breul+github@gmail.com>, 2016.
+# Arndt Heuvel <codeforpb@schatzkarten.net>, 2018.
+# Gordon <gkone@gmx.net>, 2018.
+# chillhelm <wilhelm@neubert.online>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-19 19:38+0000\n"
-"Last-Translator: nimradium <nimra242001@gmail.com>\n"
+"PO-Revision-Date: 2018-07-05 12:38+0000\n"
+"Last-Translator: So Wieso <sowieso@dukun.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -40,7 +43,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -331,8 +334,7 @@ msgstr "Optimieren"
#: editor/animation_editor.cpp
msgid "Select an AnimationPlayer from the Scene Tree to edit animations."
msgstr ""
-"Wählen Sie einen AnimationPlayer aus dem Szenenbaum aus, um Animationen zu "
-"bearbeiten."
+"AnimationPlayer aus dem Szenenbaum auswählen um Animationen zu bearbeiten."
#: editor/animation_editor.cpp
msgid "Key"
@@ -1948,7 +1950,7 @@ msgstr "Umwandeln zu..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr "MeshLibrary..."
+msgstr "Mesh-Bibliothek..."
#: editor/editor_node.cpp
msgid "TileSet..."
@@ -2483,7 +2485,7 @@ msgstr "Mirrors werden geladen, bitte warten..."
#: editor/export_template_manager.cpp
msgid "Remove template version '%s'?"
-msgstr "Template-Version '%s' entfernen?"
+msgstr "Template-Version ‚%s‘ entfernen?"
#: editor/export_template_manager.cpp
msgid "Can't open export templates zip."
@@ -6048,8 +6050,8 @@ msgid ""
"Couldn't load project.godot in project path (error %d). It may be missing or "
"corrupted."
msgstr ""
-"Konnte project.godot im Projektpfad nicht laden (Fehler %d). Sie könnte "
-"fehlen oder beschädigt worden sein."
+"Die Datei project.godot im Projektpfad konnte nicht geladen werden (Fehler "
+"%d). Sie könnte fehlen oder beschädigt sein."
#: editor/project_manager.cpp
msgid "Couldn't edit project.godot in project path."
@@ -7490,6 +7492,11 @@ msgstr "Projekt bauen"
msgid "Warnings"
msgstr "Warnungen"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Dateien anzeigen"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Ende des inneren Exception-Stack-Traces"
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index 26f824bc4b..7d11a9d09f 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -7424,6 +7424,11 @@ msgstr "Projektname:"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Datei(en) öffnen"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 1cb31e0ee9..d0f1d04a10 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -7265,6 +7265,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index b3275b4647..4a9560e602 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -2,13 +2,11 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# George Tsiamasiotis <gtsiam@windowslive.com>, 2017-2018.
-#
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-20 09:37+0000\n"
+"PO-Revision-Date: 2018-07-21 22:38+0000\n"
"Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
@@ -16,7 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -1135,7 +1133,7 @@ msgstr "Εμφάνιση στη διαχείριση αρχείων"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
-msgstr "Νέος φάκελος"
+msgstr "Νέος φάκελος..."
#: editor/editor_file_dialog.cpp
msgid "Refresh"
@@ -2698,7 +2696,7 @@ msgstr "Μετονομασία..."
#: editor/filesystem_dock.cpp
msgid "Move To..."
-msgstr "Μετακίνηση σε"
+msgstr "Μετακίνηση σε..."
#: editor/filesystem_dock.cpp
msgid "Open Scene(s)"
@@ -2710,15 +2708,15 @@ msgstr "Στιγμιότυπο"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
-msgstr "Επεξεργασία εξαρτήσεων"
+msgstr "Επεξεργασία εξαρτήσεων..."
#: editor/filesystem_dock.cpp
msgid "View Owners..."
-msgstr "Προβολή ιδιοκτητών"
+msgstr "Προβολή ιδιοκτητών..."
#: editor/filesystem_dock.cpp
msgid "Duplicate..."
-msgstr "Αναπαραγωγή"
+msgstr "Αναπαραγωγή..."
#: editor/filesystem_dock.cpp
msgid "Previous Directory"
@@ -4031,7 +4029,7 @@ msgstr "Δημιουργία περιγράμματος"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Πλέγμα"
+msgstr "Πλέγμα..."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5712,9 +5710,8 @@ msgid "Options"
msgstr "Επιλογές"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Has,Many,Options"
-msgstr "Έχει,Πάρα,Πολλές,Επιλογές!"
+msgstr "Έχει,Πολλές,Επιλογές"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -6001,9 +5998,8 @@ msgid "Imported Project"
msgstr "Εισαγμένο έργο"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "Όνομα έργου:"
+msgstr "Άκυρο όνομα έργου."
#: editor/project_manager.cpp
msgid "Couldn't create folder."
@@ -6207,13 +6203,12 @@ msgid "Mouse Button"
msgstr "Κουμπί ποντικιού"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid ""
"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'."
msgstr ""
"Άκυρο όνομα ενέργειας. Δεν μπορεί να είναι άδειο ή να περιέχει '/', ':', "
-"'=', '\\' ή '\"'"
+"'=', '\\' ή '\"'."
#: editor/project_settings_editor.cpp
msgid "Action '%s' already exists!"
@@ -7474,6 +7469,11 @@ msgstr "Δόμηση έργου"
msgid "Warnings"
msgstr "Προειδοποιήσεις"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Προβολή αρχείων"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Τέλος ιχνηλάτησης στοίβας εσωτερικής εξαίρεσης"
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 89118d2501..8e1f0b13c9 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -29,12 +29,13 @@
# Swyter <swyterzone@gmail.com>, 2016-2017.
# Vazquinhos <vazquinhos@gmail.com>, 2018.
# Yovani Damián <blackblex@gmail.com>, 2018.
+# Andrus Diaz German <andrusdiazaleman@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-22 08:31+0000\n"
-"Last-Translator: R. Joshua Seville <rjoshua@protonmail.com>\n"
+"PO-Revision-Date: 2018-07-20 16:43+0000\n"
+"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -54,19 +55,19 @@ msgstr "Toda la Selección"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr "Cambiar el tiempo del Fotograma Clave de Animación"
+msgstr "Cambiar el Tiempo del Fotograma Clave de Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
-msgstr "Cambiar Transición de Animación"
+msgstr "Cambiar la Transición de Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Transform"
-msgstr "Cambiar transformación de animación"
+msgstr "Cambiar la Transformación de la Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Cambiar valor del Fotograma Clave de Animación"
+msgstr "Cambiar valor de la Clave de Animación"
#: editor/animation_editor.cpp
msgid "Anim Change Call"
@@ -114,7 +115,7 @@ msgstr "Cambiar Modo de Ciclo de Pista de Animación"
#: editor/animation_editor.cpp
msgid "Edit Node Curve"
-msgstr "Editar Nodo de Curva"
+msgstr "Editar Curva del Nodo"
#: editor/animation_editor.cpp
msgid "Edit Selection Curve"
@@ -163,7 +164,7 @@ msgstr "Escalar Selección"
#: editor/animation_editor.cpp
msgid "Scale From Cursor"
-msgstr "Escalar desde cursor"
+msgstr "Escalar Desde Cursor"
#: editor/animation_editor.cpp
msgid "Goto Next Step"
@@ -212,11 +213,11 @@ msgstr "Limpiar Animación"
#: editor/animation_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr "¿Quieres crear una NUEVA pista para %s e insertar clave?"
+msgstr "¿Crear NUEVA pista para %s e insertar clave?"
#: editor/animation_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr "¿Quieres crear %d NUEVAS pistas e insertar claves?"
+msgstr "¿Crear %d NUEVAS pistas e insertar claves?"
#: editor/animation_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/plugins/abstract_polygon_2d_editor.cpp
@@ -288,7 +289,7 @@ msgstr "Activar/Desactivar Bucle de Animación."
#: editor/animation_editor.cpp
msgid "Add new tracks."
-msgstr "Añadir Nuevas Pistas."
+msgstr "Añadir nuevas pistas."
#: editor/animation_editor.cpp
msgid "Move current track up."
@@ -308,7 +309,7 @@ msgstr "Herramientas de pistas"
#: editor/animation_editor.cpp
msgid "Enable editing of individual keys by clicking them."
-msgstr "Habilitar la edición de claves individuales al hacer clic."
+msgstr "Habilitar la edición de claves individuales haciendo clic en ellas."
#: editor/animation_editor.cpp
msgid "Anim. Optimizer"
@@ -366,7 +367,7 @@ msgstr "Limpiar todas las animaciones"
#: editor/animation_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr "Limpiar todas las animaciones (IRREVERSIBLE)"
+msgstr "Limpiar las Animación(es) (¡IRREVERSIBLE!)"
#: editor/animation_editor.cpp
msgid "Clean-Up"
@@ -374,39 +375,39 @@ msgstr "Limpiar"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr "Redimensionar «array»"
+msgstr "Redimensionar Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr "Cambiar tipo de valor del «array»"
+msgstr "Cambiar Tipo de Valor del Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr "Cambiar valor del «array»"
+msgstr "Cambiar Valor del Array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr "Ir a línea"
+msgstr "Ir a Línea"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr "Número de línea:"
+msgstr "Número de Línea:"
#: editor/code_editor.cpp
msgid "No Matches"
-msgstr "Sin coincidencias"
+msgstr "Sin Coincidencias"
#: editor/code_editor.cpp
msgid "Replaced %d occurrence(s)."
-msgstr "%d ocurrencia/s reemplazadas."
+msgstr "%d Ocurrencia(s) Reemplazada(s)."
#: editor/code_editor.cpp
msgid "Match Case"
-msgstr "Coincidir mayús/minúsculas"
+msgstr "Coincidir Mayús/Minúsculas"
#: editor/code_editor.cpp
msgid "Whole Words"
-msgstr "Palabras completas"
+msgstr "Palabras Completas"
#: editor/code_editor.cpp
msgid "Replace"
@@ -414,11 +415,11 @@ msgstr "Reemplazar"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr "Reemplazar todo"
+msgstr "Reemplazar Todo"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr "Sólo selección"
+msgstr "Sólo Selección"
#: editor/code_editor.cpp
msgid "Zoom In"
@@ -430,7 +431,7 @@ msgstr "Alejar"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Restablecer zoom"
+msgstr "Restablecer Zoom"
#: editor/code_editor.cpp editor/script_editor_debugger.cpp
msgid "Line:"
@@ -449,8 +450,8 @@ msgid ""
"Target method not found! Specify a valid method or attach a script to target "
"Node."
msgstr ""
-"No se encontró el método del objetivo! Especifica un método válido o adjunta "
-"un script al Nodo objetivo."
+"¡Método objetivo no encontrado! Especifica un método válido o añade un "
+"script al Nodo objetivo."
#: editor/connections_dialog.cpp
msgid "Connect To Node:"
@@ -471,11 +472,11 @@ msgstr "Quitar"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "Añadir argumento extra de llamada:"
+msgstr "Añadir Argumento Extra de Llamada:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr "Argumentos extras de llamada:"
+msgstr "Argumentos Extras de Llamada:"
#: editor/connections_dialog.cpp
msgid "Path to Node:"
@@ -483,7 +484,7 @@ msgstr "Ruta al Nodo:"
#: editor/connections_dialog.cpp
msgid "Make Function"
-msgstr "Crear función"
+msgstr "Crear Función"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -538,7 +539,7 @@ msgstr "Señales"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr "Cambiar el tipo de %s"
+msgstr "Cambiar el Tipo de %s"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -579,11 +580,11 @@ msgstr "Descripción:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
-msgstr "Buscar reemplazo para:"
+msgstr "Buscar Reemplazo Para:"
#: editor/dependency_editor.cpp
msgid "Dependencies For:"
-msgstr "Dependencias para:"
+msgstr "Dependencias Para:"
#: editor/dependency_editor.cpp
msgid ""
@@ -622,7 +623,7 @@ msgstr "Dependencias:"
#: editor/dependency_editor.cpp
msgid "Fix Broken"
-msgstr "Arreglar rota(s)"
+msgstr "Arreglar Rota(s)"
#: editor/dependency_editor.cpp
msgid "Dependency Editor"
@@ -630,7 +631,7 @@ msgstr "Editor de Dependencias"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr "Buscar recurso de reemplazo:"
+msgstr "Buscar Recurso de Reemplazo:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help.cpp editor/editor_node.cpp editor/filesystem_dock.cpp
@@ -641,13 +642,11 @@ msgstr "Abrir"
#: editor/dependency_editor.cpp
msgid "Owners Of:"
-msgstr "Dueños de:"
+msgstr "Dueños De:"
#: editor/dependency_editor.cpp
msgid "Remove selected files from the project? (no undo)"
-msgstr ""
-"¿Quieres quitar los archivos seleccionados del proyecto? (No puedes "
-"deshacerlo)"
+msgstr "¿Quitar los archivos seleccionados del proyecto? (irreversible)"
#: editor/dependency_editor.cpp
msgid ""
@@ -657,7 +656,7 @@ msgid ""
msgstr ""
"Otros recursos necesitan los archivos que estás intentando quitar para "
"funcionar.\n"
-"¿Seguro que quieres quitarlos? (No puedes deshacerlo)"
+"¿Quitarlos de todos modos? (irreversible)"
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -673,7 +672,7 @@ msgstr "La escena no se pudo cargar porque faltan las siguientes dependencias:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
-msgstr "Abrir de todos modos"
+msgstr "Abrir de Todos Modos"
#: editor/dependency_editor.cpp
msgid "Which action should be taken?"
@@ -689,23 +688,23 @@ msgstr "¡Hubo errores al cargar!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "¿Quieres eliminar permanentemente %d elementos? (Irreversible)"
+msgstr "¿Eliminar permanentemente %d elemento(s)? (¡Irreversible!)"
#: editor/dependency_editor.cpp
msgid "Owns"
-msgstr "Es dueño de"
+msgstr "Dueño de"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr "Recursos sin propietario explícito:"
+msgstr "Recursos Sin Propietario Explícito:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Orphan Resource Explorer"
-msgstr "Explorador de recursos huérfanos"
+msgstr "Explorador de Recursos Huérfanos"
#: editor/dependency_editor.cpp
msgid "Delete selected files?"
-msgstr "¿Quieres eliminar los archivos seleccionados?"
+msgstr "¿Eliminar los archivos seleccionados?"
#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
@@ -745,7 +744,7 @@ msgstr "Desarrollador Principal"
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Administrador de proyectos "
+msgstr "Administrador de Proyectos "
#: editor/editor_about.cpp
msgid "Developers"
@@ -757,11 +756,11 @@ msgstr "Autores"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr "Patrocinadores Platinum"
+msgstr "Patrocinadores de Platino"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr "Patrocinadores Gold"
+msgstr "Patrocinadores de Oro"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
@@ -769,11 +768,11 @@ msgstr "Mini Patrocinadores"
#: editor/editor_about.cpp
msgid "Gold Donors"
-msgstr "Donantes Gold"
+msgstr "Donantes de Oro"
#: editor/editor_about.cpp
msgid "Silver Donors"
-msgstr "Donantes Silver"
+msgstr "Donantes de Plata"
#: editor/editor_about.cpp
msgid "Bronze Donors"
@@ -825,7 +824,7 @@ msgstr "Descomprimiendo Assets"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package Installed Successfully!"
-msgstr "¡El paquete se ha instalado correctamente!"
+msgstr "¡Paquete Instalado Exitosamente!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -859,19 +858,19 @@ msgstr "Cambiar Volumen de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
-msgstr "Act./Desact. Solo de Bus de Audio"
+msgstr "Alternar Solo de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr "Alternar Mute del Bus de Audio"
+msgstr "Alternar Silencio de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
-msgstr "Alternar puenteado de efectos en Bus de Audio"
+msgstr "Alternar Puenteado de Efectos de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr "Seleccionar Envío de Audio Bus"
+msgstr "Seleccionar Envío de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
@@ -928,7 +927,7 @@ msgstr "Añadir Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr "¡No se puede borrar el Bus Maestro!"
+msgstr "¡No se puede borrar el bus maestro!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
@@ -940,7 +939,7 @@ msgstr "Duplicar Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr "Restablecer Volumen del Bus"
+msgstr "Restablecer Volumen de Bus"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
@@ -948,7 +947,7 @@ msgstr "Mover Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr "Guardar configuración de los Buses de Audio como..."
+msgstr "Guardar Configuración de Bus de Audio Como..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
@@ -956,7 +955,7 @@ msgstr "Ubicación para Nueva Configuración..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr "Abrir configuración de Bus de Audio"
+msgstr "Abrir Configuración de Bus de Audio"
#: editor/editor_audio_buses.cpp
msgid "There is no 'res://default_bus_layout.tres' file."
@@ -1002,7 +1001,7 @@ msgstr "Cargar configuración de Bus por defecto."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
-msgstr "El nombre no es correcto."
+msgstr "Nombre inválido."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1011,24 +1010,24 @@ msgstr "Letras válidas:"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing engine class name."
msgstr ""
-"El nombre no es correcto. No puede coincidir con el nombre de una clase que "
-"ya exista en el motor gráfico."
+"Nombre inválido. No debe coincidir con el nombre de una clase que ya exista "
+"en el motor gráfico."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing buit-in type name."
msgstr ""
-"El nombre no es correcto. No puede coincidir con un nombre de tipo que ya "
-"esté integrado en el motor gráfico."
+"Nombre inválido. No debe coincidir con un nombre de tipo que ya esté "
+"integrado en el motor gráfico."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing global constant name."
msgstr ""
-"El nombre no es correcto. No puede coincidir con un nombre de constante "
-"global ya existente en el motor gráfico."
+"Nombre inválido. No debe coincidir con un nombre de constante global ya "
+"existente en el motor gráfico."
#: editor/editor_autoload_settings.cpp
msgid "Invalid Path."
-msgstr "Ruta incorrecta."
+msgstr "Ruta Inválida."
#: editor/editor_autoload_settings.cpp
msgid "File does not exist."
@@ -1052,7 +1051,7 @@ msgstr "Renombrar Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
-msgstr "Des/Activar Globales de Autoload"
+msgstr "Alternar Globales de Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
@@ -1106,7 +1105,7 @@ msgstr "[vacío]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr "[no guardado]"
+msgstr "[sin guardar]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first"
@@ -1114,12 +1113,12 @@ msgstr "Por favor, selecciona primero un directorio base"
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
-msgstr "Elige una carpeta"
+msgstr "Elige un Directorio"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
msgid "Create Folder"
-msgstr "Crear carpeta"
+msgstr "Crear Carpeta"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
@@ -1139,7 +1138,7 @@ msgstr "Elegir"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr "Archivo de almacenamiento:"
+msgstr "Archivo de Almacenamiento:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1147,11 +1146,11 @@ msgstr "Empaquetando"
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
-msgstr "No se encontró archivo de plantilla:"
+msgstr "Archivo de plantilla no encontrado:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File Exists, Overwrite?"
-msgstr "El archivo ya existe, ¿quieres sobreescribirlo?"
+msgstr "El Archivo ya Existe, ¿Quieres Sobreescribirlo?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1159,15 +1158,15 @@ msgstr "Seleccionar Carpeta Actual"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr "Copiar ruta"
+msgstr "Copiar Ruta"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Show In File Manager"
-msgstr "Mostrar en el navegador de archivos"
+msgstr "Mostrar en el Navegador de Archivos"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
-msgstr "Nueva carpeta..."
+msgstr "Nueva Carpeta..."
#: editor/editor_file_dialog.cpp
msgid "Refresh"
@@ -1183,19 +1182,19 @@ msgstr "Todos los archivos (*)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
-msgstr "Abrir un archivo"
+msgstr "Abrir un Archivo"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
-msgstr "Abrir archivo/s"
+msgstr "Abrir Archivo(s)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a Directory"
-msgstr "Abrir una carpeta"
+msgstr "Abrir un Directorio"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File or Directory"
-msgstr "Abrir un archivo o carpeta"
+msgstr "Abrir un Archivo o Directorio"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1205,7 +1204,7 @@ msgstr "Guardar"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr "Guardar un archivo"
+msgstr "Guardar un Archivo"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -1221,27 +1220,27 @@ msgstr "Subir"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr "Ver/ocultar archivos ocultos"
+msgstr "Ver/ocultar Archivos Ocultos"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr "Añadir/quitar favorito"
+msgstr "Añadir/quitar Favorito"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr "Cambiar modo"
+msgstr "Cambiar Modo"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr "Seleccionar ruta"
+msgstr "Seleccionar Ruta"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr "Subir favorito"
+msgstr "Subir Favorito"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr "Bajar favorito"
+msgstr "Bajar Favorito"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder"
@@ -1249,7 +1248,7 @@ msgstr "Ir a la carpeta principal"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
-msgstr "Carpetas y archivos:"
+msgstr "Directorios y Archivos:"
#: editor/editor_file_dialog.cpp
msgid "Preview:"
@@ -1266,7 +1265,7 @@ msgstr "Debe tener una extensión válida."
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr "Analizando fuentes"
+msgstr "Analizando Fuentes"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -1275,15 +1274,15 @@ msgstr "(Re)Importando Assets"
#: editor/editor_help.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "Ayuda de búsqueda"
+msgstr "Ayuda de Búsqueda"
#: editor/editor_help.cpp
msgid "Class List:"
-msgstr "Lista de clases:"
+msgstr "Lista de Clases:"
#: editor/editor_help.cpp
msgid "Search Classes"
-msgstr "Buscar clases"
+msgstr "Buscar Clases"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
@@ -1303,7 +1302,7 @@ msgstr "Heredada por:"
#: editor/editor_help.cpp
msgid "Brief Description:"
-msgstr "Descripción breve:"
+msgstr "Descripción Breve:"
#: editor/editor_help.cpp
msgid "Members"
@@ -1323,11 +1322,11 @@ msgstr "Métodos públicos:"
#: editor/editor_help.cpp
msgid "GUI Theme Items"
-msgstr "Elementos del Tema de GUI"
+msgstr "Elementos del Tema de Interfaz"
#: editor/editor_help.cpp
msgid "GUI Theme Items:"
-msgstr "Elementos de tema de interfaz:"
+msgstr "Elementos del Tema de Interfaz:"
#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
@@ -1359,7 +1358,7 @@ msgstr "Descripción"
#: editor/editor_help.cpp
msgid "Online Tutorials:"
-msgstr "Tutoriales en línea:"
+msgstr "Tutoriales en Línea:"
#: editor/editor_help.cpp
msgid ""
@@ -1367,8 +1366,8 @@ msgid ""
"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
"url][/color]."
msgstr ""
-"De momento no hay tutoriales para esta clase, puedes [color=$color][url="
-"$url]añadir uno[/url][/color] o [color=$color][url=$url2]pedir uno[color="
+"Actualmente no hay tutoriales para esta clase, puedes [color=$color][url="
+"$url]aportar uno[/url][/color] o [color=$color][url=$url2]pedir uno[color="
"$color][url=$url2]."
#: editor/editor_help.cpp
@@ -1393,7 +1392,7 @@ msgstr "Métodos"
#: editor/editor_help.cpp
msgid "Method Description:"
-msgstr "Descripción de métodos:"
+msgstr "Descripción del Método:"
#: editor/editor_help.cpp
msgid ""
@@ -1405,11 +1404,11 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Search Text"
-msgstr "Texto de búsqueda"
+msgstr "Texto de Búsqueda"
#: editor/editor_help.cpp
msgid "Find"
-msgstr "Búsqueda"
+msgstr "Buscar"
#: editor/editor_log.cpp
msgid "Output:"
@@ -1420,11 +1419,11 @@ msgstr "Salida:"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr "Borrar todo"
+msgstr "Borrar Todo"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr "Borrar salida"
+msgstr "Borrar Salida"
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
@@ -1432,7 +1431,7 @@ msgstr "La exportación del proyecto falló con el código de error %d."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr "¡Hubo un error al guardar el recurso!"
+msgstr "¡Error al guardar el recurso!"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -1485,7 +1484,7 @@ msgstr "Analizando"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr "Creando miniatura"
+msgstr "Creando Miniatura"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
@@ -1501,7 +1500,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Failed to load resource."
-msgstr "Hubo un problema al cargar el recurso."
+msgstr "Error al cargar el recurso."
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
@@ -1529,7 +1528,7 @@ msgstr "Se han sobrescrito los ajustes predeterminados del editor."
#: editor/editor_node.cpp
msgid "Layout name not found!"
-msgstr "¡No se encuentra el nombre del ajuste!"
+msgstr "¡Nombre del ajuste no encontrado!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
@@ -1594,23 +1593,23 @@ msgstr "Ocultar todas las propiedades"
#: editor/editor_node.cpp
msgid "Copy Params"
-msgstr "Copiar parámetros"
+msgstr "Copiar Parámetros"
#: editor/editor_node.cpp
msgid "Paste Params"
-msgstr "Pegar parámetros"
+msgstr "Pegar Parámetros"
#: editor/editor_node.cpp editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Paste Resource"
-msgstr "Pegar recurso"
+msgstr "Pegar Recurso"
#: editor/editor_node.cpp
msgid "Copy Resource"
-msgstr "Copiar recurso"
+msgstr "Copiar Recurso"
#: editor/editor_node.cpp
msgid "Make Built-In"
-msgstr "Convertirlo en integrado"
+msgstr "Convertirlo en Integrado"
#: editor/editor_node.cpp
msgid "Make Sub-Resources Unique"
@@ -1618,7 +1617,7 @@ msgstr "Creación de Subrecursos Únicos"
#: editor/editor_node.cpp
msgid "Open in Help"
-msgstr "Abrir en la ayuda"
+msgstr "Abrir en la Ayuda"
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
@@ -1711,11 +1710,11 @@ msgstr "Esta operación no puede realizarse sin una escena."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr "Exportar biblioteca de mallas"
+msgstr "Exportar Librería de Mallas"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr "Esta operación no puede realizarse sin un Nodo Raíz."
+msgstr "Esta operación no puede realizarse sin un nodo raíz."
#: editor/editor_node.cpp
msgid "Export Tile Set"
@@ -1727,7 +1726,7 @@ msgstr "Esta operación no puede realizarse sin un nodo seleccionado."
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr "La escena actual no se ha guardado. ¿Quieres abrirla de todos modos?"
+msgstr "Escena actual no guardada ¿Abrir de todos modos?"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
@@ -2320,7 +2319,7 @@ msgstr "Abrir Editor anterior"
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr "Creando vistas previas de las mallas"
+msgstr "Creación de Vistas Previas de Malla"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
@@ -2851,7 +2850,7 @@ msgstr "Generando \"Lightmaps\""
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr "Generando para modelo: "
+msgstr "Generando para Malla: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
@@ -3122,7 +3121,7 @@ msgstr "Posterior"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
-msgstr "Profundidad"
+msgstr "Depth"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
@@ -3996,7 +3995,7 @@ msgstr "Clic derecho: Borrar punto."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh is empty!"
-msgstr "¡La malla está vacía!"
+msgstr "¡La Malla está vacía!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
@@ -4020,11 +4019,11 @@ msgstr "Crear forma convexa"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
-msgstr "Crear malla de navegación"
+msgstr "Crear Malla de Navegación"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Contained Mesh is not of type ArrayMesh."
-msgstr "La malla que contiene no es del tipo ArrayMesh."
+msgstr "La Malla contenedora no es del tipo ArrayMesh."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Unwrap failed, mesh may not be manifold?"
@@ -4042,7 +4041,7 @@ msgstr "El modelo no tiene UV en esta capa"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "MeshInstance lacks a Mesh!"
-msgstr "¡MeshInstance no tiene malla!"
+msgstr "¡MeshInstance no tiene Malla!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh has not surface to create outlines from!"
@@ -4050,7 +4049,7 @@ msgstr "¡La malla no tiene superficie de la que crear contornos!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
-msgstr "El tipo de la malla primitiva no es PRIMITIVE_TRIANGLES!"
+msgstr "¡El tipo primitivo de malla no es PRIMITIVE_TRIANGLES!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Could not create outline!"
@@ -4098,7 +4097,7 @@ msgstr "Desenvuelva UV2 para Lightmap/AO"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh"
-msgstr "Crear contorno de malla"
+msgstr "Crear Contorno de Malla"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Outline Size:"
@@ -4107,12 +4106,14 @@ msgstr "Tamaño del contorno:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
msgstr ""
-"No se especificó malla de origen (y no hay MultiMesh establecido en el nodo)."
+"No se ha especificado ninguna malla de origen (y no hay MultiMesh "
+"establecido en el nodo)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and MultiMesh contains no Mesh)."
msgstr ""
-"No se especificó malla de origen (y MultiMesh no contiene ningún Mesh)."
+"No se ha especificado ninguna malla de origen (y MultiMesh no contiene "
+"ninguna Mesh)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
@@ -4120,11 +4121,11 @@ msgstr "El origen de la malla es inválido (ruta inválida)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (not a MeshInstance)."
-msgstr "La malla elegida no es correcta (no es un MeshInstance)."
+msgstr "El origen de la malla es inválido (no es un MeshInstance)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (contains no Mesh resource)."
-msgstr "La malla elegida no es correcta (no contiene ningún recurso Mesh)."
+msgstr "El origen de la malla es inválido (no contiene ningún recurso Mesh)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No surface source specified."
@@ -4152,7 +4153,7 @@ msgstr "No se pudo mapear el área."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
-msgstr "Elige un origen de malla:"
+msgstr "Elige un origen de Malla:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Target Surface:"
@@ -4172,7 +4173,7 @@ msgstr "Superficie objetivo:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Source Mesh:"
-msgstr "Modelo 3D elegido:"
+msgstr "Malla de origen:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "X-Axis"
@@ -4212,11 +4213,11 @@ msgstr "¡Calcular!"
#: editor/plugins/navigation_mesh_editor_plugin.cpp
msgid "Bake the navigation mesh."
-msgstr "Pre-calcular la malla de navegación 3D."
+msgstr "Pre-calcular la malla de navegación."
#: editor/plugins/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr "Vaciar malla de navegación 3D."
+msgstr "Vaciar malla de navegación."
#: editor/plugins/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
@@ -4501,7 +4502,7 @@ msgstr "Crear mapa UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Transform UV Map"
-msgstr "Transformar mapa UV"
+msgstr "Transformar Mapa UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
@@ -5416,11 +5417,11 @@ msgstr "Activar Vista Libre"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform"
-msgstr "Transform"
+msgstr "Transformar"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
-msgstr "Ventana de transformación..."
+msgstr "Dialogo de Transformación..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
@@ -5497,7 +5498,7 @@ msgstr "Profundidad máxima de vista:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Change"
-msgstr "Transformar"
+msgstr "Cambio de Transformación"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate:"
@@ -6644,7 +6645,7 @@ msgstr "Reemparentar ubicación (selecciona un nuevo padre):"
#: editor/reparent_dialog.cpp
msgid "Keep Global Transform"
-msgstr "Mantener transformación global"
+msgstr "Mantener Transformación Global"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent"
@@ -7498,6 +7499,11 @@ msgstr "Compilar Proyecto"
msgid "Warnings"
msgstr "Advertencias"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Archivos"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fin del reporte de la pila de excepciones"
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 64ee2404f1..bea184b813 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -7464,6 +7464,11 @@ msgstr "Construir Proyecto"
msgid "Warnings"
msgstr "Advertencias"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Archivos"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fin del stack trace de excepción interna"
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index f674ef99cc..eb192ececb 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -2,26 +2,25 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# alabd14313 <alabd14313@yahoo.com>, 2016.
# Dante Marshal <Marshal.Devilhunter@gmail.com>, 2018.
# hamed nasib <cghamed752@chmail.ir>, 2016.
# Hasan Hejdari Nasab <hsn6@openmailbox.org>, 2017.
# rezapouya <r.pouya@chmail.ir>, 2016.
# sayyed hamed nasib <cghamed752@chmail.ir>, 2017.
-#
+# Behrooz Kashani <bkashani@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-04-29 05:39+0000\n"
-"Last-Translator: Dante Marshal <Marshal.Devilhunter@gmail.com>\n"
+"PO-Revision-Date: 2018-07-24 19:42+0000\n"
+"Last-Translator: Behrooz Kashani <bkashani@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -636,9 +635,8 @@ msgstr ""
"آیا در هر صورت حذف شوند؟(بدون برگشت)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Cannot remove:"
-msgstr "ناتوانی در حذف :"
+msgstr "امکان حذف وجود ندارد :"
#: editor/dependency_editor.cpp
msgid "Error loading:"
@@ -743,9 +741,8 @@ msgid "Gold Sponsors"
msgstr "اسپانسر‌های درجه ۲"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Mini Sponsors"
-msgstr "اسپانسر‌های دیگر"
+msgstr "اسپانسر‌های کوچک"
#: editor/editor_about.cpp
msgid "Gold Donors"
@@ -789,7 +786,7 @@ msgstr "اجزا"
#: editor/editor_about.cpp
msgid "Licenses"
-msgstr ""
+msgstr "گواهینامه"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Error opening package file, not in zip format."
@@ -7420,6 +7417,11 @@ msgstr "پروژه"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "نمایش پرونده ها"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index f80efffd42..11f9bb51c7 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -12,7 +12,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-14 20:37+0000\n"
+"PO-Revision-Date: 2018-07-19 10:36+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -2128,7 +2128,7 @@ msgstr "Käynnistä muokattavana oleva skene."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "Toista skene"
+msgstr "Pelaa skeneä"
#: editor/editor_node.cpp
msgid "Play custom scene"
@@ -2414,7 +2414,7 @@ msgstr "Lataa uudelleen"
#: editor/export_template_manager.cpp
msgid "Uninstall"
-msgstr "Poista"
+msgstr "Poista asennus"
#: editor/export_template_manager.cpp
msgid "(Installed)"
@@ -2475,7 +2475,7 @@ msgstr ""
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't resolve."
-msgstr "Yhdistäminen epäonnistui."
+msgstr "Yhdeydenselvitys epäonnistui."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -2520,11 +2520,11 @@ msgstr "Yhteys katkaistu"
#: editor/export_template_manager.cpp
msgid "Resolving"
-msgstr "Selvitetään"
+msgstr "Selvitetään yhteyttä"
#: editor/export_template_manager.cpp
msgid "Can't Resolve"
-msgstr "Yhdistäminen epäonnistui"
+msgstr "Yhteyden selvittäminen epäonnistui"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -2809,7 +2809,7 @@ msgstr "Luodaan meshille: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr "Suorita valitsemasi skripti..."
+msgstr "Suoritetaan mukautettua skriptiä..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
@@ -2940,7 +2940,7 @@ msgstr "VIRHE: Virheellinen animaation nimi!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "ERROR: Animation name already exists!"
-msgstr "VIrhe: Samanniminen animaatio on jo olemassa!"
+msgstr "VIRHE: Samanniminen animaatio on jo olemassa!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -3316,7 +3316,8 @@ msgstr "Pyyntö epäonnistui, liikaa uudelleenohjauksia"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
-msgstr "Latauksessa väärä hash, oletetaan että tiedostoa on näpelöity."
+msgstr ""
+"Latauksessa väärä hajautuskoodi, oletetaan että tiedostoa on näpelöity."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Expected:"
@@ -3328,7 +3329,7 @@ msgstr "Saatiin:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed sha256 hash check"
-msgstr "sha256 hash-tarkistus epäonnistui"
+msgstr "sha256-hajautusarvon tarkistus epäonnistui"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -3442,7 +3443,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
-"Lightmap-kuvien luonti epäonnistui, varmista, että polku on "
+"Lightmap-kuvien luonti epäonnistui. Varmista, että polku on "
"kirjoituskelpoinen."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5301,11 +5302,11 @@ msgstr "Tarttumisen tila (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
-msgstr "Pohjanäkymä"
+msgstr "Alanäkymä"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View"
-msgstr "Huippunäkymä"
+msgstr "Ylänäkymä"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
@@ -7110,7 +7111,7 @@ msgstr "Aseta puusta"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
-msgstr "Pikakuvakkeet"
+msgstr "Pikanäppäimet"
#: editor/settings_config_dialog.cpp
msgid "Binding"
@@ -7435,6 +7436,11 @@ msgstr "Käännä projekti"
msgid "Warnings"
msgstr "Varoitukset"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Näytä tiedostot"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Sisemmän poikkeuksen kutsupinon loppu"
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index ee1d7b2cad..5c28d84a90 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -40,12 +40,14 @@
# Tommy Melançon-Roy <tommel1234@hotmail.com>, 2017-2018.
# Willow <theotimefd@aol.com>, 2018.
# Xananax <xananax@yelostudio.com>, 2017-2018.
+# Perrier Mathis <mathis.perrier73@gmail.com>, 2018.
+# Ewan Lehnebach <ewan.lehnebach@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-12 16:38+0000\n"
-"Last-Translator: Philippe Gervaise <blah@malvese.org>\n"
+"PO-Revision-Date: 2018-07-21 12:37+0000\n"
+"Last-Translator: Perrier Mathis <mathis.perrier73@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -53,7 +55,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -65,11 +67,11 @@ msgstr "Toute la sélection"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr "Changer l'heure de l'animation des images clés"
+msgstr "Animation Changer l'heure de l'image clé"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
-msgstr "Transition du changement d'animation"
+msgstr "Animation Changer la transition"
#: editor/animation_editor.cpp
msgid "Anim Change Transform"
@@ -77,7 +79,7 @@ msgstr "Animation Changer la transformation"
#: editor/animation_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Changer la valeur de l'animation des images clés"
+msgstr "Animation Changer la valeur de l'image clé"
#: editor/animation_editor.cpp
msgid "Anim Change Call"
@@ -4076,7 +4078,7 @@ msgstr "Créer le contour"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Maillage"
+msgstr "Maillages"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -6512,7 +6514,7 @@ msgstr "Remaps par langue :"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr "Langue"
+msgstr "Localisation"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -7513,6 +7515,11 @@ msgstr "Compiler le projet"
msgid "Warnings"
msgstr "Avertissements"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Voir Fichiers"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fin de la trace d'appel (stack trace) intrinsèque"
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 0f1881211f..6dfd0ab3a5 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -7294,6 +7294,10 @@ msgstr ""
msgid "Warnings"
msgstr "אזהרות"
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 3340f13471..606da1d118 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -7327,6 +7327,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index b04dd073df..84c64138dc 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -7405,6 +7405,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Fájlok Megtekintése"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 3956378ce7..a0356b8178 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -10,7 +10,7 @@
# Fajar Ru <kzofajar@gmail.com>, 2018.
# Khairul Hidayat <khairulcyber4rt@gmail.com>, 2016.
# Reza Hidayat Bayu Prabowo <rh.bayu.prabowo@gmail.com>, 2018.
-# Romi Kusuma Bakti <romikusumab@gmail.com>, 2017.
+# Romi Kusuma Bakti <romikusumab@gmail.com>, 2017, 2018.
# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018.
# Tito <ijavadroid@gmail.com>, 2018.
# Tom My <tom.asadinawan@gmail.com>, 2017.
@@ -18,8 +18,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-22 08:30+0000\n"
-"Last-Translator: Fajar Ru <kzofajar@gmail.com>\n"
+"PO-Revision-Date: 2018-07-15 12:38+0000\n"
+"Last-Translator: Romi Kusuma Bakti <romikusumab@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -917,9 +917,8 @@ msgid "Delete Audio Bus"
msgstr "Hapus Bus Audio"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Duplicate Audio Bus"
-msgstr "Duplikat Audio Bus"
+msgstr "Duplikatkan Bus Audio"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
@@ -976,9 +975,8 @@ msgid "Save this Bus Layout to a file."
msgstr "Simpan Layout Bus ke berkas."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
-#, fuzzy
msgid "Load Default"
-msgstr "Muat Konfigurasi Bawaan"
+msgstr "Muat Default"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
@@ -1294,18 +1292,16 @@ msgid "Members:"
msgstr "Member-member:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Public Methods"
-msgstr "Fungsi Publik"
+msgstr "Metode Publik"
#: editor/editor_help.cpp
msgid "Public Methods:"
msgstr "Metode Publik:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "GUI Theme Items"
-msgstr "Item-item Tema GUI:"
+msgstr "Item Tema GUI"
#: editor/editor_help.cpp
msgid "GUI Theme Items:"
@@ -1422,9 +1418,8 @@ msgstr "Simpan Resource Sebagai..."
#: editor/editor_node.cpp editor/plugins/spatial_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "I see..."
-msgstr "Aku tahu..."
+msgstr "Mengerti..."
#: editor/editor_node.cpp
msgid "Can't open file for writing:"
@@ -1471,9 +1466,8 @@ msgid "Creating Thumbnail"
msgstr "Membuat Thumbnail"
#: editor/editor_node.cpp
-#, fuzzy
msgid "This operation can't be done without a tree root."
-msgstr "Tindakan ini tidak bisa dilakukan tanpa \"tree root\""
+msgstr "Operasi ini tidak dapat diselesaikan tanpa root pohon."
#: editor/editor_node.cpp
msgid ""
@@ -2712,7 +2706,7 @@ msgstr "Buka Scene"
#: editor/filesystem_dock.cpp
msgid "Instance"
-msgstr ""
+msgstr "Instance"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
@@ -2821,18 +2815,16 @@ msgid "Importing Scene..."
msgstr "Mengimpor scene..."
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Generating Lightmaps"
-msgstr "Sedang Membuat Pemetaan Cahaya"
+msgstr "Membuat Pemetaan Cahaya"
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
msgstr ""
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Running Custom Script..."
-msgstr "Menjalankan Skrip Buatan..."
+msgstr "Menjalankan Script Khusus..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
@@ -2868,7 +2860,7 @@ msgstr "Impor sebagai:"
#: editor/import_dock.cpp editor/property_editor.cpp
msgid "Preset..."
-msgstr ""
+msgstr "Prasetel..."
#: editor/import_dock.cpp
msgid "Reimport"
@@ -7563,6 +7555,11 @@ msgstr "Proyek"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "File:"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 98a376edca..0d6200fba1 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -7301,6 +7301,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 2d566fe163..afb8c5cfb8 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Alessio Corridori <alessiocorridori@hotmail.com>, 2018.
# Dario Bonfanti <bonfi.96@hotmail.it>, 2016-2017.
# Dario D'Ambra <legione0@gmail.com>, 2017.
@@ -15,13 +14,13 @@
# RealAquilus <JamesHeller@live.it>, 2017.
# Samuele Zolfanelli <samdazel@gmail.com>, 2018.
# Sean Bone <seanbone@zumguy.com>, 2017.
-#
+# Red Pill <redpill902@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-05-18 16:39+0000\n"
-"Last-Translator: Alessio Corridori <alessiocorridori@hotmail.com>\n"
+"PO-Revision-Date: 2018-06-25 18:40+0000\n"
+"Last-Translator: Red Pill <redpill902@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -29,7 +28,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -40,9 +39,8 @@ msgid "All Selection"
msgstr "Seleziona Tutto"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
-msgstr "Anim Cambia Valore"
+msgstr "Anim Cambia Tempo di Keyframe"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
@@ -7640,6 +7638,11 @@ msgstr "Progetto"
msgid "Warnings"
msgstr "Avvertimento"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vedi Files"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 5ce73d0442..d7e2c07ac2 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -8251,6 +8251,11 @@ msgstr "プロジェクト"
msgid "Warnings"
msgstr "警告"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "ビューファイル:"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index be6b540a9a..197a11efa2 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -14,8 +14,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-07 16:40+0000\n"
-"Last-Translator: pgyage3263 <pgyage3263@naver.com>\n"
+"PO-Revision-Date: 2018-07-21 04:38+0000\n"
+"Last-Translator: 송태섭 <xotjq237@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -23,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -4003,7 +4003,7 @@ msgstr "외곽선 만들기"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "메시"
+msgstr "Mesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -7412,6 +7412,11 @@ msgstr "프로젝트 빌드"
msgid "Warnings"
msgstr "경고"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "파일 보기"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "내부 예외 스택 추적의 끝"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index bf4443627a..639e086d4c 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -7295,6 +7295,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 19d8b6b7d8..09c7b39e08 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -2,22 +2,21 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Sam Vanguard <syafz119@gmail.com>, 2018.
# Shaqir Rafiq <moshamoradev@gmail.com>, 2018.
-#
+# Syaz Amirin <amirin123z@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-05 19:27+0000\n"
-"Last-Translator: Shaqir Rafiq <moshamoradev@gmail.com>\n"
+"PO-Revision-Date: 2018-06-30 09:40+0000\n"
+"Last-Translator: Syaz Amirin <amirin123z@gmail.com>\n"
"Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/"
"ms/>\n"
"Language: ms\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -2014,11 +2013,11 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr ""
+msgstr "Komuniti"
#: editor/editor_node.cpp
msgid "About"
-msgstr ""
+msgstr "Tentang"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -6244,7 +6243,7 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr ""
+msgstr "Am"
#: editor/project_settings_editor.cpp editor/property_editor.cpp
msgid "Property:"
@@ -7273,6 +7272,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index e76053150c..abc026771d 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -14,8 +14,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-22 08:31+0000\n"
-"Last-Translator: Frank T. Rambol <frank@d-fect.com>\n"
+"PO-Revision-Date: 2018-06-28 14:40+0000\n"
+"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb/>\n"
"Language: nb\n"
@@ -1756,7 +1756,9 @@ msgstr "Velg en HovedScene"
#: editor/editor_node.cpp
#, fuzzy
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
-msgstr "Kan ikke aktivere addon-plugin på: '%s' parsing av konfig feilet."
+msgstr ""
+"Kan ikke aktivere tilleggs-programtillegg på: \"%s\" tolking av oppsett "
+"mislyktes."
#: editor/editor_node.cpp
msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
@@ -1912,9 +1914,8 @@ msgid "MeshLibrary..."
msgstr "MeshBibliotek..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "TileSet..."
-msgstr "TileSet…"
+msgstr "Flissett…"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -7495,6 +7496,11 @@ msgstr "Prosjekt"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vis Filer"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index bfedf322b3..240d99182f 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# aelspire <aelspire@gmail.com>, 2017.
# Aram Nap <xyphex.aram@gmail.com>, 2017.
# Arjan219 <arjannugteren1@gmail.com>, 2017-2018.
@@ -24,19 +23,19 @@
# Willem <studiebolmail@gmail.com>, 2018.
# Wout Standaert <wout@blobkat.com>, 2017.
# Zatherz <zatherz@linux.pl>, 2017.
-#
+# Tahar Meijs <tntmeijs@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-21 18:36+0000\n"
-"Last-Translator: Johannes Smit <smitjohannes96@gmail.com>\n"
+"PO-Revision-Date: 2018-06-30 15:36+0000\n"
+"Last-Translator: Tahar Meijs <tntmeijs@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
"Language: nl\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -6427,7 +6426,7 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr ""
+msgstr "Algemeen"
#: editor/project_settings_editor.cpp editor/property_editor.cpp
msgid "Property:"
@@ -7492,6 +7491,11 @@ msgstr "Project"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Bekijk Bestanden"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 5ca2760249..a133a4d8d5 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -27,7 +27,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-22 08:31+0000\n"
+"PO-Revision-Date: 2018-07-14 08:42+0000\n"
"Last-Translator: RM <synaptykq@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
@@ -1975,7 +1975,7 @@ msgstr "Wyjdź do Listy Projektów"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Debug"
-msgstr "Debuguj"
+msgstr "Debugowanie"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -3093,7 +3093,7 @@ msgstr "Poprzednie"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr "Następne"
+msgstr "Przyszłość"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
@@ -3154,7 +3154,7 @@ msgstr "Czas Przejścia Między Animacjami"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Animation"
-msgstr "Animacja"
+msgstr "Animacje"
#: editor/plugins/animation_tree_editor_plugin.cpp
msgid "New name:"
@@ -6514,7 +6514,7 @@ msgstr "Mapowanie w zależności od lokalizacji:"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr "Lokalizacja"
+msgstr "Języki"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -7137,7 +7137,7 @@ msgstr "Monitor"
#: editor/script_editor_debugger.cpp
msgid "Value"
-msgstr "Wartość"
+msgstr "Value"
#: editor/script_editor_debugger.cpp
msgid "Monitors"
@@ -7525,6 +7525,11 @@ msgstr "Zbuduj projekt"
msgid "Warnings"
msgstr "Ostrzeżenia"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Pokaż pliki"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
@@ -7672,11 +7677,11 @@ msgstr "Dodaj węzeł(y) z drzewa"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Getter Property"
-msgstr ""
+msgstr "Dodaj właściwość Gettera"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Setter Property"
-msgstr ""
+msgstr "Dodaj właściwość Settera"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Base Type"
@@ -7712,7 +7717,7 @@ msgstr "Iterator"
#: modules/visual_script/visual_script_editor.cpp
msgid "While"
-msgstr ""
+msgstr "While"
#: modules/visual_script/visual_script_editor.cpp
msgid "Return"
@@ -8045,7 +8050,7 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVRCamera must have an ARVROrigin node as its parent"
-msgstr "ARVRCamera musi dziedziczyć po ARVROrigin node"
+msgstr "ARVRCamera musi dziedziczyć po węźle ARVROrigin"
#: scene/3d/arvr_nodes.cpp
#, fuzzy
@@ -8073,11 +8078,11 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVROrigin requires an ARVRCamera child node"
-msgstr "ARVROrigin wymaga by ARVRCamera dziedziczyła po node"
+msgstr "ARVROrigin wymaga dziedziczącego po nim ARVRCamera"
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
-msgstr ""
+msgstr "%d%%"
#: scene/3d/baked_lightmap.cpp
msgid "(Time Left: %d:%02d s)"
@@ -8106,6 +8111,10 @@ msgid ""
"Consider adding CollisionShape or CollisionPolygon children nodes to define "
"its shape."
msgstr ""
+"Ten węzeł nie posiada podwezła, który definiowałby jego kształt, więc nie "
+"może wchodzić w interakcje z przestrzenią.\n"
+"Powinieneś dodać węzeł \"CollisionShape2D\" lub \"CollisionPolygon2D\" jako "
+"jego podwęzeł aby zdefiniować jego kształt."
#: scene/3d/collision_polygon.cpp
msgid ""
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 0c085024e0..ee30748cee 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -7350,6 +7350,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 6d26cbc500..472fb1e7bc 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -23,12 +23,13 @@
# Renato Rotenberg <renato.rotenberg@gmail.com>, 2017.
# Rodolfo R Gomes <rodolforg@gmail.com>, 2017-2018.
# Tiago Almeida <thyagoeap@gmail.com>, 2017.
+# Mauricio Luan Carneiro deSouza <newmailmlcs@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2018-06-16 18:43+0000\n"
-"Last-Translator: Rodolfo R Gomes <rodolforg@gmail.com>\n"
+"PO-Revision-Date: 2018-07-26 09:14+0000\n"
+"Last-Translator: Mauricio Luan Carneiro deSouza <newmailmlcs@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -36,7 +37,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -4036,7 +4037,7 @@ msgstr "Criar Contorno"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Mesh"
+msgstr "Malha"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5100,7 +5101,7 @@ msgstr "Transformação do Eixo-Z."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Plane Transform."
-msgstr "Visualizar Transformação do Plano."
+msgstr "Transformação do Plano de Visão."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scaling: "
@@ -5236,7 +5237,7 @@ msgstr "Visualizar Gizmos"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
-msgstr "VIsualizar Informação"
+msgstr "Visualizar Informações"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View FPS"
@@ -7049,7 +7050,7 @@ msgstr "Processo Filho Conectado"
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
-msgstr "Erro ao Copiar"
+msgstr "Copiar Erro"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -7463,6 +7464,11 @@ msgstr "Compilar Projeto"
msgid "Warnings"
msgstr "Avisos"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Arquivos"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fim da pilha de rastreamento de exceção interna"
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index 71275cd19a..d111d1dd4b 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -7442,6 +7442,11 @@ msgstr "Construir Projeto"
msgid "Warnings"
msgstr "Avisos"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ver Ficheiros"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Fim do stack trace de exceção interna"
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index eaf931092a..c5a4e35903 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -7400,6 +7400,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Vizualizează Fișierele"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 97c7284404..1c888d3330 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -17,12 +17,15 @@
# Sergey <maligin.serega2010@yandex.ru>, 2018.
# Sergey Agarkov <zorgsoft@gmail.com>, 2017.
# teriva <spirin.cos@yandex.ru>, 2018.
+# Aleksey Terentyev <terentjew.alexey@ya.ru>, 2018.
+# Игорь Д <protorian.di@gmail.com>, 2018.
+# Егор Бураков <fend.q@mail.ru>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-06-18 19:42+0000\n"
-"Last-Translator: ijet <my-ijet@mail.ru>\n"
+"PO-Revision-Date: 2018-07-22 04:43+0000\n"
+"Last-Translator: Егор Бураков <fend.q@mail.ru>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -31,7 +34,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 3.0.1\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -2347,7 +2350,7 @@ msgstr "Кадр %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr "Физический шаг %"
+msgstr "Кадр физики %"
#: editor/editor_profiler.cpp editor/script_editor_debugger.cpp
msgid "Time:"
@@ -2359,7 +2362,7 @@ msgstr "Включительно"
#: editor/editor_profiler.cpp
msgid "Self"
-msgstr ""
+msgstr "Субъект"
#: editor/editor_profiler.cpp
msgid "Frame #:"
@@ -4029,7 +4032,7 @@ msgstr "Создать контур"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr "Полисетка"
+msgstr "Массив"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5561,7 +5564,7 @@ msgstr "Предпросмотр StyleBox:"
#: editor/plugins/style_box_editor_plugin.cpp
msgid "StyleBox"
-msgstr ""
+msgstr "StyleBox"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
@@ -5684,14 +5687,12 @@ msgid "Checked Item"
msgstr "Отмеченный элемент"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Radio Item"
-msgstr "Добавить элемент"
+msgstr "Переключатель"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Checked Radio Item"
-msgstr "Отмеченный элемент"
+msgstr "Отмеченный переключатель"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
@@ -7233,7 +7234,7 @@ msgstr "Библиотеки: "
#: modules/gdnative/register_types.cpp
msgid "GDNative"
-msgstr ""
+msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -7450,6 +7451,11 @@ msgstr "Собрать проект"
msgid "Warnings"
msgstr "Предупреждения"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Просмотр Файлов"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Конец трассировки внутреннего стека исключений"
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 9716dee696..94b6c137d0 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -7354,6 +7354,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Súbor:"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 0fe619654f..66e3c43bee 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -10,7 +10,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-10 08:44+0000\n"
+"PO-Revision-Date: 2018-06-27 13:43+0000\n"
"Last-Translator: matevž lapajne <sivar.lapajne@gmail.com>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/"
"godot/sl/>\n"
@@ -19,7 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3;\n"
-"X-Generator: Weblate 3.0.1-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -3340,23 +3340,23 @@ msgstr "Razreševanje..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Error making request"
-msgstr ""
+msgstr "Napaka pri izdelavi zahteve"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Idle"
-msgstr ""
+msgstr "Nedejaven"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
-msgstr ""
+msgstr "Ponovi"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download Error"
-msgstr ""
+msgstr "Napaka Pri Prenosu"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download for this asset is already in progress!"
-msgstr ""
+msgstr "Prenos za ta dodatek je že v teku!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "first"
@@ -3382,7 +3382,7 @@ msgstr "Vse"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
msgid "Plugins"
-msgstr ""
+msgstr "Vtičniki"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Sort:"
@@ -3390,7 +3390,7 @@ msgstr "Razvrsti:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Reverse"
-msgstr ""
+msgstr "Obrni"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -3407,15 +3407,15 @@ msgstr "Podpora..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
-msgstr ""
+msgstr "Uradno"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Testing"
-msgstr ""
+msgstr "Preskušanje"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
-msgstr ""
+msgstr "Dodatki v ZIP Datoteki"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -3423,6 +3423,9 @@ msgid ""
"Save your scene (for images to be saved in the same dir), or pick a save "
"path from the BakedLightmap properties."
msgstr ""
+"Ni mogoče določiti poti shranjevanja slik svetlobnih kart.\n"
+"Shrani prizor (za slike, da bodo shranjene v isti mapi), ali izberi pot za "
+"shranitev iz lastnosti Zapečene Svetlobne karte."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -3435,53 +3438,54 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
+"Napaka pri izdelavi slik, svetlobnih kart. Poskrbite, da je pot zapisljiva."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr ""
+msgstr "Zapeči Svetlobne karte"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
-msgstr ""
+msgstr "Predogled"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
-msgstr ""
+msgstr "Nastavi Zaskok"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr ""
+msgstr "Mrežni Zamik:"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step:"
-msgstr ""
+msgstr "Mrežni Korak:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
-msgstr ""
+msgstr "Rotacijski Odmik:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
-msgstr ""
+msgstr "Rotacijski Korak:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move Pivot"
-msgstr ""
+msgstr "Premakni Točko"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move Action"
-msgstr ""
+msgstr "Premakni Dejanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move vertical guide"
-msgstr ""
+msgstr "Premakni navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create new vertical guide"
-msgstr ""
+msgstr "Ustvari nov navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Remove vertical guide"
@@ -3489,59 +3493,61 @@ msgstr "Odstranite navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move horizontal guide"
-msgstr ""
+msgstr "Premakni vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create new horizontal guide"
-msgstr ""
+msgstr "Ustvari nov vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Remove horizontal guide"
-msgstr "Odstrani vodoravno vodilo"
+msgstr "Odstrani vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create new horizontal and vertical guides"
-msgstr ""
+msgstr "Ustvari nov vodoravni in navpični vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Edit IK Chain"
-msgstr ""
+msgstr "Uredi Verigo IK"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Edit CanvasItem"
-msgstr ""
+msgstr "Uredi Platno Stvari"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
-msgstr ""
+msgstr "Samo Sidrišča"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors and Margins"
-msgstr ""
+msgstr "Spremeni Sidrišča in Robove"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors"
-msgstr ""
+msgstr "Spremeni Sidrišča"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
-msgstr ""
+msgstr "Prilepi Pozicijo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Select Mode"
-msgstr "Izberite Način"
+msgstr "Izberi Način"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
-msgstr "Povlecite: Zavrti"
+msgstr "Povleci: Vrtenje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+Drag: Move"
-msgstr ""
+msgstr "Alt+Drag: Premakni"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
msgstr ""
+"Pritisni 'v' za Spremembo Točke in 'Shift+v' za Vleko Točke (med "
+"premikanjem)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
@@ -3561,16 +3567,16 @@ msgid ""
"Show a list of all objects at the position clicked\n"
"(same as Alt+RMB in select mode)."
msgstr ""
-"Ob kliku prikaži seznam vseh objektov na tem mestu.\n"
+"Ob kliku prikaži seznam vseh objektov na tem mestu\n"
"(isto kot Alt+RMB v načinu izbire)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Click to change object's rotation pivot."
-msgstr ""
+msgstr "Klikni, če želiš spremeniti rotacijsko točko objekta."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan Mode"
-msgstr ""
+msgstr "Način Plošče"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggles snapping"
@@ -3578,66 +3584,66 @@ msgstr "Preklopi pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Snap"
-msgstr ""
+msgstr "Uporabi Pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snapping options"
-msgstr ""
+msgstr "Možnosti pripenjanja"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to grid"
-msgstr ""
+msgstr "Pripni na mrežo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
-msgstr ""
+msgstr "Uporabi Rotacijsko Pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Configure Snap..."
-msgstr "Preoblikuj Zaskok..."
+msgstr "Nastavi Pripenjanje..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
-msgstr ""
+msgstr "Pripni Relativno"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Pixel Snap"
-msgstr ""
+msgstr "Uporabi Pripenjanje Pikslov"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Smart snapping"
-msgstr ""
+msgstr "Pametno pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to parent"
-msgstr ""
+msgstr "Pripni na Predhodnika"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to node anchor"
-msgstr ""
+msgstr "Pripni na gradnik vodilo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to node sides"
-msgstr ""
+msgstr "Pripni na gradnik strani"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to other nodes"
-msgstr ""
+msgstr "Pripni na druge gradnike"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to guides"
-msgstr ""
+msgstr "Pripni na vodnike"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock the selected object in place (can't be moved)."
-msgstr "Izbrani predmet zaklenite na svoje mesto (ga ni mogoče premakniti)."
+msgstr "Izbrani predmet zakleni na svoje mesto (ni ga mogoče premakniti)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock the selected object (can be moved)."
-msgstr "Odklenite izbrani predmet (ga lahko premaknete)."
+msgstr "Odkleni izbrani predmet (lahko ga premaknete)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Makes sure the object's children are not selectable."
@@ -5945,9 +5951,8 @@ msgid "Imported Project"
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "Ime Projekta:"
+msgstr "Neveljavno Ime Projekta."
#: editor/project_manager.cpp
msgid "Couldn't create folder."
@@ -7374,6 +7379,11 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Ogled datotek"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index c838174131..9998a16e3a 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -7461,6 +7461,11 @@ msgstr "Пројекат"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Погледај датотеке"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 975418d4fb..4d293a592d 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -7272,6 +7272,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index 9ec654128a..f9e65bb600 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -2,24 +2,24 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# bergmarklund <davemcgroin@gmail.com>, 2017, 2018.
# Christoffer Sundbom <christoffer_karlsson@live.se>, 2017.
# Jakob Sinclair <sinclair.jakob@mailbox.org>, 2018.
# . <grenoscar@gmail.com>, 2018.
-#
+# Kristoffer Grundström <kristoffer.grundstrom1983@gmail.com>, 2018.
+# Magnus Helander <helander@fastmail.net>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-05-07 11:42+0000\n"
-"Last-Translator: anonymous <>\n"
+"PO-Revision-Date: 2018-07-24 12:44+0000\n"
+"Last-Translator: Magnus Helander <helander@fastmail.net>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/"
"godot/sv/>\n"
"Language: sv\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -30,9 +30,8 @@ msgid "All Selection"
msgstr "Alla urval"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
-msgstr "Anim Ändra Värde"
+msgstr "Anim Ändra Nyckelram Tid"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
@@ -88,16 +87,15 @@ msgstr "Ändra Anim Spårets Värde Läge"
#: editor/animation_editor.cpp
msgid "Anim Track Change Wrap Mode"
-msgstr ""
+msgstr "Anim Spåra Ändra Linda om Läge"
#: editor/animation_editor.cpp
msgid "Edit Node Curve"
msgstr "Redigera Nodkurva"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Edit Selection Curve"
-msgstr "Redigera Urval Kurva"
+msgstr "Redigera Urvalsurva"
#: editor/animation_editor.cpp
msgid "Anim Delete Keys"
@@ -7903,6 +7901,11 @@ msgstr "Projekt"
msgid "Warnings"
msgstr "Varning"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Visa Filer"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index d7910c2c87..d3d80facc3 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -7274,6 +7274,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 4db8459f1b..2393ca98a9 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -7359,6 +7359,11 @@ msgstr "Build โปรเจกต์"
msgid "Warnings"
msgstr "คำเตือน"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "ดูไฟล์"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "สิ้นสุดสแตคข้อผิดพลาดภายใน"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 292cec4063..abe7d485fa 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -17,18 +17,19 @@
# razah <icnikerazah@gmail.com>, 2017-2018.
# stnmycri <satenmeycri@gmail.com>, 2017-2018.
# Yavuz Günay <yavuzgunay@gmail.com>, 2017.
+# Onur Sanır <onursanir@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-06-10 09:46+0000\n"
-"Last-Translator: Aykut YILDIRIM <aykutyildirim@windowslive.com>\n"
+"PO-Revision-Date: 2018-07-07 20:42+0000\n"
+"Last-Translator: Onur Sanır <onursanir@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0.1-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -5696,9 +5697,8 @@ msgid "Options"
msgstr "Seçenekler"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Has,Many,Options"
-msgstr "Bir Çok,Seçenek,Var!"
+msgstr "Birçok,Seçenek,Var"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -7438,6 +7438,11 @@ msgstr "Projeyi İnşa et"
msgid "Warnings"
msgstr "Uyarılar"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Dosyaları Görüntüle"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "İç özel durum yığını izlemesinin sonu"
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 067c7be724..d940561131 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -7447,6 +7447,11 @@ msgstr "Зібрати проект"
msgid "Warnings"
msgstr "Попередження"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "Перегляд файлів"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "Кінець трасування стека для внутрішнього виключення"
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 0162eb0788..3857bff9b0 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -7331,6 +7331,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 6651bd170c..faf77300b8 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -2,25 +2,24 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# 01lifeleft <01lifeleft@gmail.com>, 2018.
# Dlean Jeans <dleanjeans@gmail.com>, 2018.
# Hai Le <dark.hades.1102@gmail.com>, 2017.
# Nguyễn Tuấn Anh <anhnt.fami@gmail.com>, 2017.
# Tung Le <tungkradle@gmail.com>, 2017.
-#
+# 38569459 <xxx38569459@gmail.com>, 2018.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-04-18 15:44+0000\n"
-"Last-Translator: 01lifeleft <01lifeleft@gmail.com>\n"
+"PO-Revision-Date: 2018-07-22 06:42+0000\n"
+"Last-Translator: 38569459 <xxx38569459@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/"
"godot/vi/>\n"
"Language: vi\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -141,24 +140,24 @@ msgstr "Chọn Scale"
#: editor/animation_editor.cpp
msgid "Scale From Cursor"
-msgstr ""
+msgstr "Scale từ trỏ chuột"
#: editor/animation_editor.cpp
msgid "Goto Next Step"
-msgstr ""
+msgstr "Đến Step tiếp theo"
#: editor/animation_editor.cpp
msgid "Goto Prev Step"
-msgstr ""
+msgstr "Đến Step trước đó"
#: editor/animation_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
msgid "Linear"
-msgstr ""
+msgstr "Tuyến"
#: editor/animation_editor.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
-msgstr ""
+msgstr "Cố định"
#: editor/animation_editor.cpp
msgid "In"
@@ -178,11 +177,11 @@ msgstr "Ngoài-Trong"
#: editor/animation_editor.cpp
msgid "Transitions"
-msgstr ""
+msgstr "Chuyển tiếp"
#: editor/animation_editor.cpp
msgid "Optimize Animation"
-msgstr ""
+msgstr "Tối ưu Animation"
#: editor/animation_editor.cpp
msgid "Clean-Up Animation"
@@ -190,11 +189,11 @@ msgstr "Dọn dẹp Animation"
#: editor/animation_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr ""
+msgstr "Tạo track mới cho %s và chèn key?"
#: editor/animation_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr ""
+msgstr "Tạo %d track mới và chèn key?"
#: editor/animation_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/plugins/abstract_polygon_2d_editor.cpp
@@ -210,15 +209,15 @@ msgstr "Tạo & Chèn Anim"
#: editor/animation_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr ""
+msgstr "Chèn Track & Key Anim"
#: editor/animation_editor.cpp
msgid "Anim Insert Key"
-msgstr ""
+msgstr "Chèn Key Anim"
#: editor/animation_editor.cpp
msgid "Change Anim Len"
-msgstr ""
+msgstr "Đổi độ dài Anim"
#: editor/animation_editor.cpp
msgid "Change Anim Loop"
@@ -226,23 +225,25 @@ msgstr "Đổi vòng lặp Anim"
#: editor/animation_editor.cpp
msgid "Anim Create Typed Value Key"
-msgstr ""
+msgstr "Tạo Key để nhập giá trị Anim"
#: editor/animation_editor.cpp
msgid "Anim Insert"
msgstr "Chèn Anim"
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Anim Scale Keys"
-msgstr ""
+msgstr "Anim Scale Keys"
#: editor/animation_editor.cpp
msgid "Anim Add Call Track"
msgstr "Thêm Track Gọi Function"
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Animation zoom."
-msgstr ""
+msgstr "Phóng Animation."
#: editor/animation_editor.cpp
msgid "Length (s):"
@@ -266,27 +267,27 @@ msgstr "Mở/Tắt lặp animation."
#: editor/animation_editor.cpp
msgid "Add new tracks."
-msgstr ""
+msgstr "Thêm track mới."
#: editor/animation_editor.cpp
msgid "Move current track up."
-msgstr ""
+msgstr "Di chuyển track lên."
#: editor/animation_editor.cpp
msgid "Move current track down."
-msgstr ""
+msgstr "Di chuyển track xuống."
#: editor/animation_editor.cpp
msgid "Remove selected track."
-msgstr ""
+msgstr "Bỏ track đang chọn."
#: editor/animation_editor.cpp
msgid "Track tools"
-msgstr ""
+msgstr "Công cụ Track"
#: editor/animation_editor.cpp
msgid "Enable editing of individual keys by clicking them."
-msgstr ""
+msgstr "Cho phép chỉnh sửa từng key riêng bằng cách chọn chúng."
#: editor/animation_editor.cpp
msgid "Anim. Optimizer"
@@ -306,162 +307,171 @@ msgstr ""
#: editor/animation_editor.cpp
msgid "Optimize"
-msgstr ""
+msgstr "Tối ưu"
#: editor/animation_editor.cpp
msgid "Select an AnimationPlayer from the Scene Tree to edit animations."
msgstr "Chọn một AnimationPlayer từ Scene Tree để chỉnh sửa animation."
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Key"
-msgstr ""
+msgstr "Mã"
#: editor/animation_editor.cpp
msgid "Transition"
-msgstr ""
+msgstr "Chuyển tiếp"
#: editor/animation_editor.cpp
msgid "Scale Ratio:"
-msgstr ""
+msgstr "Tỉ lệ Scale:"
#: editor/animation_editor.cpp
msgid "Call Functions in Which Node?"
-msgstr ""
+msgstr "Gọi Function từ Node nào?"
#: editor/animation_editor.cpp
msgid "Remove invalid keys"
-msgstr ""
+msgstr "Hủy key không đúng chuẩn"
#: editor/animation_editor.cpp
+#, fuzzy
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "Gỡ bỏ track trống và không tìm thấy"
#: editor/animation_editor.cpp
msgid "Clean-up all animations"
-msgstr ""
+msgstr "Dọn dẹp tất cả animations"
#: editor/animation_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr ""
+msgstr "Dọn dẹp tất cả Animation (KHÔNG THỂ HỒI LẠI)"
#: editor/animation_editor.cpp
msgid "Clean-Up"
-msgstr ""
+msgstr "Dọn dẹp"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr ""
+msgstr "Đổi lại size Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr ""
+msgstr "Đổi loại giá trị Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr ""
+msgstr "Đổi giá trị Array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr ""
+msgstr "Đến Dòng"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr ""
+msgstr "Dòng số:"
#: editor/code_editor.cpp
msgid "No Matches"
-msgstr ""
+msgstr "Không tìm thấy"
#: editor/code_editor.cpp
msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp
+#, fuzzy
msgid "Match Case"
-msgstr ""
+msgstr "Trùng khớp"
#: editor/code_editor.cpp
msgid "Whole Words"
-msgstr ""
+msgstr "Cả từ"
#: editor/code_editor.cpp
msgid "Replace"
-msgstr ""
+msgstr "Thay thế"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr ""
+msgstr "Thay thế tất cả"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr ""
+msgstr "Chỉ lựa chọn"
#: editor/code_editor.cpp
msgid "Zoom In"
-msgstr ""
+msgstr "Phóng to"
#: editor/code_editor.cpp
msgid "Zoom Out"
-msgstr ""
+msgstr "Thu nhỏ"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr ""
+msgstr "Đặt lại phóng"
#: editor/code_editor.cpp editor/script_editor_debugger.cpp
msgid "Line:"
-msgstr ""
+msgstr "Dòng:"
#: editor/code_editor.cpp
+#, fuzzy
msgid "Col:"
-msgstr ""
+msgstr "Col:"
#: editor/connections_dialog.cpp
msgid "Method in target Node must be specified!"
-msgstr ""
+msgstr "Cách thức trong Node được chọn phải được ghi rõ!"
#: editor/connections_dialog.cpp
msgid ""
"Target method not found! Specify a valid method or attach a script to target "
"Node."
msgstr ""
+"Cách thức của đối tượng không tìm thấy! ghi rõ một cách thức hợp lệ hoặc "
+"đính kèm một script cho đối tượng Node."
#: editor/connections_dialog.cpp
msgid "Connect To Node:"
-msgstr ""
+msgstr "Kết nối đến Node:"
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
msgid "Add"
-msgstr ""
+msgstr "Thêm"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
-msgstr ""
+msgstr "Xóa"
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Add Extra Call Argument:"
-msgstr ""
+msgstr "Thêm đối số:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
msgstr ""
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Path to Node:"
-msgstr ""
+msgstr "Đường đến Node:"
#: editor/connections_dialog.cpp
msgid "Make Function"
-msgstr ""
+msgstr "Tạo Function"
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Deferred"
-msgstr ""
+msgstr "Hoãn lại"
#: editor/connections_dialog.cpp
msgid "Oneshot"
@@ -479,45 +489,45 @@ msgstr ""
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr ""
+msgstr "Tắt"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr ""
+msgstr "Kết nối"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr ""
+msgstr "Kết nối '%s' đến '%s'"
#: editor/connections_dialog.cpp
msgid "Connecting Signal:"
-msgstr ""
+msgstr "Đang kết nối Signal:"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr ""
+msgstr "Hủy kết nối '%s' từ '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
-msgstr ""
+msgstr "Kết nối..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_editor_plugin.cpp
msgid "Disconnect"
-msgstr ""
+msgstr "Hủy kết nối"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr ""
+msgstr "Tín hiệu"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr ""
+msgstr "Đổi %s Type"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Change"
-msgstr ""
+msgstr "Đổi"
#: editor/create_dialog.cpp
msgid "Create New %s"
@@ -526,38 +536,39 @@ msgstr "Tạo %s Mới"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
msgid "Favorites:"
-msgstr ""
+msgstr "Ưa thích:"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
msgid "Recent:"
-msgstr ""
+msgstr "Gần đây:"
#: editor/create_dialog.cpp editor/editor_node.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp
#: editor/quick_open.cpp
msgid "Search:"
-msgstr ""
+msgstr "Tìm kiếm:"
#: editor/create_dialog.cpp editor/editor_help.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp
#: editor/quick_open.cpp
msgid "Matches:"
-msgstr ""
+msgstr "Phù hợp:"
#: editor/create_dialog.cpp editor/editor_help.cpp
#: editor/plugins/asset_library_editor_plugin.cpp editor/property_selector.cpp
#: editor/script_editor_debugger.cpp
msgid "Description:"
-msgstr ""
+msgstr "Mô tả:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
-msgstr ""
+msgstr "Tìm kiếm thay thế cho:"
#: editor/dependency_editor.cpp
+#, fuzzy
msgid "Dependencies For:"
-msgstr ""
+msgstr "Phần phụ thuộc cho:"
#: editor/dependency_editor.cpp
msgid ""
@@ -2017,12 +2028,14 @@ msgid "Issue Tracker"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Community"
-msgstr ""
+msgstr "Cộng đồng"
#: editor/editor_node.cpp
+#, fuzzy
msgid "About"
-msgstr ""
+msgstr "Thông tin"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -4223,7 +4236,7 @@ msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
msgid "Volume"
-msgstr ""
+msgstr "Âm lượng"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Emission Source: "
@@ -4265,7 +4278,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Select Points"
-msgstr ""
+msgstr "Chọn Points"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -4275,12 +4288,12 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Click: Add Point"
-msgstr ""
+msgstr "Nhấp: Tạo Point"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Right Click: Delete Point"
-msgstr ""
+msgstr "Nhấp chuột phải: Xóa Point"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Select Control Points (Shift+Drag)"
@@ -4299,7 +4312,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Delete Point"
-msgstr ""
+msgstr "Xóa Point"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -4562,27 +4575,27 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme"
-msgstr ""
+msgstr "Lưu Theme"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As"
-msgstr ""
+msgstr "Lưu Theme thành"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close Docs"
-msgstr ""
+msgstr "Đóng Docs"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
-msgstr ""
+msgstr "Đóng tất cả"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
-msgstr ""
+msgstr "Đóng tất cả Tab"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
-msgstr ""
+msgstr "Chạy"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
@@ -4591,12 +4604,12 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find..."
-msgstr ""
+msgstr "Tìm..."
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr ""
+msgstr "Tìm tiếp theo"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
@@ -4613,7 +4626,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr ""
+msgstr "Tiếp tục"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
@@ -4645,11 +4658,11 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Discard"
-msgstr ""
+msgstr "Hủy"
#: editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
-msgstr ""
+msgstr "Tạo Script"
#: editor/plugins/script_editor_plugin.cpp
msgid ""
@@ -4680,7 +4693,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "Pick Color"
-msgstr ""
+msgstr "Chọn màu"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Case"
@@ -4701,13 +4714,13 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Cut"
-msgstr ""
+msgstr "Cắt"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
-msgstr ""
+msgstr "Copy"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6252,8 +6265,9 @@ msgid "Project Settings (project.godot)"
msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+#, fuzzy
msgid "General"
-msgstr ""
+msgstr "Tổng quan"
#: editor/project_settings_editor.cpp editor/property_editor.cpp
msgid "Property:"
@@ -7283,6 +7297,10 @@ msgstr ""
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+msgid "View log"
+msgstr ""
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 48e30ceab3..51e0181fc8 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -7372,6 +7372,11 @@ msgstr "构建项目"
msgid "Warnings"
msgstr "警告"
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "查看文件"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr "内部异常堆栈追朔结束"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index 568390a7a8..de03512af1 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -7589,6 +7589,11 @@ msgstr "專案"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "檔案"
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 38b565a37f..df0c474322 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -2,7 +2,6 @@
# Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-#
# Allen H <w84miracle@gmail.com>, 2017.
# Billy SU <g4691821@gmail.com>, 2018.
# Chao Yu <casd82@gmail.com>, 2017.
@@ -12,19 +11,18 @@
# popcade <popcade@gmail.com>, 2016.
# Qing <icinriiq@gmail.com>, 2018.
# Sam Pan <sampan66@gmail.com>, 2016.
-#
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2018-04-24 09:35+0000\n"
-"Last-Translator: Qing <icinriiq@gmail.com>\n"
+"PO-Revision-Date: 2018-07-15 16:35+0000\n"
+"Last-Translator: Kisaragi Hiu <mail@kisaragi-hiu.com>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
"Language: zh_TW\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
#: editor/animation_editor.cpp
msgid "Disabled"
@@ -35,9 +33,8 @@ msgid "All Selection"
msgstr "所有的選擇"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
-msgstr "動畫更改座標"
+msgstr "動畫更改關鍵幀時間"
#: editor/animation_editor.cpp
msgid "Anim Change Transition"
@@ -52,9 +49,8 @@ msgid "Anim Change Keyframe Value"
msgstr "動畫更改關鍵幀數值"
#: editor/animation_editor.cpp
-#, fuzzy
msgid "Anim Change Call"
-msgstr "動畫改變呼叫"
+msgstr "動畫更改呼叫"
#: editor/animation_editor.cpp
msgid "Anim Add Track"
@@ -345,7 +341,7 @@ msgstr "移除無效按鍵"
#: editor/animation_editor.cpp
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "刪除未解決或是空的軌道"
#: editor/animation_editor.cpp
msgid "Clean-up all animations"
@@ -523,9 +519,8 @@ msgid "Signals"
msgstr "信號"
#: editor/create_dialog.cpp
-#, fuzzy
msgid "Change %s Type"
-msgstr "變更鏡頭尺寸"
+msgstr "變更 %s 尺寸"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -533,9 +528,8 @@ msgid "Change"
msgstr "更換"
#: editor/create_dialog.cpp
-#, fuzzy
msgid "Create New %s"
-msgstr "新增"
+msgstr "新增 %s"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
@@ -618,7 +612,7 @@ msgstr "相依性編輯器"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr ""
+msgstr "搜尋替代資源:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help.cpp editor/editor_node.cpp editor/filesystem_dock.cpp
@@ -670,7 +664,7 @@ msgstr "修復相依性"
#: editor/dependency_editor.cpp
msgid "Errors loading!"
-msgstr ""
+msgstr "載入錯誤!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
@@ -682,7 +676,7 @@ msgstr "擁有"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr ""
+msgstr "沒有明定擁有者的資源:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Orphan Resource Explorer"
@@ -701,16 +695,19 @@ msgid "Delete"
msgstr "刪除"
#: editor/dictionary_property_edit.cpp
+#, fuzzy
msgid "Change Dictionary Key"
-msgstr ""
+msgstr "改變字典 key"
#: editor/dictionary_property_edit.cpp
+#, fuzzy
msgid "Change Dictionary Value"
-msgstr ""
+msgstr "改變字典 value"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Thanks from the Godot community!"
-msgstr ""
+msgstr "Godot 社群感謝你!"
#: editor/editor_about.cpp
msgid "Thanks!"
@@ -718,7 +715,7 @@ msgstr "謝謝!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
-msgstr ""
+msgstr "Godot Engine 貢獻者"
#: editor/editor_about.cpp
msgid "Project Founders"
@@ -726,12 +723,11 @@ msgstr "專案創始人"
#: editor/editor_about.cpp
msgid "Lead Developer"
-msgstr ""
+msgstr "主開發者"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Project Manager "
-msgstr "專案創始人"
+msgstr "專案管理人 "
#: editor/editor_about.cpp
msgid "Developers"
@@ -739,35 +735,38 @@ msgstr "開發者"
#: editor/editor_about.cpp
msgid "Authors"
-msgstr ""
+msgstr "作者"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr ""
+msgstr "白金贊助"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr ""
+msgstr "黃金贊助"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Mini Sponsors"
-msgstr ""
+msgstr "迷你贊助"
#: editor/editor_about.cpp
msgid "Gold Donors"
-msgstr ""
+msgstr "黃金捐贈者"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Silver Donors"
-msgstr ""
+msgstr "白銀捐贈者"
#: editor/editor_about.cpp
+#, fuzzy
msgid "Bronze Donors"
-msgstr ""
+msgstr "紅銅捐贈者"
#: editor/editor_about.cpp
msgid "Donors"
-msgstr ""
+msgstr "捐贈者"
#: editor/editor_about.cpp
msgid "License"
@@ -775,7 +774,7 @@ msgstr "授權"
#: editor/editor_about.cpp
msgid "Thirdparty License"
-msgstr ""
+msgstr "第三方授權條款"
#: editor/editor_about.cpp
msgid ""
@@ -784,14 +783,16 @@ msgid ""
"is an exhaustive list of all such thirdparty components with their "
"respective copyright statements and license terms."
msgstr ""
+"Godot Engine 依賴著許多與 MIT 授權條款相容、自由開源的第三方函式庫。以下是這"
+"些第三方元件的完整列表,附有它們各自的著作權宣示與授權條款。"
#: editor/editor_about.cpp
msgid "All Components"
-msgstr ""
+msgstr "所有元件"
#: editor/editor_about.cpp
msgid "Components"
-msgstr ""
+msgstr "元件"
#: editor/editor_about.cpp
msgid "Licenses"
@@ -799,21 +800,20 @@ msgstr "授權"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Error opening package file, not in zip format."
-msgstr ""
+msgstr "開啟套件檔案出錯,非 zip 格式。"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Uncompressing Assets"
-msgstr "(重新)載入素材"
+msgstr "正在解壓縮素材"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package Installed Successfully!"
-msgstr ""
+msgstr "套件安裝成功!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr ""
+msgstr "成功!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -821,147 +821,148 @@ msgid "Install"
msgstr "安裝"
#: editor/editor_asset_installer.cpp
+#, fuzzy
msgid "Package Installer"
-msgstr ""
+msgstr "套件安裝"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
-msgstr ""
+msgstr "喇叭"
#: editor/editor_audio_buses.cpp
msgid "Add Effect"
-msgstr ""
+msgstr "新增效果"
#: editor/editor_audio_buses.cpp
msgid "Rename Audio Bus"
-msgstr ""
+msgstr "重新命名 Audio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Change Audio Bus Volume"
-msgstr "重設縮放大小"
+msgstr "變更 Audio Bus 音量"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Toggle Audio Bus Solo"
-msgstr ""
+msgstr "切換 Audio Bus 的 Solo"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Toggle Audio Bus Mute"
-msgstr ""
+msgstr "切換 Audio Bus 的 Mute"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Toggle Audio Bus Bypass Effects"
-msgstr ""
+msgstr "切換 Audio Bus 忽略效果"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr ""
+msgstr "選擇 Audio Bus 輸出地點"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr ""
+msgstr "新增 Audio Bus 效果"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr ""
+msgstr "移動 Bus 效果"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr ""
+msgstr "刪除 Bus 效果"
#: editor/editor_audio_buses.cpp
msgid "Audio Bus, Drag and Drop to rearrange."
-msgstr ""
+msgstr "Audio Bus。拖放以重新排列。"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Solo"
-msgstr ""
+msgstr "Solo"
#: editor/editor_audio_buses.cpp
msgid "Mute"
msgstr "靜音"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Bypass"
-msgstr ""
+msgstr "忽略效果 (Bypass)"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Bus options"
-msgstr "除錯選項"
+msgstr "Bus 選項"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr ""
+msgstr "製作複本"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Reset Volume"
-msgstr "重設縮放大小"
+msgstr "重設音量"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Delete Effect"
-msgstr "刪除"
+msgstr "刪除效果"
#: editor/editor_audio_buses.cpp
msgid "Audio"
-msgstr ""
+msgstr "聲音"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "新增 Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "Master Bus 不能被刪除!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr ""
+msgstr "刪除 Audio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Duplicate Audio Bus"
-msgstr "複製所選"
+msgstr "製作 Audio Bus 的複本"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Reset Bus Volume"
-msgstr "重設縮放大小"
+msgstr "重設 Bus 音量"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr ""
+msgstr "移動 Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr ""
+msgstr "另存 Audio Bus 配置為..."
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Location for New Layout..."
-msgstr ""
+msgstr "新配置的位置..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr ""
+msgstr "開啟 Audio Bus 配置"
#: editor/editor_audio_buses.cpp
msgid "There is no 'res://default_bus_layout.tres' file."
-msgstr ""
+msgstr "「res://default_bus_layout.tres」檔案不存在。"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr ""
+msgstr "檔案格式不正確,不是 Audio Bus 配置檔。"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr ""
+msgstr "新增 Bus"
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr ""
+msgstr "建立新的 Bus 配置。"
#: editor/editor_audio_buses.cpp editor/property_editor.cpp
#: editor/script_create_dialog.cpp
@@ -970,7 +971,7 @@ msgstr "載入"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr ""
+msgstr "讀取現存的 Bus 配置。"
#: editor/editor_audio_buses.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -979,7 +980,7 @@ msgstr "另存新檔"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr ""
+msgstr "儲存目前的 Bus 配置到檔案裡。"
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -987,7 +988,7 @@ msgstr "載入預設值"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr ""
+msgstr "載入預設的 Bus 配置。"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -999,7 +1000,7 @@ msgstr "合法字元:"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing engine class name."
-msgstr ""
+msgstr "不正確的名字。名字不能與現有的 engine class 名衝突。"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name. Must not collide with an existing buit-in type name."
@@ -1022,16 +1023,19 @@ msgid "Not in resource path."
msgstr "在資源路徑中找不到"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Add AutoLoad"
-msgstr ""
+msgstr "新增 AutoLoad"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Autoload '%s' already exists!"
-msgstr ""
+msgstr "Autoload「%s」已經存在!"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Rename Autoload"
-msgstr ""
+msgstr "重新命名 Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
@@ -1039,19 +1043,21 @@ msgstr ""
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
-msgstr ""
+msgstr "移動 Autoload"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Remove Autoload"
-msgstr ""
+msgstr "刪除 Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Enable"
msgstr "啟用"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Rearrange Autoloads"
-msgstr ""
+msgstr "重新排列 Autoload"
#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
#: scene/gui/file_dialog.cpp
@@ -1084,16 +1090,18 @@ msgid "Updating scene..."
msgstr "更新場景中..."
#: editor/editor_data.cpp
+#, fuzzy
msgid "[empty]"
-msgstr ""
+msgstr "(空)"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr ""
+msgstr "(未儲存)"
#: editor/editor_dir_dialog.cpp
+#, fuzzy
msgid "Please select a base directory first"
-msgstr ""
+msgstr "請先選擇一個基底的資料夾"
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1122,7 +1130,7 @@ msgstr "選擇"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr ""
+msgstr "儲存檔案:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1137,22 +1145,20 @@ msgid "File Exists, Overwrite?"
msgstr "檔案已經存在, 要覆寫嗎?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select Current Folder"
-msgstr "新增資料夾"
+msgstr "選擇目前的資料夾"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr ""
+msgstr "複製路徑"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Show In File Manager"
-msgstr ""
+msgstr "在檔案管理員內顯示"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Folder..."
-msgstr "新增資料夾"
+msgstr "新增資料夾..."
#: editor/editor_file_dialog.cpp
msgid "Refresh"
@@ -1160,7 +1166,7 @@ msgstr "重新整理"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr ""
+msgstr "可認得全部"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
@@ -1168,7 +1174,7 @@ msgstr "所有類型檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
-msgstr ""
+msgstr "開啟檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
@@ -1190,7 +1196,7 @@ msgstr "儲存"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr ""
+msgstr "儲存檔案"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -1209,12 +1215,13 @@ msgid "Toggle Hidden Files"
msgstr "切換顯示隱藏檔案"
#: editor/editor_file_dialog.cpp
+#, fuzzy
msgid "Toggle Favorite"
-msgstr ""
+msgstr "切換最愛"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr ""
+msgstr "切換模式"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
@@ -1247,8 +1254,9 @@ msgid "File:"
msgstr "檔案:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
msgid "Must use a valid extension."
-msgstr ""
+msgstr "必須使用有效的副檔名。"
#: editor/editor_file_system.cpp
msgid "ScanSources"
@@ -1261,27 +1269,28 @@ msgstr "(重新)載入素材"
#: editor/editor_help.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr ""
+msgstr "搜尋幫助"
#: editor/editor_help.cpp
msgid "Class List:"
-msgstr ""
+msgstr "Class 列表:"
#: editor/editor_help.cpp
msgid "Search Classes"
-msgstr ""
+msgstr "搜尋 Class"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Top"
-msgstr ""
+msgstr "上面"
#: editor/editor_help.cpp editor/property_editor.cpp
msgid "Class:"
-msgstr ""
+msgstr "Class:"
#: editor/editor_help.cpp editor/scene_tree_editor.cpp
msgid "Inherits:"
-msgstr ""
+msgstr "繼承:"
#: editor/editor_help.cpp
msgid "Inherited by:"
@@ -1305,19 +1314,19 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Public Methods:"
-msgstr ""
+msgstr "公開 method:"
#: editor/editor_help.cpp
msgid "GUI Theme Items"
-msgstr ""
+msgstr "介面主題項目"
#: editor/editor_help.cpp
msgid "GUI Theme Items:"
-msgstr ""
+msgstr "介面主題項目:"
#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
-msgstr ""
+msgstr "訊號:"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -1333,11 +1342,11 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Constants"
-msgstr ""
+msgstr "定數"
#: editor/editor_help.cpp
msgid "Constants:"
-msgstr ""
+msgstr "定數:"
#: editor/editor_help.cpp
msgid "Description"
@@ -1345,7 +1354,7 @@ msgstr "描述:"
#: editor/editor_help.cpp
msgid "Online Tutorials:"
-msgstr ""
+msgstr "線上教學:"
#: editor/editor_help.cpp
msgid ""
@@ -1353,20 +1362,25 @@ msgid ""
"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
"url][/color]."
msgstr ""
+"目前沒有這個 class 的教學,你可以[color=$color][url=$url]貢獻一個[/url][/"
+"color]或[color=$color][url=$url2]要求一個[/url][/color]。"
#: editor/editor_help.cpp
msgid "Properties"
msgstr ""
#: editor/editor_help.cpp
+#, fuzzy
msgid "Property Description:"
-msgstr ""
+msgstr "Property 說明:"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this property. Please help us by "
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"目前沒有這個 property 的說明。請幫我們[color=$color][url=$url]貢獻[/url][/"
+"color]一個!"
#: editor/editor_help.cpp
msgid "Methods"
@@ -1374,13 +1388,15 @@ msgstr "方法"
#: editor/editor_help.cpp
msgid "Method Description:"
-msgstr ""
+msgstr "Method 說明:"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this method. Please help us by [color="
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"目前沒有這個 method 的說明。請幫我們[color=$color][url=$url]貢獻[/url][/"
+"color]一個!"
#: editor/editor_help.cpp
msgid "Search Text"
@@ -1408,15 +1424,15 @@ msgstr "輸出:"
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
-msgstr ""
+msgstr "專案輸出失敗,錯誤代碼是 %d。"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr ""
+msgstr "儲存資源錯誤!"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
-msgstr ""
+msgstr "另存資源為..."
#: editor/editor_node.cpp editor/plugins/spatial_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
@@ -1424,16 +1440,17 @@ msgid "I see..."
msgstr "我知道了"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Can't open file for writing:"
-msgstr ""
+msgstr "無法以寫入模式開啟檔案:"
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr ""
+msgstr "要求了不明的檔案格式:"
#: editor/editor_node.cpp
msgid "Error while saving."
-msgstr ""
+msgstr "儲存中發生了錯誤。"
#: editor/editor_node.cpp
msgid "Can't open '%s'."
@@ -1445,11 +1462,12 @@ msgstr "分析 \"%s\" 時發生錯誤。"
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr ""
+msgstr "意料外的檔案結尾 (EOF) '%s'。"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "缺失 '%s' 或它的依存。"
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
@@ -1457,7 +1475,7 @@ msgstr "載入 \"%s\" 時發生錯誤。"
#: editor/editor_node.cpp
msgid "Saving Scene"
-msgstr ""
+msgstr "正在儲存場景"
#: editor/editor_node.cpp
msgid "Analyzing"
@@ -7424,6 +7442,11 @@ msgstr "專案設定"
msgid "Warnings"
msgstr ""
+#: modules/mono/editor/mono_bottom_panel.cpp
+#, fuzzy
+msgid "View log"
+msgstr "過濾檔案..."
+
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
msgstr ""