diff options
310 files changed, 10901 insertions, 2108 deletions
diff --git a/SConstruct b/SConstruct index df0e40381f..7ef4d646a7 100644 --- a/SConstruct +++ b/SConstruct @@ -118,6 +118,7 @@ env_base.__class__.split_lib = methods.split_lib env_base.__class__.add_shared_library = methods.add_shared_library env_base.__class__.add_library = methods.add_library env_base.__class__.add_program = methods.add_program +env_base.__class__.CommandNoCache = methods.CommandNoCache env_base["x86_libtheora_opt_gcc"] = False env_base["x86_libtheora_opt_vc"] = False diff --git a/core/SCsub b/core/SCsub index c4f1cdbe97..c508ecc37e 100644 --- a/core/SCsub +++ b/core/SCsub @@ -93,19 +93,19 @@ env.add_source_files(env.core_sources, "*.cpp") # Make binders import make_binders -env.Command(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run) +env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run) # Authors env.Depends('#core/authors.gen.h', "../AUTHORS.md") -env.Command('#core/authors.gen.h', "../AUTHORS.md", methods.make_authors_header) +env.CommandNoCache('#core/authors.gen.h', "../AUTHORS.md", methods.make_authors_header) # Donors env.Depends('#core/donors.gen.h', "../DONORS.md") -env.Command('#core/donors.gen.h', "../DONORS.md", methods.make_donors_header) +env.CommandNoCache('#core/donors.gen.h', "../DONORS.md", methods.make_donors_header) # License env.Depends('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) -env.Command('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], methods.make_license_header) +env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], methods.make_license_header) # Chain load SCsubs SConscript('os/SCsub') diff --git a/core/math/delaunay.cpp b/core/math/delaunay.cpp new file mode 100644 index 0000000000..8cae92b7c0 --- /dev/null +++ b/core/math/delaunay.cpp @@ -0,0 +1 @@ +#include "delaunay.h" diff --git a/core/math/delaunay.h b/core/math/delaunay.h new file mode 100644 index 0000000000..09aebc773f --- /dev/null +++ b/core/math/delaunay.h @@ -0,0 +1,145 @@ +#ifndef DELAUNAY_H +#define DELAUNAY_H + +#include "math_2d.h" + +class Delaunay2D { +public: + struct Triangle { + + int points[3]; + bool bad; + Triangle() { bad = false; } + Triangle(int p_a, int p_b, int p_c) { + points[0] = p_a; + points[1] = p_b; + points[2] = p_c; + bad = false; + } + }; + + struct Edge { + int edge[2]; + bool bad; + Edge() { bad = false; } + Edge(int p_a, int p_b) { + bad = false; + edge[0] = p_a; + edge[1] = p_b; + } + }; + + static bool circum_circle_contains(const Vector<Vector2> &p_vertices, const Triangle &p_triangle, int p_vertex) { + + Vector2 p1 = p_vertices[p_triangle.points[0]]; + Vector2 p2 = p_vertices[p_triangle.points[1]]; + Vector2 p3 = p_vertices[p_triangle.points[2]]; + + real_t ab = p1.x * p1.x + p1.y * p1.y; + real_t cd = p2.x * p2.x + p2.y * p2.y; + real_t ef = p3.x * p3.x + p3.y * p3.y; + + Vector2 circum( + (ab * (p3.y - p2.y) + cd * (p1.y - p3.y) + ef * (p2.y - p1.y)) / (p1.x * (p3.y - p2.y) + p2.x * (p1.y - p3.y) + p3.x * (p2.y - p1.y)), + (ab * (p3.x - p2.x) + cd * (p1.x - p3.x) + ef * (p2.x - p1.x)) / (p1.y * (p3.x - p2.x) + p2.y * (p1.x - p3.x) + p3.y * (p2.x - p1.x))); + + circum *= 0.5; + float r = p1.distance_squared_to(circum); + float d = p_vertices[p_vertex].distance_squared_to(circum); + return d <= r; + } + + static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) { + if (p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]]) < CMP_EPSILON && p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]) < CMP_EPSILON) { + return true; + } + + if (p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]]) < CMP_EPSILON && p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]) < CMP_EPSILON) { + return true; + } + + return false; + } + + static Vector<Triangle> triangulate(const Vector<Vector2> &p_points) { + + Vector<Vector2> points = p_points; + Vector<Triangle> triangles; + + Rect2 rect; + for (int i = 0; i < p_points.size(); i++) { + if (i == 0) { + rect.position = p_points[i]; + } else { + rect.expand_to(p_points[i]); + } + } + + float delta_max = MAX(rect.size.width, rect.size.height); + Vector2 center = rect.position + rect.size * 0.5; + + points.push_back(Vector2(center.x - 20 * delta_max, center.y - delta_max)); + points.push_back(Vector2(center.x, center.y + 20 * delta_max)); + points.push_back(Vector2(center.x + 20 * delta_max, center.y - delta_max)); + + triangles.push_back(Triangle(p_points.size() + 0, p_points.size() + 1, p_points.size() + 2)); + + for (int i = 0; i < p_points.size(); i++) { + //std::cout << "Traitement du point " << *p << std::endl; + //std::cout << "_triangles contains " << _triangles.size() << " elements" << std::endl; + + Vector<Edge> polygon; + + for (int j = 0; j < triangles.size(); j++) { + if (circum_circle_contains(points, triangles[j], i)) { + triangles[j].bad = true; + polygon.push_back(Edge(triangles[j].points[0], triangles[j].points[1])); + polygon.push_back(Edge(triangles[j].points[1], triangles[j].points[2])); + polygon.push_back(Edge(triangles[j].points[2], triangles[j].points[0])); + } + } + + for (int j = 0; j < triangles.size(); j++) { + if (triangles[j].bad) { + triangles.remove(j); + j--; + } + } + + for (int j = 0; j < polygon.size(); j++) { + for (int k = j + 1; k < polygon.size(); k++) { + if (edge_compare(points, polygon[j], polygon[k])) { + polygon[j].bad = true; + polygon[k].bad = true; + } + } + } + + for (int j = 0; j < polygon.size(); j++) { + + if (polygon[j].bad) { + continue; + } + triangles.push_back(Triangle(polygon[j].edge[0], polygon[j].edge[1], i)); + } + } + + for (int i = 0; i < triangles.size(); i++) { + bool invalid = false; + for (int j = 0; j < 3; j++) { + if (triangles[i].points[j] >= p_points.size()) { + invalid = true; + break; + } + } + if (invalid) { + triangles.remove(i); + i--; + } + } + + return triangles; + } +}; + +#endif // DELAUNAY_H diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 202115e2ca..2371f49561 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -356,8 +356,7 @@ void Basis::rotate(const Quat &p_quat) { *this = rotated(p_quat); } -// TODO: rename this to get_rotation_euler -Vector3 Basis::get_rotation() const { +Vector3 Basis::get_rotation_euler() const { // Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S, // and returns the Euler angles corresponding to the rotation part, complementing get_scale(). // See the comment in get_scale() for further information. @@ -371,6 +370,20 @@ Vector3 Basis::get_rotation() const { return m.get_euler(); } +Quat Basis::get_rotation_quat() const { + // Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S, + // and returns the Euler angles corresponding to the rotation part, complementing get_scale(). + // See the comment in get_scale() for further information. + Basis m = orthonormalized(); + real_t det = m.determinant(); + if (det < 0) { + // Ensure that the determinant is 1, such that result is a proper rotation matrix which can be represented by Euler angles. + m.scale(Vector3(-1, -1, -1)); + } + + return m.get_quat(); +} + void Basis::get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const { // Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S, // and returns the Euler angles corresponding to the rotation part, complementing get_scale(). @@ -591,10 +604,9 @@ Basis::operator String() const { } Quat Basis::get_quat() const { - //commenting this check because precision issues cause it to fail when it shouldn't - //#ifdef MATH_CHECKS - //ERR_FAIL_COND_V(is_rotation() == false, Quat()); - //#endif +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(is_rotation() == false, Quat()); +#endif real_t trace = elements[0][0] + elements[1][1] + elements[2][2]; real_t temp[4]; diff --git a/core/math/matrix3.h b/core/math/matrix3.h index 63d4f5d79d..cd1b51baa6 100644 --- a/core/math/matrix3.h +++ b/core/math/matrix3.h @@ -84,9 +84,11 @@ public: void rotate(const Quat &p_quat); Basis rotated(const Quat &p_quat) const; - Vector3 get_rotation() const; + Vector3 get_rotation_euler() const; void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const; void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const; + Quat get_rotation_quat() const; + Vector3 get_rotation() const { return get_rotation_euler(); }; Vector3 rotref_posscale_decomposition(Basis &rotref) const; diff --git a/core/math/quat.cpp b/core/math/quat.cpp index b938fc3cfd..67c9048a41 100644 --- a/core/math/quat.cpp +++ b/core/math/quat.cpp @@ -139,15 +139,15 @@ bool Quat::is_normalized() const { Quat Quat::inverse() const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V(is_normalized() == false, Quat(0, 0, 0, 0)); + ERR_FAIL_COND_V(is_normalized() == false, Quat()); #endif return Quat(-x, -y, -z, w); } Quat Quat::slerp(const Quat &q, const real_t &t) const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V(is_normalized() == false, Quat(0, 0, 0, 0)); - ERR_FAIL_COND_V(q.is_normalized() == false, Quat(0, 0, 0, 0)); + ERR_FAIL_COND_V(is_normalized() == false, Quat()); + ERR_FAIL_COND_V(q.is_normalized() == false, Quat()); #endif Quat to1; real_t omega, cosom, sinom, scale0, scale1; @@ -192,7 +192,10 @@ Quat Quat::slerp(const Quat &q, const real_t &t) const { } Quat Quat::slerpni(const Quat &q, const real_t &t) const { - +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(is_normalized() == false, Quat()); + ERR_FAIL_COND_V(q.is_normalized() == false, Quat()); +#endif const Quat &from = *this; real_t dot = from.dot(q); @@ -211,7 +214,10 @@ Quat Quat::slerpni(const Quat &q, const real_t &t) const { } Quat Quat::cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const real_t &t) const { - +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(is_normalized() == false, Quat()); + ERR_FAIL_COND_V(q.is_normalized() == false, Quat()); +#endif //the only way to do slerp :| real_t t2 = (1.0 - t) * t * 2; Quat sp = this->slerp(q, t); diff --git a/core/math/quat.h b/core/math/quat.h index 3e1344a913..6dc8d66f60 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -84,7 +84,9 @@ public: } _FORCE_INLINE_ Vector3 xform(const Vector3 &v) const { - +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(is_normalized() == false, v); +#endif Vector3 u(x, y, z); Vector3 uv = u.cross(v); return v + ((uv * w) + u.cross(uv)) * ((real_t)2); diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 7cd186ca60..d1e190f4b9 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -120,11 +120,11 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) /* not sure if very "efficient" but good enough? */ Vector3 src_scale = basis.get_scale(); - Quat src_rot = basis.orthonormalized(); + Quat src_rot = basis.get_rotation_quat(); Vector3 src_loc = origin; Vector3 dst_scale = p_transform.basis.get_scale(); - Quat dst_rot = p_transform.basis; + Quat dst_rot = p_transform.basis.get_rotation_quat(); Vector3 dst_loc = p_transform.origin; Transform dst; //this could be made faster by using a single function in Basis.. diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index 2007c3def5..677e8e1fb2 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -214,6 +214,50 @@ struct PtrToArg<const T *> { } \ } +#define MAKE_VECARG_ALT(m_type, m_type_alt) \ + template <> \ + struct PtrToArg<Vector<m_type_alt> > { \ + _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ + const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \ + Vector<m_type_alt> ret; \ + int len = dvs->size(); \ + ret.resize(len); \ + { \ + PoolVector<m_type>::Read r = dvs->read(); \ + for (int i = 0; i < len; i++) { \ + ret[i] = r[i]; \ + } \ + } \ + return ret; \ + } \ + _FORCE_INLINE_ static void encode(Vector<m_type_alt> p_vec, void *p_ptr) { \ + PoolVector<m_type> *dv = reinterpret_cast<PoolVector<m_type> *>(p_ptr); \ + int len = p_vec.size(); \ + dv->resize(len); \ + { \ + PoolVector<m_type>::Write w = dv->write(); \ + for (int i = 0; i < len; i++) { \ + w[i] = p_vec[i]; \ + } \ + } \ + } \ + }; \ + template <> \ + struct PtrToArg<const Vector<m_type_alt> &> { \ + _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ + const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \ + Vector<m_type_alt> ret; \ + int len = dvs->size(); \ + ret.resize(len); \ + { \ + PoolVector<m_type>::Read r = dvs->read(); \ + for (int i = 0; i < len; i++) { \ + ret[i] = r[i]; \ + } \ + } \ + return ret; \ + } \ + } MAKE_VECARG(String); MAKE_VECARG(uint8_t); MAKE_VECARG(int); @@ -221,6 +265,7 @@ MAKE_VECARG(float); MAKE_VECARG(Vector2); MAKE_VECARG(Vector3); MAKE_VECARG(Color); +MAKE_VECARG_ALT(String, StringName); //for stuff that gets converted to Array vectors #define MAKE_VECARR(m_type) \ diff --git a/core/object.h b/core/object.h index 7963a43fd6..badb432885 100644 --- a/core/object.h +++ b/core/object.h @@ -85,6 +85,7 @@ enum PropertyHint { PROPERTY_HINT_PROPERTY_OF_INSTANCE, ///< a property of an instance PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send + PROPERTY_HINT_NODE_PATH_VALID_TYPES, PROPERTY_HINT_MAX, // When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit }; diff --git a/core/resource.cpp b/core/resource.cpp index f100f4447b..4cca73be5d 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -287,7 +287,7 @@ uint32_t Resource::hash_edited_version() const { for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { + if (E->get().usage & PROPERTY_USAGE_STORAGE && E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { RES res = get(E->get().name); if (res.is_valid()) { hash = hash_djb2_one_32(res->hash_edited_version(), hash); diff --git a/core/type_info.h b/core/type_info.h index c1af4fac69..bf497f1e5f 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -194,6 +194,7 @@ MAKE_TEMPLATE_TYPE_INFO(Vector, Color, Variant::POOL_COLOR_ARRAY) MAKE_TEMPLATE_TYPE_INFO(Vector, Variant, Variant::ARRAY) MAKE_TEMPLATE_TYPE_INFO(Vector, RID, Variant::ARRAY) MAKE_TEMPLATE_TYPE_INFO(Vector, Plane, Variant::ARRAY) +MAKE_TEMPLATE_TYPE_INFO(Vector, StringName, Variant::POOL_STRING_ARRAY) MAKE_TEMPLATE_TYPE_INFO(PoolVector, Plane, Variant::ARRAY) MAKE_TEMPLATE_TYPE_INFO(PoolVector, Face3, Variant::POOL_VECTOR3_ARRAY) diff --git a/core/variant.cpp b/core/variant.cpp index a6df95e310..c48aa57652 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2012,6 +2012,19 @@ Variant::operator Vector<String>() const { } return to; } +Variant::operator Vector<StringName>() const { + + PoolVector<String> from = operator PoolVector<String>(); + Vector<StringName> to; + int len = from.size(); + to.resize(len); + for (int i = 0; i < len; i++) { + + to[i] = from[i]; + } + return to; +} + Variant::operator Vector<Vector3>() const { PoolVector<Vector3> from = operator PoolVector<Vector3>(); @@ -2444,6 +2457,17 @@ Variant::Variant(const Vector<String> &p_array) { *this = v; } +Variant::Variant(const Vector<StringName> &p_array) { + + type = NIL; + PoolVector<String> v; + int len = p_array.size(); + v.resize(len); + for (int i = 0; i < len; i++) + v.set(i, p_array[i]); + *this = v; +} + Variant::Variant(const Vector<Vector3> &p_array) { type = NIL; diff --git a/core/variant.h b/core/variant.h index f227e4bfdb..4b245d25e6 100644 --- a/core/variant.h +++ b/core/variant.h @@ -216,6 +216,7 @@ public: operator Vector<int>() const; operator Vector<real_t>() const; operator Vector<String>() const; + operator Vector<StringName>() const; operator Vector<Vector3>() const; operator Vector<Color>() const; operator Vector<RID>() const; @@ -280,6 +281,7 @@ public: Variant(const Vector<int> &p_int_array); Variant(const Vector<real_t> &p_real_array); Variant(const Vector<String> &p_string_array); + Variant(const Vector<StringName> &p_string_array); Variant(const Vector<Vector3> &p_vector3_array); Variant(const Vector<Color> &p_color_array); Variant(const Vector<Plane> &p_array); // helper diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index ba62a385af..6ffeddf5c1 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -207,6 +207,7 @@ <return type="Vector2"> </return> <description> + Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. </description> </method> <method name="slerp"> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index c754b27f1e..62a480166a 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -208,6 +208,7 @@ <return type="Vector3"> </return> <description> + Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. </description> </method> <method name="slerp"> diff --git a/editor/SCsub b/editor/SCsub index c29da8dd8a..a9343f7f36 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -192,10 +192,10 @@ if env['tools']: docs = sorted(docs) env.Depends("#editor/doc_data_compressed.gen.h", docs) - env.Command("#editor/doc_data_compressed.gen.h", docs, make_doc_header) + env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, make_doc_header) # Certificates env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt") - env.Command("#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", make_certs_header) import glob path = env.Dir('.').abspath @@ -203,13 +203,13 @@ if env['tools']: # Translations tlist = glob.glob(path + "/translations/*.po") env.Depends('#editor/translations.gen.h', tlist) - env.Command('#editor/translations.gen.h', tlist, make_translations_header) + env.CommandNoCache('#editor/translations.gen.h', tlist, 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.Command('#editor/builtin_fonts.gen.h', flist, make_fonts_header) + env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, make_fonts_header) env.add_source_files(env.editor_sources, "*.cpp") env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 30983ca149..2f0982e5d9 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -753,7 +753,6 @@ EditorAutoloadSettings::EditorAutoloadSettings() { autoload_cache.push_back(info); } - List<Node *> to_add; for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) { AutoLoadInfo &info = E->get(); @@ -763,9 +762,6 @@ EditorAutoloadSettings::EditorAutoloadSettings() { Ref<Script> scr = info.node->get_script(); info.in_editor = scr.is_valid() && scr->is_tool(); info.node->set_name(info.name); - if (info.in_editor) { - to_add.push_back(info.node); - } } if (info.is_singleton) { @@ -780,10 +776,6 @@ EditorAutoloadSettings::EditorAutoloadSettings() { } } - for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) { - get_tree()->get_root()->add_child(E->get()); - } - autoload_changed = "autoload_changed"; updating_autoload = false; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9a3174fb1a..79746dcb5a 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1464,7 +1464,8 @@ void EditorInspector::update_tree() { #endif for (List<Ref<EditorInspectorPlugin> >::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); - ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage); + bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage); + List<EditorInspectorPlugin::AddedEditor> editors = ped->added_editors; //make a copy, since plugins may be used again in a sub-inspector ped->added_editors.clear(); @@ -1532,6 +1533,10 @@ void EditorInspector::update_tree() { } } } + + if (exclusive) { + break; + } } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index a34aebc63a..f099f29204 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -66,8 +66,11 @@ #include "editor/import/resource_importer_scene.h" #include "editor/import/resource_importer_texture.h" #include "editor/import/resource_importer_wav.h" +#include "editor/plugins/animation_blend_space_1d_editor.h" +#include "editor/plugins/animation_blend_space_2d_editor.h" #include "editor/plugins/animation_blend_tree_editor_plugin.h" #include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/plugins/animation_state_machine_editor.h" #include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" #include "editor/plugins/baked_lightmap_editor_plugin.h" @@ -96,6 +99,7 @@ #include "editor/plugins/physical_bone_plugin.h" #include "editor/plugins/polygon_2d_editor_plugin.h" #include "editor/plugins/resource_preloader_editor_plugin.h" +#include "editor/plugins/root_motion_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_text_editor.h" #include "editor/plugins/shader_editor_plugin.h" @@ -583,7 +587,6 @@ void EditorNode::edit_node(Node *p_node) { void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) { editor_data.apply_changes_in_editors(); - int flg = 0; if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) flg |= ResourceSaver::FLAG_COMPRESS; @@ -1070,8 +1073,7 @@ void EditorNode::_save_scene(String p_file, int idx) { void EditorNode::_save_all_scenes() { - int i = _next_unsaved_scene(true, 0); - while (i != -1) { + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { Node *scene = editor_data.get_edited_scene_root(i); if (scene && scene->get_filename() != "") { if (i != editor_data.get_edited_scene()) @@ -1079,7 +1081,6 @@ void EditorNode::_save_all_scenes() { else _save_scene_with_preview(scene->get_filename()); } // else: ignore new scenes - i = _next_unsaved_scene(true, ++i); } _save_default_environment(); @@ -1308,7 +1309,11 @@ bool EditorNode::item_has_editor(Object *p_object) { void EditorNode::edit_item(Object *p_object) { - Vector<EditorPlugin *> sub_plugins = editor_data.get_subeditors(p_object); + Vector<EditorPlugin *> sub_plugins; + + if (p_object) { + sub_plugins = editor_data.get_subeditors(p_object); + } if (!sub_plugins.empty()) { _display_top_editors(false); @@ -1316,6 +1321,8 @@ void EditorNode::edit_item(Object *p_object) { _set_top_editors(sub_plugins); _set_editing_top_editors(p_object); _display_top_editors(true); + } else { + _hide_top_editors(); } } @@ -1349,8 +1356,7 @@ void EditorNode::_save_default_environment() { if (fallback.is_valid() && fallback->get_path().is_resource_file()) { Map<RES, bool> processed; _find_and_save_edited_subresources(fallback.ptr(), processed, 0); - if (fallback->get_last_modified_time() != fallback->get_import_last_modified_time()) - save_resource_in_path(fallback, fallback->get_path()); + save_resource_in_path(fallback, fallback->get_path()); } } @@ -4626,6 +4632,10 @@ EditorNode::EditorNode() { Ref<EditorInspectorDefaultPlugin> eidp; eidp.instance(); EditorInspector::add_inspector_plugin(eidp); + + Ref<EditorInspectorRootMotionPlugin> rmp; + rmp.instance(); + EditorInspector::add_inspector_plugin(rmp); } _pvrtc_register_compressors(); @@ -4651,9 +4661,7 @@ EditorNode::EditorNode() { GLOBAL_DEF("editor/main_run_args", ""); - ClassDB::set_class_enabled("CollisionShape", true); - ClassDB::set_class_enabled("CollisionShape2D", true); - ClassDB::set_class_enabled("CollisionPolygon2D", true); + ClassDB::set_class_enabled("RootMotionView", true); //defs here, use EDITOR_GET in logic EDITOR_DEF("interface/scene_tabs/always_show_close_button", false); @@ -5371,8 +5379,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(SpatialEditorPlugin(this))); add_editor_plugin(memnew(ScriptEditorPlugin(this))); - add_editor_plugin(memnew(AnimationNodeBlendTreeEditorPlugin(this))); - EditorAudioBuses *audio_bus_editor = EditorAudioBuses::register_editor(); ScriptTextEditor::register_editor(); //register one for text scripts @@ -5394,6 +5400,10 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(ShaderEditorPlugin(this))); // FIXME: Disabled for Godot 3.0 as made incompatible, it needs to be ported to the new API. //add_editor_plugin(memnew(ShaderGraphEditorPlugin(this))); + add_editor_plugin(memnew(AnimationNodeBlendTreeEditorPlugin(this))); + add_editor_plugin(memnew(AnimationNodeBlendSpace1DEditorPlugin(this))); + add_editor_plugin(memnew(AnimationNodeBlendSpace2DEditorPlugin(this))); + add_editor_plugin(memnew(AnimationNodeStateMachineEditorPlugin(this))); add_editor_plugin(memnew(CameraEditorPlugin(this))); add_editor_plugin(memnew(ThemeEditorPlugin(this))); diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp index fcd3dc2f68..d4a97b7095 100644 --- a/editor/editor_profiler.cpp +++ b/editor/editor_profiler.cpp @@ -424,20 +424,25 @@ void EditorProfiler::_update_frame() { void EditorProfiler::_activate_pressed() { if (activate->is_pressed()) { - clear(); activate->set_icon(get_icon("Stop", "EditorIcons")); - activate->set_text(TTR("Stop Profiling")); + activate->set_text(TTR("Stop")); } else { activate->set_icon(get_icon("Play", "EditorIcons")); - activate->set_text(TTR("Start Profiling")); + activate->set_text(TTR("Start")); } emit_signal("enable_profiling", activate->is_pressed()); } +void EditorProfiler::_clear_pressed() { + + clear(); +} + void EditorProfiler::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { activate->set_icon(get_icon("Play", "EditorIcons")); + clear_button->set_icon(get_icon("Clear", "EditorIcons")); } } @@ -599,6 +604,7 @@ void EditorProfiler::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_frame"), &EditorProfiler::_update_frame); ClassDB::bind_method(D_METHOD("_update_plot"), &EditorProfiler::_update_plot); ClassDB::bind_method(D_METHOD("_activate_pressed"), &EditorProfiler::_activate_pressed); + ClassDB::bind_method(D_METHOD("_clear_pressed"), &EditorProfiler::_clear_pressed); ClassDB::bind_method(D_METHOD("_graph_tex_draw"), &EditorProfiler::_graph_tex_draw); ClassDB::bind_method(D_METHOD("_graph_tex_input"), &EditorProfiler::_graph_tex_input); ClassDB::bind_method(D_METHOD("_graph_tex_mouse_exit"), &EditorProfiler::_graph_tex_mouse_exit); @@ -625,10 +631,15 @@ EditorProfiler::EditorProfiler() { add_child(hb); activate = memnew(Button); activate->set_toggle_mode(true); - activate->set_text(TTR("Start Profiling")); + activate->set_text(TTR("Start")); activate->connect("pressed", this, "_activate_pressed"); hb->add_child(activate); + clear_button = memnew(Button); + clear_button->set_text(TTR("Clear")); + clear_button->connect("pressed", this, "_clear_pressed"); + hb->add_child(clear_button); + hb->add_child(memnew(Label(TTR("Measure:")))); display_mode = memnew(OptionButton); diff --git a/editor/editor_profiler.h b/editor/editor_profiler.h index d902a97c5d..cb451475e7 100644 --- a/editor/editor_profiler.h +++ b/editor/editor_profiler.h @@ -100,6 +100,7 @@ public: private: Button *activate; + Button *clear_button; TextureRect *graph; Ref<ImageTexture> graph_texture; PoolVector<uint8_t> graph_image; @@ -133,6 +134,7 @@ private: void _update_frame(); void _activate_pressed(); + void _clear_pressed(); String _get_time_as_text(Metric &m, float p_time, int p_calls); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 5abcae80e0..2c22484d85 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1530,6 +1530,8 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) { void EditorPropertyNodePath::_node_assign() { if (!scene_tree) { scene_tree = memnew(SceneTreeDialog); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); + scene_tree->get_scene_tree()->set_valid_types(valid_types); add_child(scene_tree); scene_tree->connect("selected", this, "_node_selected"); } @@ -1584,9 +1586,10 @@ void EditorPropertyNodePath::update_property() { assign->set_icon(icon); } -void EditorPropertyNodePath::setup(const NodePath &p_base_hint) { +void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types) { base_hint = p_base_hint; + valid_types = p_valid_types; } void EditorPropertyNodePath::_notification(int p_what) { @@ -1779,6 +1782,7 @@ void EditorPropertyResource::_menu_option(int p_which) { if (!scene_tree) { scene_tree = memnew(SceneTreeDialog); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); add_child(scene_tree); scene_tree->connect("selected", this, "_viewport_selected"); scene_tree->set_title(TTR("Pick a Viewport")); @@ -2665,7 +2669,12 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath); if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) { - editor->setup(p_hint_text); + editor->setup(p_hint_text, Vector<StringName>()); + } + if (p_hint == PROPERTY_HINT_NODE_PATH_VALID_TYPES && p_hint_text != String()) { + Vector<String> types = p_hint_text.split(",", false); + Vector<StringName> sn = Variant(types); //convert via variant + editor->setup(NodePath(), sn); } add_property_editor(p_path, editor); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 734ca2de82..c67eccb60e 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -453,6 +453,7 @@ class EditorPropertyNodePath : public EditorProperty { SceneTreeDialog *scene_tree; NodePath base_hint; + Vector<StringName> valid_types; void _node_selected(const NodePath &p_path); void _node_assign(); void _node_clear(); @@ -463,7 +464,7 @@ protected: public: virtual void update_property(); - void setup(const NodePath &p_base_hint); + void setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types); EditorPropertyNodePath(); }; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index ff644ad126..4045d6c3d3 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -313,8 +313,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("interface/editor/save_each_scene_on_quit", true); // Regression _initial_set("interface/editor/quit_confirmation", true); - _initial_set("interface/theme/preset", 0); - hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Custom,Grey,Godot 2,Arc,Light,Alien,Solarized (Dark),Solarized (Light)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + _initial_set("interface/theme/preset", "Default"); + hints["interface/theme/preset"] = PropertyInfo(Variant::STRING, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Alien,Arc,Godot 2,Grey,Light,Solarized (Dark),Solarized (Light),Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/theme/icon_and_font_color", 0); hints["interface/theme/icon_and_font_color"] = PropertyInfo(Variant::INT, "interface/theme/icon_and_font_color", PROPERTY_HINT_ENUM, "Auto,Dark,Light", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/theme/base_color", Color::html("#323b4f")); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 78aa3da546..98402d8df5 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -254,7 +254,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#323b4f")); float contrast = EDITOR_DEF("interface/theme/contrast", default_contrast); - int preset = EDITOR_DEF("interface/theme/preset", 0); + String preset = EDITOR_DEF("interface/theme/preset", "Default"); + int icon_font_color_setting = EDITOR_DEF("interface/theme/icon_and_font_color", 0); bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false); int border_size = EDITOR_DEF("interface/theme/border_size", 1); @@ -266,55 +267,52 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color preset_accent_color; Color preset_base_color; float preset_contrast; - switch (preset) { - case 0: { // Default - preset_accent_color = Color::html("#699ce8"); - preset_base_color = Color::html("#323b4f"); - preset_contrast = default_contrast; - } break; - case 1: { // Custom - accent_color = EDITOR_DEF("interface/theme/accent_color", Color::html("#699ce8")); - base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#323b4f")); - contrast = EDITOR_DEF("interface/theme/contrast", default_contrast); - } break; - case 2: { // Grey - preset_accent_color = Color::html("#b8e4ff"); - preset_base_color = Color::html("#3d3d3d"); - preset_contrast = 0.2; - } break; - case 3: { // Godot 2 - preset_accent_color = Color::html("#86ace2"); - preset_base_color = Color::html("#3C3A44"); - preset_contrast = 0.25; - } break; - case 4: { // Arc - preset_accent_color = Color::html("#5294e2"); - preset_base_color = Color::html("#383c4a"); - preset_contrast = 0.25; - } break; - case 5: { // Light - preset_accent_color = Color::html("#2070ff"); - preset_base_color = Color::html("#ffffff"); - preset_contrast = 0.08; - } break; - case 6: { // Alien - preset_accent_color = Color::html("#1bfe99"); - preset_base_color = Color::html("#2f373f"); - preset_contrast = 0.25; - } break; - case 7: { // Solarized (Dark) - preset_accent_color = Color::html("#268bd2"); - preset_base_color = Color::html("#073642"); - preset_contrast = 0.15; - } break; - case 8: { // Solarized (Light) - preset_accent_color = Color::html("#268bd2"); - preset_base_color = Color::html("#fdf6e3"); - preset_contrast = 0.06; - } break; + + // Please, use alphabet order if you've added new theme here(After "Default" and "Custom") + + if (preset == "Default") { + preset_accent_color = Color::html("#699ce8"); + preset_base_color = Color::html("#323b4f"); + preset_contrast = default_contrast; + } else if (preset == "Custom") { + accent_color = EDITOR_DEF("interface/theme/accent_color", Color::html("#699ce8")); + base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#323b4f")); + contrast = EDITOR_DEF("interface/theme/contrast", default_contrast); + } else if (preset == "Alien") { + preset_accent_color = Color::html("#1bfe99"); + preset_base_color = Color::html("#2f373f"); + preset_contrast = 0.25; + } else if (preset == "Arc") { + preset_accent_color = Color::html("#5294e2"); + preset_base_color = Color::html("#383c4a"); + preset_contrast = 0.25; + } else if (preset == "Godot 2") { + preset_accent_color = Color::html("#86ace2"); + preset_base_color = Color::html("#3C3A44"); + preset_contrast = 0.25; + } else if (preset == "Grey") { + preset_accent_color = Color::html("#b8e4ff"); + preset_base_color = Color::html("#3d3d3d"); + preset_contrast = 0.2; + } else if (preset == "Light") { + preset_accent_color = Color::html("#2070ff"); + preset_base_color = Color::html("#ffffff"); + preset_contrast = 0.08; + } else if (preset == "Solarized (Dark)") { + preset_accent_color = Color::html("#268bd2"); + preset_base_color = Color::html("#073642"); + preset_contrast = 0.15; + } else if (preset == "Solarized (Light)") { + preset_accent_color = Color::html("#268bd2"); + preset_base_color = Color::html("#fdf6e3"); + preset_contrast = 0.06; + } else { // Default + preset_accent_color = Color::html("#699ce8"); + preset_base_color = Color::html("#323b4f"); + preset_contrast = default_contrast; } - if (preset != 1) { + if (preset != "Custom") { accent_color = preset_accent_color; base_color = preset_base_color; contrast = preset_contrast; diff --git a/editor/icons/icon_animation_tree.svg b/editor/icons/icon_animation_tree.svg new file mode 100644 index 0000000000..046506fa37 --- /dev/null +++ b/editor/icons/icon_animation_tree.svg @@ -0,0 +1,5 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m1 1v14h1.166v-2h1.834v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.834v-2h-1.166zm4 3h2v1 1h1 3v2h-2v1 1h1 1v2h-1-2a1.0001 1.0001 0 0 1 -1 -1v-1-2h-1a1.0001 1.0001 0 0 1 -1 -1v-1-1-1zm-2.834 1h1.834v2h-1.834v-2zm9.834 0h2v2h-2v-2zm-9.834 4h1.834v2h-1.834v-2zm9.834 0h2v2h-2v-2z" fill="#cea4f1"/> +</g> +</svg> diff --git a/editor/icons/icon_auto_end.svg b/editor/icons/icon_auto_end.svg new file mode 100644 index 0000000000..9e779c69f4 --- /dev/null +++ b/editor/icons/icon_auto_end.svg @@ -0,0 +1,68 @@ +<?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_auto_end.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="1273" + inkscape:window-height="766" + id="namedview8" + showgrid="false" + inkscape:zoom="41.7193" + inkscape:cx="12.08616" + inkscape:cy="6.9898672" + inkscape:window-x="539" + inkscape:window-y="208" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <path + inkscape:connector-curvature="0" + id="path2" + style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + d="m 13.999798,14 c 0.552262,-5.5e-5 0.999945,-0.447738 1,-1 V 3 c -5.5e-5,-0.5522619 -0.447738,-0.9999448 -1,-1 H 5.9997976 C 5.6959349,1.9998247 5.4084731,2.1378063 5.2185476,2.375 l -4,5 c -0.29139692,0.3649711 -0.29139692,0.8830289 0,1.248 l 4,5 c 0.189538,0.237924 0.4770584,0.376652 0.78125,0.37695 h 8.0000004 z m -1,-2 H 6.4802976 l -3.1992,-4 3.1992,-4 H 12.999798 Z M 6.9997976,10 V 6 l -2,2 z" + sodipodi:nodetypes="cccccccccccccccccccccc" /> + <g + aria-label="E" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:40px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:1;stroke:none" + id="text829" + transform="matrix(0.20475474,0,0,0.20475474,4.7903856,12.365563)"> + <path + d="M 15.129502,-36.414393 H 35.422471 V -30.7308 H 22.649034 v 5.429688 h 12.011718 v 5.683594 H 22.649034 v 6.679687 h 13.203125 v 5.6835938 H 15.129502 Z" + style="fill:#e0e0e0;fill-opacity:1" + id="path831" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/editor/icons/icon_auto_triangle.svg b/editor/icons/icon_auto_triangle.svg new file mode 100644 index 0000000000..631f259452 --- /dev/null +++ b/editor/icons/icon_auto_triangle.svg @@ -0,0 +1,64 @@ +<?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_auto_triangle.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="1853" + inkscape:window-height="1016" + id="namedview10" + showgrid="false" + inkscape:zoom="29.5" + inkscape:cx="17.168167" + inkscape:cy="5.5708575" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="g4" /> + <g + transform="translate(0 -1036.4)" + id="g6"> + <g + transform="translate(-26.001 -9.8683)" + id="g4"> + <path + style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:1.87616086;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 8.2324219 0.67773438 L 0.64453125 15.289062 L 15.355469 15.289062 L 8.2324219 0.67773438 z M 6.9414062 5.4433594 L 9.2109375 5.4433594 C 9.5561128 6.0670927 9.8954447 6.7088542 10.230469 7.3671875 C 10.565492 8.0167875 10.901304 8.703974 11.236328 9.4316406 C 11.581503 10.159241 11.931781 10.934946 12.287109 11.757812 C 12.642437 12.580746 13.018126 13.477066 13.414062 14.447266 L 10.871094 14.447266 C 10.75942 14.135399 10.632366 13.815528 10.490234 13.486328 C 10.358255 13.157195 10.225729 12.827247 10.09375 12.498047 L 5.9824219 12.498047 C 5.8504432 12.827247 5.7143976 13.157195 5.5722656 13.486328 C 5.440287 13.815528 5.3167521 14.135399 5.2050781 14.447266 L 2.7382812 14.447266 C 3.1342186 13.477066 3.5099064 12.580746 3.8652344 11.757812 C 4.2205624 10.934946 4.5673204 10.159241 4.9023438 9.4316406 C 5.2475197 8.703974 5.5813793 8.0167875 5.90625 7.3671875 C 6.2412733 6.7088542 6.5860782 6.0670927 6.9414062 5.4433594 z M 8.0234375 7.4824219 C 7.9726708 7.6123552 7.8964385 7.790425 7.7949219 8.015625 C 7.6933999 8.240825 7.5772912 8.5003885 7.4453125 8.7949219 C 7.3133332 9.0894552 7.1643891 9.4143979 7.0019531 9.7695312 C 6.8496698 10.124665 6.6936847 10.496919 6.53125 10.886719 L 9.53125 10.886719 C 9.368814 10.496919 9.2108764 10.124665 9.0585938 9.7695312 C 8.9063104 9.4143979 8.7593188 9.0894552 8.6171875 8.7949219 C 8.4852082 8.5003885 8.3691001 8.240825 8.2675781 8.015625 C 8.1660555 7.790425 8.0843508 7.6123552 8.0234375 7.4824219 z " + transform="translate(26.001,1046.2683)" + id="path821" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_play_travel.svg b/editor/icons/icon_play_travel.svg new file mode 100644 index 0000000000..5cd3e07e20 --- /dev/null +++ b/editor/icons/icon_play_travel.svg @@ -0,0 +1,85 @@ +<?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_play_travel.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="1446" + inkscape:window-height="646" + id="namedview10" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="8.2818541" + inkscape:cy="5.7694884" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="matrix(0.59321602,0,0,0.59321602,-1.2203136,-611.14809)" + id="g6"> + <g + id="g4"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <g + transform="matrix(0.59321602,0,0,0.59321602,7.5254716,-610.94451)" + id="g6-3"> + <g + id="g4-6"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2-7" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect842" + width="9.5593224" + height="0.54237264" + x="3.0058463" + y="8.1280737" + ry="0.27118632" /> +</svg> diff --git a/editor/icons/icon_tool_add_node.svg b/editor/icons/icon_tool_add_node.svg new file mode 100644 index 0000000000..a4ff4d08a0 --- /dev/null +++ b/editor/icons/icon_tool_add_node.svg @@ -0,0 +1,80 @@ +<?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_tool_add_node.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="1516" + inkscape:window-height="747" + id="namedview10" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="8" + inkscape:cy="8" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="translate(0 -1036.4)" + id="g6"> + <g + transform="translate(-26.001 -9.8683)" + id="g4"> + <path + style="fill:#e0e0e0;fill-opacity:1" + d="m 27.917081,1047.5557 c -0.422624,0 -0.763672,0.3411 -0.763672,0.7637 v 11.8301 c 0,0.4226 0.341048,0.7637 0.763672,0.7637 h 12.507813 c 0.422624,0 0.761719,-0.3411 0.761719,-0.7637 v -11.8301 c 0,-0.4226 -0.339095,-0.7637 -0.761719,-0.7637 z m 1.898438,1.6954 h 8.642578 c 0.422624,0 0.763672,0.341 0.763672,0.7636 v 8.5078 c 0,0.4227 -0.341048,0.7618 -0.763672,0.7618 h -8.642578 c -0.422625,0 -0.763672,-0.3391 -0.763672,-0.7618 v -8.5078 c 0,-0.4226 0.341047,-0.7636 0.763672,-0.7636 z" + id="rect821" + inkscape:connector-curvature="0" /> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect826" + width="7.7966104" + height="2.3728814" + x="30.20439" + y="1052.9802" + ry="0.76286" /> + <rect + style="fill:#e0e0e0;fill-opacity:1;stroke-width:0.88253576" + id="rect828" + width="2.3728814" + height="7.5254235" + x="32.916256" + y="1050.3361" + ry="0.72997814" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_tool_connect.svg b/editor/icons/icon_tool_connect.svg new file mode 100644 index 0000000000..91d5893163 --- /dev/null +++ b/editor/icons/icon_tool_connect.svg @@ -0,0 +1,72 @@ +<?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_tool_connect.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="1516" + inkscape:window-height="747" + id="namedview10" + showgrid="false" + inkscape:zoom="3.6875" + inkscape:cx="8.5909556" + inkscape:cy="7.8012075" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="translate(0 -1036.4)" + id="g6"> + <g + transform="translate(-26.001 -9.8683)" + id="g4"> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect849" + width="14.305085" + height="2.1694915" + x="26.766621" + y="1053.1389" + ry="0.76286" /> + <path + style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:1.16725671px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 30.596131,1046.927 v 14.8861 l 8.228847,-7.5722 z" + id="path853" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_tool_triangle.svg b/editor/icons/icon_tool_triangle.svg new file mode 100644 index 0000000000..5696008767 --- /dev/null +++ b/editor/icons/icon_tool_triangle.svg @@ -0,0 +1,82 @@ +<?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_tool_triangle.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 /> + </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="1204" + inkscape:window-height="703" + id="namedview10" + showgrid="false" + inkscape:zoom="29.5" + inkscape:cx="8.0650451" + inkscape:cy="7.0341257" + inkscape:window-x="542" + inkscape:window-y="205" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="translate(0 -1036.4)" + id="g6"> + <g + transform="translate(-26.001 -9.8683)" + id="g4"> + <path + style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 27.695915,1056.3022 c 0,0 7.457627,-8.0678 7.118644,-7.8644 -0.338983,0.2034 5.830509,11.7288 5.830509,11.7288 z" + id="path821" + inkscape:connector-curvature="0" /> + <circle + style="fill:#4b4b4b;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.51200002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path825" + cx="34.662014" + cy="1048.5903" + r="1.607564" /> + <circle + style="fill:#4b4b4b;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.51200002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path825-3" + cx="39.933205" + cy="1059.6581" + r="1.607564" /> + <circle + style="fill:#4b4b4b;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.51200002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path825-3-6" + cx="28.17049" + cy="1056.2683" + r="1.607564" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_transition_end.svg b/editor/icons/icon_transition_end.svg new file mode 100644 index 0000000000..8a1937670a --- /dev/null +++ b/editor/icons/icon_transition_end.svg @@ -0,0 +1,72 @@ +<?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_transition_end.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="10.204146" + inkscape:cy="5.3391396" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="translate(-2,-1036.4)" + id="g6"> + <g + id="g4"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east_asian:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect862" + width="3.0681243" + height="10.067283" + x="11.16989" + y="3.0084109" + ry="0.76286" /> +</svg> diff --git a/editor/icons/icon_transition_end_auto.svg b/editor/icons/icon_transition_end_auto.svg new file mode 100644 index 0000000000..18927bc4ef --- /dev/null +++ b/editor/icons/icon_transition_end_auto.svg @@ -0,0 +1,74 @@ +<?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_transition_automatic.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 /> + </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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="0.56831798" + inkscape:cy="5.1473818" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="translate(-2,-1036.4)" + id="g6" + style="fill:#77ce57;fill-opacity:1"> + <g + id="g4" + style="fill:#77ce57;fill-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east_asian:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#77ce57;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto;fill-opacity:1" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#77ce57;fill-opacity:1" + id="rect862" + width="3.0681243" + height="10.067283" + x="11.16989" + y="3.0084109" + ry="0.76286" /> +</svg> diff --git a/editor/icons/icon_transition_end_auto_big.svg b/editor/icons/icon_transition_end_auto_big.svg new file mode 100644 index 0000000000..aaedafaf04 --- /dev/null +++ b/editor/icons/icon_transition_end_auto_big.svg @@ -0,0 +1,74 @@ +<?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="20" + height="20" + version="1.1" + viewBox="0 0 20 20" + id="svg8" + sodipodi:docname="icon_transition_automatic_big.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="0.3064671" + inkscape:cy="14.348448" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="matrix(1.4099529,0,0,1.4099529,-4.1975887,-1462.5094)" + id="g6" + style="fill:#77ce57;fill-opacity:1;stroke:#41562e;stroke-opacity:1"> + <g + id="g4" + style="fill:#77ce57;fill-opacity:1;stroke:#41562e;stroke-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#77ce57;fill-opacity:1;fill-rule:evenodd;stroke:#41562e;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#77ce57;fill-opacity:1;stroke:#41562e;stroke-width:1.409953;stroke-opacity:1" + id="rect862" + width="4.3259106" + height="14.194397" + x="14.371336" + y="3.0076122" + ry="1.0755967" /> +</svg> diff --git a/editor/icons/icon_transition_end_big.svg b/editor/icons/icon_transition_end_big.svg new file mode 100644 index 0000000000..46d42e95e3 --- /dev/null +++ b/editor/icons/icon_transition_end_big.svg @@ -0,0 +1,74 @@ +<?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="20" + height="20" + version="1.1" + viewBox="0 0 20 20" + id="svg8" + sodipodi:docname="icon_transition_end_big.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="-1.1122019" + inkscape:cy="10.839132" + inkscape:window-x="517" + inkscape:window-y="261" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="matrix(1.4203458,0,0,1.4203458,-4.29479,-1473.1325)" + id="g6" + style="stroke:#424242;stroke-width:0.99994373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + <g + id="g4" + style="stroke:#424242;stroke-width:0.99994373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;stroke:#424242;stroke-width:0.99994373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#e0e0e0;fill-opacity:1;stroke:#424242;stroke-width:1.42026603;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect862" + width="4.3577976" + height="14.299023" + x="14.411009" + y="3.1868868" + ry="1.0835251" /> +</svg> diff --git a/editor/icons/icon_transition_immediate.svg b/editor/icons/icon_transition_immediate.svg new file mode 100644 index 0000000000..ba16a33c91 --- /dev/null +++ b/editor/icons/icon_transition_immediate.svg @@ -0,0 +1,64 @@ +<?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_transition_immediate.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 /> + </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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="4.0199579" + inkscape:cy="5.3391396" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="translate(-2,-1036.4)" + id="g6"> + <g + id="g4"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east_asian:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto;fill-opacity:1" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_transition_immediate_auto.svg b/editor/icons/icon_transition_immediate_auto.svg new file mode 100644 index 0000000000..c127560145 --- /dev/null +++ b/editor/icons/icon_transition_immediate_auto.svg @@ -0,0 +1,64 @@ +<?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_transition_immediate_auto.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="-9.2592678" + inkscape:cy="5.3391396" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="translate(-2,-1036.4)" + id="g6"> + <g + id="g4"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east_asian:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#77ce57;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto;fill-opacity:1" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_transition_immediate_auto_big.svg b/editor/icons/icon_transition_immediate_auto_big.svg new file mode 100644 index 0000000000..80d35a36f3 --- /dev/null +++ b/editor/icons/icon_transition_immediate_auto_big.svg @@ -0,0 +1,66 @@ +<?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="20" + height="20" + version="1.1" + viewBox="0 0 20 20" + id="svg8" + sodipodi:docname="icon_transition_immediate_auto_big.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="11.321237" + inkscape:cy="3.5752171" + inkscape:window-x="517" + inkscape:window-y="261" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="matrix(1.571031,0,0,1.571031,-2.7257681,-1630.6239)" + id="g6" + style="stroke:#404040;stroke-opacity:1"> + <g + id="g4" + style="stroke:#404040;stroke-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#77ce57;fill-rule:evenodd;stroke:#41562e;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;fill-opacity:1" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_transition_immediate_big.svg b/editor/icons/icon_transition_immediate_big.svg new file mode 100644 index 0000000000..108dcdd500 --- /dev/null +++ b/editor/icons/icon_transition_immediate_big.svg @@ -0,0 +1,66 @@ +<?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="20" + height="20" + version="1.1" + viewBox="0 0 20 20" + id="svg8" + sodipodi:docname="icon_transition_immediate_big.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 /> + </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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="0.19928629" + inkscape:cy="4.534006" + inkscape:window-x="517" + inkscape:window-y="261" + inkscape:window-maximized="0" + inkscape:current-layer="g4" /> + <g + transform="matrix(1.571031,0,0,1.571031,-2.7257681,-1630.6239)" + id="g6" + style="stroke:#404040;stroke-opacity:1"> + <g + id="g4" + style="stroke:#404040;stroke-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;stroke:#404040;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;fill-opacity:1" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg> diff --git a/editor/icons/icon_transition_sync.svg b/editor/icons/icon_transition_sync.svg new file mode 100644 index 0000000000..267d806615 --- /dev/null +++ b/editor/icons/icon_transition_sync.svg @@ -0,0 +1,72 @@ +<?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_transition_sync.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="10.204146" + inkscape:cy="5.3391396" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="translate(2.5542471,-1036.4)" + id="g6"> + <g + id="g4"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#e0e0e0;fill-opacity:1" + id="rect862" + width="3.0681243" + height="10.067283" + x="1.9655174" + y="3.0084109" + ry="0.76286" /> +</svg> diff --git a/editor/icons/icon_transition_sync_auto.svg b/editor/icons/icon_transition_sync_auto.svg new file mode 100644 index 0000000000..5ce61e3a6a --- /dev/null +++ b/editor/icons/icon_transition_sync_auto.svg @@ -0,0 +1,74 @@ +<?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_transition_sync_auto.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="20.85965" + inkscape:cx="0.56831798" + inkscape:cy="5.1473818" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="translate(3.0815809,-1036.4)" + id="g6" + style="fill:#77ce57;fill-opacity:1"> + <g + id="g4" + style="fill:#77ce57;fill-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#77ce57;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#77ce57;fill-opacity:1" + id="rect862" + width="3.0681243" + height="10.067283" + x="1.9655174" + y="3.0084109" + ry="0.76286" /> +</svg> diff --git a/editor/icons/icon_transition_sync_auto_big.svg b/editor/icons/icon_transition_sync_auto_big.svg new file mode 100644 index 0000000000..3e84d76398 --- /dev/null +++ b/editor/icons/icon_transition_sync_auto_big.svg @@ -0,0 +1,74 @@ +<?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="20" + height="20" + version="1.1" + viewBox="0 0 20 20" + id="svg8" + sodipodi:docname="icon_transition_sync_auto_big.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="0.3064671" + inkscape:cy="14.348448" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="matrix(1.4099529,0,0,1.4099529,2.1752927,-1462.5094)" + id="g6" + style="fill:#77ce57;fill-opacity:1;stroke:#41562e;stroke-opacity:1"> + <g + id="g4" + style="fill:#77ce57;fill-opacity:1;stroke:#41562e;stroke-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#77ce57;fill-opacity:1;fill-rule:evenodd;stroke:#41562e;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#77ce57;fill-opacity:1;stroke:#41562e;stroke-width:1.409953;stroke-opacity:1" + id="rect862" + width="4.3259106" + height="14.194397" + x="1.6255733" + y="3.0076122" + ry="1.0755967" /> +</svg> diff --git a/editor/icons/icon_transition_sync_big.svg b/editor/icons/icon_transition_sync_big.svg new file mode 100644 index 0000000000..e7cf63e0b3 --- /dev/null +++ b/editor/icons/icon_transition_sync_big.svg @@ -0,0 +1,74 @@ +<?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="20" + height="20" + version="1.1" + viewBox="0 0 20 20" + id="svg8" + sodipodi:docname="icon_transition_sync_big.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="1403" + inkscape:window-height="782" + id="namedview10" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="19.226781" + inkscape:cy="9.27981" + inkscape:window-x="302" + inkscape:window-y="226" + inkscape:window-maximized="0" + inkscape:current-layer="svg8" /> + <g + transform="matrix(1.4203458,0,0,1.4203458,1.8747015,-1473.1325)" + id="g6" + style="stroke:#424242;stroke-width:0.99994373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + <g + id="g4" + style="stroke:#424242;stroke-width:0.99994373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + <path + d="m 4.9883,1039.4 c -0.5469,0.01 -0.98717,0.4511 -0.98828,0.998 v 8 c 1.163e-4,0.7986 0.89011,1.275 1.5547,0.8321 l 6,-4 c 0.59362,-0.3959 0.59362,-1.2682 0,-1.6641 l -6,-4 c -0.1678,-0.1111 -0.3652,-0.1689 -0.56641,-0.166 z" + dominant-baseline="auto" + style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;dominant-baseline:auto;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-rule:evenodd;stroke:#424242;stroke-width:0.99994373;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto" + id="path2" + inkscape:connector-curvature="0" /> + </g> + </g> + <rect + style="fill:#e0e0e0;fill-opacity:1;stroke:#424242;stroke-width:1.42026603;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect862" + width="4.3577976" + height="14.299023" + x="1.4618562" + y="3.1868868" + ry="1.0835251" /> +</svg> diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 2fb3bf7b1e..a13f741ee7 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -1785,8 +1785,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones } } - Quat q = xform.basis; - q.normalize(); + Quat q = xform.basis.get_rotation_quat(); Vector3 s = xform.basis.get_scale(); Vector3 l = xform.origin; @@ -1838,8 +1837,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; - Quat q = xform.basis; - q.normalize(); + Quat q = xform.basis.get_rotation_quat(); Vector3 s = xform.basis.get_scale(); Vector3 l = xform.origin; diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 07a4cf5884..eb0bc0f782 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1256,12 +1256,15 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) { } if (mr.has("metallicFactor")) { - material->set_metallic(mr["metallicFactor"]); + } else { + material->set_metallic(1.0); } - if (mr.has("roughnessFactor")) { + if (mr.has("roughnessFactor")) { material->set_roughness(mr["roughnessFactor"]); + } else { + material->set_roughness(1.0); } if (mr.has("metallicRoughnessTexture")) { @@ -1986,8 +1989,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye int bone = node->joints[i].godot_bone_index; xform = skeleton->get_bone_rest(bone).affine_inverse() * xform; - rot = xform.basis; - rot.normalize(); + rot = xform.basis.get_rotation_quat(); scale = xform.basis.get_scale(); pos = xform.origin; } diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp new file mode 100644 index 0000000000..2e128db883 --- /dev/null +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -0,0 +1,741 @@ +#include "animation_blend_space_1d_editor.h" + +#include "os/keyboard.h" +#include "scene/animation/animation_blend_tree.h" + +void AnimationNodeBlendSpace1DEditorPlugin::edit(Object *p_object) { + anim_tree_editor->edit(Object::cast_to<AnimationNodeBlendSpace1D>(p_object)); +} + +bool AnimationNodeBlendSpace1DEditorPlugin::handles(Object *p_object) const { + return p_object->is_class("AnimationNodeBlendSpace1D"); +} + +void AnimationNodeBlendSpace1DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + button->show(); + editor->make_bottom_panel_item_visible(anim_tree_editor); + anim_tree_editor->set_process(true); + } else { + if (anim_tree_editor->is_visible_in_tree()) { + editor->hide_bottom_panel(); + } + + button->hide(); + anim_tree_editor->set_process(false); + } +} + +AnimationNodeBlendSpace1DEditorPlugin::AnimationNodeBlendSpace1DEditorPlugin(EditorNode *p_node) { + editor = p_node; + anim_tree_editor = memnew(AnimationNodeBlendSpace1DEditor); + anim_tree_editor->set_custom_minimum_size(Size2(0, 150 * EDSCALE)); + + button = editor->add_bottom_panel_item(TTR("BlendSpace1D"), anim_tree_editor); + button->hide(); +} + +AnimationNodeBlendSpace1DEditorPlugin::~AnimationNodeBlendSpace1DEditorPlugin() { +} + +void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEvent> &p_event) { + Ref<InputEventKey> k = p_event; + + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && !k->is_echo()) { + if (selected_point != -1) { + _erase_selected(); + accept_event(); + } + } + + Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (mb->get_button_index() == BUTTON_LEFT && tool_create->is_pressed()))) { + menu->clear(); + animations_menu->clear(); + animations_to_add.clear(); + + List<StringName> classes; + ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); + classes.sort_custom<StringName::AlphCompare>(); + + menu->add_submenu_item(TTR("Add Animation"), "animations"); + + AnimationTree *gp = blend_space->get_tree(); + ERR_FAIL_COND(!gp); + + if (gp->has_node(gp->get_animation_player())) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); + + if (ap) { + List<StringName> names; + ap->get_animation_list(&names); + + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + animations_menu->add_icon_item(get_icon("Animation", "Editoricons"), E->get()); + animations_to_add.push_back(E->get()); + } + } + } + + for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { + String name = String(E->get()).replace_first("AnimationNode", ""); + if (name == "Animation") + continue; + + int idx = menu->get_item_count(); + menu->add_item(vformat("Add %s", name)); + menu->set_item_metadata(idx, E->get()); + } + + menu->set_global_position(blend_space_draw->get_global_transform().xform(mb->get_position())); + menu->popup(); + + add_point_pos = (mb->get_position() / blend_space_draw->get_size()).x; + add_point_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); + add_point_pos += blend_space->get_min_space(); + + if (snap->is_pressed()) { + add_point_pos = Math::stepify(add_point_pos, blend_space->get_snap()); + } + } + + if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + blend_space_draw->update(); // why not + + // try to see if a point can be selected + selected_point = -1; + _update_tool_erase(); + + for (int i = 0; i < points.size(); i++) { + + if (Math::abs(float(points[i] - mb->get_position().x)) < 10 * EDSCALE) { + selected_point = i; + + Ref<AnimationNode> node = blend_space->get_blend_point_node(i); + EditorNode::get_singleton()->push_item(node.ptr(), "", true); + dragging_selected_attempt = true; + drag_from = mb->get_position(); + _update_tool_erase(); + _update_edited_point_pos(); + return; + } + } + } + + if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT) { + if (dragging_selected) { + // move + float point = blend_space->get_blend_point_position(selected_point); + point += drag_ofs.x; + + if (snap->is_pressed()) { + point = Math::stepify(point, blend_space->get_snap()); + } + + updating = true; + undo_redo->create_action("Move Node Point"); + undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point); + undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->add_do_method(this, "_update_edited_point_pos"); + undo_redo->add_undo_method(this, "_update_edited_point_pos"); + undo_redo->commit_action(); + updating = false; + _update_edited_point_pos(); + } + + dragging_selected_attempt = false; + dragging_selected = false; + blend_space_draw->update(); + } + + // *set* the blend + if (mb.is_valid() && !mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + float blend_pos = mb->get_position().x / blend_space_draw->get_size().x; + blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); + blend_pos += blend_space->get_min_space(); + + blend_space->set_blend_pos(blend_pos); + blend_space_draw->update(); + } + + Ref<InputEventMouseMotion> mm = p_event; + + if (mm.is_valid() && !blend_space_draw->has_focus()) { + blend_space_draw->grab_focus(); + blend_space_draw->update(); + } + + if (mm.is_valid() && dragging_selected_attempt) { + dragging_selected = true; + drag_ofs = ((mm->get_position() - drag_from) / blend_space_draw->get_size()) * ((blend_space->get_max_space() - blend_space->get_min_space()) * Vector2(1, 0)); + blend_space_draw->update(); + _update_edited_point_pos(); + } + + if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + float blend_pos = mm->get_position().x / blend_space_draw->get_size().x; + blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); + blend_pos += blend_space->get_min_space(); + + blend_space->set_blend_pos(blend_pos); + blend_space_draw->update(); + } +} + +void AnimationNodeBlendSpace1DEditor::_blend_space_draw() { + + Color linecolor = get_color("font_color", "Label"); + Color linecolor_soft = linecolor; + linecolor_soft.a *= 0.5; + + Ref<Font> font = get_font("font", "Label"); + Ref<Texture> icon = get_icon("KeyValue", "EditorIcons"); + Ref<Texture> icon_selected = get_icon("KeySelected", "EditorIcons"); + + Size2 s = blend_space_draw->get_size(); + + if (blend_space_draw->has_focus()) { + Color color = get_color("accent_color", "Editor"); + blend_space_draw->draw_rect(Rect2(Point2(), s), color, false); + } + + blend_space_draw->draw_line(Point2(1, s.height - 1), Point2(s.width - 1, s.height - 1), linecolor); + + if (blend_space->get_min_space() < 0) { + float point = 0.0; + point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); + point *= s.width; + + float x = point; + + blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor); + blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height() + font->get_ascent()), "0", linecolor); + blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft); + } + + if (snap->is_pressed()) { + + linecolor_soft.a = linecolor.a * 0.1; + + if (blend_space->get_snap() > 0) { + int prev_idx = -1; + + for (int i = 0; i < s.x; i++) { + float v = blend_space->get_min_space() + i * (blend_space->get_max_space() - blend_space->get_min_space()) / s.x; + int idx = int(v / blend_space->get_snap()); + + if (i > 0 && prev_idx != idx) { + blend_space_draw->draw_line(Point2(i, 0), Point2(i, s.height), linecolor_soft); + } + + prev_idx = idx; + } + } + } + + points.clear(); + + for (int i = 0; i < blend_space->get_blend_point_count(); i++) { + float point = blend_space->get_blend_point_position(i); + + if (dragging_selected && selected_point == i) { + point += drag_ofs.x; + if (snap->is_pressed()) { + point = Math::stepify(point, blend_space->get_snap()); + } + } + + point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); + point *= s.width; + + points.push_back(point); + + Vector2 gui_point = Vector2(point, s.height / 2.0); + + gui_point -= (icon->get_size() / 2.0); + + gui_point = gui_point.floor(); + + if (i == selected_point) { + blend_space_draw->draw_texture(icon_selected, gui_point); + } else { + blend_space_draw->draw_texture(icon, gui_point); + } + } + + // blend position + { + Color color; + if (tool_blend->is_pressed()) { + color = get_color("accent_color", "Editor"); + } else { + color = linecolor; + color.a *= 0.5; + } + + float point = blend_space->get_blend_pos(); + point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); + point *= s.width; + + Vector2 gui_point = Vector2(point, s.height / 2.0); + + float mind = 5 * EDSCALE; + float maxd = 15 * EDSCALE; + blend_space_draw->draw_line(gui_point + Vector2(mind, 0), gui_point + Vector2(maxd, 0), color, 2); + blend_space_draw->draw_line(gui_point + Vector2(-mind, 0), gui_point + Vector2(-maxd, 0), color, 2); + blend_space_draw->draw_line(gui_point + Vector2(0, mind), gui_point + Vector2(0, maxd), color, 2); + blend_space_draw->draw_line(gui_point + Vector2(0, -mind), gui_point + Vector2(0, -maxd), color, 2); + } +} + +void AnimationNodeBlendSpace1DEditor::_update_space() { + + if (updating) + return; + + updating = true; + + if (blend_space->get_parent().is_valid()) { + goto_parent_hb->show(); + } else { + goto_parent_hb->hide(); + } + + max_value->set_value(blend_space->get_max_space()); + min_value->set_value(blend_space->get_min_space()); + + label_value->set_text(blend_space->get_value_label()); + + snap_value->set_value(blend_space->get_snap()); + + blend_space_draw->update(); + + updating = false; +} + +void AnimationNodeBlendSpace1DEditor::_config_changed(double) { + if (updating) + return; + + updating = true; + undo_redo->create_action("Change BlendSpace1D Limits"); + undo_redo->add_do_method(blend_space.ptr(), "set_max_space", max_value->get_value()); + undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space()); + undo_redo->add_do_method(blend_space.ptr(), "set_min_space", min_value->get_value()); + undo_redo->add_undo_method(blend_space.ptr(), "set_min_space", blend_space->get_min_space()); + undo_redo->add_do_method(blend_space.ptr(), "set_snap", snap_value->get_value()); + undo_redo->add_undo_method(blend_space.ptr(), "set_snap", blend_space->get_snap()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace1DEditor::_labels_changed(String) { + if (updating) + return; + + updating = true; + undo_redo->create_action("Change BlendSpace1D Labels", UndoRedo::MERGE_ENDS); + undo_redo->add_do_method(blend_space.ptr(), "set_value_label", label_value->get_text()); + undo_redo->add_undo_method(blend_space.ptr(), "set_value_label", blend_space->get_value_label()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; +} + +void AnimationNodeBlendSpace1DEditor::_snap_toggled() { + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) { + String type = menu->get_item_metadata(p_index); + + Object *obj = ClassDB::instance(type); + ERR_FAIL_COND(!obj); + AnimationNode *an = Object::cast_to<AnimationNode>(obj); + ERR_FAIL_COND(!an); + + Ref<AnimationNode> node(an); + + updating = true; + undo_redo->create_action("Add Node Point"); + undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", node, add_point_pos); + undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace1DEditor::_add_animation_type(int p_index) { + Ref<AnimationNodeAnimation> anim; + anim.instance(); + + anim->set_animation(animations_to_add[p_index]); + + updating = true; + undo_redo->create_action("Add Animation Point"); + undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", anim, add_point_pos); + undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace1DEditor::_tool_switch(int p_tool) { + + if (p_tool == 0) { + tool_erase->show(); + tool_erase_sep->show(); + } else { + tool_erase->hide(); + tool_erase_sep->hide(); + } + + _update_tool_erase(); + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace1DEditor::_update_edited_point_pos() { + if (updating) + return; + + if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) { + float pos = blend_space->get_blend_point_position(selected_point); + + if (dragging_selected) { + pos += drag_ofs.x; + + if (snap->is_pressed()) { + pos = Math::stepify(pos, blend_space->get_snap()); + } + } + + updating = true; + edit_value->set_value(pos); + updating = false; + } +} + +void AnimationNodeBlendSpace1DEditor::_update_tool_erase() { + + bool point_valid = selected_point >= 0 && selected_point < blend_space->get_blend_point_count(); + tool_erase->set_disabled(!point_valid); + + if (point_valid) { + Ref<AnimationNode> an = blend_space->get_blend_point_node(selected_point); + + if (EditorNode::get_singleton()->item_has_editor(an.ptr())) { + open_editor->show(); + } else { + open_editor->hide(); + } + + edit_hb->show(); + } else { + edit_hb->hide(); + } +} + +void AnimationNodeBlendSpace1DEditor::_erase_selected() { + if (selected_point != -1) { + updating = true; + + undo_redo->create_action("Remove BlendSpace1D Point"); + undo_redo->add_do_method(blend_space.ptr(), "remove_blend_point", selected_point); + undo_redo->add_undo_method(blend_space.ptr(), "add_blend_point", blend_space->get_blend_point_node(selected_point), blend_space->get_blend_point_position(selected_point), selected_point); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + + updating = false; + + blend_space_draw->update(); + } +} + +void AnimationNodeBlendSpace1DEditor::_edit_point_pos(double) { + if (updating) + return; + + updating = true; + undo_redo->create_action("Move BlendSpace1D Node Point"); + undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, edit_value->get_value()); + undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->add_do_method(this, "_update_edited_point_pos"); + undo_redo->add_undo_method(this, "_update_edited_point_pos"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace1DEditor::_open_editor() { + + if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) { + Ref<AnimationNode> an = blend_space->get_blend_point_node(selected_point); + ERR_FAIL_COND(an.is_null()); + EditorNode::get_singleton()->edit_item(an.ptr()); + } +} + +void AnimationNodeBlendSpace1DEditor::_goto_parent() { + EditorNode::get_singleton()->edit_item(blend_space->get_parent().ptr()); +} + +void AnimationNodeBlendSpace1DEditor::_removed_from_graph() { + EditorNode::get_singleton()->edit_item(NULL); +} + +void AnimationNodeBlendSpace1DEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + error_panel->add_style_override("panel", get_stylebox("bg", "Tree")); + error_label->add_color_override("font_color", get_color("error_color", "Editor")); + panel->add_style_override("panel", get_stylebox("bg", "Tree")); + tool_blend->set_icon(get_icon("EditPivot", "EditorIcons")); + tool_select->set_icon(get_icon("ToolSelect", "EditorIcons")); + tool_create->set_icon(get_icon("EditKey", "EditorIcons")); + tool_erase->set_icon(get_icon("Remove", "EditorIcons")); + snap->set_icon(get_icon("SnapGrid", "EditorIcons")); + open_editor->set_icon(get_icon("Edit", "EditorIcons")); + goto_parent->set_icon(get_icon("MoveUp", "EditorIcons")); + } + + if (p_what == NOTIFICATION_PROCESS) { + String error; + + if (!blend_space->get_tree()) { + error = TTR("BlendSpace1D does not belong to an AnimationTree node."); + } else if (!blend_space->get_tree()->is_active()) { + error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); + } else if (blend_space->get_tree()->is_state_invalid()) { + error = blend_space->get_tree()->get_invalid_state_reason(); + } + + if (error != error_label->get_text()) { + error_label->set_text(error); + if (error != String()) { + error_panel->show(); + } else { + error_panel->hide(); + } + } + } +} + +void AnimationNodeBlendSpace1DEditor::_bind_methods() { + ClassDB::bind_method("_blend_space_gui_input", &AnimationNodeBlendSpace1DEditor::_blend_space_gui_input); + ClassDB::bind_method("_blend_space_draw", &AnimationNodeBlendSpace1DEditor::_blend_space_draw); + ClassDB::bind_method("_config_changed", &AnimationNodeBlendSpace1DEditor::_config_changed); + ClassDB::bind_method("_labels_changed", &AnimationNodeBlendSpace1DEditor::_labels_changed); + ClassDB::bind_method("_update_space", &AnimationNodeBlendSpace1DEditor::_update_space); + ClassDB::bind_method("_snap_toggled", &AnimationNodeBlendSpace1DEditor::_snap_toggled); + ClassDB::bind_method("_tool_switch", &AnimationNodeBlendSpace1DEditor::_tool_switch); + ClassDB::bind_method("_erase_selected", &AnimationNodeBlendSpace1DEditor::_erase_selected); + ClassDB::bind_method("_update_tool_erase", &AnimationNodeBlendSpace1DEditor::_update_tool_erase); + ClassDB::bind_method("_edit_point_pos", &AnimationNodeBlendSpace1DEditor::_edit_point_pos); + + ClassDB::bind_method("_add_menu_type", &AnimationNodeBlendSpace1DEditor::_add_menu_type); + ClassDB::bind_method("_add_animation_type", &AnimationNodeBlendSpace1DEditor::_add_animation_type); + + ClassDB::bind_method("_update_edited_point_pos", &AnimationNodeBlendSpace1DEditor::_update_edited_point_pos); + + ClassDB::bind_method("_open_editor", &AnimationNodeBlendSpace1DEditor::_open_editor); + ClassDB::bind_method("_goto_parent", &AnimationNodeBlendSpace1DEditor::_goto_parent); + + ClassDB::bind_method("_removed_from_graph", &AnimationNodeBlendSpace1DEditor::_removed_from_graph); +} + +void AnimationNodeBlendSpace1DEditor::edit(AnimationNodeBlendSpace1D *p_blend_space) { + + if (blend_space.is_valid()) { + blend_space->disconnect("removed_from_graph", this, "_removed_from_graph"); + } + + if (p_blend_space) { + blend_space = Ref<AnimationNodeBlendSpace1D>(p_blend_space); + } else { + blend_space.unref(); + } + + if (blend_space.is_null()) { + hide(); + } else { + blend_space->connect("removed_from_graph", this, "_removed_from_graph"); + + _update_space(); + } +} + +AnimationNodeBlendSpace1DEditor *AnimationNodeBlendSpace1DEditor::singleton = NULL; + +AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { + singleton = this; + updating = false; + + HBoxContainer *top_hb = memnew(HBoxContainer); + add_child(top_hb); + + Ref<ButtonGroup> bg; + bg.instance(); + + goto_parent_hb = memnew(HBoxContainer); + top_hb->add_child(goto_parent_hb); + + goto_parent = memnew(ToolButton); + goto_parent->connect("pressed", this, "_goto_parent", varray(), CONNECT_DEFERRED); + goto_parent_hb->add_child(goto_parent); + goto_parent_hb->add_child(memnew(VSeparator)); + goto_parent_hb->hide(); + + tool_blend = memnew(ToolButton); + tool_blend->set_toggle_mode(true); + tool_blend->set_button_group(bg); + top_hb->add_child(tool_blend); + tool_blend->set_pressed(true); + tool_blend->set_tooltip(TTR("Set the blending position within the space")); + tool_blend->connect("pressed", this, "_tool_switch", varray(3)); + + tool_select = memnew(ToolButton); + tool_select->set_toggle_mode(true); + tool_select->set_button_group(bg); + top_hb->add_child(tool_select); + tool_select->set_tooltip(TTR("Select and move points, create points with RMB.")); + tool_select->connect("pressed", this, "_tool_switch", varray(0)); + + tool_create = memnew(ToolButton); + tool_create->set_toggle_mode(true); + tool_create->set_button_group(bg); + top_hb->add_child(tool_create); + tool_create->set_tooltip(TTR("Create points.")); + tool_create->connect("pressed", this, "_tool_switch", varray(1)); + + tool_erase_sep = memnew(VSeparator); + top_hb->add_child(tool_erase_sep); + tool_erase = memnew(ToolButton); + top_hb->add_child(tool_erase); + tool_erase->set_tooltip(TTR("Erase points.")); + tool_erase->connect("pressed", this, "_erase_selected"); + + top_hb->add_child(memnew(VSeparator)); + + snap = memnew(ToolButton); + snap->set_toggle_mode(true); + top_hb->add_child(snap); + snap->set_pressed(true); + snap->connect("pressed", this, "_snap_toggled"); + + snap_value = memnew(SpinBox); + top_hb->add_child(snap_value); + snap_value->set_min(0.01); + snap_value->set_step(0.01); + snap_value->set_max(1000); + + edit_hb = memnew(HBoxContainer); + top_hb->add_child(edit_hb); + edit_hb->add_child(memnew(VSeparator)); + edit_hb->add_child(memnew(Label(TTR("Point")))); + + edit_value = memnew(SpinBox); + edit_hb->add_child(edit_value); + edit_value->set_min(-1000); + edit_value->set_max(1000); + edit_value->set_step(0.01); + edit_value->connect("value_changed", this, "_edit_point_pos"); + + open_editor = memnew(Button); + edit_hb->add_child(open_editor); + open_editor->set_text(TTR("Open Editor")); + open_editor->connect("pressed", this, "_open_editor", varray(), CONNECT_DEFERRED); + + edit_hb->hide(); + open_editor->hide(); + + VBoxContainer *main_vb = memnew(VBoxContainer); + add_child(main_vb); + main_vb->set_v_size_flags(SIZE_EXPAND_FILL); + + panel = memnew(PanelContainer); + panel->set_clip_contents(true); + main_vb->add_child(panel); + panel->set_h_size_flags(SIZE_EXPAND_FILL); + panel->set_v_size_flags(SIZE_EXPAND_FILL); + + blend_space_draw = memnew(Control); + blend_space_draw->connect("gui_input", this, "_blend_space_gui_input"); + blend_space_draw->connect("draw", this, "_blend_space_draw"); + blend_space_draw->set_focus_mode(FOCUS_ALL); + + panel->add_child(blend_space_draw); + + { + HBoxContainer *bottom_hb = memnew(HBoxContainer); + main_vb->add_child(bottom_hb); + bottom_hb->set_h_size_flags(SIZE_EXPAND_FILL); + + min_value = memnew(SpinBox); + min_value->set_max(0); + min_value->set_min(-10000); + min_value->set_step(0.01); + + max_value = memnew(SpinBox); + max_value->set_max(10000); + max_value->set_min(0.01); + max_value->set_step(0.01); + + label_value = memnew(LineEdit); + label_value->set_expand_to_text_length(true); + + // now add + + bottom_hb->add_child(min_value); + bottom_hb->add_spacer(); + bottom_hb->add_child(label_value); + bottom_hb->add_spacer(); + bottom_hb->add_child(max_value); + } + + snap_value->connect("value_changed", this, "_config_changed"); + min_value->connect("value_changed", this, "_config_changed"); + max_value->connect("value_changed", this, "_config_changed"); + label_value->connect("text_changed", this, "_labels_changed"); + + error_panel = memnew(PanelContainer); + add_child(error_panel); + + error_label = memnew(Label); + error_panel->add_child(error_label); + error_label->set_text("hmmm"); + + undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + menu = memnew(PopupMenu); + add_child(menu); + menu->connect("index_pressed", this, "_add_menu_type"); + + animations_menu = memnew(PopupMenu); + menu->add_child(animations_menu); + animations_menu->set_name("animations"); + animations_menu->connect("index_pressed", this, "_add_animation_type"); + + selected_point = -1; + dragging_selected = false; + dragging_selected_attempt = false; + + set_custom_minimum_size(Size2(0, 150 * EDSCALE)); +} diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h new file mode 100644 index 0000000000..52139626e6 --- /dev/null +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -0,0 +1,117 @@ +#ifndef ANIMATION_BLEND_SPACE_1D_EDITOR_H +#define ANIMATION_BLEND_SPACE_1D_EDITOR_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "editor/property_editor.h" +#include "scene/animation/animation_blend_space_1d.h" +#include "scene/gui/button.h" +#include "scene/gui/graph_edit.h" +#include "scene/gui/popup.h" +#include "scene/gui/tree.h" + +class AnimationNodeBlendSpace1DEditor : public VBoxContainer { + + GDCLASS(AnimationNodeBlendSpace1DEditor, VBoxContainer) + + Ref<AnimationNodeBlendSpace1D> blend_space; + + HBoxContainer *goto_parent_hb; + ToolButton *goto_parent; + + PanelContainer *panel; + ToolButton *tool_blend; + ToolButton *tool_select; + ToolButton *tool_create; + VSeparator *tool_erase_sep; + ToolButton *tool_erase; + ToolButton *snap; + SpinBox *snap_value; + + LineEdit *label_value; + SpinBox *max_value; + SpinBox *min_value; + + HBoxContainer *edit_hb; + SpinBox *edit_value; + Button *open_editor; + + int selected_point; + + Control *blend_space_draw; + + PanelContainer *error_panel; + Label *error_label; + + bool updating; + + UndoRedo *undo_redo; + + static AnimationNodeBlendSpace1DEditor *singleton; + + void _blend_space_gui_input(const Ref<InputEvent> &p_event); + void _blend_space_draw(); + + void _update_space(); + + void _config_changed(double); + void _labels_changed(String); + void _snap_toggled(); + + PopupMenu *menu; + PopupMenu *animations_menu; + Vector<String> animations_to_add; + float add_point_pos; + Vector<float> points; + + bool dragging_selected_attempt; + bool dragging_selected; + Vector2 drag_from; + Vector2 drag_ofs; + + void _add_menu_type(int p_index); + void _add_animation_type(int p_index); + + void _tool_switch(int p_tool); + void _update_edited_point_pos(); + void _update_tool_erase(); + void _erase_selected(); + void _edit_point_pos(double); + void _open_editor(); + + void _goto_parent(); + + void _removed_from_graph(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static AnimationNodeBlendSpace1DEditor *get_singleton() { return singleton; } + void edit(AnimationNodeBlendSpace1D *p_blend_space); + AnimationNodeBlendSpace1DEditor(); +}; + +class AnimationNodeBlendSpace1DEditorPlugin : public EditorPlugin { + + GDCLASS(AnimationNodeBlendSpace1DEditorPlugin, EditorPlugin) + + AnimationNodeBlendSpace1DEditor *anim_tree_editor; + EditorNode *editor; + Button *button; + +public: + virtual String get_name() const { return "BlendSpace1D"; } + + 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); + + AnimationNodeBlendSpace1DEditorPlugin(EditorNode *p_node); + ~AnimationNodeBlendSpace1DEditorPlugin(); +}; + +#endif // ANIMATION_BLEND_SPACE_1D_EDITOR_H diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp new file mode 100644 index 0000000000..8d17062248 --- /dev/null +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -0,0 +1,1023 @@ +#include "animation_blend_space_2d_editor.h" + +#include "core/io/resource_loader.h" +#include "core/project_settings.h" +#include "math/delaunay.h" +#include "os/input.h" +#include "os/keyboard.h" +#include "scene/animation/animation_blend_tree.h" +#include "scene/animation/animation_player.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/panel.h" +#include "scene/main/viewport.h" + +void AnimationNodeBlendSpace2DEditor::edit(AnimationNodeBlendSpace2D *p_blend_space) { + + if (blend_space.is_valid()) { + blend_space->disconnect("removed_from_graph", this, "_removed_from_graph"); + } + + if (p_blend_space) { + blend_space = Ref<AnimationNodeBlendSpace2D>(p_blend_space); + } else { + blend_space.unref(); + } + + if (blend_space.is_null()) { + hide(); + } else { + blend_space->connect("removed_from_graph", this, "_removed_from_graph"); + + _update_space(); + } +} + +void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEvent> &p_event) { + + Ref<InputEventKey> k = p_event; + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && !k->is_echo()) { + if (selected_point != -1 || selected_triangle != -1) { + _erase_selected(); + accept_event(); + } + } + + Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (mb->get_button_index() == BUTTON_LEFT && tool_create->is_pressed()))) { + menu->clear(); + animations_menu->clear(); + animations_to_add.clear(); + List<StringName> classes; + classes.sort_custom<StringName::AlphCompare>(); + + ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); + menu->add_submenu_item(TTR("Add Animation"), "animations"); + + AnimationTree *gp = blend_space->get_tree(); + ERR_FAIL_COND(!gp); + if (gp && gp->has_node(gp->get_animation_player())) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); + if (ap) { + List<StringName> names; + ap->get_animation_list(&names); + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + animations_menu->add_icon_item(get_icon("Animation", "EditorIcons"), E->get()); + animations_to_add.push_back(E->get()); + } + } + } + + for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { + + String name = String(E->get()).replace_first("AnimationNode", ""); + if (name == "Animation") + continue; // nope + int idx = menu->get_item_count(); + menu->add_item(vformat("Add %s", name)); + menu->set_item_metadata(idx, E->get()); + } + + menu->set_global_position(blend_space_draw->get_global_transform().xform(mb->get_position())); + menu->popup(); + add_point_pos = (mb->get_position() / blend_space_draw->get_size()); + add_point_pos.y = 1.0 - add_point_pos.y; + add_point_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); + add_point_pos += blend_space->get_min_space(); + + if (snap->is_pressed()) { + add_point_pos.x = Math::stepify(add_point_pos.x, blend_space->get_snap().x); + add_point_pos.y = Math::stepify(add_point_pos.y, blend_space->get_snap().y); + } + } + + if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + + blend_space_draw->update(); //update anyway + //try to see if a point can be selected + selected_point = -1; + selected_triangle = -1; + _update_tool_erase(); + + for (int i = 0; i < points.size(); i++) { + + if (points[i].distance_to(mb->get_position()) < 10 * EDSCALE) { + selected_point = i; + Ref<AnimationNode> node = blend_space->get_blend_point_node(i); + EditorNode::get_singleton()->push_item(node.ptr(), "", true); + dragging_selected_attempt = true; + drag_from = mb->get_position(); + _update_tool_erase(); + _update_edited_point_pos(); + return; + } + } + + //then try to see if a triangle can be selected + if (!blend_space->get_auto_triangles()) { //if autotriangles use, disable this + for (int i = 0; i < blend_space->get_triangle_count(); i++) { + Vector<Vector2> triangle; + + for (int j = 0; j < 3; j++) { + int idx = blend_space->get_triangle_point(i, j); + ERR_FAIL_INDEX(idx, points.size()); + triangle.push_back(points[idx]); + } + + if (Geometry::is_point_in_triangle(mb->get_position(), triangle[0], triangle[1], triangle[2])) { + selected_triangle = i; + _update_tool_erase(); + return; + } + } + } + } + + if (mb.is_valid() && mb->is_pressed() && tool_triangle->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + + blend_space_draw->update(); //update anyway + //try to see if a point can be selected + selected_point = -1; + + for (int i = 0; i < points.size(); i++) { + + if (making_triangle.find(i) != -1) + continue; + + if (points[i].distance_to(mb->get_position()) < 10 * EDSCALE) { + making_triangle.push_back(i); + if (making_triangle.size() == 3) { + //add triangle! + if (blend_space->has_triangle(making_triangle[0], making_triangle[1], making_triangle[2])) { + making_triangle.clear(); + EditorNode::get_singleton()->show_warning(TTR("Triangle already exists")); + return; + } + + updating = true; + undo_redo->create_action("Add Triangle"); + undo_redo->add_do_method(blend_space.ptr(), "add_triangle", making_triangle[0], making_triangle[1], making_triangle[2]); + undo_redo->add_undo_method(blend_space.ptr(), "remove_triangle", blend_space->get_triangle_count()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + making_triangle.clear(); + } + return; + } + } + } + + if (mb.is_valid() && !mb->is_pressed() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT) { + if (dragging_selected) { + //move + Vector2 point = blend_space->get_blend_point_position(selected_point); + point += drag_ofs; + if (snap->is_pressed()) { + point.x = Math::stepify(point.x, blend_space->get_snap().x); + point.y = Math::stepify(point.y, blend_space->get_snap().y); + } + + updating = true; + undo_redo->create_action("Move Node Point"); + undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point); + undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->add_do_method(this, "_update_edited_point_pos"); + undo_redo->add_undo_method(this, "_update_edited_point_pos"); + undo_redo->commit_action(); + updating = false; + _update_edited_point_pos(); + } + dragging_selected_attempt = false; + dragging_selected = false; + blend_space_draw->update(); + } + + if (mb.is_valid() && mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + + Vector2 blend_pos = (mb->get_position() / blend_space_draw->get_size()); + blend_pos.y = 1.0 - blend_pos.y; + blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); + blend_pos += blend_space->get_min_space(); + + blend_space->set_blend_position(blend_pos); + blend_space_draw->update(); + } + + Ref<InputEventMouseMotion> mm = p_event; + + if (mm.is_valid() && !blend_space_draw->has_focus()) { + blend_space_draw->grab_focus(); + blend_space_draw->update(); + } + + if (mm.is_valid() && dragging_selected_attempt) { + dragging_selected = true; + drag_ofs = ((mm->get_position() - drag_from) / blend_space_draw->get_size()) * (blend_space->get_max_space() - blend_space->get_min_space()) * Vector2(1, -1); + blend_space_draw->update(); + _update_edited_point_pos(); + } + + if (mm.is_valid() && tool_triangle->is_pressed() && making_triangle.size()) { + blend_space_draw->update(); + } + + if (mm.is_valid() && !tool_triangle->is_pressed() && making_triangle.size()) { + making_triangle.clear(); + blend_space_draw->update(); + } + + if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & BUTTON_MASK_LEFT) { + + Vector2 blend_pos = (mm->get_position() / blend_space_draw->get_size()); + blend_pos.y = 1.0 - blend_pos.y; + blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); + blend_pos += blend_space->get_min_space(); + + blend_space->set_blend_position(blend_pos); + blend_space_draw->update(); + } +} + +void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) { + + String type = menu->get_item_metadata(p_index); + + Object *obj = ClassDB::instance(type); + ERR_FAIL_COND(!obj); + AnimationNode *an = Object::cast_to<AnimationNode>(obj); + ERR_FAIL_COND(!an); + + Ref<AnimationNode> node(an); + + updating = true; + undo_redo->create_action("Add Node Point"); + undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", node, add_point_pos); + undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace2DEditor::_add_animation_type(int p_index) { + + Ref<AnimationNodeAnimation> anim; + anim.instance(); + + anim->set_animation(animations_to_add[p_index]); + + updating = true; + undo_redo->create_action("Add Animation Point"); + undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", anim, add_point_pos); + undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace2DEditor::_update_tool_erase() { + tool_erase->set_disabled(!(selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) && !(selected_triangle >= 0 && selected_triangle < blend_space->get_triangle_count())); + if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) { + Ref<AnimationNode> an = blend_space->get_blend_point_node(selected_point); + if (EditorNode::get_singleton()->item_has_editor(an.ptr())) { + open_editor->show(); + } else { + open_editor->hide(); + } + edit_hb->show(); + } else { + edit_hb->hide(); + } +} + +void AnimationNodeBlendSpace2DEditor::_tool_switch(int p_tool) { + making_triangle.clear(); + + if (p_tool == 2) { + Vector<Vector2> points; + for (int i = 0; i < blend_space->get_blend_point_count(); i++) { + points.push_back(blend_space->get_blend_point_position(i)); + } + Vector<Delaunay2D::Triangle> tr = Delaunay2D::triangulate(points); + print_line("triangleS: " + itos(tr.size())); + for (int i = 0; i < tr.size(); i++) { + blend_space->add_triangle(tr[i].points[0], tr[i].points[1], tr[i].points[2]); + } + } + + if (p_tool == 0) { + tool_erase->show(); + tool_erase_sep->show(); + } else { + tool_erase->hide(); + tool_erase_sep->hide(); + } + _update_tool_erase(); + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { + + Color linecolor = get_color("font_color", "Label"); + Color linecolor_soft = linecolor; + linecolor_soft.a *= 0.5; + Ref<Font> font = get_font("font", "Label"); + Ref<Texture> icon = get_icon("KeyValue", "EditorIcons"); + Ref<Texture> icon_selected = get_icon("KeySelected", "EditorIcons"); + + Size2 s = blend_space_draw->get_size(); + + if (blend_space_draw->has_focus()) { + Color color = get_color("accent_color", "Editor"); + blend_space_draw->draw_rect(Rect2(Point2(), s), color, false); + } + blend_space_draw->draw_line(Point2(1, 0), Point2(1, s.height - 1), linecolor); + blend_space_draw->draw_line(Point2(1, s.height - 1), Point2(s.width - 1, s.height - 1), linecolor); + + blend_space_draw->draw_line(Point2(0, 0), Point2(5 * EDSCALE, 0), linecolor); + if (blend_space->get_min_space().y < 0) { + int y = (blend_space->get_max_space().y / (blend_space->get_max_space().y - blend_space->get_min_space().y)) * s.height; + blend_space_draw->draw_line(Point2(0, y), Point2(5 * EDSCALE, y), linecolor); + blend_space_draw->draw_string(font, Point2(2 * EDSCALE, y - font->get_height() + font->get_ascent()), "0", linecolor); + blend_space_draw->draw_line(Point2(5 * EDSCALE, y), Point2(s.width, y), linecolor_soft); + } + + if (blend_space->get_min_space().x < 0) { + int x = (-blend_space->get_min_space().x / (blend_space->get_max_space().x - blend_space->get_min_space().x)) * s.width; + blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor); + blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height() + font->get_ascent()), "0", linecolor); + blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft); + } + + if (snap->is_pressed()) { + + linecolor_soft.a = linecolor.a * 0.1; + + if (blend_space->get_snap().x > 0) { + + int prev_idx; + for (int i = 0; i < s.x; i++) { + + float v = blend_space->get_min_space().x + i * (blend_space->get_max_space().x - blend_space->get_min_space().x) / s.x; + int idx = int(v / blend_space->get_snap().x); + + if (i > 0 && prev_idx != idx) { + blend_space_draw->draw_line(Point2(i, 0), Point2(i, s.height), linecolor_soft); + } + + prev_idx = idx; + } + } + + if (blend_space->get_snap().y > 0) { + + int prev_idx; + for (int i = 0; i < s.y; i++) { + + float v = blend_space->get_max_space().y - i * (blend_space->get_max_space().y - blend_space->get_min_space().y) / s.y; + int idx = int(v / blend_space->get_snap().y); + + if (i > 0 && prev_idx != idx) { + blend_space_draw->draw_line(Point2(0, i), Point2(s.width, i), linecolor_soft); + } + + prev_idx = idx; + } + } + } + + //triangles first + for (int i = 0; i < blend_space->get_triangle_count(); i++) { + + Vector<Vector2> points; + points.resize(3); + + for (int j = 0; j < 3; j++) { + int point_idx = blend_space->get_triangle_point(i, j); + Vector2 point = blend_space->get_blend_point_position(point_idx); + if (dragging_selected && selected_point == point_idx) { + point += drag_ofs; + if (snap->is_pressed()) { + point.x = Math::stepify(point.x, blend_space->get_snap().x); + point.y = Math::stepify(point.y, blend_space->get_snap().y); + } + } + 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; + } + + for (int j = 0; j < 3; j++) { + blend_space_draw->draw_line(points[j], points[(j + 1) % 3], linecolor, 1, true); + } + + Color color; + if (i == selected_triangle) { + color = get_color("accent_color", "Editor"); + color.a *= 0.5; + } else { + color = linecolor; + color.a *= 0.2; + } + + Vector<Color> colors; + colors.push_back(color); + colors.push_back(color); + colors.push_back(color); + blend_space_draw->draw_primitive(points, colors, Vector<Vector2>()); + } + + points.clear(); + for (int i = 0; i < blend_space->get_blend_point_count(); i++) { + + Vector2 point = blend_space->get_blend_point_position(i); + if (dragging_selected && selected_point == i) { + point += drag_ofs; + if (snap->is_pressed()) { + point.x = Math::stepify(point.x, blend_space->get_snap().x); + point.y = Math::stepify(point.y, blend_space->get_snap().y); + } + } + 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.push_back(point); + point -= (icon->get_size() / 2); + point = point.floor(); + + if (i == selected_point) { + blend_space_draw->draw_texture(icon_selected, point); + } else { + blend_space_draw->draw_texture(icon, point); + } + } + + if (making_triangle.size()) { + Vector<Vector2> points; + for (int i = 0; i < making_triangle.size(); i++) { + Vector2 point = blend_space->get_blend_point_position(making_triangle[i]); + 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.push_back(point); + } + + for (int i = 0; i < points.size() - 1; i++) { + blend_space_draw->draw_line(points[i], points[i + 1], linecolor, 2, true); + } + blend_space_draw->draw_line(points[points.size() - 1], blend_space_draw->get_local_mouse_position(), linecolor, 2, true); + } + + ///draw cursor position + + { + Color color; + if (tool_blend->is_pressed()) { + color = get_color("accent_color", "Editor"); + } else { + color = linecolor; + color.a *= 0.5; + } + + Vector2 point = blend_space->get_blend_position(); + 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; + + if (blend_space->get_triangle_count()) { + Vector2 closest = blend_space->get_closest_point(blend_space->get_blend_position()); + closest = (closest - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); + closest *= s; + closest.y = s.height - closest.y; + + Color lcol = color; + lcol.a *= 0.4; + blend_space_draw->draw_line(point, closest, lcol, 2); + } + + float mind = 5 * EDSCALE; + float maxd = 15 * EDSCALE; + blend_space_draw->draw_line(point + Vector2(mind, 0), point + Vector2(maxd, 0), color, 2); + blend_space_draw->draw_line(point + Vector2(-mind, 0), point + Vector2(-maxd, 0), color, 2); + blend_space_draw->draw_line(point + Vector2(0, mind), point + Vector2(0, maxd), color, 2); + blend_space_draw->draw_line(point + Vector2(0, -mind), point + Vector2(0, -maxd), color, 2); + } +} + +void AnimationNodeBlendSpace2DEditor::_snap_toggled() { + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace2DEditor::_update_space() { + + if (updating) + return; + + updating = true; + + if (blend_space->get_parent().is_valid()) { + goto_parent_hb->show(); + } else { + goto_parent_hb->hide(); + } + + if (blend_space->get_auto_triangles()) { + tool_triangle->hide(); + } else { + tool_triangle->show(); + } + + auto_triangles->set_pressed(blend_space->get_auto_triangles()); + + max_x_value->set_value(blend_space->get_max_space().x); + max_y_value->set_value(blend_space->get_max_space().y); + + min_x_value->set_value(blend_space->get_min_space().x); + min_y_value->set_value(blend_space->get_min_space().y); + + label_x->set_text(blend_space->get_x_label()); + label_y->set_text(blend_space->get_y_label()); + + snap_x->set_value(blend_space->get_snap().x); + snap_y->set_value(blend_space->get_snap().y); + + blend_space_draw->update(); + + updating = false; +} + +void AnimationNodeBlendSpace2DEditor::_config_changed(double) { + if (updating) + return; + + updating = true; + undo_redo->create_action("Change BlendSpace2D Limits"); + undo_redo->add_do_method(blend_space.ptr(), "set_max_space", Vector2(max_x_value->get_value(), max_y_value->get_value())); + undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space()); + undo_redo->add_do_method(blend_space.ptr(), "set_min_space", Vector2(min_x_value->get_value(), min_y_value->get_value())); + undo_redo->add_undo_method(blend_space.ptr(), "set_min_space", blend_space->get_min_space()); + undo_redo->add_do_method(blend_space.ptr(), "set_snap", Vector2(snap_x->get_value(), snap_y->get_value())); + undo_redo->add_undo_method(blend_space.ptr(), "set_snap", blend_space->get_snap()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace2DEditor::_labels_changed(String) { + if (updating) + return; + + updating = true; + undo_redo->create_action("Change BlendSpace2D Labels", UndoRedo::MERGE_ENDS); + undo_redo->add_do_method(blend_space.ptr(), "set_x_label", label_x->get_text()); + undo_redo->add_undo_method(blend_space.ptr(), "set_x_label", blend_space->get_x_label()); + undo_redo->add_do_method(blend_space.ptr(), "set_y_label", label_y->get_text()); + undo_redo->add_undo_method(blend_space.ptr(), "set_y_label", blend_space->get_y_label()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; +} + +void AnimationNodeBlendSpace2DEditor::_erase_selected() { + + if (selected_point != -1) { + + updating = true; + undo_redo->create_action("Remove BlendSpace2D Point"); + undo_redo->add_do_method(blend_space.ptr(), "remove_blend_point", selected_point); + undo_redo->add_undo_method(blend_space.ptr(), "add_blend_point", blend_space->get_blend_point_node(selected_point), blend_space->get_blend_point_position(selected_point), selected_point); + + //restore triangles using this point + for (int i = 0; i < blend_space->get_triangle_count(); i++) { + for (int j = 0; j < 3; j++) { + if (blend_space->get_triangle_point(i, j) == selected_point) { + undo_redo->add_undo_method(blend_space.ptr(), "add_triangle", blend_space->get_triangle_point(i, 0), blend_space->get_triangle_point(i, 1), blend_space->get_triangle_point(i, 2), i); + break; + } + } + } + + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); + } else if (selected_triangle != -1) { + + updating = true; + undo_redo->create_action("Remove BlendSpace2D Triangle"); + undo_redo->add_do_method(blend_space.ptr(), "remove_triangle", selected_triangle); + undo_redo->add_undo_method(blend_space.ptr(), "add_triangle", blend_space->get_triangle_point(selected_triangle, 0), blend_space->get_triangle_point(selected_triangle, 1), blend_space->get_triangle_point(selected_triangle, 2), selected_triangle); + + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); + } +} + +void AnimationNodeBlendSpace2DEditor::_update_edited_point_pos() { + if (updating) + return; + + if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) { + Vector2 pos = blend_space->get_blend_point_position(selected_point); + if (dragging_selected) { + pos += drag_ofs; + if (snap->is_pressed()) { + pos.x = Math::stepify(pos.x, blend_space->get_snap().x); + pos.y = Math::stepify(pos.y, blend_space->get_snap().y); + } + } + updating = true; + edit_x->set_value(pos.x); + edit_y->set_value(pos.y); + updating = false; + } +} + +void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) { + if (updating) + return; + updating = true; + undo_redo->create_action("Move Node Point"); + undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, Vector2(edit_x->get_value(), edit_y->get_value())); + undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->add_do_method(this, "_update_edited_point_pos"); + undo_redo->add_undo_method(this, "_update_edited_point_pos"); + undo_redo->commit_action(); + updating = false; + + blend_space_draw->update(); +} + +void AnimationNodeBlendSpace2DEditor::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + error_panel->add_style_override("panel", get_stylebox("bg", "Tree")); + error_label->add_color_override("font_color", get_color("error_color", "Editor")); + panel->add_style_override("panel", get_stylebox("bg", "Tree")); + tool_blend->set_icon(get_icon("EditPivot", "EditorIcons")); + tool_select->set_icon(get_icon("ToolSelect", "EditorIcons")); + tool_create->set_icon(get_icon("EditKey", "EditorIcons")); + tool_triangle->set_icon(get_icon("ToolTriangle", "EditorIcons")); + tool_erase->set_icon(get_icon("Remove", "EditorIcons")); + snap->set_icon(get_icon("SnapGrid", "EditorIcons")); + open_editor->set_icon(get_icon("Edit", "EditorIcons")); + goto_parent->set_icon(get_icon("MoveUp", "EditorIcons")); + auto_triangles->set_icon(get_icon("AutoTriangle", "EditorIcons")); + } + + if (p_what == NOTIFICATION_PROCESS) { + + String error; + + if (!blend_space->get_tree()) { + error = TTR("BlendSpace2D does not belong to an AnimationTree node."); + } else if (!blend_space->get_tree()->is_active()) { + error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); + } else if (blend_space->get_tree()->is_state_invalid()) { + error = blend_space->get_tree()->get_invalid_state_reason(); + } else if (blend_space->get_triangle_count() == 0) { + error = TTR("No triangles exist, so no blending can take place."); + } + + if (error != error_label->get_text()) { + error_label->set_text(error); + if (error != String()) { + error_panel->show(); + } else { + error_panel->hide(); + } + } + } +} + +void AnimationNodeBlendSpace2DEditor::_open_editor() { + + if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) { + Ref<AnimationNode> an = blend_space->get_blend_point_node(selected_point); + ERR_FAIL_COND(!an.is_valid()); + EditorNode::get_singleton()->edit_item(an.ptr()); + } +} + +void AnimationNodeBlendSpace2DEditor::_goto_parent() { + + EditorNode::get_singleton()->edit_item(blend_space->get_parent().ptr()); +} + +void AnimationNodeBlendSpace2DEditor::_removed_from_graph() { + EditorNode::get_singleton()->edit_item(NULL); +} + +void AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled() { + + undo_redo->create_action("Toggle Auto Triangles"); + undo_redo->add_do_method(blend_space.ptr(), "set_auto_triangles", auto_triangles->is_pressed()); + undo_redo->add_undo_method(blend_space.ptr(), "set_auto_triangles", blend_space->get_auto_triangles()); + undo_redo->add_do_method(this, "_update_space"); + undo_redo->add_undo_method(this, "_update_space"); + undo_redo->commit_action(); +} + +void AnimationNodeBlendSpace2DEditor::_bind_methods() { + + ClassDB::bind_method("_blend_space_gui_input", &AnimationNodeBlendSpace2DEditor::_blend_space_gui_input); + ClassDB::bind_method("_blend_space_draw", &AnimationNodeBlendSpace2DEditor::_blend_space_draw); + ClassDB::bind_method("_config_changed", &AnimationNodeBlendSpace2DEditor::_config_changed); + ClassDB::bind_method("_labels_changed", &AnimationNodeBlendSpace2DEditor::_labels_changed); + ClassDB::bind_method("_update_space", &AnimationNodeBlendSpace2DEditor::_update_space); + ClassDB::bind_method("_snap_toggled", &AnimationNodeBlendSpace2DEditor::_snap_toggled); + ClassDB::bind_method("_tool_switch", &AnimationNodeBlendSpace2DEditor::_tool_switch); + ClassDB::bind_method("_erase_selected", &AnimationNodeBlendSpace2DEditor::_erase_selected); + ClassDB::bind_method("_update_tool_erase", &AnimationNodeBlendSpace2DEditor::_update_tool_erase); + ClassDB::bind_method("_edit_point_pos", &AnimationNodeBlendSpace2DEditor::_edit_point_pos); + + ClassDB::bind_method("_add_menu_type", &AnimationNodeBlendSpace2DEditor::_add_menu_type); + ClassDB::bind_method("_add_animation_type", &AnimationNodeBlendSpace2DEditor::_add_animation_type); + + ClassDB::bind_method("_update_edited_point_pos", &AnimationNodeBlendSpace2DEditor::_update_edited_point_pos); + + ClassDB::bind_method("_open_editor", &AnimationNodeBlendSpace2DEditor::_open_editor); + ClassDB::bind_method("_goto_parent", &AnimationNodeBlendSpace2DEditor::_goto_parent); + + ClassDB::bind_method("_removed_from_graph", &AnimationNodeBlendSpace2DEditor::_removed_from_graph); + + ClassDB::bind_method("_auto_triangles_toggled", &AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled); +} + +AnimationNodeBlendSpace2DEditor *AnimationNodeBlendSpace2DEditor::singleton = NULL; + +AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { + + singleton = this; + updating = false; + + HBoxContainer *top_hb = memnew(HBoxContainer); + add_child(top_hb); + + Ref<ButtonGroup> bg; + bg.instance(); + + goto_parent_hb = memnew(HBoxContainer); + top_hb->add_child(goto_parent_hb); + goto_parent = memnew(ToolButton); + goto_parent->connect("pressed", this, "_goto_parent", varray(), CONNECT_DEFERRED); + goto_parent_hb->add_child(goto_parent); + goto_parent_hb->add_child(memnew(VSeparator)); + goto_parent_hb->hide(); + + tool_blend = memnew(ToolButton); + tool_blend->set_toggle_mode(true); + tool_blend->set_button_group(bg); + top_hb->add_child(tool_blend); + tool_blend->set_pressed(true); + tool_blend->set_tooltip(TTR("Set the blending position within the space")); + tool_blend->connect("pressed", this, "_tool_switch", varray(3)); + + tool_select = memnew(ToolButton); + tool_select->set_toggle_mode(true); + tool_select->set_button_group(bg); + top_hb->add_child(tool_select); + tool_select->set_tooltip(TTR("Select and move points, create points with RMB.")); + tool_select->connect("pressed", this, "_tool_switch", varray(0)); + + tool_create = memnew(ToolButton); + tool_create->set_toggle_mode(true); + tool_create->set_button_group(bg); + top_hb->add_child(tool_create); + tool_create->set_tooltip(TTR("Create points.")); + tool_create->connect("pressed", this, "_tool_switch", varray(1)); + + tool_triangle = memnew(ToolButton); + tool_triangle->set_toggle_mode(true); + tool_triangle->set_button_group(bg); + top_hb->add_child(tool_triangle); + tool_triangle->set_tooltip(TTR("Create triangles by connecting points.")); + tool_triangle->connect("pressed", this, "_tool_switch", varray(2)); + + tool_erase_sep = memnew(VSeparator); + top_hb->add_child(tool_erase_sep); + tool_erase = memnew(ToolButton); + top_hb->add_child(tool_erase); + tool_erase->set_tooltip(TTR("Erase points and triangles.")); + tool_erase->connect("pressed", this, "_erase_selected"); + tool_erase->set_disabled(true); + + top_hb->add_child(memnew(VSeparator)); + + auto_triangles = memnew(ToolButton); + top_hb->add_child(auto_triangles); + auto_triangles->connect("pressed", this, "_auto_triangles_toggled"); + auto_triangles->set_toggle_mode(true); + auto_triangles->set_tooltip(TTR("Generate blend triangles automatically (instead of manually)")); + + top_hb->add_child(memnew(VSeparator)); + + snap = memnew(ToolButton); + snap->set_toggle_mode(true); + top_hb->add_child(snap); + //snap->set_text(TTR("Snap")); + snap->set_pressed(true); + snap->connect("pressed", this, "_snap_toggled"); + + snap_x = memnew(SpinBox); + top_hb->add_child(snap_x); + snap_x->set_prefix("x:"); + snap_x->set_min(0.01); + snap_x->set_step(0.01); + snap_x->set_max(1000); + + snap_y = memnew(SpinBox); + top_hb->add_child(snap_y); + snap_y->set_prefix("y:"); + snap_y->set_min(0.01); + snap_y->set_step(0.01); + snap_y->set_max(1000); + + edit_hb = memnew(HBoxContainer); + top_hb->add_child(edit_hb); + edit_hb->add_child(memnew(VSeparator)); + edit_hb->add_child(memnew(Label(TTR("Point")))); + edit_x = memnew(SpinBox); + edit_hb->add_child(edit_x); + edit_x->set_min(-1000); + edit_x->set_step(0.01); + edit_x->set_max(1000); + edit_x->connect("value_changed", this, "_edit_point_pos"); + edit_y = memnew(SpinBox); + edit_hb->add_child(edit_y); + edit_y->set_min(-1000); + edit_y->set_step(0.01); + edit_y->set_max(1000); + edit_y->connect("value_changed", this, "_edit_point_pos"); + open_editor = memnew(Button); + edit_hb->add_child(open_editor); + open_editor->set_text(TTR("Open Editor")); + open_editor->connect("pressed", this, "_open_editor", varray(), CONNECT_DEFERRED); + edit_hb->hide(); + open_editor->hide(); + + HBoxContainer *main_hb = memnew(HBoxContainer); + add_child(main_hb); + main_hb->set_v_size_flags(SIZE_EXPAND_FILL); + + GridContainer *main_grid = memnew(GridContainer); + main_grid->set_columns(2); + main_hb->add_child(main_grid); + main_grid->set_h_size_flags(SIZE_EXPAND_FILL); + { + VBoxContainer *left_vbox = memnew(VBoxContainer); + main_grid->add_child(left_vbox); + left_vbox->set_v_size_flags(SIZE_EXPAND_FILL); + max_y_value = memnew(SpinBox); + left_vbox->add_child(max_y_value); + left_vbox->add_spacer(); + label_y = memnew(LineEdit); + left_vbox->add_child(label_y); + label_y->set_expand_to_text_length(true); + left_vbox->add_spacer(); + min_y_value = memnew(SpinBox); + left_vbox->add_child(min_y_value); + + max_y_value->set_max(10000); + max_y_value->set_min(0.01); + max_y_value->set_step(0.01); + + min_y_value->set_min(-10000); + min_y_value->set_max(0); + min_y_value->set_step(0.01); + } + + panel = memnew(PanelContainer); + panel->set_clip_contents(true); + main_grid->add_child(panel); + panel->set_h_size_flags(SIZE_EXPAND_FILL); + + blend_space_draw = memnew(Control); + blend_space_draw->connect("gui_input", this, "_blend_space_gui_input"); + blend_space_draw->connect("draw", this, "_blend_space_draw"); + blend_space_draw->set_focus_mode(FOCUS_ALL); + + panel->add_child(blend_space_draw); + main_grid->add_child(memnew(Control)); //empty bottom left + + { + HBoxContainer *bottom_vbox = memnew(HBoxContainer); + main_grid->add_child(bottom_vbox); + bottom_vbox->set_h_size_flags(SIZE_EXPAND_FILL); + min_x_value = memnew(SpinBox); + bottom_vbox->add_child(min_x_value); + bottom_vbox->add_spacer(); + label_x = memnew(LineEdit); + bottom_vbox->add_child(label_x); + label_x->set_expand_to_text_length(true); + bottom_vbox->add_spacer(); + max_x_value = memnew(SpinBox); + bottom_vbox->add_child(max_x_value); + + max_x_value->set_max(10000); + max_x_value->set_min(0.01); + max_x_value->set_step(0.01); + + min_x_value->set_min(-10000); + min_x_value->set_max(0); + min_x_value->set_step(0.01); + } + + snap_x->connect("value_changed", this, "_config_changed"); + snap_y->connect("value_changed", this, "_config_changed"); + max_x_value->connect("value_changed", this, "_config_changed"); + min_x_value->connect("value_changed", this, "_config_changed"); + max_y_value->connect("value_changed", this, "_config_changed"); + min_y_value->connect("value_changed", this, "_config_changed"); + label_x->connect("text_changed", this, "_labels_changed"); + label_y->connect("text_changed", this, "_labels_changed"); + + error_panel = memnew(PanelContainer); + add_child(error_panel); + error_label = memnew(Label); + error_panel->add_child(error_label); + error_label->set_text("eh"); + + undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + set_custom_minimum_size(Size2(0, 300 * EDSCALE)); + + menu = memnew(PopupMenu); + add_child(menu); + menu->connect("index_pressed", this, "_add_menu_type"); + + animations_menu = memnew(PopupMenu); + menu->add_child(animations_menu); + animations_menu->set_name("animations"); + animations_menu->connect("index_pressed", this, "_add_animation_type"); + + selected_point = -1; + selected_triangle = -1; + + dragging_selected = false; + dragging_selected_attempt = false; +} + +void AnimationNodeBlendSpace2DEditorPlugin::edit(Object *p_object) { + + anim_tree_editor->edit(Object::cast_to<AnimationNodeBlendSpace2D>(p_object)); +} + +bool AnimationNodeBlendSpace2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("AnimationNodeBlendSpace2D"); +} + +void AnimationNodeBlendSpace2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + //editor->hide_animation_player_editors(); + //editor->animation_panel_make_visible(true); + button->show(); + editor->make_bottom_panel_item_visible(anim_tree_editor); + anim_tree_editor->set_process(true); + } else { + + if (anim_tree_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + button->hide(); + anim_tree_editor->set_process(false); + } +} + +AnimationNodeBlendSpace2DEditorPlugin::AnimationNodeBlendSpace2DEditorPlugin(EditorNode *p_node) { + + editor = p_node; + anim_tree_editor = memnew(AnimationNodeBlendSpace2DEditor); + anim_tree_editor->set_custom_minimum_size(Size2(0, 300)); + + button = editor->add_bottom_panel_item(TTR("BlendSpace2D"), anim_tree_editor); + button->hide(); +} + +AnimationNodeBlendSpace2DEditorPlugin::~AnimationNodeBlendSpace2DEditorPlugin() { +} diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h new file mode 100644 index 0000000000..a0e497804e --- /dev/null +++ b/editor/plugins/animation_blend_space_2d_editor.h @@ -0,0 +1,130 @@ +#ifndef ANIMATION_BLEND_SPACE_2D_EDITOR_H +#define ANIMATION_BLEND_SPACE_2D_EDITOR_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "editor/property_editor.h" +#include "scene/animation/animation_blend_space_2d.h" +#include "scene/gui/button.h" +#include "scene/gui/graph_edit.h" +#include "scene/gui/popup.h" +#include "scene/gui/tree.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class AnimationNodeBlendSpace2DEditor : public VBoxContainer { + + GDCLASS(AnimationNodeBlendSpace2DEditor, VBoxContainer); + + Ref<AnimationNodeBlendSpace2D> blend_space; + + HBoxContainer *goto_parent_hb; + ToolButton *goto_parent; + + PanelContainer *panel; + ToolButton *tool_blend; + ToolButton *tool_select; + ToolButton *tool_create; + ToolButton *tool_triangle; + VSeparator *tool_erase_sep; + ToolButton *tool_erase; + ToolButton *snap; + SpinBox *snap_x; + SpinBox *snap_y; + + ToolButton *auto_triangles; + + LineEdit *label_x; + LineEdit *label_y; + SpinBox *max_x_value; + SpinBox *min_x_value; + SpinBox *max_y_value; + SpinBox *min_y_value; + + HBoxContainer *edit_hb; + SpinBox *edit_x; + SpinBox *edit_y; + Button *open_editor; + + int selected_point; + int selected_triangle; + + Control *blend_space_draw; + + PanelContainer *error_panel; + Label *error_label; + + bool updating; + + UndoRedo *undo_redo; + + static AnimationNodeBlendSpace2DEditor *singleton; + + void _blend_space_gui_input(const Ref<InputEvent> &p_event); + void _blend_space_draw(); + + void _update_space(); + + void _config_changed(double); + void _labels_changed(String); + void _snap_toggled(); + + PopupMenu *menu; + PopupMenu *animations_menu; + Vector<String> animations_to_add; + Vector2 add_point_pos; + Vector<Vector2> points; + + bool dragging_selected_attempt; + bool dragging_selected; + Vector2 drag_from; + Vector2 drag_ofs; + + Vector<int> making_triangle; + + void _add_menu_type(int p_index); + void _add_animation_type(int p_index); + + void _tool_switch(int p_tool); + void _update_edited_point_pos(); + void _update_tool_erase(); + void _erase_selected(); + void _edit_point_pos(double); + void _open_editor(); + + void _goto_parent(); + + void _removed_from_graph(); + + void _auto_triangles_toggled(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static AnimationNodeBlendSpace2DEditor *get_singleton() { return singleton; } + void edit(AnimationNodeBlendSpace2D *p_blend_space); + AnimationNodeBlendSpace2DEditor(); +}; + +class AnimationNodeBlendSpace2DEditorPlugin : public EditorPlugin { + + GDCLASS(AnimationNodeBlendSpace2DEditorPlugin, EditorPlugin); + + AnimationNodeBlendSpace2DEditor *anim_tree_editor; + EditorNode *editor; + Button *button; + +public: + virtual String get_name() const { return "BlendSpace2D"; } + 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); + + AnimationNodeBlendSpace2DEditorPlugin(EditorNode *p_node); + ~AnimationNodeBlendSpace2DEditorPlugin(); +}; +#endif // ANIMATION_BLEND_SPACE_2D_EDITOR_H diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index f466758917..3efb2736b5 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -11,11 +11,21 @@ void AnimationNodeBlendTreeEditor::edit(AnimationNodeBlendTree *p_blend_tree) { - blend_tree = p_blend_tree; + if (blend_tree.is_valid()) { + blend_tree->disconnect("removed_from_graph", this, "_removed_from_graph"); + } - if (!blend_tree) { + if (p_blend_tree) { + blend_tree = Ref<AnimationNodeBlendTree>(p_blend_tree); + } else { + blend_tree.unref(); + } + + if (blend_tree.is_null()) { hide(); } else { + blend_tree->connect("removed_from_graph", this, "_removed_from_graph"); + _update_graph(); } } @@ -66,7 +76,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { graph->set_scroll_ofs(blend_tree->get_graph_offset() * EDSCALE); - if (blend_tree->get_tree().is_valid()) { + if (blend_tree->get_parent().is_valid()) { goto_parent->show(); } else { goto_parent->hide(); @@ -159,7 +169,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() { ProgressBar *pb = memnew(ProgressBar); - AnimationGraphPlayer *player = anim->get_graph_player(); + AnimationTree *player = anim->get_tree(); if (player->has_node(player->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(player->get_node(player->get_animation_player())); if (ap) { @@ -247,8 +257,8 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { } undo_redo->create_action("Add Node to BlendTree"); - undo_redo->add_do_method(blend_tree, "add_node", name, anode); - undo_redo->add_undo_method(blend_tree, "remove_node", name); + undo_redo->add_do_method(blend_tree.ptr(), "add_node", name, anode); + undo_redo->add_undo_method(blend_tree.ptr(), "remove_node", name); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -276,8 +286,8 @@ void AnimationNodeBlendTreeEditor::_connection_request(const String &p_from, int } undo_redo->create_action("Nodes Connected"); - undo_redo->add_do_method(blend_tree, "connect_node", p_to, p_to_index, p_from); - undo_redo->add_undo_method(blend_tree, "disconnect_node", p_to, p_to_index, p_from); + undo_redo->add_do_method(blend_tree.ptr(), "connect_node", p_to, p_to_index, p_from); + undo_redo->add_undo_method(blend_tree.ptr(), "disconnect_node", p_to, p_to_index, p_from); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -289,8 +299,8 @@ void AnimationNodeBlendTreeEditor::_disconnection_request(const String &p_from, updating = true; undo_redo->create_action("Nodes Disconnected"); - undo_redo->add_do_method(blend_tree, "disconnect_node", p_to, p_to_index); - undo_redo->add_undo_method(blend_tree, "connect_node", p_to, p_to_index, p_from); + undo_redo->add_do_method(blend_tree.ptr(), "disconnect_node", p_to, p_to_index); + undo_redo->add_undo_method(blend_tree.ptr(), "connect_node", p_to, p_to_index, p_from); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -315,15 +325,15 @@ void AnimationNodeBlendTreeEditor::_anim_selected(int p_index, Array p_options, void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) { undo_redo->create_action("Delete Node"); - undo_redo->add_do_method(blend_tree, "remove_node", p_which); - undo_redo->add_undo_method(blend_tree, "add_node", p_which, blend_tree->get_node(p_which)); + undo_redo->add_do_method(blend_tree.ptr(), "remove_node", p_which); + undo_redo->add_undo_method(blend_tree.ptr(), "add_node", p_which, blend_tree->get_node(p_which)); List<AnimationNodeBlendTree::NodeConnection> conns; blend_tree->get_node_connections(&conns); for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = conns.front(); E; E = E->next()) { if (E->get().output_node == p_which || E->get().input_node == p_which) { - undo_redo->add_undo_method(blend_tree, "connect_node", E->get().input_node, E->get().input_index, E->get().output_node); + undo_redo->add_undo_method(blend_tree.ptr(), "connect_node", E->get().input_node, E->get().input_index, E->get().output_node); } } @@ -367,8 +377,8 @@ void AnimationNodeBlendTreeEditor::_open_in_editor(const String &p_which) { } void AnimationNodeBlendTreeEditor::_open_parent() { - if (blend_tree->get_tree().is_valid()) { - EditorNode::get_singleton()->edit_item(blend_tree->get_tree().ptr()); + if (blend_tree->get_parent().is_valid()) { + EditorNode::get_singleton()->edit_item(blend_tree->get_parent().ptr()); } } @@ -407,14 +417,14 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano if (updating || _filter_edit != anode) return false; - NodePath player_path = anode->get_graph_player()->get_animation_player(); + NodePath player_path = anode->get_tree()->get_animation_player(); - if (!anode->get_graph_player()->has_node(player_path)) { + if (!anode->get_tree()->has_node(player_path)) { EditorNode::get_singleton()->show_warning(TTR("No animation player set, so unable to retrieve track names.")); return false; } - AnimationPlayer *player = Object::cast_to<AnimationPlayer>(anode->get_graph_player()->get_node(player_path)); + AnimationPlayer *player = Object::cast_to<AnimationPlayer>(anode->get_tree()->get_node(player_path)); if (!player) { EditorNode::get_singleton()->show_warning(TTR("Player path set is invalid, so unable to retrieve track names.")); return false; @@ -573,6 +583,12 @@ void AnimationNodeBlendTreeEditor::_edit_filters(const String &p_which) { filter_dialog->popup_centered_minsize(Size2(500, 500) * EDSCALE); } +void AnimationNodeBlendTreeEditor::_removed_from_graph() { + if (is_visible()) { + EditorNode::get_singleton()->edit_item(NULL); + } +} + void AnimationNodeBlendTreeEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { @@ -587,12 +603,12 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { String error; - if (!blend_tree->get_graph_player()) { - error = TTR("BlendTree does not belong to an AnimationGraphPlayer node."); - } else if (!blend_tree->get_graph_player()->is_active()) { - error = TTR("AnimationGraphPlayer is inactive.\nActivate to enable playback, check node warnings if activation fails."); - } else if (blend_tree->get_graph_player()->is_state_invalid()) { - error = blend_tree->get_graph_player()->get_invalid_state_reason(); + if (!blend_tree->get_tree()) { + error = TTR("BlendTree does not belong to an AnimationTree node."); + } else if (!blend_tree->get_tree()->is_active()) { + error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); + } else if (blend_tree->get_tree()->is_state_invalid()) { + error = blend_tree->get_tree()->get_invalid_state_reason(); } if (error != error_label->get_text()) { @@ -608,13 +624,13 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { blend_tree->get_node_connections(&conns); for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = conns.front(); E; E = E->next()) { float activity = 0; - if (blend_tree->get_graph_player() && !blend_tree->get_graph_player()->is_state_invalid()) { + if (blend_tree->get_tree() && !blend_tree->get_tree()->is_state_invalid()) { activity = blend_tree->get_connection_activity(E->get().input_node, E->get().input_index); } graph->set_connection_activity(E->get().output_node, 0, E->get().input_node, E->get().input_index, activity); } - AnimationGraphPlayer *graph_player = blend_tree->get_graph_player(); + AnimationTree *graph_player = blend_tree->get_tree(); AnimationPlayer *player = NULL; if (graph_player->has_node(graph_player->get_animation_player())) { player = Object::cast_to<AnimationPlayer>(graph_player->get_node(graph_player->get_animation_player())); @@ -648,7 +664,7 @@ void AnimationNodeBlendTreeEditor::_scroll_changed(const Vector2 &p_scroll) { void AnimationNodeBlendTreeEditor::_node_changed(ObjectID p_node) { AnimationNode *an = Object::cast_to<AnimationNode>(ObjectDB::get_instance(p_node)); - if (an && an->get_tree() == blend_tree) { + if (an && an->get_parent() == blend_tree) { _update_graph(); } } @@ -674,6 +690,7 @@ void AnimationNodeBlendTreeEditor::_bind_methods() { ClassDB::bind_method("_oneshot_start", &AnimationNodeBlendTreeEditor::_oneshot_start); ClassDB::bind_method("_oneshot_stop", &AnimationNodeBlendTreeEditor::_oneshot_stop); ClassDB::bind_method("_node_changed", &AnimationNodeBlendTreeEditor::_node_changed); + ClassDB::bind_method("_removed_from_graph", &AnimationNodeBlendTreeEditor::_removed_from_graph); ClassDB::bind_method("_anim_selected", &AnimationNodeBlendTreeEditor::_anim_selected); } @@ -703,8 +720,8 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima updating = true; undo_redo->create_action("Node Renamed"); - undo_redo->add_do_method(blend_tree, "rename_node", prev_name, name); - undo_redo->add_undo_method(blend_tree, "rename_node", name, prev_name); + undo_redo->add_do_method(blend_tree.ptr(), "rename_node", prev_name, name); + undo_redo->add_undo_method(blend_tree.ptr(), "rename_node", name, prev_name); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); @@ -722,7 +739,6 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { singleton = this; updating = false; - blend_tree = NULL; graph = memnew(GraphEdit); add_child(graph); graph->add_valid_right_disconnect_type(0); @@ -737,28 +753,31 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->get_zoom_hbox()->add_child(vs); graph->get_zoom_hbox()->move_child(vs, 0); - goto_parent = memnew(Button); - goto_parent->set_text(TTR("Goto Parent")); - graph->get_zoom_hbox()->add_child(goto_parent); - graph->get_zoom_hbox()->move_child(goto_parent, 0); - goto_parent->hide(); - goto_parent->connect("pressed", this, "_open_parent"); - add_node = memnew(MenuButton); graph->get_zoom_hbox()->add_child(add_node); add_node->set_text(TTR("Add Node..")); graph->get_zoom_hbox()->move_child(add_node, 0); add_node->get_popup()->connect("index_pressed", this, "_add_node"); + goto_parent = memnew(Button); + graph->get_zoom_hbox()->add_child(goto_parent); + graph->get_zoom_hbox()->move_child(goto_parent, 0); + goto_parent->hide(); + goto_parent->connect("pressed", this, "_open_parent"); + add_options.push_back(AddOption("Animation", "AnimationNodeAnimation")); add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot")); - add_options.push_back(AddOption("Add", "AnimationNodeAdd")); + add_options.push_back(AddOption("Add2", "AnimationNodeAdd2")); + add_options.push_back(AddOption("Add3", "AnimationNodeAdd3")); add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2")); add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3")); add_options.push_back(AddOption("Seek", "AnimationNodeTimeSeek")); add_options.push_back(AddOption("TimeScale", "AnimationNodeTimeScale")); add_options.push_back(AddOption("Transition", "AnimationNodeTransition")); add_options.push_back(AddOption("BlendTree", "AnimationNodeBlendTree")); + add_options.push_back(AddOption("BlendSpace1D", "AnimationNodeBlendSpace1D")); + add_options.push_back(AddOption("BlendSpace2D", "AnimationNodeBlendSpace2D")); + add_options.push_back(AddOption("StateMachine", "AnimationNodeStateMachine")); _update_options_menu(); error_panel = memnew(PanelContainer); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index 71efed6da6..deba3b2b0e 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -17,7 +17,7 @@ class AnimationNodeBlendTreeEditor : public VBoxContainer { GDCLASS(AnimationNodeBlendTreeEditor, VBoxContainer); - AnimationNodeBlendTree *blend_tree; + Ref<AnimationNodeBlendTree> blend_tree; GraphEdit *graph; MenuButton *add_node; Button *goto_parent; @@ -78,6 +78,8 @@ class AnimationNodeBlendTreeEditor : public VBoxContainer { void _node_changed(ObjectID p_node); + void _removed_from_graph(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp new file mode 100644 index 0000000000..04bd5f0cec --- /dev/null +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -0,0 +1,1313 @@ +#include "animation_state_machine_editor.h" + +#include "core/io/resource_loader.h" +#include "core/project_settings.h" +#include "math/delaunay.h" +#include "os/input.h" +#include "os/keyboard.h" +#include "scene/animation/animation_blend_tree.h" +#include "scene/animation/animation_player.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/panel.h" +#include "scene/main/viewport.h" + +void AnimationNodeStateMachineEditor::edit(AnimationNodeStateMachine *p_state_machine) { + + if (state_machine.is_valid()) { + state_machine->disconnect("removed_from_graph", this, "_removed_from_graph"); + } + + if (p_state_machine) { + state_machine = Ref<AnimationNodeStateMachine>(p_state_machine); + } else { + state_machine.unref(); + } + + if (state_machine.is_null()) { + hide(); + } else { + state_machine->connect("removed_from_graph", this, "_removed_from_graph"); + + selected_transition_from = StringName(); + selected_transition_to = StringName(); + selected_node = StringName(); + _update_mode(); + _update_graph(); + } +} + +void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEvent> &p_event) { + + Ref<InputEventKey> k = p_event; + if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && !k->is_echo()) { + if (selected_node != StringName() || selected_transition_to != StringName() || selected_transition_from != StringName()) { + _erase_selected(); + accept_event(); + } + } + + Ref<InputEventMouseButton> mb = p_event; + + //Add new node + if (mb.is_valid() && mb->is_pressed() && ((tool_select->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) || (tool_create->is_pressed() && mb->get_button_index() == BUTTON_LEFT))) { + menu->clear(); + animations_menu->clear(); + animations_to_add.clear(); + List<StringName> classes; + classes.sort_custom<StringName::AlphCompare>(); + + ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); + menu->add_submenu_item(TTR("Add Animation"), "animations"); + + AnimationTree *gp = state_machine->get_tree(); + ERR_FAIL_COND(!gp); + if (gp && gp->has_node(gp->get_animation_player())) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); + if (ap) { + List<StringName> names; + ap->get_animation_list(&names); + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + animations_menu->add_icon_item(get_icon("Animation", "EditorIcons"), E->get()); + animations_to_add.push_back(E->get()); + } + } + } + + for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { + + String name = String(E->get()).replace_first("AnimationNode", ""); + if (name == "Animation") + continue; // nope + int idx = menu->get_item_count(); + menu->add_item(vformat("Add %s", name)); + menu->set_item_metadata(idx, E->get()); + } + + menu->set_global_position(state_machine_draw->get_global_transform().xform(mb->get_position())); + menu->popup(); + add_node_pos = mb->get_position() / EDSCALE + state_machine->get_graph_offset(); + } + + // select node or push a field inside + if (mb.is_valid() && !mb->get_shift() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + + selected_transition_from = StringName(); + selected_transition_to = StringName(); + selected_node = StringName(); + + for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order + + if (node_rects[i].play.has_point(mb->get_position())) { //edit name + if (play_mode->get_selected() == 1 || !state_machine->is_playing()) { + //start + state_machine->start(node_rects[i].node_name); + } else { + //travel + if (!state_machine->travel(node_rects[i].node_name)) { + + state_machine->start(node_rects[i].node_name); + //removing this due to usability.. + //error_time = 5; + //error_text = vformat(TTR("No path found from '%s' to '%s'."), state_machine->get_current_node(), node_rects[i].node_name); + } + } + state_machine_draw->update(); + return; + } + + if (node_rects[i].name.has_point(mb->get_position())) { //edit name + + Ref<StyleBox> line_sb = get_stylebox("normal", "LineEdit"); + + Rect2 edit_rect = node_rects[i].name; + edit_rect.position -= line_sb->get_offset(); + edit_rect.size += line_sb->get_minimum_size(); + + name_edit->set_global_position(state_machine_draw->get_global_transform().xform(edit_rect.position)); + name_edit->set_size(edit_rect.size); + name_edit->set_text(node_rects[i].node_name); + name_edit->show_modal(); + name_edit->grab_focus(); + name_edit->select_all(); + + prev_name = node_rects[i].node_name; + return; + } + + if (node_rects[i].edit.has_point(mb->get_position())) { //edit name + call_deferred("_open_editor", node_rects[i].node_name); + return; + } + + if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected + selected_node = node_rects[i].node_name; + + Ref<AnimationNode> anode = state_machine->get_node(selected_node); + EditorNode::get_singleton()->push_item(anode.ptr(), "", true); + state_machine_draw->update(); + dragging_selected_attempt = true; + dragging_selected = false; + drag_from = mb->get_position(); + snap_x = StringName(); + snap_y = StringName(); + _update_mode(); + return; + } + } + + //test the lines now + int closest = -1; + float closest_d = 1e20; + for (int i = 0; i < transition_lines.size(); i++) { + + Vector2 s[2] = { + transition_lines[i].from, + transition_lines[i].to + }; + Vector2 cpoint = Geometry::get_closest_point_to_segment_2d(mb->get_position(), s); + float d = cpoint.distance_to(mb->get_position()); + if (d > transition_lines[i].width) { + continue; + } + + if (d < closest_d) { + closest = i; + closest_d = d; + } + } + + if (closest >= 0) { + selected_transition_from = transition_lines[closest].from_node; + selected_transition_to = transition_lines[closest].to_node; + + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(closest); + EditorNode::get_singleton()->push_item(tr.ptr(), "", true); + } + + state_machine_draw->update(); + _update_mode(); + } + + //end moving node + if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { + + if (dragging_selected) { + + Ref<AnimationNode> an = state_machine->get_node(selected_node); + updating = true; + undo_redo->create_action("Move Node"); + undo_redo->add_do_method(an.ptr(), "set_position", an->get_position() + drag_ofs / EDSCALE); + undo_redo->add_undo_method(an.ptr(), "set_position", an->get_position()); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + } + snap_x = StringName(); + snap_y = StringName(); + + dragging_selected_attempt = false; + dragging_selected = false; + state_machine_draw->update(); + } + + //connect nodes + if (mb.is_valid() && ((tool_select->is_pressed() && mb->get_shift()) || tool_connect->is_pressed()) && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { + + for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order + if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected + connecting = true; + connecting_from = node_rects[i].node_name; + connecting_to = mb->get_position(); + connecting_to_node = StringName(); + return; + } + } + } + + //end connecting nodes + if (mb.is_valid() && connecting && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) { + + if (connecting_to_node != StringName()) { + + if (state_machine->has_transition(connecting_from, connecting_to_node)) { + EditorNode::get_singleton()->show_warning("Transition exists!"); + + } else { + + Ref<AnimationNodeStateMachineTransition> tr; + tr.instance(); + tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); + + updating = true; + undo_redo->create_action("Add Transition"); + undo_redo->add_do_method(state_machine.ptr(), "add_transition", connecting_from, connecting_to_node, tr); + undo_redo->add_undo_method(state_machine.ptr(), "remove_transition", connecting_from, connecting_to_node); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + + selected_transition_from = connecting_from; + selected_transition_to = connecting_to_node; + + EditorNode::get_singleton()->push_item(tr.ptr(), "", true); + _update_mode(); + } + } + connecting_to_node = StringName(); + connecting = false; + state_machine_draw->update(); + } + + Ref<InputEventMouseMotion> mm = p_event; + + //pan window + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_MIDDLE) { + + h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); + v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); + } + + //move mouse while connecting + if (mm.is_valid() && connecting) { + + connecting_to = mm->get_position(); + connecting_to_node = StringName(); + state_machine_draw->update(); + + for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order + if (node_rects[i].node_name != connecting_from && node_rects[i].node.has_point(connecting_to)) { //select node since nothing else was selected + connecting_to_node = node_rects[i].node_name; + return; + } + } + } + + //move mouse while moving a node + if (mm.is_valid() && dragging_selected_attempt) { + + dragging_selected = true; + drag_ofs = mm->get_position() - drag_from; + snap_x = StringName(); + snap_y = StringName(); + { + //snap + Vector2 cpos = state_machine->get_node(selected_node)->get_position() + drag_ofs / EDSCALE; + List<StringName> nodes; + state_machine->get_node_list(&nodes); + + float best_d_x = 1e20; + float best_d_y = 1e20; + + for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { + if (E->get() == selected_node) + continue; + Vector2 npos = state_machine->get_node(E->get())->get_position(); + + float d_x = ABS(npos.x - cpos.x); + if (d_x < MIN(5, best_d_x)) { + drag_ofs.x -= cpos.x - npos.x; + best_d_x = d_x; + snap_x = E->get(); + } + + float d_y = ABS(npos.y - cpos.y); + if (d_y < MIN(5, best_d_y)) { + drag_ofs.y -= cpos.y - npos.y; + best_d_y = d_y; + snap_y = E->get(); + } + } + } + + state_machine_draw->update(); + } + + //put ibeam (text cursor) over names to make it clearer that they are editable + if (mm.is_valid()) { + + state_machine_draw->grab_focus(); + + bool over_text_now = false; + String new_over_node = StringName(); + int new_over_node_what = -1; + if (tool_select->is_pressed()) { + + for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order + + if (node_rects[i].name.has_point(mm->get_position())) { + over_text_now = true; + break; + } + + if (node_rects[i].node.has_point(mm->get_position())) { + new_over_node = node_rects[i].node_name; + if (node_rects[i].play.has_point(mm->get_position())) { + new_over_node_what = 0; + } + if (node_rects[i].edit.has_point(mm->get_position())) { + new_over_node_what = 1; + } + } + } + } + + if (new_over_node != over_node || new_over_node_what != over_node_what) { + over_node = new_over_node; + over_node_what = new_over_node_what; + state_machine_draw->update(); + } + + if (over_text != over_text_now) { + + if (over_text_now) { + state_machine_draw->set_default_cursor_shape(CURSOR_IBEAM); + } else { + state_machine_draw->set_default_cursor_shape(CURSOR_ARROW); + } + + over_text = over_text_now; + } + } +} + +void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) { + + String type = menu->get_item_metadata(p_index); + + Object *obj = ClassDB::instance(type); + ERR_FAIL_COND(!obj); + AnimationNode *an = Object::cast_to<AnimationNode>(obj); + ERR_FAIL_COND(!an); + + Ref<AnimationNode> node(an); + node->set_position(add_node_pos); + + String base_name = type.replace_first("AnimationNode", ""); + int base = 1; + String name = base_name; + while (state_machine->has_node(name)) { + base++; + name = base_name + " " + itos(base); + } + + updating = true; + undo_redo->create_action("Add Node"); + undo_redo->add_do_method(state_machine.ptr(), "add_node", name, node); + undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + + state_machine_draw->update(); +} + +void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { + + Ref<AnimationNodeAnimation> anim; + anim.instance(); + + anim->set_animation(animations_to_add[p_index]); + + String base_name = animations_to_add[p_index]; + int base = 1; + String name = base_name; + while (state_machine->has_node(name)) { + base++; + name = base_name + " " + itos(base); + } + + anim->set_position(add_node_pos); + + updating = true; + undo_redo->create_action("Add Node"); + undo_redo->add_do_method(state_machine.ptr(), "add_node", name, anim); + undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + + state_machine_draw->update(); +} + +void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance) { + + Color linecolor = get_color("font_color", "Label"); + Color icon_color(1, 1, 1); + Color accent = get_color("accent_color", "Editor"); + + if (!p_enabled) { + linecolor.a *= 0.2; + icon_color.a *= 0.2; + accent.a *= 0.6; + } + + Ref<Texture> icons[6] = { + get_icon("TransitionImmediateBig", "EditorIcons"), + get_icon("TransitionSyncBig", "EditorIcons"), + get_icon("TransitionEndBig", "EditorIcons"), + get_icon("TransitionImmediateAutoBig", "EditorIcons"), + get_icon("TransitionSyncAutoBig", "EditorIcons"), + get_icon("TransitionEndAutoBig", "EditorIcons") + }; + + if (p_selected) { + state_machine_draw->draw_line(p_from, p_to, accent, 6, true); + } + + if (p_travel) { + linecolor = accent; + linecolor.set_hsv(1.0, linecolor.get_s(), linecolor.get_v()); + } + state_machine_draw->draw_line(p_from, p_to, linecolor, 2, true); + + Ref<Texture> icon = icons[p_mode + (p_auto_advance ? 3 : 0)]; + + Transform2D xf; + xf.elements[0] = (p_to - p_from).normalized(); + xf.elements[1] = xf.elements[0].tangent(); + xf.elements[2] = (p_from + p_to) * 0.5 - xf.elements[1] * icon->get_height() * 0.5 - xf.elements[0] * icon->get_height() * 0.5; + + state_machine_draw->draw_set_transform_matrix(xf); + state_machine_draw->draw_texture(icon, Vector2(), icon_color); + state_machine_draw->draw_set_transform_matrix(Transform2D()); +} + +void AnimationNodeStateMachineEditor::_clip_src_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect) { + + if (r_to == r_from) + return; + + //this could be optimized... + Vector2 n = (r_to - r_from).normalized(); + while (p_rect.has_point(r_from)) { + r_from += n; + } +} + +void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect) { + + if (r_to == r_from) + return; + + //this could be optimized... + Vector2 n = (r_to - r_from).normalized(); + while (p_rect.has_point(r_to)) { + r_to -= n; + } +} + +void AnimationNodeStateMachineEditor::_state_machine_draw() { + + Ref<StyleBox> style = get_stylebox("frame", "GraphNode"); + Ref<StyleBox> style_selected = get_stylebox("selectedframe", "GraphNode"); + + Ref<Font> font = get_font("title_font", "GraphNode"); + Color font_color = get_color("title_color", "GraphNode"); + Ref<Texture> play = get_icon("Play", "EditorIcons"); + Ref<Texture> auto_play = get_icon("AutoPlay", "EditorIcons"); + Ref<Texture> edit = get_icon("Edit", "EditorIcons"); + Color accent = get_color("accent_color", "Editor"); + Color linecolor = get_color("font_color", "Label"); + linecolor.a *= 0.3; + Ref<StyleBox> playing_overlay = get_stylebox("position", "GraphNode"); + + bool playing = state_machine->is_playing(); + StringName current = state_machine->get_current_node(); + StringName blend_from = state_machine->get_blend_from_node(); + Vector<StringName> travel_path = state_machine->get_travel_path(); + + if (state_machine_draw->has_focus()) { + state_machine_draw->draw_rect(Rect2(Point2(), state_machine_draw->get_size()), accent, false); + } + int sep = 3 * EDSCALE; + + List<StringName> nodes; + state_machine->get_node_list(&nodes); + + node_rects.clear(); + Rect2 scroll_range(Point2(), state_machine_draw->get_size()); + + //snap lines + if (dragging_selected) { + + Vector2 from = (state_machine->get_node(selected_node)->get_position() * EDSCALE) + drag_ofs - state_machine->get_graph_offset() * EDSCALE; + if (snap_x != StringName()) { + Vector2 to = (state_machine->get_node(snap_x)->get_position() * EDSCALE) - state_machine->get_graph_offset() * EDSCALE; + state_machine_draw->draw_line(from, to, linecolor, 2); + } + if (snap_y != StringName()) { + Vector2 to = (state_machine->get_node(snap_y)->get_position() * EDSCALE) - state_machine->get_graph_offset() * EDSCALE; + state_machine_draw->draw_line(from, to, linecolor, 2); + } + } + + //pre pass nodes so we know the rectangles + for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { + + Ref<AnimationNode> anode = state_machine->get_node(E->get()); + String name = E->get(); + bool needs_editor = EditorNode::get_singleton()->item_has_editor(anode.ptr()); + Ref<StyleBox> sb = E->get() == selected_node ? style_selected : style; + + Size2 s = sb->get_minimum_size(); + int strsize = font->get_string_size(name).width; + s.width += strsize; + s.height += MAX(font->get_height(), play->get_height()); + s.width += sep + play->get_width(); + if (needs_editor) { + s.width += sep + edit->get_width(); + } + + Vector2 offset; + offset += anode->get_position() * EDSCALE; + if (selected_node == E->get() && dragging_selected) { + offset += drag_ofs; + } + offset -= s / 2; + offset = offset.floor(); + + //prepre rect + + NodeRect nr; + nr.node = Rect2(offset, s); + nr.node_name = E->get(); + + scroll_range = scroll_range.merge(nr.node); //merge with range + + //now scroll it to draw + nr.node.position -= state_machine->get_graph_offset() * EDSCALE; + + node_rects.push_back(nr); + } + + transition_lines.clear(); + + //draw conecting line for potential new transition + if (connecting) { + Vector2 from = (state_machine->get_node(connecting_from)->get_position() * EDSCALE) - state_machine->get_graph_offset() * EDSCALE; + Vector2 to; + if (connecting_to_node != StringName()) { + to = (state_machine->get_node(connecting_to_node)->get_position() * EDSCALE) - state_machine->get_graph_offset() * EDSCALE; + } else { + to = connecting_to; + } + + for (int i = 0; i < node_rects.size(); i++) { + if (node_rects[i].node_name == connecting_from) { + _clip_src_line_to_rect(from, to, node_rects[i].node); + } + if (node_rects[i].node_name == connecting_to_node) { + _clip_dst_line_to_rect(from, to, node_rects[i].node); + } + } + + _connection_draw(from, to, AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()), true, false, false, false); + } + + Ref<Texture> tr_reference_icon = get_icon("TransitionImmediateBig", "EditorIcons"); + float tr_bidi_offset = int(tr_reference_icon->get_height() * 0.8); + + //draw transition lines + for (int i = 0; i < state_machine->get_transition_count(); i++) { + + TransitionLine tl; + tl.from_node = state_machine->get_transition_from(i); + Vector2 ofs_from = (dragging_selected && tl.from_node == selected_node) ? drag_ofs : Vector2(); + tl.from = (state_machine->get_node(tl.from_node)->get_position() * EDSCALE) + ofs_from - state_machine->get_graph_offset() * EDSCALE; + + tl.to_node = state_machine->get_transition_to(i); + Vector2 ofs_to = (dragging_selected && tl.to_node == selected_node) ? drag_ofs : Vector2(); + tl.to = (state_machine->get_node(tl.to_node)->get_position() * EDSCALE) + ofs_to - state_machine->get_graph_offset() * EDSCALE; + + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(i); + tl.disabled = tr->is_disabled(); + tl.auto_advance = tr->has_auto_advance(); + tl.mode = tr->get_switch_mode(); + tl.width = tr_bidi_offset; + + if (state_machine->has_transition(tl.to_node, tl.from_node)) { //offset if same exists + Vector2 offset = -(tl.from - tl.to).normalized().tangent() * tr_bidi_offset; + tl.from += offset; + tl.to += offset; + } + + for (int i = 0; i < node_rects.size(); i++) { + if (node_rects[i].node_name == tl.from_node) { + _clip_src_line_to_rect(tl.from, tl.to, node_rects[i].node); + } + if (node_rects[i].node_name == tl.to_node) { + _clip_dst_line_to_rect(tl.from, tl.to, node_rects[i].node); + } + } + + bool selected = selected_transition_from == tl.from_node && selected_transition_to == tl.to_node; + + bool travel = false; + + if (blend_from == tl.from_node && current == tl.to_node) { + travel = true; + } + + if (travel_path.size()) { + + if (current == tl.from_node && travel_path[0] == tl.to_node) { + travel = true; + } else { + for (int j = 0; j < travel_path.size() - 1; j++) { + if (travel_path[j] == tl.from_node && travel_path[j + 1] == tl.to_node) { + travel = true; + break; + } + } + } + } + _connection_draw(tl.from, tl.to, tl.mode, !tl.disabled, selected, travel, tl.auto_advance); + + transition_lines.push_back(tl); + } + + //draw actual nodes + for (int i = 0; i < node_rects.size(); i++) { + + String name = node_rects[i].node_name; + Ref<AnimationNode> anode = state_machine->get_node(name); + bool needs_editor = EditorNode::get_singleton()->item_has_editor(anode.ptr()); + Ref<StyleBox> sb = name == selected_node ? style_selected : style; + int strsize = font->get_string_size(name).width; + + NodeRect &nr = node_rects[i]; + + Vector2 offset = nr.node.position; + int h = nr.node.size.height; + + //prepre rect + + //now scroll it to draw + state_machine_draw->draw_style_box(sb, nr.node); + + if (playing && (blend_from == name || current == name || travel_path.find(name) != -1)) { + state_machine_draw->draw_style_box(playing_overlay, nr.node); + } + + bool onstart = state_machine->get_start_node() == name; + if (onstart) { + state_machine_draw->draw_string(font, offset + Vector2(0, -font->get_height() - 3 * EDSCALE + font->get_ascent()), TTR("Start"), font_color); + } + + if (state_machine->get_end_node() == name) { + + int endofs = nr.node.size.x - font->get_string_size(TTR("End")).x; + state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height() - 3 * EDSCALE + font->get_ascent()), TTR("End"), font_color); + } + + offset.x += sb->get_offset().x; + + nr.play.position = offset + Vector2(0, (h - play->get_height()) / 2).floor(); + nr.play.size = play->get_size(); + + Ref<Texture> play_tex = onstart ? auto_play : play; + + if (over_node == name && over_node_what == 0) { + state_machine_draw->draw_texture(play_tex, nr.play.position, accent); + } else { + state_machine_draw->draw_texture(play_tex, nr.play.position); + } + offset.x += sep + play->get_width(); + + nr.name.position = offset + Vector2(0, (h - font->get_height()) / 2).floor(); + nr.name.size = Vector2(strsize, font->get_height()); + + state_machine_draw->draw_string(font, nr.name.position + Vector2(0, font->get_ascent()), name, font_color); + offset.x += strsize + sep; + + if (needs_editor) { + nr.edit.position = offset + Vector2(0, (h - edit->get_height()) / 2).floor(); + nr.edit.size = edit->get_size(); + + if (over_node == name && over_node_what == 1) { + state_machine_draw->draw_texture(edit, nr.edit.position, accent); + } else { + state_machine_draw->draw_texture(edit, nr.edit.position); + } + offset.x += sep + edit->get_width(); + } + } + + scroll_range = scroll_range.grow(200 * EDSCALE); + + //adjust scrollbars + updating = true; + h_scroll->set_min(scroll_range.position.x); + h_scroll->set_max(scroll_range.position.x + scroll_range.size.x); + h_scroll->set_page(state_machine_draw->get_size().x); + h_scroll->set_value(state_machine->get_graph_offset().x); + + v_scroll->set_min(scroll_range.position.y); + v_scroll->set_max(scroll_range.position.y + scroll_range.size.y); + v_scroll->set_page(state_machine_draw->get_size().y); + v_scroll->set_value(state_machine->get_graph_offset().y); + updating = false; + + state_machine_play_pos->update(); +} + +void AnimationNodeStateMachineEditor::_state_machine_pos_draw() { + + if (!state_machine->is_playing()) + return; + + int idx = -1; + for (int i = 0; node_rects.size(); i++) { + if (node_rects[i].node_name == state_machine->get_current_node()) { + idx = i; + break; + } + } + + if (idx == -1) + return; + + NodeRect &nr = node_rects[idx]; + + Vector2 from; + from.x = nr.play.position.x; + from.y = (nr.play.position.y + nr.play.size.y + nr.node.position.y + nr.node.size.y) * 0.5; + + Vector2 to; + if (nr.edit.size.x) { + to.x = nr.edit.position.x + nr.edit.size.x; + } else { + to.x = nr.name.position.x + nr.name.size.x; + } + to.y = from.y; + + float len = MAX(0.0001, state_machine->get_current_length()); + + float pos = CLAMP(state_machine->get_current_play_pos(), 0, len); + float c = pos / len; + Color fg = get_color("font_color", "Label"); + Color bg = fg; + bg.a *= 0.3; + + state_machine_play_pos->draw_line(from, to, bg, 2); + + to = from.linear_interpolate(to, c); + + state_machine_play_pos->draw_line(from, to, fg, 2); +} + +void AnimationNodeStateMachineEditor::_update_graph() { + + if (updating) + return; + + updating = true; + + if (state_machine->get_parent().is_valid()) { + goto_parent_hbox->show(); + } else { + goto_parent_hbox->hide(); + } + + state_machine_draw->update(); + + updating = false; +} + +void AnimationNodeStateMachineEditor::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + error_panel->add_style_override("panel", get_stylebox("bg", "Tree")); + error_label->add_color_override("font_color", get_color("error_color", "Editor")); + panel->add_style_override("panel", get_stylebox("bg", "Tree")); + goto_parent->set_icon(get_icon("MoveUp", "EditorIcons")); + + tool_select->set_icon(get_icon("ToolSelect", "EditorIcons")); + tool_create->set_icon(get_icon("ToolAddNode", "EditorIcons")); + tool_connect->set_icon(get_icon("ToolConnect", "EditorIcons")); + + transition_mode->clear(); + transition_mode->add_icon_item(get_icon("TransitionImmediate", "EditorIcons"), TTR("Immediate")); + transition_mode->add_icon_item(get_icon("TransitionSync", "EditorIcons"), TTR("Sync")); + transition_mode->add_icon_item(get_icon("TransitionEnd", "EditorIcons"), TTR("At End")); + + //force filter on those, so they deform better + get_icon("TransitionImmediateBig", "EditorIcons")->set_flags(Texture::FLAG_FILTER); + get_icon("TransitionEndBig", "EditorIcons")->set_flags(Texture::FLAG_FILTER); + get_icon("TransitionSyncBig", "EditorIcons")->set_flags(Texture::FLAG_FILTER); + get_icon("TransitionImmediateAutoBig", "EditorIcons")->set_flags(Texture::FLAG_FILTER); + get_icon("TransitionEndAutoBig", "EditorIcons")->set_flags(Texture::FLAG_FILTER); + get_icon("TransitionSyncAutoBig", "EditorIcons")->set_flags(Texture::FLAG_FILTER); + + tool_erase->set_icon(get_icon("Remove", "EditorIcons")); + tool_autoplay->set_icon(get_icon("AutoPlay", "EditorIcons")); + tool_end->set_icon(get_icon("AutoEnd", "EditorIcons")); + + play_mode->clear(); + play_mode->add_icon_item(get_icon("PlayTravel", "EditorIcons"), TTR("Travel")); + play_mode->add_icon_item(get_icon("Play", "EditorIcons"), TTR("Immediate")); + } + + if (p_what == NOTIFICATION_PROCESS) { + + String error; + + if (error_time > 0) { + error = error_text; + error_time -= get_process_delta_time(); + } else if (!state_machine->get_tree()) { + error = TTR("StateMachine does not belong to an AnimationTree node."); + } else if (!state_machine->get_tree()->is_active()) { + error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); + } else if (state_machine->get_tree()->is_state_invalid()) { + error = state_machine->get_tree()->get_invalid_state_reason(); + } else if (state_machine->get_parent().is_valid() && state_machine->get_parent()->is_class("AnimationNodeStateMachine")) { + if (state_machine->get_start_node() == StringName() || state_machine->get_end_node() == StringName()) { + error = TTR("Start and end nodes are needed for a sub-transition."); + } + } + + if (error != error_label->get_text()) { + error_label->set_text(error); + if (error != String()) { + error_panel->show(); + } else { + error_panel->hide(); + } + } + + for (int i = 0; i < transition_lines.size(); i++) { + int tidx = -1; + for (int j = 0; j < state_machine->get_transition_count(); j++) { + if (transition_lines[i].from_node == state_machine->get_transition_from(j) && transition_lines[i].to_node == state_machine->get_transition_to(j)) { + tidx = j; + break; + } + } + + if (tidx == -1) { //missing transition, should redraw + state_machine_draw->update(); + break; + } + + if (transition_lines[i].disabled != state_machine->get_transition(tidx)->is_disabled()) { + state_machine_draw->update(); + break; + } + + if (transition_lines[i].auto_advance != state_machine->get_transition(tidx)->has_auto_advance()) { + state_machine_draw->update(); + break; + } + + if (transition_lines[i].mode != state_machine->get_transition(tidx)->get_switch_mode()) { + state_machine_draw->update(); + break; + } + } + + bool same_travel_path = true; + Vector<StringName> tp = state_machine->get_travel_path(); + + { + + if (last_travel_path.size() != tp.size()) { + same_travel_path = false; + } else { + for (int i = 0; i < last_travel_path.size(); i++) { + if (last_travel_path[i] != tp[i]) { + same_travel_path = false; + break; + } + } + } + } + + //update if travel state changed + if (!same_travel_path || last_active != state_machine->is_playing() || last_current_node != state_machine->get_current_node() || last_blend_from_node != state_machine->get_blend_from_node()) { + + state_machine_draw->update(); + last_travel_path = tp; + last_current_node = state_machine->get_current_node(); + last_active = state_machine->is_playing(); + last_blend_from_node = state_machine->get_blend_from_node(); + state_machine_play_pos->update(); + } + + if (last_play_pos != state_machine->get_current_play_pos()) { + + last_play_pos = state_machine->get_current_play_pos(); + state_machine_play_pos->update(); + } + } + + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + over_node = StringName(); + } +} + +void AnimationNodeStateMachineEditor::_open_editor(const String &p_name) { + Ref<AnimationNode> an = state_machine->get_node(p_name); + ERR_FAIL_COND(!an.is_valid()); + EditorNode::get_singleton()->edit_item(an.ptr()); +} + +void AnimationNodeStateMachineEditor::_goto_parent() { + + EditorNode::get_singleton()->edit_item(state_machine->get_parent().ptr()); +} + +void AnimationNodeStateMachineEditor::_removed_from_graph() { + EditorNode::get_singleton()->edit_item(NULL); +} + +void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) { + + String new_name = p_text; + + ERR_FAIL_COND(new_name == "" || new_name.find(".") != -1 || new_name.find("/") != -1) + + ERR_FAIL_COND(new_name == prev_name); + + String base_name = new_name; + int base = 1; + String name = base_name; + while (state_machine->has_node(name)) { + base++; + name = base_name + " " + itos(base); + } + + updating = true; + undo_redo->create_action("Node Renamed"); + undo_redo->add_do_method(state_machine.ptr(), "rename_node", prev_name, name); + undo_redo->add_undo_method(state_machine.ptr(), "rename_node", name, prev_name); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + + state_machine_draw->update(); + + name_edit->hide(); +} + +void AnimationNodeStateMachineEditor::_scroll_changed(double) { + if (updating) + return; + + state_machine->set_graph_offset(Vector2(h_scroll->get_value(), v_scroll->get_value())); + state_machine_draw->update(); +} + +void AnimationNodeStateMachineEditor::_erase_selected() { + + if (selected_node != StringName() && state_machine->has_node(selected_node)) { + updating = true; + undo_redo->create_action("Node Removed"); + undo_redo->add_do_method(state_machine.ptr(), "remove_node", selected_node); + undo_redo->add_undo_method(state_machine.ptr(), "add_node", selected_node, state_machine->get_node(selected_node)); + for (int i = 0; i < state_machine->get_transition_count(); i++) { + String from = state_machine->get_transition_from(i); + String to = state_machine->get_transition_to(i); + if (from == selected_node || to == selected_node) { + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", from, to, state_machine->get_transition(i)); + } + } + if (String(state_machine->get_start_node()) == selected_node) { + undo_redo->add_undo_method(state_machine.ptr(), "set_start_node", selected_node); + } + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + selected_node = StringName(); + } + + if (selected_transition_to != StringName() && selected_transition_from != StringName() && state_machine->has_transition(selected_transition_from, selected_transition_to)) { + + Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(state_machine->find_transition(selected_transition_from, selected_transition_to)); + updating = true; + undo_redo->create_action("Transition Removed"); + undo_redo->add_do_method(state_machine.ptr(), "remove_transition", selected_transition_from, selected_transition_to); + undo_redo->add_undo_method(state_machine.ptr(), "add_transition", selected_transition_from, selected_transition_to, tr); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + selected_transition_from = StringName(); + selected_transition_to = StringName(); + } + + state_machine_draw->update(); +} + +void AnimationNodeStateMachineEditor::_autoplay_selected() { + + if (selected_node != StringName() && state_machine->has_node(selected_node)) { + + StringName new_start_node; + if (state_machine->get_start_node() == selected_node) { //toggle it + new_start_node = StringName(); + } else { + new_start_node = selected_node; + } + + updating = true; + undo_redo->create_action("Set Start Node (Autoplay)"); + undo_redo->add_do_method(state_machine.ptr(), "set_start_node", new_start_node); + undo_redo->add_undo_method(state_machine.ptr(), "set_start_node", state_machine->get_start_node()); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + state_machine_draw->update(); + } +} + +void AnimationNodeStateMachineEditor::_end_selected() { + + if (selected_node != StringName() && state_machine->has_node(selected_node)) { + + StringName new_end_node; + if (state_machine->get_end_node() == selected_node) { //toggle it + new_end_node = StringName(); + } else { + new_end_node = selected_node; + } + + updating = true; + undo_redo->create_action("Set Start Node (Autoplay)"); + undo_redo->add_do_method(state_machine.ptr(), "set_end_node", new_end_node); + undo_redo->add_undo_method(state_machine.ptr(), "set_end_node", state_machine->get_end_node()); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + undo_redo->commit_action(); + updating = false; + state_machine_draw->update(); + } +} +void AnimationNodeStateMachineEditor::_update_mode() { + + if (tool_select->is_pressed()) { + tool_erase_hb->show(); + tool_erase->set_disabled(selected_node == StringName() && selected_transition_from == StringName() && selected_transition_to == StringName()); + tool_autoplay->set_disabled(selected_node == StringName()); + tool_end->set_disabled(selected_node == StringName()); + } else { + tool_erase_hb->hide(); + } +} + +void AnimationNodeStateMachineEditor::_bind_methods() { + + ClassDB::bind_method("_state_machine_gui_input", &AnimationNodeStateMachineEditor::_state_machine_gui_input); + ClassDB::bind_method("_state_machine_draw", &AnimationNodeStateMachineEditor::_state_machine_draw); + ClassDB::bind_method("_state_machine_pos_draw", &AnimationNodeStateMachineEditor::_state_machine_pos_draw); + ClassDB::bind_method("_update_graph", &AnimationNodeStateMachineEditor::_update_graph); + + ClassDB::bind_method("_add_menu_type", &AnimationNodeStateMachineEditor::_add_menu_type); + ClassDB::bind_method("_add_animation_type", &AnimationNodeStateMachineEditor::_add_animation_type); + + ClassDB::bind_method("_name_edited", &AnimationNodeStateMachineEditor::_name_edited); + + ClassDB::bind_method("_goto_parent", &AnimationNodeStateMachineEditor::_goto_parent); + ClassDB::bind_method("_removed_from_graph", &AnimationNodeStateMachineEditor::_removed_from_graph); + + ClassDB::bind_method("_open_editor", &AnimationNodeStateMachineEditor::_open_editor); + ClassDB::bind_method("_scroll_changed", &AnimationNodeStateMachineEditor::_scroll_changed); + + ClassDB::bind_method("_erase_selected", &AnimationNodeStateMachineEditor::_erase_selected); + ClassDB::bind_method("_autoplay_selected", &AnimationNodeStateMachineEditor::_autoplay_selected); + ClassDB::bind_method("_end_selected", &AnimationNodeStateMachineEditor::_end_selected); + ClassDB::bind_method("_update_mode", &AnimationNodeStateMachineEditor::_update_mode); +} + +AnimationNodeStateMachineEditor *AnimationNodeStateMachineEditor::singleton = NULL; + +AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { + + singleton = this; + updating = false; + + HBoxContainer *top_hb = memnew(HBoxContainer); + add_child(top_hb); + + goto_parent_hbox = memnew(HBoxContainer); + goto_parent = memnew(ToolButton); + goto_parent->connect("pressed", this, "_goto_parent", varray(), CONNECT_DEFERRED); + goto_parent_hbox->add_child(goto_parent); + goto_parent_hbox->add_child(memnew(VSeparator)); + top_hb->add_child(goto_parent_hbox); + + Ref<ButtonGroup> bg; + bg.instance(); + + tool_select = memnew(ToolButton); + top_hb->add_child(tool_select); + tool_select->set_toggle_mode(true); + tool_select->set_button_group(bg); + tool_select->set_pressed(true); + tool_select->set_tooltip(TTR("Select and move nodes.\nRMB to add new nodes.\nShift+LMB to create connections.")); + tool_select->connect("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED); + + tool_create = memnew(ToolButton); + top_hb->add_child(tool_create); + tool_create->set_toggle_mode(true); + tool_create->set_button_group(bg); + tool_create->set_tooltip(TTR("Create new nodes.")); + tool_create->connect("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED); + + tool_connect = memnew(ToolButton); + top_hb->add_child(tool_connect); + tool_connect->set_toggle_mode(true); + tool_connect->set_button_group(bg); + tool_connect->set_tooltip(TTR("Connect nodes.")); + tool_connect->connect("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED); + + tool_erase_hb = memnew(HBoxContainer); + top_hb->add_child(tool_erase_hb); + tool_erase_hb->add_child(memnew(VSeparator)); + tool_erase = memnew(ToolButton); + tool_erase->set_tooltip(TTR("Remove selected node or transition")); + tool_erase_hb->add_child(tool_erase); + tool_erase->connect("pressed", this, "_erase_selected"); + tool_erase->set_disabled(true); + + tool_erase_hb->add_child(memnew(VSeparator)); + + tool_autoplay = memnew(ToolButton); + tool_autoplay->set_tooltip(TTR("Toggle autoplay this animation on start, restart or seek to zero.")); + tool_erase_hb->add_child(tool_autoplay); + tool_autoplay->connect("pressed", this, "_autoplay_selected"); + tool_autoplay->set_disabled(true); + + tool_end = memnew(ToolButton); + tool_end->set_tooltip(TTR("Set the end animation. This is useful for sub-transitions.")); + tool_erase_hb->add_child(tool_end); + tool_end->connect("pressed", this, "_end_selected"); + tool_end->set_disabled(true); + + top_hb->add_child(memnew(VSeparator)); + top_hb->add_child(memnew(Label(TTR("Transition: ")))); + transition_mode = memnew(OptionButton); + top_hb->add_child(transition_mode); + + top_hb->add_spacer(); + + top_hb->add_child(memnew(Label("Play Mode:"))); + play_mode = memnew(OptionButton); + top_hb->add_child(play_mode); + + GridContainer *main_grid = memnew(GridContainer); + main_grid->set_columns(2); + add_child(main_grid); + main_grid->set_v_size_flags(SIZE_EXPAND_FILL); + + panel = memnew(PanelContainer); + panel->set_clip_contents(true); + main_grid->add_child(panel); + panel->set_h_size_flags(SIZE_EXPAND_FILL); + + state_machine_draw = memnew(Control); + state_machine_draw->connect("gui_input", this, "_state_machine_gui_input"); + state_machine_draw->connect("draw", this, "_state_machine_draw"); + state_machine_draw->set_focus_mode(FOCUS_ALL); + + state_machine_play_pos = memnew(Control); + state_machine_draw->add_child(state_machine_play_pos); + state_machine_play_pos->set_mouse_filter(MOUSE_FILTER_PASS); //pass all to parent + state_machine_play_pos->set_anchors_and_margins_preset(PRESET_WIDE); + state_machine_play_pos->connect("draw", this, "_state_machine_pos_draw"); + + panel->add_child(state_machine_draw); + panel->set_v_size_flags(SIZE_EXPAND_FILL); + + v_scroll = memnew(VScrollBar); + main_grid->add_child(v_scroll); + v_scroll->connect("value_changed", this, "_scroll_changed"); + + h_scroll = memnew(HScrollBar); + main_grid->add_child(h_scroll); + h_scroll->connect("value_changed", this, "_scroll_changed"); + + main_grid->add_child(memnew(Control)); //empty bottom right + + error_panel = memnew(PanelContainer); + add_child(error_panel); + error_label = memnew(Label); + error_panel->add_child(error_label); + error_label->set_text("eh"); + + undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + set_custom_minimum_size(Size2(0, 300 * EDSCALE)); + + menu = memnew(PopupMenu); + add_child(menu); + menu->connect("index_pressed", this, "_add_menu_type"); + + animations_menu = memnew(PopupMenu); + menu->add_child(animations_menu); + animations_menu->set_name("animations"); + animations_menu->connect("index_pressed", this, "_add_animation_type"); + + name_edit = memnew(LineEdit); + state_machine_draw->add_child(name_edit); + name_edit->hide(); + name_edit->connect("text_entered", this, "_name_edited"); + name_edit->set_as_toplevel(true); + + over_text = false; + + over_node_what = -1; + dragging_selected_attempt = false; + connecting = false; + + last_active = false; + + error_time = 0; +} + +void AnimationNodeStateMachineEditorPlugin::edit(Object *p_object) { + + anim_tree_editor->edit(Object::cast_to<AnimationNodeStateMachine>(p_object)); +} + +bool AnimationNodeStateMachineEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("AnimationNodeStateMachine"); +} + +void AnimationNodeStateMachineEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + //editor->hide_animation_player_editors(); + //editor->animation_panel_make_visible(true); + button->show(); + editor->make_bottom_panel_item_visible(anim_tree_editor); + anim_tree_editor->set_process(true); + } else { + + if (anim_tree_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + button->hide(); + anim_tree_editor->set_process(false); + } +} + +AnimationNodeStateMachineEditorPlugin::AnimationNodeStateMachineEditorPlugin(EditorNode *p_node) { + + editor = p_node; + anim_tree_editor = memnew(AnimationNodeStateMachineEditor); + anim_tree_editor->set_custom_minimum_size(Size2(0, 300)); + + button = editor->add_bottom_panel_item(TTR("StateMachine"), anim_tree_editor); + button->hide(); +} + +AnimationNodeStateMachineEditorPlugin::~AnimationNodeStateMachineEditorPlugin() { +} diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h new file mode 100644 index 0000000000..efd3de7415 --- /dev/null +++ b/editor/plugins/animation_state_machine_editor.h @@ -0,0 +1,167 @@ +#ifndef ANIMATION_STATE_MACHINE_EDITOR_H +#define ANIMATION_STATE_MACHINE_EDITOR_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "editor/property_editor.h" +#include "scene/animation/animation_node_state_machine.h" +#include "scene/gui/button.h" +#include "scene/gui/graph_edit.h" +#include "scene/gui/popup.h" +#include "scene/gui/tree.h" + +class AnimationNodeStateMachineEditor : public VBoxContainer { + + GDCLASS(AnimationNodeStateMachineEditor, VBoxContainer); + + Ref<AnimationNodeStateMachine> state_machine; + + ToolButton *tool_select; + ToolButton *tool_create; + ToolButton *tool_connect; + LineEdit *name_edit; + + HBoxContainer *tool_erase_hb; + ToolButton *tool_erase; + ToolButton *tool_autoplay; + ToolButton *tool_end; + + OptionButton *transition_mode; + OptionButton *play_mode; + + HBoxContainer *goto_parent_hbox; + ToolButton *goto_parent; + + PanelContainer *panel; + + StringName selected_node; + + HScrollBar *h_scroll; + VScrollBar *v_scroll; + + Control *state_machine_draw; + Control *state_machine_play_pos; + + PanelContainer *error_panel; + Label *error_label; + + bool updating; + + UndoRedo *undo_redo; + + static AnimationNodeStateMachineEditor *singleton; + + void _state_machine_gui_input(const Ref<InputEvent> &p_event); + void _connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance); + void _state_machine_draw(); + void _state_machine_pos_draw(); + + void _update_graph(); + + PopupMenu *menu; + PopupMenu *animations_menu; + Vector<String> animations_to_add; + + Vector2 add_node_pos; + + bool dragging_selected_attempt; + bool dragging_selected; + Vector2 drag_from; + Vector2 drag_ofs; + StringName snap_x; + StringName snap_y; + + bool connecting; + StringName connecting_from; + Vector2 connecting_to; + StringName connecting_to_node; + + void _add_menu_type(int p_index); + void _add_animation_type(int p_index); + + void _goto_parent(); + + void _removed_from_graph(); + + struct NodeRect { + StringName node_name; + Rect2 node; + Rect2 play; + Rect2 name; + Rect2 edit; + }; + + Vector<NodeRect> node_rects; + + struct TransitionLine { + StringName from_node; + StringName to_node; + Vector2 from; + Vector2 to; + AnimationNodeStateMachineTransition::SwitchMode mode; + bool disabled; + bool auto_advance; + float width; + }; + + Vector<TransitionLine> transition_lines; + + StringName selected_transition_from; + StringName selected_transition_to; + + bool over_text; + StringName over_node; + int over_node_what; + + String prev_name; + void _name_edited(const String &p_text); + void _open_editor(const String &p_name); + void _scroll_changed(double); + + void _clip_src_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect); + void _clip_dst_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect); + + void _erase_selected(); + void _update_mode(); + void _autoplay_selected(); + void _end_selected(); + + bool last_active; + StringName last_blend_from_node; + StringName last_current_node; + Vector<StringName> last_travel_path; + float last_play_pos; + + float error_time; + String error_text; + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static AnimationNodeStateMachineEditor *get_singleton() { return singleton; } + void edit(AnimationNodeStateMachine *p_state_machine); + AnimationNodeStateMachineEditor(); +}; + +class AnimationNodeStateMachineEditorPlugin : public EditorPlugin { + + GDCLASS(AnimationNodeStateMachineEditorPlugin, EditorPlugin); + + AnimationNodeStateMachineEditor *anim_tree_editor; + EditorNode *editor; + Button *button; + +public: + virtual String get_name() const { return "StateMachine"; } + 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); + + AnimationNodeStateMachineEditorPlugin(EditorNode *p_node); + ~AnimationNodeStateMachineEditorPlugin(); +}; + +#endif // ANIMATION_STATE_MACHINE_EDITOR_H diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp new file mode 100644 index 0000000000..89c1b3a978 --- /dev/null +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -0,0 +1,293 @@ +#include "root_motion_editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/main/viewport.h" + +void EditorPropertyRootMotion::_confirmed() { + + TreeItem *ti = filters->get_selected(); + if (!ti) + return; + + NodePath path = ti->get_metadata(0); + emit_signal("property_changed", get_edited_property(), path); + update_property(); + filter_dialog->hide(); //may come from activated +} + +void EditorPropertyRootMotion::_node_assign() { + + NodePath current = get_edited_object()->get(get_edited_property()); + + AnimationTree *atree = Object::cast_to<AnimationTree>(get_edited_object()); + if (!atree->has_node(atree->get_animation_player())) { + EditorNode::get_singleton()->show_warning(TTR("AnimationTree has no path set to an AnimationPlayer")); + return; + } + AnimationPlayer *player = Object::cast_to<AnimationPlayer>(atree->get_node(atree->get_animation_player())); + if (!player) { + EditorNode::get_singleton()->show_warning(TTR("Path to AnimationPlayer is invalid")); + return; + } + + Node *base = player->get_node(player->get_root()); + + if (!base) { + EditorNode::get_singleton()->show_warning(TTR("Animation player has no valid root node path, so unable to retrieve track names.")); + return; + } + + Set<String> paths; + { + List<StringName> animations; + player->get_animation_list(&animations); + + for (List<StringName>::Element *E = animations.front(); E; E = E->next()) { + + Ref<Animation> anim = player->get_animation(E->get()); + for (int i = 0; i < anim->get_track_count(); i++) { + paths.insert(anim->track_get_path(i)); + } + } + } + + filters->clear(); + TreeItem *root = filters->create_item(); + + Map<String, TreeItem *> parenthood; + + for (Set<String>::Element *E = paths.front(); E; E = E->next()) { + + NodePath path = E->get(); + TreeItem *ti = NULL; + String accum; + for (int i = 0; i < path.get_name_count(); i++) { + String name = path.get_name(i); + if (accum != String()) { + accum += "/"; + } + accum += name; + if (!parenthood.has(accum)) { + if (ti) { + ti = filters->create_item(ti); + } else { + ti = filters->create_item(root); + } + parenthood[accum] = ti; + ti->set_text(0, name); + ti->set_selectable(0, false); + ti->set_editable(0, false); + + if (base->has_node(accum)) { + Node *node = base->get_node(accum); + if (has_icon(node->get_class(), "EditorIcons")) { + ti->set_icon(0, get_icon(node->get_class(), "EditorIcons")); + } else { + ti->set_icon(0, get_icon("Node", "EditorIcons")); + } + } + + } else { + ti = parenthood[accum]; + } + } + + Node *node = NULL; + if (base->has_node(accum)) { + node = base->get_node(accum); + } + if (!node) + continue; //no node, cant edit + + if (path.get_subname_count()) { + + String concat = path.get_concatenated_subnames(); + + Skeleton *skeleton = Object::cast_to<Skeleton>(node); + if (skeleton && skeleton->find_bone(concat) != -1) { + //path in skeleton + String bone = concat; + int idx = skeleton->find_bone(bone); + List<String> bone_path; + while (idx != -1) { + bone_path.push_front(skeleton->get_bone_name(idx)); + idx = skeleton->get_bone_parent(idx); + } + + accum += ":"; + for (List<String>::Element *F = bone_path.front(); F; F = F->next()) { + if (F != bone_path.front()) { + accum += "/"; + } + + accum += F->get(); + if (!parenthood.has(accum)) { + ti = filters->create_item(ti); + parenthood[accum] = ti; + ti->set_text(0, F->get()); + ti->set_selectable(0, true); + ti->set_editable(0, false); + ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons")); + ti->set_metadata(0, accum); + } else { + ti = parenthood[accum]; + } + } + + ti->set_selectable(0, true); + ti->set_text(0, concat); + ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons")); + ti->set_metadata(0, path); + if (path == current) { + ti->select(0); + } + + } else { + //just a property + ti = filters->create_item(ti); + ti->set_text(0, concat); + ti->set_selectable(0, true); + ti->set_metadata(0, path); + if (path == current) { + ti->select(0); + } + } + } else { + if (ti) { + //just a node, likely call or animation track + ti->set_selectable(0, true); + ti->set_metadata(0, path); + if (path == current) { + ti->select(0); + } + } + } + } + + filters->ensure_cursor_is_visible(); + filter_dialog->popup_centered_ratio(); +} + +void EditorPropertyRootMotion::_node_clear() { + + emit_signal("property_changed", get_edited_property(), NodePath()); + update_property(); +} + +void EditorPropertyRootMotion::update_property() { + + NodePath p = get_edited_object()->get(get_edited_property()); + + assign->set_tooltip(p); + if (p == NodePath()) { + assign->set_icon(Ref<Texture>()); + assign->set_text(TTR("Assign..")); + assign->set_flat(false); + return; + } + assign->set_flat(true); + + Node *base_node = NULL; + if (base_hint != NodePath()) { + if (get_tree()->get_root()->has_node(base_hint)) { + base_node = get_tree()->get_root()->get_node(base_hint); + } + } else { + base_node = Object::cast_to<Node>(get_edited_object()); + } + + if (!base_node || !base_node->has_node(p)) { + assign->set_icon(Ref<Texture>()); + assign->set_text(p); + return; + } + + Node *target_node = base_node->get_node(p); + ERR_FAIL_COND(!target_node); + + assign->set_text(target_node->get_name()); + + Ref<Texture> icon; + if (has_icon(target_node->get_class(), "EditorIcons")) + icon = get_icon(target_node->get_class(), "EditorIcons"); + else + icon = get_icon("Node", "EditorIcons"); + + assign->set_icon(icon); +} + +void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) { + + base_hint = p_base_hint; +} + +void EditorPropertyRootMotion::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Ref<Texture> t = get_icon("Clear", "EditorIcons"); + clear->set_icon(t); + } +} + +void EditorPropertyRootMotion::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_confirmed"), &EditorPropertyRootMotion::_confirmed); + ClassDB::bind_method(D_METHOD("_node_assign"), &EditorPropertyRootMotion::_node_assign); + ClassDB::bind_method(D_METHOD("_node_clear"), &EditorPropertyRootMotion::_node_clear); +} + +EditorPropertyRootMotion::EditorPropertyRootMotion() { + + HBoxContainer *hbc = memnew(HBoxContainer); + add_child(hbc); + assign = memnew(Button); + assign->set_flat(true); + assign->set_h_size_flags(SIZE_EXPAND_FILL); + assign->set_clip_text(true); + assign->connect("pressed", this, "_node_assign"); + hbc->add_child(assign); + + clear = memnew(Button); + clear->set_flat(true); + clear->connect("pressed", this, "_node_clear"); + hbc->add_child(clear); + + filter_dialog = memnew(ConfirmationDialog); + add_child(filter_dialog); + filter_dialog->set_title(TTR("Edit Filtered Tracks:")); + filter_dialog->connect("confirmed", this, "_confirmed"); + + filters = memnew(Tree); + filter_dialog->add_child(filters); + filters->set_v_size_flags(SIZE_EXPAND_FILL); + filters->set_hide_root(true); + filters->connect("item_activated", this, "_confirmed"); + //filters->connect("item_edited", this, "_filter_edited"); +} +////////////////////////// + +bool EditorInspectorRootMotionPlugin::can_handle(Object *p_object) { + return true; //can handle everything +} + +void EditorInspectorRootMotionPlugin::parse_begin(Object *p_object) { + //do none +} + +bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { + + if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) { + print_line("use custom!"); + EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion); + if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) { + editor->setup(p_hint_text); + } + add_property_editor(p_path, editor); + return true; + } + + return false; //can be overriden, although it will most likely be last anyway +} + +void EditorInspectorRootMotionPlugin::parse_end() { + //do none +} diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h new file mode 100644 index 0000000000..84af47872f --- /dev/null +++ b/editor/plugins/root_motion_editor_plugin.h @@ -0,0 +1,42 @@ +#ifndef ROOT_MOTION_EDITOR_PLUGIN_H +#define ROOT_MOTION_EDITOR_PLUGIN_H + +#include "editor/editor_inspector.h" +#include "editor/editor_spin_slider.h" +#include "editor/property_selector.h" +#include "scene/animation/animation_tree.h" + +class EditorPropertyRootMotion : public EditorProperty { + GDCLASS(EditorPropertyRootMotion, EditorProperty) + Button *assign; + Button *clear; + NodePath base_hint; + + ConfirmationDialog *filter_dialog; + Tree *filters; + + void _confirmed(); + void _node_assign(); + void _node_clear(); + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + virtual void update_property(); + void setup(const NodePath &p_base_hint); + EditorPropertyRootMotion(); +}; + +class EditorInspectorRootMotionPlugin : public EditorInspectorPlugin { + GDCLASS(EditorInspectorRootMotionPlugin, EditorInspectorPlugin) + +public: + virtual bool can_handle(Object *p_object); + virtual void parse_begin(Object *p_object); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual void parse_end(); +}; + +#endif // ROOT_MOTION_EDITOR_PLUGIN_H diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 83072534b8..9724017787 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -804,12 +804,12 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) { void ScriptEditor::_file_dialog_action(String p_file) { switch (file_dialog_option) { - case FILE_SAVE_THEME_AS: { + case THEME_SAVE_AS: { if (!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) { editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); } } break; - case FILE_IMPORT_THEME: { + case THEME_IMPORT: { if (!EditorSettings::get_singleton()->import_text_editor_theme(p_file)) { editor->show_warning(TTR("Error importing theme"), TTR("Error importing")); } @@ -859,33 +859,6 @@ void ScriptEditor::_menu_option(int p_option) { save_all_scripts(); } break; - case FILE_IMPORT_THEME: { - file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); - file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file_dialog_option = FILE_IMPORT_THEME; - file_dialog->clear_filters(); - file_dialog->add_filter("*.tet"); - file_dialog->popup_centered_ratio(); - file_dialog->set_title(TTR("Import Theme")); - } break; - case FILE_RELOAD_THEME: { - EditorSettings::get_singleton()->load_text_editor_theme(); - } break; - case FILE_SAVE_THEME: { - if (!EditorSettings::get_singleton()->save_text_editor_theme()) { - editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); - } - } break; - case FILE_SAVE_THEME_AS: { - file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); - file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file_dialog_option = FILE_SAVE_THEME_AS; - file_dialog->clear_filters(); - file_dialog->add_filter("*.tet"); - file_dialog->set_current_path(EditorSettings::get_singleton()->get_text_editor_themes_dir().plus_file(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))); - file_dialog->popup_centered_ratio(); - file_dialog->set_title(TTR("Save Theme As...")); - } break; case SEARCH_HELP: { help_search_dialog->popup(); @@ -1143,6 +1116,38 @@ void ScriptEditor::_menu_option(int p_option) { } } +void ScriptEditor::_theme_option(int p_option) { + switch (p_option) { + case THEME_IMPORT: { + file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); + file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_dialog_option = THEME_IMPORT; + file_dialog->clear_filters(); + file_dialog->add_filter("*.tet"); + file_dialog->popup_centered_ratio(); + file_dialog->set_title(TTR("Import Theme")); + } break; + case THEME_RELOAD: { + EditorSettings::get_singleton()->load_text_editor_theme(); + } break; + case THEME_SAVE: { + if (!EditorSettings::get_singleton()->save_text_editor_theme()) { + editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); + } + } break; + case THEME_SAVE_AS: { + file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); + file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_dialog_option = THEME_SAVE_AS; + file_dialog->clear_filters(); + file_dialog->add_filter("*.tet"); + file_dialog->set_current_path(EditorSettings::get_singleton()->get_text_editor_themes_dir().plus_file(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))); + file_dialog->popup_centered_ratio(); + file_dialog->set_title(TTR("Save Theme As...")); + } break; + } +} + void ScriptEditor::_tab_changed(int p_which) { ensure_select_current(); @@ -2591,6 +2596,7 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_close_all_tabs", &ScriptEditor::_close_all_tabs); ClassDB::bind_method("_close_other_tabs", &ScriptEditor::_close_other_tabs); ClassDB::bind_method("_open_recent_script", &ScriptEditor::_open_recent_script); + ClassDB::bind_method("_theme_option", &ScriptEditor::_theme_option); ClassDB::bind_method("_editor_play", &ScriptEditor::_editor_play); ClassDB::bind_method("_editor_pause", &ScriptEditor::_editor_pause); ClassDB::bind_method("_editor_stop", &ScriptEditor::_editor_stop); @@ -2763,10 +2769,18 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Prev"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_next", TTR("History Next"), KEY_MASK_ALT | KEY_RIGHT), WINDOW_NEXT); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme")), FILE_IMPORT_THEME); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), FILE_RELOAD_THEME); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), FILE_SAVE_THEME); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As")), FILE_SAVE_THEME_AS); + + file_menu->get_popup()->add_submenu_item(TTR("Theme"), "Theme", FILE_THEME); + + theme_submenu = memnew(PopupMenu); + theme_submenu->set_name("Theme"); + file_menu->get_popup()->add_child(theme_submenu); + theme_submenu->connect("id_pressed", this, "_theme_option"); + theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme")), THEME_IMPORT); + theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), THEME_RELOAD); + theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), THEME_SAVE); + theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As")), THEME_SAVE_AS); + file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 769612bdb6..67f506fdda 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -134,10 +134,7 @@ class ScriptEditor : public PanelContainer { FILE_SAVE, FILE_SAVE_AS, FILE_SAVE_ALL, - FILE_IMPORT_THEME, - FILE_RELOAD_THEME, - FILE_SAVE_THEME, - FILE_SAVE_THEME_AS, + FILE_THEME, FILE_RUN, FILE_CLOSE, CLOSE_DOCS, @@ -168,6 +165,13 @@ class ScriptEditor : public PanelContainer { WINDOW_SELECT_BASE = 100 }; + enum { + THEME_IMPORT, + THEME_RELOAD, + THEME_SAVE, + THEME_SAVE_AS + }; + enum ScriptSortBy { SORT_BY_NAME, SORT_BY_PATH, @@ -190,6 +194,7 @@ class ScriptEditor : public PanelContainer { uint64_t idle; PopupMenu *recent_scripts; + PopupMenu *theme_submenu; Button *help_search; Button *site_search; @@ -251,6 +256,7 @@ class ScriptEditor : public PanelContainer { void _tab_changed(int p_which); void _menu_option(int p_option); + void _theme_option(int p_option); Tree *disk_changed_list; ConfirmationDialog *disk_changed; diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index ea133cd749..7264af3488 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -133,16 +133,14 @@ void TileMapEditor::_menu_option(int p_option) { if (!selection_active) return; - undo_redo->create_action(TTR("Erase Selection")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Erase Selection")); for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false); } } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); selection_active = false; copydata.clear(); @@ -208,6 +206,46 @@ void TileMapEditor::set_selected_tile(int p_tile) { } } +void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) { + + Dictionary cell_old; + Dictionary cell_new; + + cell_old["id"] = p_cell_old.idx; + cell_old["flip_h"] = p_cell_old.xf; + cell_old["flip_y"] = p_cell_old.yf; + cell_old["transpose"] = p_cell_old.tr; + cell_old["auto_coord"] = p_cell_old.ac; + + cell_new["id"] = p_cell_new.idx; + cell_new["flip_h"] = p_cell_new.xf; + cell_new["flip_y"] = p_cell_new.yf; + cell_new["transpose"] = p_cell_new.tr; + cell_new["auto_coord"] = p_cell_new.ac; + + undo_redo->add_undo_method(node, "set_celld", p_vec, cell_old); + undo_redo->add_do_method(node, "set_celld", p_vec, cell_new); +} + +void TileMapEditor::_start_undo(const String &p_action) { + + undo_data.clear(); + undo_redo->create_action(p_action); +} + +void TileMapEditor::_finish_undo() { + + if (undo_data.size()) { + for (Map<Point2i, CellOp>::Element *E = undo_data.front(); E; E = E->next()) { + _create_set_cell_undo(E->key(), E->get(), _get_op_from_cell(E->key())); + } + + undo_data.clear(); + } + + undo_redo->commit_action(); +} + void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose) { ERR_FAIL_COND(!node); @@ -234,6 +272,15 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose && prev_position == position) return; //check that it's actually different + for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { + for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { + Point2i p = Point2i(x, y); + if (!undo_data.has(p)) { + undo_data[p] = _get_op_from_cell(p); + } + } + } + node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose); if (manual_autotile) { if (current != -1) { @@ -844,8 +891,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { tool = TOOL_PAINTING; - undo_redo->create_action(TTR("Paint TileMap")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Paint TileMap")); } } else if (tool == TOOL_PICKING) { @@ -869,8 +915,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (id != TileMap::INVALID_CELL) { _set_cell(over_tile, id, flip_h, flip_v, transpose); - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); paint_undo.clear(); } @@ -880,14 +925,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (id != TileMap::INVALID_CELL) { - undo_redo->create_action(TTR("Line Draw")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Line Draw")); for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) { _set_cell(E->key(), id, flip_h, flip_v, transpose); } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); paint_undo.clear(); @@ -899,16 +942,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (id != TileMap::INVALID_CELL) { - undo_redo->create_action(TTR("Rectangle Paint")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Rectangle Paint")); for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose); } } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); canvas_item_editor->update(); } @@ -916,14 +957,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Point2 ofs = over_tile - rectangle.position; - undo_redo->create_action(TTR("Duplicate")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Duplicate")); for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) { _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose); } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); copydata.clear(); @@ -932,8 +971,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Point2 ofs = over_tile - rectangle.position; - undo_redo->create_action(TTR("Move")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Move")); for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { @@ -944,8 +982,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose); } - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); copydata.clear(); selection_active = false; @@ -964,7 +1001,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return false; undo_redo->create_action(TTR("Bucket Fill")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); Dictionary op; op["id"] = get_selected_tile(); @@ -974,7 +1010,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { _fill_points(points, op); - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); undo_redo->commit_action(); // We want to keep the bucket-tool active @@ -1026,8 +1061,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { Point2 local = node->world_to_map(xform_inv.xform(mb->get_position())); - undo_redo->create_action(TTR("Erase TileMap")); - undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + _start_undo(TTR("Erase TileMap")); if (mb->get_shift()) { #ifdef APPLE_STYLE_KEYS @@ -1054,8 +1088,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } else { if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) { - undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); - undo_redo->commit_action(); + _finish_undo(); if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) { canvas_item_editor->update(); @@ -1621,6 +1654,7 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i &p_pos) { op.yf = true; if (node->is_cell_transposed(p_pos.x, p_pos.y)) op.tr = true; + op.ac = node->get_cell_autotile_coord(p_pos.x, p_pos.y); } return op; } diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index a1f5d93a8d..77e9a33892 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -129,6 +129,7 @@ class TileMapEditor : public VBoxContainer { bool xf; bool yf; bool tr; + Vector2 ac; CellOp() : idx(TileMap::INVALID_CELL), @@ -155,6 +156,8 @@ class TileMapEditor : public VBoxContainer { List<TileData> copydata; + Map<Point2i, CellOp> undo_data; + void _pick_tile(const Point2 &p_pos); PoolVector<Vector2> _bucket_fill(const Point2i &p_start, bool erase = false, bool preview = false); @@ -181,6 +184,9 @@ class TileMapEditor : public VBoxContainer { void _menu_option(int p_option); void _palette_selected(int index); + void _start_undo(const String &p_action); + void _finish_undo(); + void _create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new); void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false); void _canvas_mouse_enter(); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 7d2127d4f8..88d614ab89 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -166,6 +166,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } TreeItem *item = tree->create_item(p_parent); + item->set_text(0, p_node->get_name()); if (can_rename && !part_of_subscene /*(p_node->get_owner() == get_scene_node() || p_node==get_scene_node())*/) item->set_editable(0, true); @@ -196,7 +197,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (part_of_subscene) { //item->set_selectable(0,marked_selectable); - item->set_custom_color(0, get_color("disabled_font_color", "Editor")); + if (valid_types.size() == 0) { + item->set_custom_color(0, get_color("disabled_font_color", "Editor")); + } } else if (marked.has(p_node)) { @@ -323,6 +326,22 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { keep = keep || child_keep; } + if (valid_types.size()) { + bool valid = false; + for (int i = 0; i < valid_types.size(); i++) { + if (p_node->is_class(valid_types[i])) { + valid = true; + break; + } + } + + if (!valid) { + //item->set_selectable(0,marked_selectable); + item->set_custom_color(0, get_color("disabled_font_color", "Editor")); + item->set_selectable(0, false); + } + } + if (!keep) { memdelete(item); return false; @@ -716,6 +735,10 @@ bool SceneTreeEditor::get_display_foreign_nodes() const { return display_foreign; } +void SceneTreeEditor::set_valid_types(const Vector<StringName> &p_valid) { + valid_types = p_valid; +} + void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) { editor_selection = p_selection; diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index b173d7d215..c4f63f5736 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -131,6 +131,8 @@ class SceneTreeEditor : public Control { List<StringName> *script_types; bool _is_script_type(const StringName &p_type) const; + Vector<StringName> valid_types; + public: void set_filter(const String &p_filter); String get_filter() const; @@ -147,6 +149,7 @@ public: void set_editor_selection(EditorSelection *p_selection); void set_show_enabled_subscene(bool p_show) { show_enabled_subscene = p_show; } + void set_valid_types(const Vector<StringName> &p_valid); void update_tree() { _update_tree(); } diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index eb9ab93228..ae88b3a035 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -61,7 +61,7 @@ void EditorSettingsDialog::_settings_property_edited(const String &p_name) { if (full_name == "text_editor/theme/color_theme") { property_editor->get_property_editor()->update_tree(); } else if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") { - EditorSettings::get_singleton()->set_manually("interface/theme/preset", 1); // set preset to Custom + EditorSettings::get_singleton()->set_manually("interface/theme/preset", "Custom"); // set preset to Custom } else if (full_name.begins_with("text_editor/highlighting")) { EditorSettings::get_singleton()->set_manually("text_editor/theme/color_theme", "Custom"); } diff --git a/editor/translations/ar.po b/editor/translations/ar.po index cd193c4fc4..ccf2b97d9a 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -8078,6 +8078,9 @@ msgstr "" msgid "Invalid font size." msgstr "" +#~ msgid "Next" +#~ msgstr "التالي" + #~ msgid "Can't contain '/' or ':'" #~ msgstr "لا يمكن أن ÙŠØتوي علي '/' أو ':'" @@ -8090,9 +8093,6 @@ msgstr "" #~ msgid "Can't write file." #~ msgstr "لا يمكن كتابة الملÙ." -#~ msgid "Next" -#~ msgstr "التالي" - #~ msgid "Not found!" #~ msgstr "لم يوجد!" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index 2704d509eb..3d00e3450c 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -8547,6 +8547,13 @@ msgstr "ফনà§à¦Ÿ তà§à¦²à¦¤à§‡/লোডে সমসà§à¦¯à¦¾ হয়েঠmsgid "Invalid font size." msgstr "ফনà§à¦Ÿà§‡à¦° আকার অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯à¥¤" +#, fuzzy +#~ msgid "Previous" +#~ msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬" + +#~ msgid "Next" +#~ msgstr "পরবরà§à¦¤à§€" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "অকারà§à¦¯à¦•à¦° অà§à¦¯à¦¾à¦•à¦¶à¦¨ ('/' বা ':' ছাড়া কিছà§à¦‡ যাবে না)।" @@ -8576,9 +8583,6 @@ msgstr "ফনà§à¦Ÿà§‡à¦° আকার অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯à¥¤" #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° পথে engine.cfg তৈরি করা সমà§à¦à¦¬ হয়নি।" -#~ msgid "Next" -#~ msgstr "পরবরà§à¦¤à§€" - #~ msgid "Not found!" #~ msgstr "খà§à¦à¦œà§‡ পাওয়া যায়নি!" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 08d842a3c3..d2bffb0f84 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -2,23 +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. -# # BennyBeat <bennybeat@gmail.com>, 2017. # Javier Ocampos <xavier.ocampos@gmail.com>, 2018. # Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-05-17 23:48+0000\n" -"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" +"PO-Revision-Date: 2018-06-08 03:41+0000\n" +"Last-Translator: Roger Blanco Ribera <roger.blancoribera@gmail.com>\n" "Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/" "godot/ca/>\n" "Language: ca\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.0\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5693,9 +5691,8 @@ msgid "Options" msgstr "Opcions" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "Tens,Moltes,Diverses,Opcions!" +msgstr "Té,Moltes,Opcions" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -5981,9 +5978,8 @@ msgid "Imported Project" msgstr "Project importat" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nom del Projecte:" +msgstr "El nom del Projecte no és và lid." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6184,13 +6180,12 @@ msgid "Mouse Button" msgstr "Botó del ratolÃ" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" -"Nom d'acció no và lid. no pot estar buit ni contenir '/', ':', '=', '\\' o " -"'\"'" +"Nom d'acció no và lid. No pot estar buit ni contenir '/', ':', '=', '\\' o " +"'\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -8218,6 +8213,13 @@ msgstr "Error carregant lletra." msgid "Invalid font size." msgstr "La mida de la lletra no és và lida." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Pestanya Anterior" + +#~ msgid "Next" +#~ msgstr "Següent" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "L'Acció no és và lida (no es pot utilitzar ' / ' o ':')." @@ -8245,9 +8247,6 @@ msgstr "La mida de la lletra no és và lida." #~ msgstr "" #~ "No es pot trobat el el fitxer 'project.godot' en el camà del projecte." -#~ msgid "Next" -#~ msgstr "Següent" - #~ msgid "Not found!" #~ msgstr "No s'ha trobat!" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 6f46ba7535..1066bbad94 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -8124,6 +8124,13 @@ msgstr "Chyba nahrávánà fontu." msgid "Invalid font size." msgstr "Neplatná velikost fontu." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "PÅ™edchozà záložka" + +#~ msgid "Next" +#~ msgstr "DalÅ¡Ã" + #~ msgid "Can't contain '/' or ':'" #~ msgstr "Nesmà obsaovat '/' nebo ':'" @@ -8137,9 +8144,6 @@ msgstr "Neplatná velikost fontu." #~ msgid "Can't write file." #~ msgstr "Nelze zapsat soubor." -#~ msgid "Next" -#~ msgstr "DalÅ¡Ã" - #~ msgid "Not found!" #~ msgstr "Nenalezeno!" diff --git a/editor/translations/da.po b/editor/translations/da.po index 3b3f4b3e54..3b5854334a 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -8192,6 +8192,13 @@ msgstr "Error loading skrifttype." msgid "Invalid font size." msgstr "Ugyldig skriftstørrelse." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Forrige fane" + +#~ msgid "Next" +#~ msgstr "Næste" + #~ msgid "Can't contain '/' or ':'" #~ msgstr "Kan ikke indeholde '/' eller ':'" @@ -8205,9 +8212,6 @@ msgstr "Ugyldig skriftstørrelse." #~ msgid "Can't write file." #~ msgstr "Kan ikke skrive til fil." -#~ msgid "Next" -#~ msgstr "Næste" - #~ msgid "Not found!" #~ msgstr "Ikke fundet!" diff --git a/editor/translations/de.po b/editor/translations/de.po index c09b11bda1..d5d63f654b 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.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. -# # Alexander Mahr <alex.mahr@gmail.com>, 2016. # Andreas Esau <andreasesau@gmail.com>, 2016. # Andreas Haas <liu.gam3@gmail.com>, 2016. @@ -18,6 +17,7 @@ # Kim <github@aggsol.de>, 2017. # Metin Celik <metincelik88@gmail.com>, 2018. # Neicul <neicul@gmx.de>, 2018. +# nimradium <nimra242001@gmail.com>, 2018. # Oliver Ruehl <oliver@ruehldesign.co>, 2016-2017. # Paul-Vincent Roll <paviro@me.com>, 2016. # Peter Friedland <peter_friedland@gmx.de>, 2016. @@ -27,13 +27,12 @@ # Tim Schellenberg <smwleod@gmail.com>, 2017. # Timo Schwarzer <account@timoschwarzer.com>, 2016-2018. # viernullvier <hannes.breul+github@gmail.com>, 2016. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-05-24 15:37+0000\n" -"Last-Translator: Metin Celik <metincelik88@gmail.com>\n" +"PO-Revision-Date: 2018-06-19 19:38+0000\n" +"Last-Translator: nimradium <nimra242001@gmail.com>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" "Language: de\n" @@ -41,7 +40,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.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -332,7 +331,8 @@ msgstr "Optimieren" #: editor/animation_editor.cpp msgid "Select an AnimationPlayer from the Scene Tree to edit animations." msgstr "" -"AnimationPlayer aus dem Szenenbaum auswählen um Animationen zu bearbeiten." +"Wählen Sie einen AnimationPlayer aus dem Szenenbaum aus, um Animationen zu " +"bearbeiten." #: editor/animation_editor.cpp msgid "Key" @@ -2483,7 +2483,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." @@ -4047,7 +4047,7 @@ msgstr "Mesh hat keine Oberfläche von der Umrisse erzeugt werden könnten!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "Mesh primitive type ist nicht PRIMITIVE_TRIANGLES!" +msgstr "Der Mesh-Grundtyp ist nicht ist nicht PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" @@ -5737,9 +5737,8 @@ msgid "Options" msgstr "Optionen" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "Enthalten,Viele,Einige,Optionen!" +msgstr "Einstellungen" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -6024,9 +6023,8 @@ msgid "Imported Project" msgstr "Importiertes Projekt" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Projektname:" +msgstr "Ungültiger Projektname." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6230,13 +6228,12 @@ msgid "Mouse Button" msgstr "Maustaste" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" -"Ungültiger Aktionsname. Er kann weder leer sein, noch kann er '/', ':', '=', " -"'\\' oder '\"' enthalten" +"Ungültiger Aktionsname. Er kann weder leer sein noch ‚/‘, ‚:‘, ‚=‘, ‘\\‘ " +"oder ‚\"‘ enthalten." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -8287,6 +8284,13 @@ msgstr "Fehler beim Laden der Schriftart." msgid "Invalid font size." msgstr "Ungültige Schriftgröße." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Vorheriger Tab" + +#~ msgid "Next" +#~ msgstr "Nächste" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "" #~ "Ungültiger Name für Aktion (alle Zeichen außer ‚/‘ und ‚:‘ möglich)." @@ -8313,9 +8317,6 @@ msgstr "Ungültige Schriftgröße." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "project.godot konnte nicht im Projektpfad gefunden werden." -#~ msgid "Next" -#~ msgstr "Nächste" - #~ msgid "Not found!" #~ msgstr "Nicht gefunden!" diff --git a/editor/translations/el.po b/editor/translations/el.po index ad2eb41c4d..b3275b4647 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -8260,6 +8260,13 @@ msgstr "Σφάλμα κατά την φόÏτωση της γÏαμματοσεΠmsgid "Invalid font size." msgstr "Μη ÎγκυÏο μÎγεθος γÏαμματοσειÏάς." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Î ÏοηγοÏμενη καÏÏ„Îλα" + +#~ msgid "Next" +#~ msgstr "Επόμενο" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Μη ÎγκυÏη ενÎÏγεια (Όλα επιτÏÎποντα εκτός από το '/' και το ':')." @@ -8287,9 +8294,6 @@ msgstr "Μη ÎγκυÏο μÎγεθος γÏαμματοσειÏάς." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Δεν βÏÎθηκε το project.godot στη διαδÏομή του ÎÏγου." -#~ msgid "Next" -#~ msgstr "Επόμενο" - #~ msgid "Not found!" #~ msgstr "Δεν βÏÎθηκε!" diff --git a/editor/translations/es.po b/editor/translations/es.po index 405130c465..89118d2501 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.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. -# # Addiel Lucena Perez <addiell2017@gmail.com>, 2017. # Aleix Sanchis <aleixsanchis@hotmail.com>, 2017, 2018. # Alejandro Alvarez <eliluminado00@gmail.com>, 2017. @@ -23,19 +22,19 @@ # Lonsfor <lotharw@protonmail.com>, 2017-2018. # Mario Nachbaur <manachbaur@gmail.com>, 2018. # Oscar Carballal <oscar.carballal@protonmail.com>, 2017-2018. +# R. Joshua Seville <rjoshua@protonmail.com>, 2018. # Rabid Orange <theorangerabid@gmail.com>, 2017, 2018. # Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018. # Sebastian Silva <sebastian@fuentelibre.org>, 2016. # Swyter <swyterzone@gmail.com>, 2016-2017. # Vazquinhos <vazquinhos@gmail.com>, 2018. # Yovani Damián <blackblex@gmail.com>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-06-01 00:44+0000\n" -"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" +"PO-Revision-Date: 2018-06-22 08:31+0000\n" +"Last-Translator: R. Joshua Seville <rjoshua@protonmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -43,7 +42,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" @@ -269,7 +268,7 @@ msgstr "Zoom de Animación." #: editor/animation_editor.cpp msgid "Length (s):" -msgstr "Duración (seg):" +msgstr "Duración (segs.):" #: editor/animation_editor.cpp msgid "Animation length (in seconds)." @@ -548,7 +547,7 @@ msgstr "Cambiar" #: editor/create_dialog.cpp msgid "Create New %s" -msgstr "Crear nuevo %s" +msgstr "Crear Nuevo %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -738,7 +737,7 @@ msgstr "Contribuidores de Godot" #: editor/editor_about.cpp msgid "Project Founders" -msgstr "Fundadores del proyecto" +msgstr "Fundadores del Proyecto" #: editor/editor_about.cpp msgid "Lead Developer" @@ -1978,7 +1977,7 @@ msgstr "Proyecto" #: editor/editor_node.cpp msgid "Project Settings" -msgstr "Ajustes del proyecto" +msgstr "Ajustes del Proyecto" #: editor/editor_node.cpp msgid "Run Script" @@ -2089,7 +2088,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Editor" -msgstr "El editor" +msgstr "Editor" #: editor/editor_node.cpp editor/settings_config_dialog.cpp msgid "Editor Settings" @@ -2144,7 +2143,7 @@ msgstr "Acerca de" #: editor/editor_node.cpp msgid "Play the project." -msgstr "Inicia el proyecto para poder jugarlo." +msgstr "Reproducir el proyecto." #: editor/editor_node.cpp msgid "Play" @@ -3496,7 +3495,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" -msgstr "Calculando «lightmaps»" +msgstr "Calculando Lightmaps" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -3519,7 +3518,7 @@ msgstr "Paso de CuadrÃcula:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" -msgstr "Desplazamiento de rotación:" +msgstr "Desplazamiento de Rotación:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Step:" @@ -4593,7 +4592,7 @@ msgstr "¡El portapapeles de recursos está vacÃo!" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Open in Editor" -msgstr "Abrir en el editor" +msgstr "Abrir en el Editor" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_editor.cpp @@ -5341,7 +5340,7 @@ msgstr "Modo escalado (R)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Coords" -msgstr "Coordenadas Locales" +msgstr "Local Coords (Coordenadas Locales)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Space Mode (%s)" @@ -5741,9 +5740,8 @@ msgid "Options" msgstr "Opciones" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "¡Tienes,Muchas,Y,Variadas,Opciones!" +msgstr "Tienes, Muchas, Opciones" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -6027,12 +6025,11 @@ msgstr "Por favor elija una carpeta vacÃa." #: editor/project_manager.cpp msgid "Imported Project" -msgstr "Proyecto importado" +msgstr "Proyecto Importado" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nombre del proyecto:" +msgstr "Nombre de Proyecto Inválido." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6076,11 +6073,11 @@ msgstr "Renombrar proyecto" #: editor/project_manager.cpp msgid "New Game Project" -msgstr "Nuevo proyecto de juego" +msgstr "Nuevo Proyecto de Juego" #: editor/project_manager.cpp msgid "Import Existing Project" -msgstr "Importar proyecto existente" +msgstr "Importar Proyecto Existente" #: editor/project_manager.cpp msgid "Import & Edit" @@ -6088,7 +6085,7 @@ msgstr "Importar y editar" #: editor/project_manager.cpp msgid "Create New Project" -msgstr "Crear proyecto nuevo" +msgstr "Crear Nuevo Proyecto" #: editor/project_manager.cpp msgid "Create & Edit" @@ -6096,7 +6093,7 @@ msgstr "Crear y editar" #: editor/project_manager.cpp msgid "Install Project:" -msgstr "Instalar proyecto:" +msgstr "Instalar Proyecto:" #: editor/project_manager.cpp msgid "Install & Edit" @@ -6104,7 +6101,7 @@ msgstr "Instalar y editar" #: editor/project_manager.cpp msgid "Project Name:" -msgstr "Nombre del proyecto:" +msgstr "Nombre del Proyecto:" #: editor/project_manager.cpp msgid "Create folder" @@ -6112,7 +6109,7 @@ msgstr "Crear carpeta" #: editor/project_manager.cpp msgid "Project Path:" -msgstr "Ruta del proyecto:" +msgstr "Ruta del Proyecto:" #: editor/project_manager.cpp msgid "Browse" @@ -6120,7 +6117,7 @@ msgstr "Examinar" #: editor/project_manager.cpp msgid "Unnamed Project" -msgstr "Proyecto sin nombre" +msgstr "Proyecto sin Nombre" #: editor/project_manager.cpp msgid "Can't open project" @@ -6137,8 +6134,8 @@ msgid "" "the \"Application\" category." msgstr "" "No hay una escena principal definida para ejecutar el proyecto.\n" -"Por favor elija la escena principal en \"Ajustes del proyecto\" en la " -"categorÃa \"Aplicación\"." +"Por favor elija la escena principal en \"Ajustes del Proyecto\" en la " +"categorÃa \"Application\"." #: editor/project_manager.cpp msgid "" @@ -6155,8 +6152,8 @@ msgstr "¿Seguro que quieres ejecutar más de un proyecto?" #: editor/project_manager.cpp msgid "Remove project from the list? (Folder contents will not be modified)" msgstr "" -"¿Quieres quitar proyecto de la lista? (El contenido de la carpeta no se " -"modificarán)" +"¿Quieres quitar el proyecto de la lista? (El contenido de la carpeta no se " +"modificará)" #: editor/project_manager.cpp msgid "" @@ -6193,7 +6190,7 @@ msgstr "Selecciona la carpeta a analizar" #: editor/project_manager.cpp msgid "New Project" -msgstr "Proyecto nuevo" +msgstr "Nuevo Proyecto" #: editor/project_manager.cpp msgid "Templates" @@ -6237,13 +6234,12 @@ msgid "Mouse Button" msgstr "Botón del ratón" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" -"Nombre de acción inválido. No puede estar vacÃo o contener '/', ':', '=', " -"'\\' or '\"'" +"Nombre de acción inválido. No puede estar vacÃo ni contener '/', ':', '=', " +"'\\' o '\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -6832,7 +6828,7 @@ msgid "" "Instance a scene file as a Node. Creates an inherited scene if no root node " "exists." msgstr "" -"Instanciar un archivo de escena como Nodo. Crear una escena heredada si no " +"Instanciar un archivo de escena como Nodo. Crea una escena heredada si no " "existe ningún nodo raÃz." #: editor/scene_tree_dock.cpp @@ -8253,8 +8249,8 @@ msgid "" "Default Environment as specified in Project Settings (Rendering -> " "Environment -> Default Environment) could not be loaded." msgstr "" -"El entorno especificado por defecto en los Ajustes del Proyecto (Renderizado " -"-> Ventana -> Entorno por Defecto) no se ha podido cargar." +"El Entorno por Defecto como se especifica en los Ajustes del Proyecto " +"(Rendering -> Environment -> Default Environment) no se ha podido cargar." #: scene/main/viewport.cpp msgid "" @@ -8284,6 +8280,13 @@ msgstr "Error al cargar la tipografÃa." msgid "Invalid font size." msgstr "Tamaño de tipografÃa incorrecto." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Pestaña anterior" + +#~ msgid "Next" +#~ msgstr "Siguiente" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "La acción no es correcta (no puedes utilizar «/» o «:»)." @@ -8310,9 +8313,6 @@ msgstr "Tamaño de tipografÃa incorrecto." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "No se encontró project.godot en la ruta del proyecto." -#~ msgid "Next" -#~ msgstr "Siguiente" - #~ msgid "Not found!" #~ msgstr "¡No se ha encontrado!" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 3514b6b2d9..64ee2404f1 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -2,17 +2,15 @@ # 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. -# # Diego López <diegodario21@gmail.com>, 2017. # Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018. # Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018. # Sebastian Silva <sebastian@sugarlabs.org>, 2016. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-05-03 14:00+0000\n" +"PO-Revision-Date: 2018-06-06 13:28+0000\n" "Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" @@ -21,7 +19,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.0\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5709,9 +5707,8 @@ msgid "Options" msgstr "Opciones" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "Tienes, Muchas, Variadas, Opciones!" +msgstr "Tiene,Muchas,Opciones" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -6000,9 +5997,8 @@ msgid "Imported Project" msgstr "Proyecto Importado" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nombre del Proyecto:" +msgstr "Nombre de Proyecto Inválido." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6207,13 +6203,12 @@ msgid "Mouse Button" msgstr "Botón de Mouse" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" "Nombre de acción inválido. No puede estar vacÃo o contener '/', ':', '=', " -"'\\' or '\"'" +"'\\' o '\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -8244,6 +8239,13 @@ msgstr "Error cargando tipografÃa." msgid "Invalid font size." msgstr "Tamaño de tipografÃa inválido." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Pestaña anterior" + +#~ msgid "Next" +#~ msgstr "Siguiente" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Acción Invalida (cualquier cosa va menos '/' o ':')." @@ -8270,9 +8272,6 @@ msgstr "Tamaño de tipografÃa inválido." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "No se pudo obtener project.godot en la ruta de proyecto." -#~ msgid "Next" -#~ msgstr "Siguiente" - #~ msgid "Not found!" #~ msgstr "No se encontró!" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index be57fa2fca..f674ef99cc 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -8185,15 +8185,19 @@ msgstr "خطای بارگذاری قلم." msgid "Invalid font size." msgstr "اندازهٔ قلم نامعتبر." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "زبانه قبلی" + +#~ msgid "Next" +#~ msgstr "بعدی" + #~ msgid "Can't contain '/' or ':'" #~ msgstr "نمی‌تواند شامل '/' یا ':' باشد" #~ msgid "Can't write file." #~ msgstr "ناتوان در نوشتن پرونده." -#~ msgid "Next" -#~ msgstr "بعدی" - #~ msgid "Not found!" #~ msgstr "چیزی یاÙت نشد!" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 091effca5d..f80efffd42 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -2,19 +2,17 @@ # 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. -# # basse <basse@roiske.org>, 2017. -# Bastian Salmela <bastian.salmela@gmail.com>, 2017. +# Bastian Salmela <bastian.salmela@gmail.com>, 2017, 2018. # ekeimaja <ekeimaja@gmail.com>, 2017-2018. # Jarmo Riikonen <amatrelan@gmail.com>, 2017. # Nuutti Varvikko <nvarvikko@gmail.com>, 2018. # Sami Lehtilä <sami.lehtila@gmail.com>, 2018. # Tapani Niemi <tapani.niemi@kapsi.fi>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-06-05 19:27+0000\n" +"PO-Revision-Date: 2018-06-14 20:37+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -22,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\n" +"X-Generator: Weblate 3.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -38,11 +36,11 @@ msgstr "Animaatio: muuta avainruudun aikaa" #: editor/animation_editor.cpp msgid "Anim Change Transition" -msgstr "Vaihda animaation siirtymää" +msgstr "Animaatio: muuta siirtymää" #: editor/animation_editor.cpp msgid "Anim Change Transform" -msgstr "Animaatio: muuta siirtymää" +msgstr "Animaatio: muuta muunnosta" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Value" @@ -50,7 +48,7 @@ msgstr "Animaatio: muuta avainruudun arvoa" #: editor/animation_editor.cpp msgid "Anim Change Call" -msgstr "Animaatio: Muuta kutsua" +msgstr "Animaatio: muuta kutsua" #: editor/animation_editor.cpp msgid "Anim Add Track" @@ -70,7 +68,7 @@ msgstr "Siirrä animaatioraita alas" #: editor/animation_editor.cpp msgid "Remove Anim Track" -msgstr "Poista animaation raita" +msgstr "Poista animaatioraita" #: editor/animation_editor.cpp msgid "Set Transitions to:" @@ -78,24 +76,23 @@ msgstr "Aseta siirtymät:" #: editor/animation_editor.cpp msgid "Anim Track Rename" -msgstr "Nimeä animaatioraita uudelleen" +msgstr "Animaatioraita: nimeä uudelleen" #: editor/animation_editor.cpp msgid "Anim Track Change Interpolation" -msgstr "Animaatio: Vaihda raidan interpolaatiota" +msgstr "Animaatioraita: muuta interpolaatiota" #: editor/animation_editor.cpp msgid "Anim Track Change Value Mode" -msgstr "Animaatio: Muuta avainta tila" +msgstr "Animaatioraita: muuta arvon tilaa" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Track Change Wrap Mode" -msgstr "Animaatio: Muuta toisto tila" +msgstr "Animaatioraita: muuta kierron tilaa" #: editor/animation_editor.cpp msgid "Edit Node Curve" -msgstr "Muokkaa noden käyrää" +msgstr "Muokkaa solmun käyrää" #: editor/animation_editor.cpp msgid "Edit Selection Curve" @@ -103,16 +100,16 @@ msgstr "Muokkaa valinnan käyrää" #: editor/animation_editor.cpp msgid "Anim Delete Keys" -msgstr "Poista avaimet" +msgstr "Animaatio: poista avaimet" #: editor/animation_editor.cpp editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "Monista valinta" +msgstr "Kahdenna valinta" #: editor/animation_editor.cpp msgid "Duplicate Transposed" -msgstr "Monista käänteisesti" +msgstr "Kahdenna käänteisesti" #: editor/animation_editor.cpp msgid "Remove Selection" @@ -132,11 +129,11 @@ msgstr "Liipaisin" #: editor/animation_editor.cpp msgid "Anim Add Key" -msgstr "Lisää avain" +msgstr "Animaatio: lisää avain" #: editor/animation_editor.cpp msgid "Anim Move Keys" -msgstr "SIirrä avaimia" +msgstr "Animaatio: siirrä avaimia" #: editor/animation_editor.cpp msgid "Scale Selection" @@ -193,7 +190,7 @@ msgstr "Siivoa animaatio" #: editor/animation_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "Luo UUSI raita %lle ja lisää avain?" +msgstr "Luo kohteelle %s UUSI raita ja lisää avain?" #: editor/animation_editor.cpp msgid "Create %d NEW tracks and insert keys?" @@ -209,7 +206,7 @@ msgstr "Luo" #: editor/animation_editor.cpp msgid "Anim Create & Insert" -msgstr "Animaatio: Luo ja lisää" +msgstr "Animaatio: luo ja lisää" #: editor/animation_editor.cpp msgid "Anim Insert Track & Key" @@ -221,7 +218,7 @@ msgstr "Animaatio: Lisää avain" #: editor/animation_editor.cpp msgid "Change Anim Len" -msgstr "Vaihda animaation pituutta" +msgstr "Muuta animaation pituutta" #: editor/animation_editor.cpp msgid "Change Anim Loop" @@ -233,7 +230,7 @@ msgstr "Animaatio: Luo tyypitetty arvoavain" #: editor/animation_editor.cpp msgid "Anim Insert" -msgstr "Animaatio: Lisää" +msgstr "Animaatio: lisää" #: editor/animation_editor.cpp msgid "Anim Scale Keys" @@ -257,7 +254,7 @@ msgstr "Animaation pituus (sekunteina)." #: editor/animation_editor.cpp msgid "Step (s):" -msgstr "Askellus:" +msgstr "Askellus (s):" #: editor/animation_editor.cpp msgid "Cursor step snap (in seconds)." @@ -265,7 +262,7 @@ msgstr "Kohdistimen askelrajoitin (sekunneissa)." #: editor/animation_editor.cpp msgid "Enable/Disable looping in animation." -msgstr "Ota käyttöön/poista käytöstä animaation toisto." +msgstr "Ota käyttöön tai poista käytöstä animaation toisto." #: editor/animation_editor.cpp msgid "Add new tracks." @@ -289,7 +286,7 @@ msgstr "Raidan työkalut" #: editor/animation_editor.cpp msgid "Enable editing of individual keys by clicking them." -msgstr "Mahdollistaa avainten muokkaamisen klikkaamalla." +msgstr "Mahdollistaa avainten muokkaamisen napsauttamalla niitä." #: editor/animation_editor.cpp msgid "Anim. Optimizer" @@ -301,11 +298,11 @@ msgstr "Max. lineaarinen virhe:" #: editor/animation_editor.cpp msgid "Max. Angular Error:" -msgstr "Max. Kulmavirhe:" +msgstr "Max. kulmavirhe:" #: editor/animation_editor.cpp msgid "Max Optimizable Angle:" -msgstr "Max. Optimoitava kulma:" +msgstr "Max. optimoitava kulma:" #: editor/animation_editor.cpp msgid "Optimize" @@ -313,7 +310,7 @@ msgstr "Optimoi" #: editor/animation_editor.cpp msgid "Select an AnimationPlayer from the Scene Tree to edit animations." -msgstr "Valitse AnimationPlayer Scenepuusta muokataksesi animaatioita." +msgstr "Valitse AnimationPlayer skenen puusta muokataksesi animaatioita." #: editor/animation_editor.cpp msgid "Key" @@ -329,7 +326,7 @@ msgstr "Skaalaussuhde:" #: editor/animation_editor.cpp msgid "Call Functions in Which Node?" -msgstr "Mistä nodesta kutsutaan funktiota?" +msgstr "Mistä solmusta kutsutaan funktiota?" #: editor/animation_editor.cpp msgid "Remove invalid keys" @@ -345,7 +342,7 @@ msgstr "Siivoa kaikki animaatiot" #: editor/animation_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "Siivoa animaatio(t) (EI VOI KUMOTA)" +msgstr "Siivoa animaatio(t) (EI VOI KUMOTA!)" #: editor/animation_editor.cpp msgid "Clean-Up" @@ -369,7 +366,7 @@ msgstr "Mene riville" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "RIvinumero:" +msgstr "Rivinumero:" #: editor/code_editor.cpp msgid "No Matches" @@ -417,23 +414,23 @@ msgstr "Rivi:" #: editor/code_editor.cpp msgid "Col:" -msgstr "Kolumni:" +msgstr "Sarake:" #: editor/connections_dialog.cpp msgid "Method in target Node must be specified!" -msgstr "Kohdenoden metodi täytyy määrittää!" +msgstr "Kohdesolmun metodi täytyy määrittää!" #: editor/connections_dialog.cpp msgid "" "Target method not found! Specify a valid method or attach a script to target " "Node." msgstr "" -"Kohde metodia ei löytynyt! Määrittele voimassa oleva metodi tai kiinnitä " -"skripti nodeen." +"Kohdemetodia ei löytynyt! Määrittele voimassa oleva metodi tai kiinnitä " +"skripti solmuun." #: editor/connections_dialog.cpp msgid "Connect To Node:" -msgstr "Yhdistä Nodeen:" +msgstr "Yhdistä solmuun:" #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -458,7 +455,7 @@ msgstr "Ylimääräiset argumentit:" #: editor/connections_dialog.cpp msgid "Path to Node:" -msgstr "Polku Nodeen:" +msgstr "Polku solmuun:" #: editor/connections_dialog.cpp msgid "Make Function" @@ -492,7 +489,7 @@ msgstr "Yhdistä" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" -msgstr "Yhdistä '%s' '%s':n" +msgstr "Yhdistä solmu '%s' solmuun '%s'" #: editor/connections_dialog.cpp msgid "Connecting Signal:" @@ -500,7 +497,7 @@ msgstr "Yhdistävä signaali:" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" -msgstr "Katkaise yhteys '%s' '%s':n" +msgstr "Katkaise yhteys solmusta '%s' solmuun '%s'" #: editor/connections_dialog.cpp msgid "Connect..." @@ -569,7 +566,7 @@ msgid "" "Scene '%s' is currently being edited.\n" "Changes will not take effect unless reloaded." msgstr "" -"Sceneä '%s' muokataan parhaillaan.\n" +"Skeneä '%s' muokataan parhaillaan.\n" "Muutokset tulevat voimaan vasta päivityksen jälkeen." #: editor/dependency_editor.cpp @@ -646,7 +643,7 @@ msgstr "Virhe ladatessa:" #: editor/dependency_editor.cpp msgid "Scene failed to load due to missing dependencies:" -msgstr "Scenen lataaminen epäonnistui puuttuvan riippuvuuden takia:" +msgstr "Skenen lataaminen epäonnistui puuttuvan riippuvuuden takia:" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Open Anyway" @@ -665,9 +662,8 @@ msgid "Errors loading!" msgstr "Virheitä ladatessa!" #: editor/dependency_editor.cpp -#, fuzzy msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "Poista pysyvästi %d ? (Ei voi kumota!)" +msgstr "Poista pysyvästi %d kohdetta? (Ei voi kumota!)" #: editor/dependency_editor.cpp msgid "Owns" @@ -678,9 +674,8 @@ msgid "Resources Without Explicit Ownership:" msgstr "Resurssit, joilla ei ole selvää omistajaa:" #: editor/dependency_editor.cpp editor/editor_node.cpp -#, fuzzy msgid "Orphan Resource Explorer" -msgstr "Orpojen resurssien selain" +msgstr "Irrallisten resurssien hallinta" #: editor/dependency_editor.cpp msgid "Delete selected files?" @@ -736,27 +731,27 @@ msgstr "Tekijät" #: editor/editor_about.cpp msgid "Platinum Sponsors" -msgstr "Platinum sponsorit" +msgstr "Platinasponsorit" #: editor/editor_about.cpp msgid "Gold Sponsors" -msgstr "Kulta sponsorit" +msgstr "Kultasponsorit" #: editor/editor_about.cpp msgid "Mini Sponsors" -msgstr "Mini sponsorit" +msgstr "Minisponsorit" #: editor/editor_about.cpp msgid "Gold Donors" -msgstr "Kulta lahjoittajat" +msgstr "Kultalahjoittajat" #: editor/editor_about.cpp msgid "Silver Donors" -msgstr "Hopea lahjoittajat" +msgstr "Hopealahjoittajat" #: editor/editor_about.cpp msgid "Bronze Donors" -msgstr "Pronssi lahjoittajat" +msgstr "Pronssilahjoittajat" #: editor/editor_about.cpp msgid "Donors" @@ -779,8 +774,8 @@ msgid "" msgstr "" "Godot moottori käyttää useita kolmannen osapuolen ilmaisia ja avoimia " "kirjastoja, jotka kaikki ovat yhteensopivia sen MIT lisenssin kanssa. " -"Seuraava tyhjentävä listaus sisältää kaikki tälläiset kolmannen osapuolen " -"komponentit ja niiden vastaavat copyright ja lisenssi määritelmät." +"Seuraava tyhjentävä listaus sisältää kaikki tällaiset kolmannen osapuolen " +"komponentit ja niiden vastaavat tekijänoikeustiedot ja käyttöoikeusehdot." #: editor/editor_about.cpp msgid "All Components" @@ -796,7 +791,7 @@ msgstr "Lisenssit" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Error opening package file, not in zip format." -msgstr "Virhe avattaessa pakettia, ei zip muotoinen." +msgstr "Virhe avattaessa pakettitiedostoa, ei zip-muodossa." #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" @@ -830,7 +825,7 @@ msgstr "Lisää efekti" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" -msgstr "Nimeä väylä uudelleen" +msgstr "Nimeä ääniväylä uudelleen" #: editor/editor_audio_buses.cpp msgid "Change Audio Bus Volume" @@ -919,7 +914,7 @@ msgstr "Monista ääniväylä" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "Palauta äänenvoimakkuus" +msgstr "Palauta väylän äänenvoimakkuus" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" @@ -1014,18 +1009,16 @@ msgid "File does not exist." msgstr "Tiedostoa ei ole olemassa." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Not in resource path." msgstr "Ei löytynyt resurssipolusta." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Add AutoLoad" msgstr "Lisää automaattisesti ladattava" #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "Automaattisesti ladattava '%s' löytyi jo!" +msgstr "Automaattisesti ladattava '%s' on jo olemassa!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" @@ -1033,10 +1026,9 @@ msgstr "Nimeä automaattisesti ladattava uudelleen" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" -msgstr "" +msgstr "Aseta globaalien automaattilataus" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Move Autoload" msgstr "Siirrä automaattisesti ladattavaa" @@ -1059,7 +1051,7 @@ msgstr "Polku:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" -msgstr "Noden nimi:" +msgstr "Solmun nimi:" #: editor/editor_autoload_settings.cpp editor/editor_profiler.cpp #: editor/project_manager.cpp editor/settings_config_dialog.cpp @@ -1067,9 +1059,8 @@ msgid "Name" msgstr "Nimi" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Singleton" -msgstr "Ainokainen" +msgstr "Singleton" #: editor/editor_data.cpp msgid "Updating Scene" @@ -1150,7 +1141,7 @@ msgstr "Näytä tiedostonhallinnassa" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "New Folder..." -msgstr "Luo kansio..." +msgstr "Uusi kansio..." #: editor/editor_file_dialog.cpp msgid "Refresh" @@ -1207,19 +1198,16 @@ msgid "Toggle Hidden Files" msgstr "Näytä piilotiedostot" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle Favorite" -msgstr "Näytä suosikit" +msgstr "Aseta suosikiksi" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle Mode" -msgstr "Näytä/piilota" +msgstr "Aseta tila" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Focus Path" -msgstr "Kohdista polku" +msgstr "Kohdista polkuun" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" @@ -1235,7 +1223,7 @@ msgstr "Siirry yläkansioon" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" -msgstr "Hakemistot & tiedostot:" +msgstr "Hakemistot ja tiedostot:" #: editor/editor_file_dialog.cpp msgid "Preview:" @@ -1252,11 +1240,11 @@ msgstr "Käytä sopivaa tiedostopäätettä." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "" +msgstr "Selaa lähdetiedostoja" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" -msgstr "Tuodaan (uudelleen) Assetteja" +msgstr "Tuodaan (uudelleen) assetteja" #: editor/editor_help.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp @@ -1273,7 +1261,7 @@ msgstr "Etsi luokkia" #: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Top" -msgstr "Pinta" +msgstr "Yläpuoli" #: editor/editor_help.cpp editor/property_editor.cpp msgid "Class:" @@ -1284,9 +1272,8 @@ msgid "Inherits:" msgstr "Perii:" #: editor/editor_help.cpp -#, fuzzy msgid "Inherited by:" -msgstr "Peritty:" +msgstr "Perivät:" #: editor/editor_help.cpp msgid "Brief Description:" @@ -1371,8 +1358,8 @@ msgid "" "There is currently no description for this property. Please help us by " "[color=$color][url=$url]contributing one[/url][/color]!" msgstr "" -"Tälle ei vielä löydy kuvailua. Voit auttaa meitä [color=$color][url=" -"$url]kirjoittamalla sellaisen[/url][/color]!" +"Tälle ominaisuudelle ei vielä löydy kuvausta. Voit auttaa meitä [color=" +"$color][url=$url]kirjoittamalla sellaisen[/url][/color]!" #: editor/editor_help.cpp msgid "Methods" @@ -1387,7 +1374,7 @@ msgid "" "There is currently no description for this method. Please help us by [color=" "$color][url=$url]contributing one[/url][/color]!" msgstr "" -"Tälle metodille ei vielä löydy kuvailua. Voit auttaa meitä [color=$color]" +"Tälle metodille ei vielä löydy kuvausta. Voit auttaa meitä [color=$color]" "[url=$url]kirjoittamalla sellaisen[/url][/color]!" #: editor/editor_help.cpp @@ -1464,7 +1451,7 @@ msgstr "Virhe ladattaessa tiedostoa '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "Tallennetaan sceneä" +msgstr "Tallennetaan skeneä" #: editor/editor_node.cpp msgid "Analyzing" @@ -1492,19 +1479,19 @@ msgstr "Resurssin lataaminen epäonnistui." #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "MalliKirjastojen yhdistäminen ei onnistunut!" +msgstr "Ei voitu ladata MeshLibrary resurssia yhdistämistä varten!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "Virhe tallennettaessa MeshLibrarya!" +msgstr "Virhe tallennettaessa MeshLibrary resurssia!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "Ei voida ladata tilesetiä tuontia varten!" +msgstr "Ei voida ladata ruutuvalikoimaa yhdistämistä varten!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "Virhe tallennettaessa tilesetiä!" +msgstr "Virhe tallennettaessa ruutuvalikoimaa!" #: editor/editor_node.cpp msgid "Error trying to save layout!" @@ -1512,16 +1499,15 @@ msgstr "Virhe tallennettaessa asettelua!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "Editorin oletusulkoasu ylikirjoitettu." +msgstr "Editorin oletusasettelu ylikirjoitettu." #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "Layoutin nimeä ei löytynyt!" +msgstr "Asettelun nimeä ei löytynyt!" #: editor/editor_node.cpp -#, fuzzy msgid "Restored default layout to base settings." -msgstr "Palautettiin oletusasettelu alkuperäiseen muotoonsa." +msgstr "Palautettiin oletusasettelu alkuperäisiin asetuksiinsa." #: editor/editor_node.cpp msgid "" @@ -1530,7 +1516,7 @@ msgid "" "understand this workflow." msgstr "" "Tämä resurssi kuuluu tuotuun skeneen, joten sitä ei voi suoraan muokata.\n" -"Lue ohjeet skenejen tuomisesta, jotta ymmärrät paremmin tämän työkulun." +"Lue ohjeet skenejen tuomisesta, jotta ymmärrät paremmin tämän työnkulun." #: editor/editor_node.cpp msgid "" @@ -1596,7 +1582,6 @@ msgid "Copy Resource" msgstr "Kopioi resurssi" #: editor/editor_node.cpp -#, fuzzy msgid "Make Built-In" msgstr "Tee sisäänrakennettu" @@ -1610,7 +1595,7 @@ msgstr "Avaa ohjeessa" #: editor/editor_node.cpp msgid "There is no defined scene to run." -msgstr "Suoritettavaa sceneä ei ole määritetty." +msgstr "Suoritettavaa skeneä ei ole määritetty." #: editor/editor_node.cpp msgid "" @@ -1627,8 +1612,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Valittua sceneä '%s' ei ole olemassa, valitse kelvollinen?\n" -"Voit muuttaa sitä myöhemmin projektin asetuksista." +"Valittua skeneä '%s' ei ole olemassa, valitse kelvollinen?\n" +"Voit muuttaa sitä myöhemmin projektin asetuksista, kohdasta 'Application'." #: editor/editor_node.cpp msgid "" @@ -1636,13 +1621,13 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Valittu scene '%s' ei ole scene-tiedosto, valitse kelvollinen?\n" -"Voit muuttaa sitä myöhemmin projektin asetuksista." +"Valittu skene '%s' ei ole scene-tiedosto, valitse kelvollinen?\n" +"Voit muuttaa sitä myöhemmin projektin asetuksista, kohdasta 'Application'." #: editor/editor_node.cpp msgid "Current scene was never saved, please save it prior to running." msgstr "" -"Nykyistä sceneä ei ole vielä tallennettu. Tallenna se ennen suorittamista." +"Nykyistä skeneä ei ole vielä tallennettu. Tallenna se ennen suorittamista." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -1650,19 +1635,19 @@ msgstr "Aliprosessia ei voitu käynnistää!" #: editor/editor_node.cpp msgid "Open Scene" -msgstr "Avaa scene" +msgstr "Avaa skene" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "Avaa kantascene" +msgstr "Avaa kantaskene" #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "Nopea skenen avaus..." +msgstr "Skenen pika-avaus..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Nopea skriptin avaus..." +msgstr "Skriptin pika-avaus..." #: editor/editor_node.cpp msgid "Save & Close" @@ -1674,7 +1659,7 @@ msgstr "Tallennetaanko muutokset tiedostoon '%s' ennen sulkemista?" #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "Tallenna scene nimellä..." +msgstr "Tallenna skene nimellä..." #: editor/editor_node.cpp msgid "No" @@ -1686,35 +1671,35 @@ msgstr "Kyllä" #: editor/editor_node.cpp msgid "This scene has never been saved. Save before running?" -msgstr "Tätä sceneä ei ole koskaan tallennettu. Tallenna ennen suorittamista?" +msgstr "Tätä skeneä ei ole koskaan tallennettu. Tallenna ennen suorittamista?" #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." -msgstr "Tätä toimintoa ei voi tehdä ilman sceneä." +msgstr "Tätä toimintoa ei voi tehdä ilman skeneä." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "Vie malli kirjasto" +msgstr "Vie mesh-kirjasto" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "Tätä toimintoa ei voida suorittaa ilman päänodea." +msgstr "Tätä toimintoa ei voida suorittaa ilman juurisolmua." #: editor/editor_node.cpp msgid "Export Tile Set" -msgstr "Vie tileset" +msgstr "Vie ruutuvalikoima" #: editor/editor_node.cpp msgid "This operation can't be done without a selected node." -msgstr "Tätä toimintoa ei voi tehdä ilman valittua nodea." +msgstr "Tätä toimintoa ei voi tehdä ilman valittua solmua." #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "Nykyistä sceneä ei ole tallennettu. Avaa joka tapauksessa?" +msgstr "Nykyistä skeneä ei ole tallennettu. Avaa joka tapauksessa?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "Ei voida uudelleen ladata skeneä jota ei ole vielä tallennettu." +msgstr "Ei voida ladata uudelleen skeneä, jota ei ole koskaan tallennettu." #: editor/editor_node.cpp msgid "Revert" @@ -1726,7 +1711,7 @@ msgstr "Tätä toimintoa ei voida peruttaa. Palauta joka tapauksessa?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "Nopea skenen käynnistys..." +msgstr "Skenen pikakäynnistys..." #: editor/editor_node.cpp msgid "Quit" @@ -1764,7 +1749,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "Valitse pääscene" +msgstr "Valitse pääskene" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." @@ -1793,8 +1778,8 @@ msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" -"Scene '%s' tuotiin automaattisesti, joten sitä ei voida muokata.\n" -"Muokataksesi sitä voit luoda uuden perityn Scenen." +"Skene '%s' tuotiin automaattisesti, joten sitä ei voida muokata.\n" +"Muokataksesi sitä voit luoda uuden perityn skenen." #: editor/editor_node.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -1806,20 +1791,20 @@ msgid "" "Error loading scene, it must be inside the project path. Use 'Import' to " "open the scene, then save it inside the project path." msgstr "" -"Virhe Scenen latauksessa, sen täytyy sijaita projektin polussa. Käytä 'Tuo' -" -"toimintoa avataksesi Scenen ja tallenna se projektin polkuun." +"Virhe skenen latauksessa, sen täytyy sijaita projektin polussa. Käytä 'Tuo'-" +"toimintoa avataksesi skenen ja tallenna se projektin polkuun." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "Scenellä '%s' on rikkinäisiä riippuvuuksia:" +msgstr "Skenellä '%s' on rikkinäisiä riippuvuuksia:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" -msgstr "Tyhjennä viimeiset scenet" +msgstr "Tyhjennä viimeisimmät skenet" #: editor/editor_node.cpp msgid "Save Layout" -msgstr "Tallenna asettelut" +msgstr "Tallenna asettelu" #: editor/editor_node.cpp msgid "Delete Layout" @@ -1832,7 +1817,7 @@ msgstr "Oletus" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "Vaihda Scenen välilehteä" +msgstr "Vaihda skenen välilehteä" #: editor/editor_node.cpp msgid "%d more files or folders" @@ -1884,7 +1869,7 @@ msgstr "Suodata tiedostot..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "Toiminnot skene tiedostoille." +msgstr "Toiminnot skenetiedostoille." #: editor/editor_node.cpp msgid "New Scene" @@ -1920,11 +1905,11 @@ msgstr "Muunna..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "MalliKirjasto..." +msgstr "Mesh-kirjastoksi..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "" +msgstr "Ruutuvalikoimaksi..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -1970,7 +1955,7 @@ msgstr "Lopeta ja palaa projektiluetteloon" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Debug" -msgstr "Testaa" +msgstr "Virheenkorjaus" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" @@ -1981,8 +1966,8 @@ msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" -"Vietäessä tai julkaistaessa, käynnistystiedosto yrittää ottaa yhteyden tämän " -"tietokoneen IP osoitteeseen testaamista varten." +"Vietäessä tai julkaistaessa, käynnistettävä ohjelma yrittää ottaa yhteyden " +"tämän tietokoneen IP-osoitteeseen testaamista varten." #: editor/editor_node.cpp msgid "Small Deploy with Network FS" @@ -2013,7 +1998,7 @@ msgid "" "Collision shapes and raycast nodes (for 2D and 3D) will be visible on the " "running game if this option is turned on." msgstr "" -"Osuma-alueet ja raycast nodet (2D ja 3D) ovat näkyvillä peliä ajettaessa " +"Törmäysmuodot ja raycast-solmut (2D ja 3D) ovat näkyvillä peliä ajettaessa " "tämän ollessa valittuna." #: editor/editor_node.cpp @@ -2041,8 +2026,7 @@ msgid "" msgstr "" "Tämän ollessa valittuna, kaikki skeneen tehdyt muutokset toteutetaan myös " "käynnissä olevassa pelissä.\n" -"Tämä on tehokkainta verkkotiedostojärjestelmän kanssa mikäli käytössä on " -"etälaite." +"Mikäli peliä ajetaan etälaitteella, on tehokkaampaa käyttää verkkolevyä." #: editor/editor_node.cpp msgid "Sync Script Changes" @@ -2057,7 +2041,7 @@ msgid "" msgstr "" "Jos tämä on valittu, kaikki tallennetut skriptit ladataan uudelleen pelin " "käynnistyessä.\n" -"Mikäli peli ajetaan etälaitteella, on tehokkaampaa käyttää verkkolevyä." +"Mikäli peliä ajetaan etälaitteella, on tehokkaampaa käyttää verkkolevyä." #: editor/editor_node.cpp msgid "Editor" @@ -2124,15 +2108,15 @@ msgstr "Pelaa" #: editor/editor_node.cpp msgid "Pause the scene" -msgstr "Pysäytä Scene" +msgstr "Keskeytä skenen suorittaminen hetkellisesti" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "Pysäytä Scene" +msgstr "Keskeytä skene" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "Lopeta Scene." +msgstr "Lopeta skenen suorittaminen." #: editor/editor_node.cpp msgid "Stop" @@ -2140,11 +2124,11 @@ msgstr "Pysäytä" #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "Käynnistä muokattu skene." +msgstr "Käynnistä muokattavana oleva skene." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "Toista Scene" +msgstr "Toista skene" #: editor/editor_node.cpp msgid "Play custom scene" @@ -2172,7 +2156,7 @@ msgstr "Poista päivitysanimaatio" #: editor/editor_node.cpp msgid "Inspector" -msgstr "Tarkastaja" +msgstr "Tarkastelu" #: editor/editor_node.cpp msgid "Create a new resource in memory and edit it." @@ -2217,7 +2201,7 @@ msgstr "Tuo" #: editor/editor_node.cpp msgid "Node" -msgstr "Node" +msgstr "Solmu" #: editor/editor_node.cpp msgid "FileSystem" @@ -2253,16 +2237,15 @@ msgstr "Salasana:" #: editor/editor_node.cpp msgid "Open & Run a Script" -msgstr "Avaa & suorita skripti" +msgstr "Avaa ja suorita skripti" #: editor/editor_node.cpp -#, fuzzy msgid "New Inherited" -msgstr "Uusi peritty Scene..." +msgstr "Uusi peritty skene" #: editor/editor_node.cpp msgid "Load Errors" -msgstr "Lataa virheet" +msgstr "Latausvirheet" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Select" @@ -2282,7 +2265,7 @@ msgstr "Avaa skriptieditori" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "Avaa Asset-kirjasto" +msgstr "Avaa asset-kirjasto" #: editor/editor_node.cpp msgid "Open the next Editor" @@ -2294,7 +2277,7 @@ msgstr "Avaa edellinen editori" #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "Luodaan mallien esikatseluita" +msgstr "Luodaan meshien esikatseluita" #: editor/editor_plugin.cpp msgid "Thumbnail..." @@ -2383,15 +2366,15 @@ msgid "" "Please add a runnable preset in the export menu." msgstr "" "Käynnistettävää vientipohjaa ei löytynyt tälle alustalle.\n" -"Lisää sellainen vienti-valikosta." +"Lisää sellainen vientivalikosta." #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "Kirjoita logiikka _run() -metodiin." +msgstr "Kirjoita logiikka _run() metodiin." #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "Muokattu Scene on jo olemassa." +msgstr "Muokattu skene on jo olemassa." #: editor/editor_run_script.cpp msgid "Couldn't instance script:" @@ -2399,7 +2382,7 @@ msgstr "Ei voitu luoda instanssia skriptistä:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "Unohditko 'tool' hakusanan?" +msgstr "Unohditko 'tool' avainsanan?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" @@ -2407,7 +2390,7 @@ msgstr "Skriptiä ei voitu suorittaa:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "Unohditko '_run' -metodin?" +msgstr "Unohditko '_run' metodin?" #: editor/editor_settings.cpp msgid "Default (Same as Editor)" @@ -2415,15 +2398,15 @@ msgstr "Oletus (sama kuin editori)" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "Valitse tuotava(t) node(t)" +msgstr "Valitse tuotavat solmut" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "Scenen polku:" +msgstr "Skenen polku:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "Tuo Nodesta:" +msgstr "Tuo solmusta:" #: editor/export_template_manager.cpp msgid "Re-Download" @@ -2459,15 +2442,15 @@ msgstr "Poista mallin versio '%s'?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." -msgstr "Vientipohjien zip-tiedostoa ei voitu avata." +msgstr "Vientimallien zip-tiedostoa ei voitu avata." #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates." -msgstr "Paketti sisältää viallisen version.txt tiedoston." +msgstr "Vientimalli sisältää virheellisen version.txt tiedoston." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "version.txt -tiedostoa ei löytynyt." +msgstr "Vientimalleista ei löytynyt version.txt tiedostoa." #: editor/export_template_manager.cpp msgid "Error creating path for templates:" @@ -2740,16 +2723,15 @@ msgstr "Merkitse kansio suosikkeihin" #: editor/filesystem_dock.cpp msgid "Instance the selected scene(s) as child of the selected node." -msgstr "Luo valituista skeneistä ilmentymä valitun noden alle." +msgstr "Luo valituista skeneistä ilmentymä valitun solmun alle." #: editor/filesystem_dock.cpp -#, fuzzy msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" "Selataan tiedostoja,\n" -"Hetkinen..." +"Hetkinen…" #: editor/filesystem_dock.cpp msgid "Move" @@ -2811,21 +2793,19 @@ msgstr "Tuo useina skeneinä ja materiaaleina" #: editor/import/resource_importer_scene.cpp #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import Scene" -msgstr "Tuo Scene" +msgstr "Tuo skene" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "Tuodaan Scene..." +msgstr "Tuodaan skene..." #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Generating Lightmaps" -msgstr "Muunna Lightmapiksi:" +msgstr "Luodaan Lightmappeja" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Generating for Mesh: " -msgstr "Luo AABB" +msgstr "Luodaan meshille: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -2874,7 +2854,7 @@ msgstr "Tuo uudelleen" #: editor/multi_node_edit.cpp msgid "MultiNode Set" -msgstr "" +msgstr "Aseta usealle solmulle" #: editor/node_dock.cpp msgid "Groups" @@ -2882,7 +2862,7 @@ msgstr "Ryhmät" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "Valitse node jonka signaaleja ja ryhmiä haluat muokata." +msgstr "Valitse solmu, jonka signaaleja ja ryhmiä haluat muokata." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -3030,11 +3010,11 @@ msgstr "Toista valittu animaatio nykyisestä kohdasta. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "Animaation sijainti (sekunneissa)." +msgstr "Animaation kohta (sekunneissa)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "Skaalaa animaation toistoa globaalisti nodelle." +msgstr "Skaalaa animaation toistoa globaalisti solmulle." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create new animation in player." @@ -3058,7 +3038,7 @@ msgstr "Näytä lista animaatioista soittimessa." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "Toista automaattisesti" +msgstr "Toista automaattisesti ladattaessa" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Target Blend Times" @@ -3078,7 +3058,7 @@ msgstr "Onion skinning" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "Käytä Onion skinningiä" +msgstr "Käytä onion skinningiä" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -3179,7 +3159,7 @@ msgstr "Sulauta" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix" -msgstr "Sekoitus" +msgstr "Sekoita" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Auto Restart:" @@ -3228,11 +3208,11 @@ msgstr "Lisää syöte" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Clear Auto-Advance" -msgstr "" +msgstr "Poista automaattinen eteneminen" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Set Auto-Advance" -msgstr "" +msgstr "Aseta automaattinen eteneminen" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Delete Input" @@ -3248,39 +3228,39 @@ msgstr "Animaatiopuu ei ole kelvollinen." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation Node" -msgstr "Animaationode" +msgstr "Animaatiosolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "OneShot Node" -msgstr "OneShot node" +msgstr "Vaiheistussolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix Node" -msgstr "Mix Node" +msgstr "Sekoitussolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend2 Node" -msgstr "Sulautus2 node" +msgstr "2-sulautussolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend3 Node" -msgstr "Sulautus3 node" +msgstr "3-sulautussolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend4 Node" -msgstr "Sulautus4 node" +msgstr "4-sulautussolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeScale Node" -msgstr "" +msgstr "Ajanskaalaussolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeSeek Node" -msgstr "" +msgstr "Ajanhakusolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Transition Node" -msgstr "Siirtymänode" +msgstr "Siirtymäsolmu" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Import Animations..." @@ -3288,16 +3268,15 @@ msgstr "Tuo animaatiot..." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Node Filters" -msgstr "Muokkaa noden suodattimia" +msgstr "Muokkaa solmun suodattimia" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Filters..." msgstr "Suodattimet..." #: editor/plugins/animation_tree_editor_plugin.cpp -#, fuzzy msgid "AnimationTree" -msgstr "Animaatio" +msgstr "Animaatiopuu" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" @@ -3435,7 +3414,6 @@ msgid "Official" msgstr "Virallinen" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Testing" msgstr "Testaus" @@ -3449,21 +3427,27 @@ msgid "" "Save your scene (for images to be saved in the same dir), or pick a save " "path from the BakedLightmap properties." msgstr "" +"Lightmap-kuvien tallennuspolun määrittäminen ei onnistu.\n" +"Tallenna skenesi (jotta kuvat tallentuisivat samaan hakemistoon), tai " +"valitse tallennuspolku BakedLightmapin asetuksista." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " "Light' flag is on." msgstr "" +"Ei meshejä kehitettävänä. Varmista, että ne sisältävät UV2-kanavan, ja että " +"'Bake Light' asetus on päällä." #: 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 " +"kirjoituskelpoinen." #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "Bake Lightmaps" -msgstr "Muunna Lightmapiksi:" +msgstr "Kehitä Lightmapit" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -3572,7 +3556,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" -msgstr "" +msgstr "Alt + Hiiren oikea painike: Syvyyslistan valinta" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Mode" @@ -3588,6 +3572,8 @@ msgid "" "Show a list of all objects at the position clicked\n" "(same as Alt+RMB in select mode)." msgstr "" +"Näytä lista kaikista napsautetussa kohdassa olevista objekteista\n" +"(sama kuin Alt + Hiiren oikea painike valintatilassa)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Click to change object's rotation pivot." @@ -3640,15 +3626,15 @@ msgstr "Tartu isäntään" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to node anchor" -msgstr "Tartu noden ankkuriin" +msgstr "Tartu solmun ankkuriin" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to node sides" -msgstr "Tartu noden reunoihin" +msgstr "Tartu solmun reunoihin" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to other nodes" -msgstr "Tartu muihin nodeihin" +msgstr "Tartu muihin solmuihin" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to guides" @@ -3736,7 +3722,7 @@ msgstr "Asettelu" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Keys" -msgstr "Lisää keyframeja" +msgstr "Lisää avainruutuja" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" @@ -3744,7 +3730,7 @@ msgstr "Lisää keyframe" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" -msgstr "Lisää keyframe (olemassaolevalle raidalle)" +msgstr "Lisää avainruutu (olemassa olevat raidat)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Copy Pose" @@ -3755,9 +3741,8 @@ msgid "Clear Pose" msgstr "Tyhjennä asento" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Drag pivot from mouse position" -msgstr "Rahaa pistettä hiiren sijainnista" +msgstr "Vedä keskipistettä hiiren sijainnista" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set pivot at mouse position" @@ -3785,12 +3770,12 @@ msgstr "Ok" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Cannot instantiate multiple nodes without root." -msgstr "Ei voida luoda ilmentymiä useasta nodesta ilman juurta." +msgstr "Ei voida luoda ilmentymiä useasta solmusta ilman juurta." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Create Node" -msgstr "Luo Node" +msgstr "Luo solmu" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -3806,8 +3791,8 @@ msgid "" "Drag & drop + Shift : Add node as sibling\n" "Drag & drop + Alt : Change node type" msgstr "" -"Vedä & pudota + Shift: Lisää Node sisarena\n" -"Vedä & pudota + Alt: Muuta Noden tyyppiä" +"Vedä & pudota + Shift: Lisää solmu sisarena\n" +"Vedä & pudota + Alt: Muuta solmun tyyppiä" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Create Poly3D" @@ -3833,19 +3818,19 @@ msgstr "Poista valitut kohteet" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import from Scene" -msgstr "Tuo Scenestä" +msgstr "Tuo skenestä" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Update from Scene" -msgstr "Päivitä Scenestä" +msgstr "Päivitä skenestä" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat0" -msgstr "" +msgstr "Tasainen0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat1" -msgstr "" +msgstr "Tasainen1" #: editor/plugins/curve_editor_plugin.cpp msgid "Ease in" @@ -3905,7 +3890,7 @@ msgstr "Pidä shift pohjassa muokataksesi tangentteja yksitellen" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "" +msgstr "Kehitä GI Probe" #: editor/plugins/gradient_editor_plugin.cpp msgid "Add/Remove Color Ramp Point" @@ -3933,12 +3918,12 @@ msgid "" "No OccluderPolygon2D resource on this node.\n" "Create and assign one?" msgstr "" -"Tälle nodelle ei ole OccluderPolygon2D resurssia.\n" -"Luodaanko sellainen?" +"Tälle solmulle ei ole OccluderPolygon2D resurssia.\n" +"Luodaanko ja asetetaanko sellainen?" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" -msgstr "Luo Occluder polygooni" +msgstr "Luo peittävä polygoni" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create a new polygon from scratch." @@ -3990,15 +3975,15 @@ msgstr "Luo navigointiverkko" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "Sisällytetty Mesh ei ole tyyppiä ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "" +msgstr "UV-aukaisu epäonnistui, mesh ei ehkä ole jaettavissa osiin?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." -msgstr "" +msgstr "Ei meshiä debugattavaksi." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Model has no UV in this layer" @@ -4006,7 +3991,7 @@ msgstr "Mallilla ei ole UV-kanavaa tällä kerroksella" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "MeshInstance nodelta puuttuu Mesh!" +msgstr "MeshInstance solmulta puuttuu Mesh!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" @@ -4026,7 +4011,7 @@ msgstr "Luo ääriviivat" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "" +msgstr "Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" @@ -4046,7 +4031,7 @@ msgstr "Luo konveksi törmäysmuoto sisareksi" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." -msgstr "" +msgstr "Luo reunoista Mesh..." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" @@ -4058,36 +4043,37 @@ msgstr "Näytä UV2" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Unwrap UV2 for Lightmap/AO" -msgstr "" +msgstr "Aukaise UV2 Lightmapille tai AO:lle" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "" +msgstr "Luo reunoista Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" msgstr "Ääriviivojen koko:" #: editor/plugins/multimesh_editor_plugin.cpp -#, fuzzy msgid "No mesh source specified (and no MultiMesh set in node)." -msgstr "Mesh:in lähdettä ei määritetty" +msgstr "" +"Meshin lähdettä ei ole määritetty (ja MultiMesh ei ole asetettu solmulle)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." msgstr "" +"Meshin lähdettä ei ole määritetty (ja MultiMesh ei sisällä Mesh solmua)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "Virheellinen Mesh:in lähde (virheellinen polku)." +msgstr "Meshin lähde on virheellinen (virheellinen polku)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "" +msgstr "Meshin lähde on virheellinen (ei MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." -msgstr "" +msgstr "Meshin lähde on virheellinen (ei sisällä Mesh resurssia)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." @@ -4107,7 +4093,7 @@ msgstr "Pinnan lähde on virheellinen (tahkot puuttuvat)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Parent has no solid faces to populate." -msgstr "" +msgstr "Lähteellä ei ole kiinteitä tahkoja täytettäväksi." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Couldn't map area." @@ -4115,7 +4101,7 @@ msgstr "Aluetta ei voitu kartoittaa." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "" +msgstr "Valitse lähdemesh:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" @@ -4127,7 +4113,7 @@ msgstr "Täytä pinta" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate MultiMesh" -msgstr "" +msgstr "Täytä MultiMesh" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Target Surface:" @@ -4135,7 +4121,7 @@ msgstr "Kohdepinta:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" -msgstr "" +msgstr "Lähde Mesh:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" @@ -4151,7 +4137,7 @@ msgstr "Z-akseli" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" -msgstr "" +msgstr "Meshin ylös-akseli:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Rotation:" @@ -4167,7 +4153,7 @@ msgstr "Satunnainen skaalaus:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate" -msgstr "" +msgstr "Täytä" #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Bake!" @@ -4245,6 +4231,7 @@ msgstr "Luodaan AABB" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Can only set point into a ParticlesMaterial process material" msgstr "" +"Piste voidaan asettaa ainoastaan ParticlesMaterial käsittelyn materiaaliin" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Error loading image:" @@ -4252,7 +4239,7 @@ msgstr "Virhe ladattaessa kuvaa:" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "No pixels with transparency > 128 in image..." -msgstr "Kuvassa ei ole pikseleitä, joiden läpinäkyvyys on enemmän kuin 128." +msgstr "Kuvassa ei ole pikseleitä, joiden läpinäkyvyys on enemmän kuin 128…" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" @@ -4294,11 +4281,11 @@ msgstr "Emission väri" #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry." -msgstr "Node ei sisällä geometriaa." +msgstr "Solmu ei sisällä geometriaa." #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry (faces)." -msgstr "Nodelta puuttuu geometria (tahkot)." +msgstr "Solmulta puuttuu geometria (tahkot)." #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -4322,10 +4309,9 @@ msgstr "Luo säteilypisteet meshistä" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "Luo säteilypisteet nodesta" +msgstr "Luo säteilypisteet solmusta" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Create Emitter" msgstr "Luo säteilijä/lähetin" @@ -4468,16 +4454,15 @@ msgstr "Muunna UV kartta" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon 2D UV Editor" -msgstr "" +msgstr "Polygon 2D UV-editori" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Point" msgstr "Siirrä pistettä" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Ctrl: Rotate" -msgstr "Ctrl: Pyöritä/kierrä" +msgstr "Ctrl: Kierrä" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" @@ -4493,7 +4478,7 @@ msgstr "Siirrä polygonia" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Rotate Polygon" -msgstr "Käännä polygonia" +msgstr "Kierrä polygonia" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Scale Polygon" @@ -4509,11 +4494,11 @@ msgstr "Muokkaa" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" -msgstr "Polygooni->UV" +msgstr "Polygoni->UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV->Polygon" -msgstr "UV->Polygooni" +msgstr "UV->Polygoni" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Clear UV" @@ -4720,13 +4705,12 @@ msgid "Find Next" msgstr "Etsi seuraava" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp -#, fuzzy msgid "Step Over" -msgstr "Ohita" +msgstr "Siirry seuraavaan" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "Siirry" +msgstr "Siirry sisään" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" @@ -4751,7 +4735,7 @@ msgstr "Avaa Godotin online-dokumentaatio" #: editor/plugins/script_editor_plugin.cpp msgid "Search the class hierarchy." -msgstr "Etsi luokkahierarkia." +msgstr "Etsi luokkahierarkiasta." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -4797,7 +4781,7 @@ msgstr "Debuggeri" msgid "" "Built-in scripts can only be edited when the scene they belong to is loaded" msgstr "" -"Sisäänrakennettuja skriptejä voi muokata ainoastaan kun Scene, johon ne " +"Sisäänrakennettuja skriptejä voi muokata ainoastaan, kun skene, johon ne " "kuuluvat, on ladattu" #: editor/plugins/script_text_editor.cpp @@ -5019,11 +5003,11 @@ msgstr "Lisää tai poista väriluiskalta" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Add/Remove to Curve Map" -msgstr "" +msgstr "Lisää tai poista käyräkartalta" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Modify Curve Map" -msgstr "" +msgstr "Muokkaa käyräkarttaa" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Input Name" @@ -5031,27 +5015,27 @@ msgstr "Vaihda syötteen nimi" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Connect Graph Nodes" -msgstr "Yhdistä graafin nodet" +msgstr "Yhdistä graafin solmut" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Disconnect Graph Nodes" -msgstr "Erota graafin nodet" +msgstr "Erota graafin solmut" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Remove Shader Graph Node" -msgstr "" +msgstr "Poista sävytingraafin solmu" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Move Shader Graph Node" -msgstr "" +msgstr "Siirrä sävytingraafin solmua" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Duplicate Graph Node(s)" -msgstr "Kahdenna graafin node(t)" +msgstr "Kahdenna graafin solmut(t)" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Delete Shader Graph Node(s)" -msgstr "" +msgstr "Poista sävytingraafin solmuja" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Error: Cyclic Connection Link" @@ -5063,7 +5047,7 @@ msgstr "Virhe: syöteliitännät puuttuvat" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Add Shader Graph Node" -msgstr "" +msgstr "Lisää sävytingraafin solmu" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" @@ -5107,7 +5091,7 @@ msgstr "Kierto %s astetta." #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." -msgstr "" +msgstr "Animaation avainnus on pois päältä (avainta ei lisätty)." #: editor/plugins/spatial_editor_plugin.cpp msgid "Animation Key Inserted." @@ -5115,7 +5099,7 @@ msgstr "Animaatioavain lisätty." #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" -msgstr "Kappaleita piirretty" +msgstr "Objekteja piirretty" #: editor/plugins/spatial_editor_plugin.cpp msgid "Material Changes" @@ -5199,7 +5183,7 @@ msgstr "Isäntää, jonka alle ilmentymä luodaan, ei ole valittu." #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "This operation requires a single selected node." -msgstr "Tämä toiminto vaatii yhden valitun noden." +msgstr "Tämä toiminto vaatii yhden valitun solmun." #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Normal" @@ -5275,12 +5259,11 @@ msgstr "Liikkumisen nopeussäädin" #: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" -msgstr "" +msgstr "XForm-ikkuna" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Select Mode (Q)" -msgstr "Valitse tila" +msgstr "Valintatila (Q)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -5288,6 +5271,9 @@ msgid "" "Alt+Drag: Move\n" "Alt+RMB: Depth list selection" msgstr "" +"Vedä: Kierrä\n" +"Alt + Vedä: Siirrä\n" +"Alt + Hiiren oikea painike: Syvyyslistan valinta" #: editor/plugins/spatial_editor_plugin.cpp msgid "Move Mode (W)" @@ -5306,9 +5292,8 @@ msgid "Local Coords" msgstr "Paikalliset koordinaatit" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Local Space Mode (%s)" -msgstr "Skaalaustila (R)" +msgstr "Paikallisavaruuden tila (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Mode (%s)" @@ -5552,23 +5537,20 @@ msgid "Move (After)" msgstr "Siirrä (jälkeen)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "SpriteFrames" -msgstr "Pinoa Framet" +msgstr "SpriteFrames" #: editor/plugins/style_box_editor_plugin.cpp msgid "StyleBox Preview:" -msgstr "StyleBox:in esikatselu:" +msgstr "StyleBoxin esikatselu:" #: editor/plugins/style_box_editor_plugin.cpp -#, fuzzy msgid "StyleBox" -msgstr "Tyyli" +msgstr "StyleBox" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "Set Region Rect" -msgstr "Tekstuurialue" +msgstr "Aseta alueen suorakulmio" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" @@ -5618,7 +5600,6 @@ msgid "Can't save theme to file:" msgstr "Teemaa ei voi tallentaa tiedostoon:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Add All Items" msgstr "Lisää kaikki" @@ -5632,9 +5613,8 @@ msgid "Remove Item" msgstr "Poista" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove All Items" -msgstr "Poista valitut" +msgstr "Poista kaikki" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove All" @@ -5646,7 +5626,7 @@ msgstr "Muokkaa teemaa..." #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." -msgstr "Teeman muokkaus." +msgstr "Teeman muokkausvalikko." #: editor/plugins/theme_editor_plugin.cpp msgid "Add Class Items" @@ -5670,15 +5650,15 @@ msgstr "Luo nykyisestä editorin teemasta" #: editor/plugins/theme_editor_plugin.cpp msgid "CheckBox Radio1" -msgstr "" +msgstr "Valintaruudun valinta 1" #: editor/plugins/theme_editor_plugin.cpp msgid "CheckBox Radio2" -msgstr "" +msgstr "Valintaruudun valinta 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" -msgstr "" +msgstr "Osanen" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -5689,32 +5669,28 @@ msgid "Checked Item" msgstr "Valittu" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Radio Item" -msgstr "Lisää" +msgstr "Valintapainike" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Checked Radio Item" -msgstr "Valittu" +msgstr "Valittu valintapainike" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" msgstr "On" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Many" -msgstr "Moni(a)/Monta" +msgstr "Useita" #: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp msgid "Options" -msgstr "Asetukset" +msgstr "Asetuksia" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "On,Monia,Useita,Asetuksia" +msgstr "On,Useita,Asetuksia" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -5753,9 +5729,8 @@ msgid "Theme" msgstr "Teema" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Erase Selection" -msgstr "Framen valinta" +msgstr "Tyhjennä valittu alue" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" @@ -5783,7 +5758,7 @@ msgstr "Tyhjennä valinta" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Find tile" -msgstr "Etsi tile" +msgstr "Etsi ruutu" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" @@ -5798,13 +5773,12 @@ msgid "Mirror Y" msgstr "Peilaa Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Paint Tile" -msgstr "Poimi tile" +msgstr "Maalaa ruutu" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" -msgstr "Poimi tile" +msgstr "Poimi ruutu" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Rotate 0 degrees" @@ -5824,7 +5798,7 @@ msgstr "Käännä 270 astetta" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Could not find tile:" -msgstr "Tileä ei löytynyt:" +msgstr "Ruutua ei löytynyt:" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Item name or ID:" @@ -5839,9 +5813,8 @@ msgid "Merge from scene?" msgstr "Yhdistä skenestä?" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Set" -msgstr "Vie tileset" +msgstr "Ruutuvalikoima" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -5856,15 +5829,16 @@ msgid "Error" msgstr "Virhe" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotiles" -msgstr "Jaa automaattisesti" +msgstr "Automaattiruudutus" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Select sub-tile to use as icon, this will be also used on invalid autotile " "bindings." msgstr "" +"Valitse aliruutu, jota käytetään ikonina ja myös virheellisten " +"automaattiruudutusten ilmaisemiseen." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -5875,13 +5849,12 @@ msgstr "" "Hiiren oikea: aseta bitti pois päältä." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Select current edited sub-tile." -msgstr "Tallenna tällä hetkellä muokattu resurssi." +msgstr "Valitse muokattavana oleva aliruutu." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select sub-tile to change its priority." -msgstr "" +msgstr "Valitse aliruutu muuttaaksesi sen tärkeyttä." #: editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" @@ -5921,7 +5894,7 @@ msgstr "Vie kaikki projektin resurssit" #: editor/project_export.cpp msgid "Export selected scenes (and dependencies)" -msgstr "Vie valitut Scenet (ja riippuvuudet)" +msgstr "Vie valitut skenet (ja riippuvuudet)" #: editor/project_export.cpp msgid "Export selected resources (and dependencies)" @@ -6002,9 +5975,8 @@ msgid "Imported Project" msgstr "Tuotu projekti" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Projektin nimi:" +msgstr "Virheellinen projektin nimi." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6023,21 +5995,20 @@ msgid "Invalid project path (changed anything?)." msgstr "Virheellinen projektin polku (muuttuiko mikään?)." #: editor/project_manager.cpp -#, fuzzy msgid "" "Couldn't load project.godot in project path (error %d). It may be missing or " "corrupted." -msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." +msgstr "" +"Tiedoston project.godot lataus projektin polusta epäonnistui (virhe %d). Se " +"saattaa puuttua tai olla vioittunut." #: editor/project_manager.cpp -#, fuzzy msgid "Couldn't edit project.godot in project path." -msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." +msgstr "Ei voitu muokata project.godot tiedostoa projektin polussa." #: editor/project_manager.cpp -#, fuzzy msgid "Couldn't create project.godot in project path." -msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." +msgstr "Tiedoston project.godot luonti projektin polkuun epäonnistui." #: editor/project_manager.cpp msgid "The following files failed extraction from package:" @@ -6109,9 +6080,9 @@ msgid "" "Please edit the project and set the main scene in \"Project Settings\" under " "the \"Application\" category." msgstr "" -"Projektia ei voida suorittaa: pääsceneä ei ole määritetty.\n" -"Ole hyvä ja muokkaa projektia ja aseta pääscene projektin asetuksista " -"\"Application\" -kategoriasta." +"Projektia ei voida suorittaa: pääskeneä ei ole määritetty.\n" +"Ole hyvä ja muokkaa projektia ja aseta pääskene projektin asetuksista " +"\"Application\"-kategoriasta." #: editor/project_manager.cpp msgid "" @@ -6205,13 +6176,12 @@ msgid "Mouse Button" msgstr "Hiiren painike" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" "Virheellinen toiminnon nimi. Se ei voi olla tyhjä eikä voi sisältää merkkejä " -"'/', ':', '=', '\\' tai '\"'" +"'/', ':', '=', '\\' tai '\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -6219,11 +6189,11 @@ msgstr "Tapahtuma '%s' on jo olemassa!" #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" -msgstr "Nimeä syöttötapahtuma uudelleen" +msgstr "Nimeä syötetoiminto uudelleen" #: editor/project_settings_editor.cpp msgid "Add Input Action Event" -msgstr "Lisää syöttötapahtuma" +msgstr "Lisää syötetoiminnon tapahtuma" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "Shift+" @@ -6294,13 +6264,12 @@ msgid "Joypad Button Index:" msgstr "Ohjaimen painikkeen indeksi:" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Erase Input Action" -msgstr "Tyhjennä syöttötapahtuma" +msgstr "Tyhjennä syötetoiminto" #: editor/project_settings_editor.cpp msgid "Erase Input Action Event" -msgstr "Tyhjennä syöttötapahtuma" +msgstr "Tyhjennä syötetoiminnon tapahtuma" #: editor/project_settings_editor.cpp msgid "Add Event" @@ -6360,7 +6329,7 @@ msgstr "On jo olemassa" #: editor/project_settings_editor.cpp msgid "Add Input Action" -msgstr "Lisää syöttötapahtuma" +msgstr "Lisää syötetapahtuma" #: editor/project_settings_editor.cpp msgid "Error saving settings." @@ -6416,7 +6385,7 @@ msgstr "Projektin asetukset (project.godot)" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" -msgstr "Yleinen" +msgstr "Yleistä" #: editor/project_settings_editor.cpp editor/property_editor.cpp msgid "Property:" @@ -6468,7 +6437,7 @@ msgstr "Korvaavuudet kielikohtaisesti:" #: editor/project_settings_editor.cpp msgid "Locale" -msgstr "Kieli" +msgstr "Kielialue" #: editor/project_settings_editor.cpp msgid "Locales Filter" @@ -6492,7 +6461,7 @@ msgstr "Kielet:" #: editor/project_settings_editor.cpp msgid "AutoLoad" -msgstr "Lataa automaattisesti" +msgstr "Automaattilataus" #: editor/property_editor.cpp msgid "Pick a Viewport" @@ -6512,11 +6481,11 @@ msgstr "Nolla" #: editor/property_editor.cpp msgid "Easing In-Out" -msgstr "" +msgstr "Helpotus sisään-ulos" #: editor/property_editor.cpp msgid "Easing Out-In" -msgstr "" +msgstr "Helpotus ulos-sisään" #: editor/property_editor.cpp msgid "File..." @@ -6532,7 +6501,7 @@ msgstr "Aseta" #: editor/property_editor.cpp msgid "Select Node" -msgstr "Valitse node" +msgstr "Valitse solmu" #: editor/property_editor.cpp msgid "New Script" @@ -6544,7 +6513,7 @@ msgstr "Uusi %s" #: editor/property_editor.cpp msgid "Make Unique" -msgstr "Tee ainutkertaiseksi" +msgstr "Tee yksilölliseksi" #: editor/property_editor.cpp msgid "Show in File System" @@ -6559,13 +6528,12 @@ msgid "Error loading file: Not a resource!" msgstr "Virhe ladattaessa tiedostoa: Ei ole resurssi!" #: editor/property_editor.cpp -#, fuzzy msgid "Selected node is not a Viewport!" -msgstr "Valitse tuotava(t) node(t)" +msgstr "Valittu solmu ei ole Viewport!" #: editor/property_editor.cpp msgid "Pick a Node" -msgstr "Poimi node" +msgstr "Poimi solmu" #: editor/property_editor.cpp msgid "Bit %d, val %d." @@ -6609,7 +6577,7 @@ msgstr "Muunnettua kuva ei voitu ladata takaisin PVRTC-työkalulla:" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent Node" -msgstr "Vaihda noden isäntää" +msgstr "Vaihda solmun isäntää" #: editor/reparent_dialog.cpp msgid "Reparent Location (Select new Parent):" @@ -6641,7 +6609,7 @@ msgstr "Pääskenen argumentit:" #: editor/run_settings_dialog.cpp msgid "Scene Run Settings" -msgstr "Scenen suorittamisasetukset" +msgstr "Skenen suorittamisasetukset" #: editor/scene_tree_dock.cpp editor/script_create_dialog.cpp #: scene/gui/dialogs.cpp @@ -6650,7 +6618,7 @@ msgstr "OK" #: editor/scene_tree_dock.cpp msgid "No parent to instance the scenes at." -msgstr "Nodea, jonka alle skenen ilmentymä luodaan, ei ole valittu." +msgstr "Solmua, jonka alle skenen ilmentymä luodaan, ei ole valittu." #: editor/scene_tree_dock.cpp msgid "Error loading scene from %s" @@ -6662,7 +6630,7 @@ msgid "" "of its nodes." msgstr "" "Skenestä '%s' ei voida luoda ilmentymää, koska nykyinen skene on olemassa " -"jossakin sen nodeista." +"jossakin sen solmuista." #: editor/scene_tree_dock.cpp msgid "Instance Scene(s)" @@ -6674,23 +6642,23 @@ msgstr "Tätä toimenpidettä ei voi tehdä puun juurelle." #: editor/scene_tree_dock.cpp msgid "Move Node In Parent" -msgstr "Siirrä node isännän alle" +msgstr "Siirrä solmu isännän alle" #: editor/scene_tree_dock.cpp msgid "Move Nodes In Parent" -msgstr "Siirrä nodet isännän alle" +msgstr "Siirrä solmut isännän alle" #: editor/scene_tree_dock.cpp msgid "Duplicate Node(s)" -msgstr "Monista node(t)" +msgstr "Kahdenna solmu(t)" #: editor/scene_tree_dock.cpp msgid "Delete Node(s)?" -msgstr "Poista Node(t)?" +msgstr "Poista solmu(t)?" #: editor/scene_tree_dock.cpp msgid "Can not perform with the root node." -msgstr "Ei voi tehdä juurinodelle." +msgstr "Ei voi tehdä juurisolmulle." #: editor/scene_tree_dock.cpp msgid "This operation can't be done on instanced scenes." @@ -6698,11 +6666,11 @@ msgstr "Tätä toimintoa ei voi tehdä skenejen ilmentymille." #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." -msgstr "Tallenna uusi scene nimellä..." +msgstr "Tallenna uusi skene nimellä..." #: editor/scene_tree_dock.cpp msgid "Editable Children" -msgstr "Muokattavat alinodet" +msgstr "Muokattavat alisolmut" #: editor/scene_tree_dock.cpp msgid "Load As Placeholder" @@ -6718,15 +6686,15 @@ msgstr "Käy järkeen!" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" -msgstr "Ei voida käyttää ulkopuolisen scenen nodeja!" +msgstr "Ei voida käyttää ulkopuolisen skenen solmuja!" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes the current scene inherits from!" -msgstr "Ei voida käyttää nodeja, jotka periytyvät nykyisestä scenestä!" +msgstr "Ei voida käyttää solmuja, joista nykyinen skene periytyy!" #: editor/scene_tree_dock.cpp msgid "Remove Node(s)" -msgstr "Poista Node(t)" +msgstr "Poista solmu(t)" #: editor/scene_tree_dock.cpp msgid "" @@ -6738,7 +6706,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Error saving scene." -msgstr "Virhe tallennettaessa sceneä." +msgstr "Virhe tallennettaessa skeneä." #: editor/scene_tree_dock.cpp msgid "Error duplicating scene to save it." @@ -6754,11 +6722,11 @@ msgstr "Poista perintä" #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "Poista Node(t)" +msgstr "Poista solmu(t)" #: editor/scene_tree_dock.cpp msgid "Add Child Node" -msgstr "Lisää lapsinode" +msgstr "Lisää alisolmu" #: editor/scene_tree_dock.cpp msgid "Instance Child Scene" @@ -6778,7 +6746,7 @@ msgstr "Tyhjennä skripti" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" -msgstr "Yhdistä scenestä" +msgstr "Yhdistä skenestä" #: editor/scene_tree_dock.cpp msgid "Save Branch as Scene" @@ -6786,7 +6754,7 @@ msgstr "Tallenna haara skenenä" #: editor/scene_tree_dock.cpp msgid "Copy Node Path" -msgstr "Kopioi Noden polku" +msgstr "Kopioi solmun polku" #: editor/scene_tree_dock.cpp msgid "Delete (No Confirm)" @@ -6794,32 +6762,31 @@ msgstr "Poista (ei varmistusta)" #: editor/scene_tree_dock.cpp msgid "Add/Create a New Node" -msgstr "Lisää/Luo uusi Node" +msgstr "Lisää/Luo uusi solmu" #: editor/scene_tree_dock.cpp msgid "" "Instance a scene file as a Node. Creates an inherited scene if no root node " "exists." msgstr "" -"Luo skenetiedostosta ilmentymän nodeksi. Luo periytetyn skenen jos " -"juurinodea ei ole olemassa." +"Luo skenetiedostosta ilmentymän solmuksi. Luo periytetyn skenen jos " +"juurisolmua ei ole olemassa." #: editor/scene_tree_dock.cpp msgid "Filter nodes" -msgstr "Suodata nodeja" +msgstr "Suodata solmuja" #: editor/scene_tree_dock.cpp msgid "Attach a new or existing script for the selected node." -msgstr "Liitä uusi tai olemassa oleva skripti valitulle nodelle." +msgstr "Liitä uusi tai olemassa oleva skripti valitulle solmulle." #: editor/scene_tree_dock.cpp msgid "Clear a script for the selected node." -msgstr "Poista skripti valitulta nodelta." +msgstr "Poista skripti valitulta solmulta." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Remote" -msgstr "Poista" +msgstr "Etäinen" #: editor/scene_tree_dock.cpp msgid "Local" @@ -6835,22 +6802,22 @@ msgstr "Tyhjennä!" #: editor/scene_tree_editor.cpp msgid "Toggle Spatial Visible" -msgstr "" +msgstr "Aseta Spatial näkyvyys päälle/pois" #: editor/scene_tree_editor.cpp msgid "Toggle CanvasItem Visible" -msgstr "" +msgstr "Aseta CanvasItem näkyvyys päälle/pois" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" -msgstr "Noden konfiguroinnin varoitus:" +msgstr "Solmun konfiguroinnin varoitus:" #: editor/scene_tree_editor.cpp msgid "" "Node has connection(s) and group(s)\n" "Click to show signals dock." msgstr "" -"Nodella on liitäntöjä ja ryhmiä\n" +"Solmulla on liitäntöjä ja ryhmiä\n" "Napsauta näyttääksesi signaalitelakan." #: editor/scene_tree_editor.cpp @@ -6858,7 +6825,7 @@ msgid "" "Node has connections.\n" "Click to show signals dock." msgstr "" -"Nodella on liitäntöjä.\n" +"Solmulla on liitäntöjä.\n" "Napsauta näyttääksesi signaalitelakan." #: editor/scene_tree_editor.cpp @@ -6866,7 +6833,7 @@ msgid "" "Node is in group(s).\n" "Click to show groups dock." msgstr "" -"Node kuuluu ryhmään.\n" +"Solmu kuuluu ryhmään.\n" "Napsauta näyttääksesi ryhmätelakan." #: editor/scene_tree_editor.cpp @@ -6878,7 +6845,7 @@ msgid "" "Node is locked.\n" "Click to unlock" msgstr "" -"Node on lukittu.\n" +"Solmu on lukittu.\n" "Napsauta lukituksen avaamiseksi" #: editor/scene_tree_editor.cpp @@ -6886,7 +6853,7 @@ msgid "" "Children are not selectable.\n" "Click to make selectable" msgstr "" -"Alinodet eivät ole valittavissa.\n" +"Alisolmut eivät ole valittavissa.\n" "Napsauta niiden tekemiseksi valittavaksi" #: editor/scene_tree_editor.cpp @@ -6895,23 +6862,23 @@ msgstr "Aseta näkyvyys" #: editor/scene_tree_editor.cpp msgid "Invalid node name, the following characters are not allowed:" -msgstr "Virheellinen noden nimi, seuraavat merkit eivät ole sallittuja:" +msgstr "Virheellinen solmun nimi, seuraavat merkit eivät ole sallittuja:" #: editor/scene_tree_editor.cpp msgid "Rename Node" -msgstr "Nimeä Node uudelleen" +msgstr "Nimeä solmu uudelleen" #: editor/scene_tree_editor.cpp msgid "Scene Tree (Nodes):" -msgstr "Skenepuu (nodet):" +msgstr "Skenepuu (solmut):" #: editor/scene_tree_editor.cpp msgid "Node Configuration Warning!" -msgstr "Noden konfigurointivaroitus!" +msgstr "Solmun konfigurointivaroitus!" #: editor/scene_tree_editor.cpp msgid "Select a Node" -msgstr "Valitse Node" +msgstr "Valitse solmu" #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -7011,7 +6978,7 @@ msgstr "Sisäänrakennettu skripti" #: editor/script_create_dialog.cpp msgid "Attach Node Script" -msgstr "Liitä Noden skripti" +msgstr "Liitä solmun skripti" #: editor/script_editor_debugger.cpp msgid "Remote " @@ -7155,7 +7122,7 @@ msgstr "Muuta valon sädettä" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" -msgstr "Muuta AudioStreamPlayer3D noden suuntausta" +msgstr "Muuta AudioStreamPlayer3D solmun suuntausta" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -7195,7 +7162,7 @@ msgstr "Muuta partikkelien AABB" #: editor/spatial_editor_gizmos.cpp msgid "Change Probe Extents" -msgstr "" +msgstr "Muuta Proben ulottuvuuksia" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Select the dynamic library for this entry" @@ -7230,7 +7197,6 @@ msgid "Add an architecture entry" msgstr "Lisää arkkitehtuurikohde" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "GDNativeLibrary" msgstr "GDNativeLibrary" @@ -7247,7 +7213,6 @@ msgid "Libraries: " msgstr "Kirjastot: " #: modules/gdnative/register_types.cpp -#, fuzzy msgid "GDNative" msgstr "GDNative" @@ -7335,18 +7300,16 @@ msgid "GridMap Duplicate Selection" msgstr "Kahdenna valinta" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Grid Map" msgstr "Ruudukko" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Snap View" -msgstr "Huippunäkymä" +msgstr "Tartu näkymään" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" -msgstr "Leikkaus poistettu käytöstä" +msgstr "Leikkaus pois käytöstä" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Above" @@ -7369,35 +7332,32 @@ msgid "Edit Z Axis" msgstr "Muokkaa Z-akselia" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Rotate X" -msgstr "Ctrl: Pyöritä/kierrä" +msgstr "Kierrä kohdistinta X-akselilla" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Rotate Y" -msgstr "Ctrl: Pyöritä/kierrä" +msgstr "Kierrä kohdistinta Y-akselilla" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Rotate Z" -msgstr "Ctrl: Pyöritä/kierrä" +msgstr "Kierrä kohdistinta Z-akselilla" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate X" -msgstr "" +msgstr "Kierrä kohdistinta X-akselilla takaperin" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate Y" -msgstr "" +msgstr "Kierrä kohdistinta Y-akselilla takaperin" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate Z" -msgstr "" +msgstr "Kierrä kohdistinta Z-akselilla takaperin" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Clear Rotation" -msgstr "" +msgstr "Poista kohdistimen kierto" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Create Area" @@ -7416,13 +7376,12 @@ msgid "Clear Selection" msgstr "Tyhjennä valinta" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Settings" -msgstr "Näyttöruudun asetukset" +msgstr "Ruudukon asetukset" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Pick Distance:" -msgstr "Poimi etäisyys:" +msgstr "Poimintaetäisyys:" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -7485,12 +7444,16 @@ msgid "" "A node yielded without working memory, please read the docs on how to yield " "properly!" msgstr "" +"Solmu väisti ilman työmuistia, ole hyvä ja lue dokumentaatiosta kuinka " +"väistö (yield) on tehtävä!" #: modules/visual_script/visual_script.cpp msgid "" "Node yielded, but did not return a function state in the first working " "memory." msgstr "" +"Solmu väisti (yield), mutta ei palauttanut funktion tilaa ensimmäiselle " +"työmuistille." #: modules/visual_script/visual_script.cpp msgid "" @@ -7498,15 +7461,15 @@ msgid "" "your node please." msgstr "" "Paluuarvo täytyy sijoittaa työmuistin ensimmäiselle elementille! Ole hyvä ja " -"korjaa nodesi." +"korjaa solmusi." #: modules/visual_script/visual_script.cpp msgid "Node returned an invalid sequence output: " -msgstr "" +msgstr "Solmu palautti virheellisen jakson tulosteen: " #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" -msgstr "" +msgstr "Jaksobitti löytyi, mutta solmua ei löydy pinosta, raportoi bugi!" #: modules/visual_script/visual_script.cpp msgid "Stack overflow with stack depth: " @@ -7578,47 +7541,52 @@ msgstr "Vaihda lauseketta" #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "Lisää Node" +msgstr "Lisää solmu" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Nodes" -msgstr "Poista VisualScript nodet" +msgstr "Poista VisualScript solmut" #: modules/visual_script/visual_script_editor.cpp msgid "Duplicate VisualScript Nodes" -msgstr "Kahdenna VisualScript nodet" +msgstr "Kahdenna VisualScript solmut" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." msgstr "" +"Pidä %s pohjassa pudottaaksesi Getterin. Pidä Shift pohjassa pudottaaksesi " +"yleisen tunnisteen." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." msgstr "" +"Pidä Ctrl pohjassa pudottaaksesi Getterin. Pidä Shift pohjassa pudottaaksesi " +"yleisen tunnisteen." #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a simple reference to the node." -msgstr "" +msgstr "Pidä %s pohjassa pudottaaksesi yksinkertaisen viittauksen solmuun." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a simple reference to the node." -msgstr "" +msgstr "Pidä Ctrl pohjassa pudottaaksesi yksinkertaisen viittauksen solmuun." #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Variable Setter." -msgstr "" +msgstr "Pidä %s pohjassa pudottaaksesi muuttujan asettajan (Variable Setter)." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Variable Setter." msgstr "" +"Pidä Ctrl pohjassa pudottaaksesi muuttujan asettajan (Variable Setter)." #: modules/visual_script/visual_script_editor.cpp msgid "Add Preload Node" -msgstr "Lisää esiladattu node" +msgstr "Lisää esiladattu solmu" #: modules/visual_script/visual_script_editor.cpp msgid "Add Node(s) From Tree" -msgstr "Lisää Nodet puusta" +msgstr "Lisää solmut puusta" #: modules/visual_script/visual_script_editor.cpp msgid "Add Getter Property" @@ -7634,15 +7602,15 @@ msgstr "Muuta kantatyyppiä" #: modules/visual_script/visual_script_editor.cpp msgid "Move Node(s)" -msgstr "Siirrä node(t)" +msgstr "Siirrä solmu(t)" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Node" -msgstr "Poista VisualScript node" +msgstr "Poista VisualScript solmu" #: modules/visual_script/visual_script_editor.cpp msgid "Connect Nodes" -msgstr "Kytke nodet" +msgstr "Kytke solmut" #: modules/visual_script/visual_script_editor.cpp msgid "Condition" @@ -7654,15 +7622,15 @@ msgstr "Sarja" #: modules/visual_script/visual_script_editor.cpp msgid "Switch" -msgstr "" +msgstr "Valinta (Switch)" #: modules/visual_script/visual_script_editor.cpp msgid "Iterator" -msgstr "" +msgstr "Iteraattori" #: modules/visual_script/visual_script_editor.cpp msgid "While" -msgstr "" +msgstr "Kun (While)" #: modules/visual_script/visual_script_editor.cpp msgid "Return" @@ -7674,7 +7642,7 @@ msgstr "Kutsu" #: modules/visual_script/visual_script_editor.cpp msgid "Get" -msgstr "" +msgstr "Get" #: modules/visual_script/visual_script_editor.cpp msgid "Script already has function '%s'" @@ -7686,7 +7654,7 @@ msgstr "Vaihda syötteen arvo" #: modules/visual_script/visual_script_editor.cpp msgid "Can't copy the function node." -msgstr "Ei voida kopioida funktionodea." +msgstr "Ei voida kopioida funktiosolmua." #: modules/visual_script/visual_script_editor.cpp msgid "Clipboard is empty!" @@ -7694,7 +7662,7 @@ msgstr "Leikepöytä on tyhjä!" #: modules/visual_script/visual_script_editor.cpp msgid "Paste VisualScript Nodes" -msgstr "Liitä VisualScript nodet" +msgstr "Liitä VisualScript solmut" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Function" @@ -7730,7 +7698,7 @@ msgstr "Kantatyyppi:" #: modules/visual_script/visual_script_editor.cpp msgid "Available Nodes:" -msgstr "Saatavilla olevat Nodet:" +msgstr "Saatavilla olevat solmut:" #: modules/visual_script/visual_script_editor.cpp msgid "Select or create a function to edit graph" @@ -7750,19 +7718,19 @@ msgstr "Poista valitut" #: modules/visual_script/visual_script_editor.cpp msgid "Find Node Type" -msgstr "Etsi Noden tyyppi" +msgstr "Etsi solmun tyyppi" #: modules/visual_script/visual_script_editor.cpp msgid "Copy Nodes" -msgstr "Kopioi Nodet" +msgstr "Kopioi solmut" #: modules/visual_script/visual_script_editor.cpp msgid "Cut Nodes" -msgstr "Leikkaa Nodet" +msgstr "Leikkaa solmut" #: modules/visual_script/visual_script_editor.cpp msgid "Paste Nodes" -msgstr "Liitä Nodet" +msgstr "Liitä solmut" #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " @@ -7782,15 +7750,15 @@ msgstr "Virheellinen osoitinominaisuuden nimi." #: modules/visual_script/visual_script_func_nodes.cpp msgid "Base object is not a Node!" -msgstr "Kantaobjekti ei ole Node!" +msgstr "Kantaobjekti ei ole solmu!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Path does not lead Node!" -msgstr "Polku ei vie Nodeen!" +msgstr "Polku ei johda solmuun!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." -msgstr "Virheellinen osoitinominaisuuden nimi '%s' nodessa %s." +msgstr "Virheellinen osoitinominaisuuden nimi '%s' solmussa %s." #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " @@ -7811,7 +7779,7 @@ msgstr "VariableSet ei löytynyt skriptistä: " #: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." msgstr "" -"Mukautetulla nodella ei ole _step() metodia, graafia ei voida käsitellä." +"Mukautetulla solmulla ei ole _step() metodia, graafia ei voida käsitellä." #: modules/visual_script/visual_script_nodes.cpp msgid "" @@ -7875,10 +7843,10 @@ msgid "" "Consider adding CollisionShape2D or CollisionPolygon2D children nodes to " "define its shape." msgstr "" -"Tämän noden alaisuudessa ei ole muotoja, joten se ei voi olla " +"Tämän solmun alaisuudessa ei ole muotoja, joten se ei voi olla " "vuorovaikutuksessa avaruuden kanssa.\n" -"Harkitse CollisionShape2D tai CollisionPolygon2D noden lisäämistä alinodeksi " -"muodon määrittämiseksi." +"Harkitse CollisionShape2D tai CollisionPolygon2D solmun lisäämistä " +"alisolmuksi muodon määrittämiseksi." #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -7887,12 +7855,12 @@ msgid "" "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" "CollisionPolygon2D toimii törmäysmuotona ainoastaan CollisionObject2D " -"nodesta perityille nodeille. Käytä sitä ainoastaan Area2D, StaticBody2D, " +"solmusta perityille solmuille. Käytä sitä ainoastaan Area2D, StaticBody2D, " "RigidBody2D, KinematicBody2D, jne. alla antaaksesi niille muodon." #: scene/2d/collision_polygon_2d.cpp msgid "An empty CollisionPolygon2D has no effect on collision." -msgstr "Tyhjällä CollisionPolygon2D:llä ei ole vaikutusta törmäyksessä." +msgstr "Tyhjällä CollisionPolygon2D solmulla ei ole vaikutusta törmäyksessä." #: scene/2d/collision_shape_2d.cpp msgid "" @@ -7900,8 +7868,8 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" -"CollisionShape2D toimii törmäysmuotona ainoastaan CollisionObject2D nodesta " -"perityille nodeille. Käytä sitä ainoastaan Area2D, StaticBody2D, " +"CollisionShape2D toimii törmäysmuotona ainoastaan CollisionObject2D solmusta " +"perityille solmuille. Käytä sitä ainoastaan Area2D, StaticBody2D, " "RigidBody2D, KinematicBody2D, jne. alla antaaksesi niille muodon." #: scene/2d/collision_shape_2d.cpp @@ -7909,7 +7877,7 @@ msgid "" "A shape must be provided for CollisionShape2D to function. Please create a " "shape resource for it!" msgstr "" -"CollisionShape2D nodella täytyy olla muoto, jotta se toimisi. Ole hyvä ja " +"CollisionShape2D solmulla täytyy olla muoto, jotta se toimisi. Ole hyvä ja " "luo sille muotoresurssi!" #: scene/2d/light_2d.cpp @@ -7937,22 +7905,22 @@ msgid "" "A NavigationPolygon resource must be set or created for this node to work. " "Please set a property or draw a polygon." msgstr "" -"Tälle nodelle on asetettava tai luotava NavigationPolygon resurssi, jotta se " -"toimisi. Ole hyvä ja aseta ominaisuus tai piirrä monikulmio." +"Tälle solmulle on asetettava tai luotava NavigationPolygon resurssi, jotta " +"se toimisi. Ole hyvä ja aseta ominaisuus tai piirrä monikulmio." #: scene/2d/navigation_polygon.cpp msgid "" "NavigationPolygonInstance must be a child or grandchild to a Navigation2D " "node. It only provides navigation data." msgstr "" -"NavigationPolygonInstance noden täytyy olla Navigation2D noden alaisuudessa. " -"Se tarjoaa vain navigointidataa." +"NavigationPolygonInstance solmun täytyy olla Navigation2D solmun " +"alaisuudessa. Se tarjoaa vain navigointidataa." #: scene/2d/parallax_layer.cpp msgid "" "ParallaxLayer node only works when set as child of a ParallaxBackground node." msgstr "" -"ParallaxLayer node toimii ainoastaan, jos se on ParallaxBackground noden " +"ParallaxLayer solmu toimii ainoastaan, jos se on ParallaxBackground solmun " "alla." #: scene/2d/particles_2d.cpp scene/3d/particles.cpp @@ -7966,8 +7934,7 @@ msgstr "" #: scene/2d/path_2d.cpp msgid "PathFollow2D only works when set as a child of a Path2D node." msgstr "" -"PathFollow2D toimii ainoastaan ollessaan asetettuna Path2D Node:n " -"lapsiolioksi." +"PathFollow2D toimii ainoastaan ollessaan asetettuna Path2D solmun alle." #: scene/2d/physics_body_2d.cpp msgid "" @@ -7975,10 +7942,14 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" +"Fysiikkamoottori ylikirjoittaa RigidBody2D kokomuutokset (hahmo- tai " +"jäykkätila) ajon aikana.\n" +"Muuta sen sijaan solmun alla olevia törmäysmuotoja." #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." -msgstr "Polku täytyy olla määritetty toimivaan Node2D solmuun toimiakseen." +msgstr "" +"Polkuominaisuuden täytyy osoittaa kelvolliseen Node2D solmuun toimiakseen." #: scene/2d/visibility_notifier_2d.cpp msgid "" @@ -7990,11 +7961,11 @@ msgstr "" #: scene/3d/arvr_nodes.cpp msgid "ARVRCamera must have an ARVROrigin node as its parent" -msgstr "ARVRCamera noden isännän täytyy olla ARVROrigin" +msgstr "ARVRCamera solmun isännän täytyy olla ARVROrigin solmu" #: scene/3d/arvr_nodes.cpp msgid "ARVRController must have an ARVROrigin node as its parent" -msgstr "ARVRController noden isännän täytyy olla ARVROrigin node" +msgstr "ARVRController solmun isännän täytyy olla ARVROrigin solmu" #: scene/3d/arvr_nodes.cpp msgid "" @@ -8006,7 +7977,7 @@ msgstr "" #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent" -msgstr "ARVRAnchor noden isännän täytyy olla ARVROrigin node" +msgstr "ARVRAnchor solmun isännän täytyy olla ARVROrigin solmu" #: scene/3d/arvr_nodes.cpp msgid "" @@ -8018,11 +7989,11 @@ msgstr "" #: scene/3d/arvr_nodes.cpp msgid "ARVROrigin requires an ARVRCamera child node" -msgstr "ARVROrigin tarvitsee ARVRCamera noden alinodeksi" +msgstr "ARVROrigin solmu tarvitsee ARVRCamera alisolmun" #: scene/3d/baked_lightmap.cpp msgid "%d%%" -msgstr "" +msgstr "%d%%" #: scene/3d/baked_lightmap.cpp msgid "(Time Left: %d:%02d s)" @@ -8030,11 +8001,11 @@ msgstr "(Aikaa jäljellä: %d:%02d s)" #: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " -msgstr "" +msgstr "Piirretään meshejä: " #: scene/3d/baked_lightmap.cpp msgid "Plotting Lights:" -msgstr "" +msgstr "Piirretään valoja:" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Finishing Plot" @@ -8042,7 +8013,7 @@ msgstr "Viimeistellään piirto" #: scene/3d/baked_lightmap.cpp msgid "Lighting Meshes: " -msgstr "" +msgstr "Valaistaan meshejä: " #: scene/3d/collision_object.cpp msgid "" @@ -8050,10 +8021,10 @@ msgid "" "Consider adding CollisionShape or CollisionPolygon children nodes to define " "its shape." msgstr "" -"Tällä nodella ei ole alimuotoja, joten se ei voi olla vuorovaikutuksessa " +"Tällä solmulla ei ole alimuotoja, joten se ei voi olla vuorovaikutuksessa " "avaruuden kanssa.\n" -"Harkitse CollisionShape tai CollisionPolygon noden lisäämistä sen alinodeksi " -"määritelläksesi sen muodon." +"Harkitse CollisionShape tai CollisionPolygon solmun lisäämistä sen " +"alisolmuksi määritelläksesi sen muodon." #: scene/3d/collision_polygon.cpp msgid "" @@ -8061,13 +8032,13 @@ msgid "" "CollisionObject derived node. Please only use it as a child of Area, " "StaticBody, RigidBody, KinematicBody, etc. to give them a shape." msgstr "" -"CollisionPolygon node antaa ainoastaan törmäysmuodon CollisionObject nodesta " -"periytyville nodeille. Käytä sitä Area, StaticBody, RigidBody, " -"KinematicBody, jne. nodejen alla antaaksesi niille muodon." +"CollisionPolygon solmu antaa ainoastaan törmäysmuodon CollisionObject " +"solmusta periytyville solmuille. Käytä sitä Area, StaticBody, RigidBody, " +"KinematicBody, jne. solmujen alla antaaksesi niille muodon." #: scene/3d/collision_polygon.cpp msgid "An empty CollisionPolygon has no effect on collision." -msgstr "Tyhjällä CollisionPolygon:illa ei ole vaikutusta törmäyksessä." +msgstr "Tyhjällä CollisionPolygon solmulla ei ole vaikutusta törmäyksessä." #: scene/3d/collision_shape.cpp msgid "" @@ -8075,26 +8046,26 @@ msgid "" "derived node. Please only use it as a child of Area, StaticBody, RigidBody, " "KinematicBody, etc. to give them a shape." msgstr "" -"CollisionShape node antaa ainoastaan törmäysmuodon CollisionObject nodesta " -"periytyville nodeille. Käytä sitä Area, StaticBody, RigidBody, " -"KinematicBody, jne. nodejen alla antaaksesi niille muodon." +"CollisionShape solmu antaa ainoastaan törmäysmuodon CollisionObject solmusta " +"periytyville solmuille. Käytä sitä Area, StaticBody, RigidBody, " +"KinematicBody, jne. solmujen alla antaaksesi niille muodon." #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " "shape resource for it!" msgstr "" -"CollisionShape nodelle täytyy antaa muoto, jotta se toimisi. Ole hyvä ja luo " -"sille muotoresurssi!" +"CollisionShape solmulle täytyy antaa muoto, jotta se toimisi. Ole hyvä ja " +"luo sille muotoresurssi!" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" -msgstr "" +msgstr "Piirretään meshejä" #: scene/3d/navigation_mesh.cpp msgid "A NavigationMesh resource must be set or created for this node to work." msgstr "" -"Tälle nodelle täytyy asettaa tai luoda NavigationMesh resurssi, jotta se " +"Tälle solmulle täytyy asettaa tai luoda NavigationMesh resurssi, jotta se " "toimisi." #: scene/3d/navigation_mesh.cpp @@ -8102,7 +8073,7 @@ msgid "" "NavigationMeshInstance must be a child or grandchild to a Navigation node. " "It only provides navigation data." msgstr "" -"NavigationMeshInstance noden täytyy olla Navigation noden alaisuudessa. Se " +"NavigationMeshInstance solmun täytyy olla Navigation solmun alaisuudessa. Se " "tarjoaa vain navigointidataa." #: scene/3d/particles.cpp @@ -8118,10 +8089,13 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" +"Fysiikkamoottori ylikirjoittaa RigidBody kokomuutokset (hahmo- tai " +"jäykkätilassa) ajon aikana.\n" +"Muuta sen sijaan solmun alla olevia törmäysmuotoja." #: scene/3d/remote_transform.cpp msgid "Path property must point to a valid Spatial node to work." -msgstr "Polkuominaisuuden täytyy osoittaa Spatial nodeen toimiakseen." +msgstr "Polkuominaisuuden täytyy osoittaa Spatial solmuun toimiakseen." #: scene/3d/scenario_fx.cpp msgid "WorldEnvironment needs an Environment resource." @@ -8148,7 +8122,7 @@ msgid "" "A SpriteFrames resource must be created or set in the 'Frames' property in " "order for AnimatedSprite3D to display frames." msgstr "" -"AnimatedSprite3D nodelle täytyy luoda tai asettaa 'Frames' ominaisuudeksi " +"AnimatedSprite3D solmulle täytyy luoda tai asettaa 'Frames' ominaisuudeksi " "SpriteFrames resurssi ruutujen näyttämiseksi." #: scene/3d/vehicle_body.cpp @@ -8156,8 +8130,8 @@ msgid "" "VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " "it as a child of a VehicleBody." msgstr "" -"VehicleWheel node tarjoaa rengasjärjestelmän VehicleBody nodelle. Ole hyvä " -"ja käytä sitä VehicleBody noden alla." +"VehicleWheel solmu tarjoaa rengasjärjestelmän VehicleBody solmulle. Ole hyvä " +"ja käytä sitä VehicleBody solmun alla." #: scene/gui/color_picker.cpp msgid "Raw Mode" @@ -8218,14 +8192,14 @@ msgid "" "obtain a size. Otherwise, make it a RenderTarget and assign its internal " "texture to some node for display." msgstr "" -"Tätä näyttöruutua ei ole asetettu renderöitäväksi. Jos haluat sen näyttävän " -"sisältöä suoraan näytölle, tee sitä Control:in lapsi, jotta se voi saada " -"koon. Muutoin tee siitä RenderTarget ja aseta sen sisäinen tekstuuri " -"johonkin Nodeen näkyväksi." +"Tätä näyttöikkunaa ei ole asetettu renderöitäväksi. Jos haluat sen näyttävän " +"sisältöä suoraan näytölle, tee sitä Control solmun alisolmu, jotta se voi " +"saada koon. Muutoin tee siitä RenderTarget ja aseta sen sisäinen tekstuuri " +"johonkin solmuun näkyväksi." #: scene/resources/dynamic_font.cpp msgid "Error initializing FreeType." -msgstr "Virhe FreetType:n alustamisessa." +msgstr "Virhe FreeType:n alustamisessa." #: scene/resources/dynamic_font.cpp msgid "Unknown font format." @@ -8239,6 +8213,13 @@ msgstr "Virhe fontin latauksessa." msgid "Invalid font size." msgstr "Virheellinen fonttikoko." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Edellinen välilehti" + +#~ msgid "Next" +#~ msgstr "Seuraava" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Virheellinen tapahtuma (muut käy, paitsi '/' tai ':')." @@ -8269,9 +8250,6 @@ msgstr "Virheellinen fonttikoko." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." -#~ msgid "Next" -#~ msgstr "Seuraava" - #~ msgid "Not found!" #~ msgstr "Ei löytynyt!" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 4c380d0b18..ee1d7b2cad 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.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. -# # Antoine Carrier <ac.g392@gmail.com>, 2017-2018. # ARocherVj <a.rocher.vj@gmail.com>, 2017. # Arthur Templé <tuturtemple@gmail.com>, 2018. @@ -20,6 +19,7 @@ # LL <lu.lecocq@free.fr>, 2018. # Luc Stepniewski <lior@gradstein.info>, 2017. # Marc <marc.gilleron@gmail.com>, 2016-2017. +# Marc-Andre Belisle <belisle.ma@gmail.com>, 2018. # Nathan Lovato <nathan.lovato.art@gmail.com>, 2017. # Nathan Vallet <nathanvalletmarseille@gmail.com>, 2018. # Nicolas <flaithotw@gmail.com>, 2017. @@ -28,6 +28,7 @@ # Nocta Senestra <nocta@net-c.com>, 2018. # Omicron <omicron666.dev@gmail.com>, 2016, 2018. # Onyx Steinheim <thevoxelmanonyx@gmail.com>, 2016. +# Philippe Gervaise <blah@malvese.org>, 2018. # Przemyslaw Gasinski <gasinski.przemek@protonmail.ch>, 2017. # rafeu <duchainer@gmail.com>, 2016-2017. # rawida <rawida@tempinbox.com>, 2018. @@ -39,13 +40,12 @@ # Tommy Melançon-Roy <tommel1234@hotmail.com>, 2017-2018. # Willow <theotimefd@aol.com>, 2018. # Xananax <xananax@yelostudio.com>, 2017-2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-06-05 19:27+0000\n" -"Last-Translator: Rémi Verschelde <akien@godotengine.org>\n" +"PO-Revision-Date: 2018-06-12 16:38+0000\n" +"Last-Translator: Philippe Gervaise <blah@malvese.org>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -53,7 +53,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\n" +"X-Generator: Weblate 3.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -1727,7 +1727,7 @@ msgstr "Exporter une bibliothèque de maillages" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "Cette opération ne peut être réalisée sans noeud parent." +msgstr "Cette opération ne peut être réalisée sans nÅ“ud racine." #: editor/editor_node.cpp msgid "Export Tile Set" @@ -2572,7 +2572,7 @@ msgstr "Erreur lors de la requête de l’URL : " #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." -msgstr "Connexion au miroir" +msgstr "Connexion au Miroir..." #: editor/export_template_manager.cpp msgid "Disconnected" @@ -3763,7 +3763,7 @@ msgstr "Afficher les règles" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Guides" -msgstr "Montrer les guides" +msgstr "Afficher les guides" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Origin" @@ -5759,9 +5759,8 @@ msgid "Options" msgstr "Options" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "Ont,Plusieurs,Possibilités,D'options !" +msgstr "Possède,Plusieurs,Options" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -6046,9 +6045,8 @@ msgid "Imported Project" msgstr "Projet importé" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nom du projet :" +msgstr "Nom du Projet Invalide." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6253,13 +6251,12 @@ msgid "Mouse Button" msgstr "Bouton de souris" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" "Nom d'action invalide. Il ne peux être vide ou contenir '/', ':', '=', '\\' " -"ou '\"'" +"ou '\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -8298,6 +8295,13 @@ msgstr "Erreur lors du chargement de la police." msgid "Invalid font size." msgstr "Taille de police invalide." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Onglet precedent" + +#~ msgid "Next" +#~ msgstr "Suivant" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Action invalide (tout passe, sauf « / » ou « : »)." @@ -8327,9 +8331,6 @@ msgstr "Taille de police invalide." #~ msgstr "" #~ "Impossible de trouver le fichier project.godot dans le chemin du projet." -#~ msgid "Next" -#~ msgstr "Suivant" - #~ msgid "Not found!" #~ msgstr "Non trouvé !" diff --git a/editor/translations/he.po b/editor/translations/he.po index 3a86197ef5..0f1881211f 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -7977,12 +7977,16 @@ msgstr "שגי××” ×‘×˜×¢×™× ×ª הגופן." msgid "Invalid font size." msgstr "גודל הגופן שגוי." -#~ msgid "Can't write file." -#~ msgstr "×œ× × ×™×ª×Ÿ לכתוב קובץ." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "×”×œ×©×•× ×™×ª הקודמת" #~ msgid "Next" #~ msgstr "הב×" +#~ msgid "Can't write file." +#~ msgstr "×œ× × ×™×ª×Ÿ לכתוב קובץ." + #~ msgid "Not found!" #~ msgstr "×œ× × ×ž×¦×!" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 28cc68be24..b04dd073df 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -2,23 +2,22 @@ # 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. -# +# Ãrpád Horváth <horvatha4@googlemail.com>, 2018. # Nagy Lajos <neutron9707@gmail.com>, 2017. # Sandor Domokos <sandor.domokos@gmail.com>, 2017-2018. # Varga Dániel <danikah.danikah@gmail.com>, 2016-2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-04-03 06:36+0000\n" -"Last-Translator: Sandor Domokos <sandor.domokos@gmail.com>\n" +"PO-Revision-Date: 2018-06-17 07:39+0000\n" +"Last-Translator: Ãrpád Horváth <horvatha4@googlemail.com>\n" "Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/" "godot/hu/>\n" "Language: hu\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 2.20-dev\n" +"X-Generator: Weblate 3.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -34,7 +33,7 @@ msgstr "Animáció kulcsképkocka idÅ‘ változtatás" #: editor/animation_editor.cpp msgid "Anim Change Transition" -msgstr "Animáció átmenet változtatás" +msgstr "Animáció átmenet változtatása" #: editor/animation_editor.cpp msgid "Anim Change Transform" @@ -236,7 +235,7 @@ msgstr "Animáció kulcsok nyújtás" #: editor/animation_editor.cpp msgid "Anim Add Call Track" -msgstr "Animáció hÃvási nyomvonal hozzáadás" +msgstr "Animációhoz hÃvási nyomvonal hozzáadása" #: editor/animation_editor.cpp msgid "Animation zoom." @@ -1396,7 +1395,7 @@ msgstr "Kimenet Törlése" #: editor/editor_node.cpp msgid "Project export failed with error code %d." -msgstr "" +msgstr "Projekt export nem sikerült, hibakód %d." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" @@ -1646,11 +1645,11 @@ msgstr "Alap Scene megnyitás" #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "Scene gyors megnyitás" +msgstr "Jelenet gyors megnyitása..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Szkript gyors megnyitás" +msgstr "Szkript gyors megnyitás..." #: editor/editor_node.cpp msgid "Save & Close" @@ -1662,7 +1661,7 @@ msgstr "Bezárás elÅ‘tt menti a '%s'-n végzett módosÃtásokat?" #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "Scene mentés másként" +msgstr "Scene mentés másként..." #: editor/editor_node.cpp msgid "No" @@ -1714,7 +1713,7 @@ msgstr "Ez a művelet nem vonható vissza. VisszaállÃtja mindenképp?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "Scene gyors futtatás" +msgstr "Scene gyors futtatás..." #: editor/editor_node.cpp msgid "Quit" @@ -1860,7 +1859,7 @@ msgstr "Hozzáad egy új jelenetet." #: editor/editor_node.cpp msgid "Scene" -msgstr "Scene" +msgstr "Jelenet" #: editor/editor_node.cpp msgid "Go to previously opened scene." @@ -1888,11 +1887,11 @@ msgstr "Új Scene" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "Új örökölt Scene" +msgstr "Új örökölt Jelenet..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "Scene megnyitása" +msgstr "Jelenet megnyitása..." #: editor/editor_node.cpp msgid "Save Scene" @@ -1982,7 +1981,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Small Deploy with Network FS" -msgstr "Kis TelepÃtés Hálózati FR-rel" +msgstr "Kis TelepÃtés Hálózati FS-sel" #: editor/editor_node.cpp msgid "" @@ -2026,7 +2025,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "Scene változtatások szinkronizálás" +msgstr "Jelenet változtatások szinkronizálása" #: editor/editor_node.cpp msgid "" @@ -2809,7 +2808,7 @@ msgstr "Scene importálás" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "Scene importálás" +msgstr "Jelenet importálása..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" @@ -3430,7 +3429,7 @@ msgstr "Hivatalos" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Testing" -msgstr "Tesztelés Alatt" +msgstr "Tesztelés" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -3718,14 +3717,12 @@ msgid "Show Guides" msgstr "VezetÅ‘vonalak MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show Origin" -msgstr "Rács MegjelenÃtése" +msgstr "Origó MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show Viewport" -msgstr "SegÃtÅ‘k MegjelenÃtése" +msgstr "Nézet MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" @@ -4019,7 +4016,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "" +msgstr "A Háló-primitÃv tÃpusa nem háromszög (PRIMITIVE_TRIANGLES)!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" @@ -4965,7 +4962,7 @@ msgstr "Vec kezelÅ‘ változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Vec Scalar Operator" -msgstr "" +msgstr "Vektor skalár kezelÅ‘ változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change RGB Operator" @@ -4973,31 +4970,31 @@ msgstr "RGB kezelÅ‘ változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Toggle Rot Only" -msgstr "" +msgstr "Csak vörös kapcsolása" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Scalar Function" -msgstr "" +msgstr "Skalár-függvény változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Vec Function" -msgstr "" +msgstr "Vektor-függvény változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Scalar Uniform" -msgstr "" +msgstr "Egységes-skalár változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Vec Uniform" -msgstr "" +msgstr "Egységes-vektor változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change RGB Uniform" -msgstr "" +msgstr "Egységes-RGB változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Default Value" -msgstr "" +msgstr "Alapérték változtatás" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change XForm Uniform" @@ -5093,7 +5090,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Plane Transform." -msgstr "" +msgstr "Megnéz a SÃklap transzformációját." #: editor/plugins/spatial_editor_plugin.cpp msgid "Scaling: " @@ -5245,7 +5242,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Doppler Enable" -msgstr "" +msgstr "Doppler engedélyezése" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" @@ -5684,9 +5681,8 @@ msgid "Checked Item" msgstr "" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Radio Item" -msgstr "Elem Hozzáadása" +msgstr "Rádió Elem" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Radio Item" @@ -5983,9 +5979,8 @@ msgid "Imported Project" msgstr "" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Érvénytelen név." +msgstr "Érvénytelen projektnév." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6380,7 +6375,7 @@ msgstr "" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" -msgstr "" +msgstr "Ãltalános" #: editor/project_settings_editor.cpp editor/property_editor.cpp msgid "Property:" @@ -7244,7 +7239,7 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" -msgstr "KövetkezÅ‘ SÃk" +msgstr "KövetkezÅ‘ SÃklap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Previous Plane" @@ -7724,7 +7719,7 @@ msgstr "" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Path does not lead Node!" -msgstr "" +msgstr "Az út nem vezeti a csomópontot!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." @@ -8102,6 +8097,13 @@ msgstr "Hiba a betűtÃpus betöltésekor." msgid "Invalid font size." msgstr "Érvénytelen betűtÃpus méret." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "ElÅ‘zÅ‘ fül" + +#~ msgid "Next" +#~ msgstr "KövetkezÅ‘" + #~ msgid "" #~ "Invalid version.txt format inside templates. Revision is not a valid " #~ "identifier." @@ -8112,9 +8114,6 @@ msgstr "Érvénytelen betűtÃpus méret." #~ msgid "Can't write file." #~ msgstr "Nem lehet fájlt Ãrni." -#~ msgid "Next" -#~ msgstr "KövetkezÅ‘" - #~ msgid "Not found!" #~ msgstr "Nincs Találat!" diff --git a/editor/translations/id.po b/editor/translations/id.po index 26a9739169..3956378ce7 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -2,12 +2,12 @@ # 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. -# # Abdul Aziz Muslim Alqudsy <abdul.aziz.muslim.alqudsy@gmail.com>, 2016. # Andevid Dynmyn <doyan4forum@gmail.com>, 2016. # Andinawan Asa <asaandinawan@gmail.com>, 2016. # Damar Inderajati <damarind@gmail.com>, 2017. # Damar S. M <the.last.walla@gmail.com>, 2017. +# 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. @@ -15,19 +15,18 @@ # Tito <ijavadroid@gmail.com>, 2018. # Tom My <tom.asadinawan@gmail.com>, 2017. # yursan9 <rizal.sagi@gmail.com>, 2016. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-05-31 16:39+0000\n" -"Last-Translator: Sofyan Sugianto <sofyanartem@gmail.com>\n" +"PO-Revision-Date: 2018-06-22 08:30+0000\n" +"Last-Translator: Fajar Ru <kzofajar@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\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" @@ -6483,7 +6482,7 @@ msgstr "" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" -msgstr "" +msgstr "Umum" #: editor/project_settings_editor.cpp editor/property_editor.cpp msgid "Property:" @@ -8350,6 +8349,13 @@ msgid "Invalid font size." msgstr "Ukuran font tidak sah." #, fuzzy +#~ msgid "Previous" +#~ msgstr "Tab sebelumnya" + +#~ msgid "Next" +#~ msgstr "Berikutnya" + +#, fuzzy #~ msgid "Can't contain '/' or ':'" #~ msgstr "Sambungkan Ke Node:" @@ -8364,9 +8370,6 @@ msgstr "Ukuran font tidak sah." #~ msgid "Can't write file." #~ msgstr "Tidak dapat membuat folder." -#~ msgid "Next" -#~ msgstr "Berikutnya" - #~ msgid "Not found!" #~ msgstr "Tidak ditemukan!" diff --git a/editor/translations/it.po b/editor/translations/it.po index 9e6833e576..2d566fe163 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -8449,6 +8449,13 @@ msgstr "Errore caricamento font." msgid "Invalid font size." msgstr "Dimensione font Invalida." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Scheda precedente" + +#~ msgid "Next" +#~ msgstr "Successivo" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Azione invalida (va bene tutto a parte '/' o ':')." @@ -8479,9 +8486,6 @@ msgstr "Dimensione font Invalida." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Impossibile creare project.godot nel percorso di progetto." -#~ msgid "Next" -#~ msgstr "Successivo" - #~ msgid "Not found!" #~ msgstr "Non trovato!" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 71b68636f6..5ce73d0442 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.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. -# # akirakido <achts.y@gmail.com>, 2016-2017. # D_first <dntk.daisei@gmail.com>, 2017, 2018. # Daisuke Saito <d.saito@coriginate.com>, 2017, 2018. @@ -14,20 +13,20 @@ # Shinsuke Masuda <shinsuke.masuda@gmail.com>, 2018. # Tetsuji Ochiai <ochiaixp@gmail.com>, 2017. # Tohru Ike (rokujyouhitoma) <rokujyouhitomajp@gmail.com>, 2017-2018. +# yu tang <0011solo@gmail.com>, 2018. # zukkun <zukkun@gmail.com>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-05-30 15:39+0000\n" -"Last-Translator: Shinsuke Masuda <shinsuke.masuda@gmail.com>\n" +"PO-Revision-Date: 2018-06-15 22:40+0000\n" +"Last-Translator: yu tang <0011solo@gmail.com>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" "Language: ja\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.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -579,7 +578,6 @@ msgstr "最近ã®:" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/quick_open.cpp -#, fuzzy msgid "Search:" msgstr "検索:" @@ -638,7 +636,6 @@ msgstr "リソース" #: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp #: editor/project_manager.cpp editor/project_settings_editor.cpp #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path" msgstr "パス" @@ -1144,7 +1141,7 @@ msgstr "自動èªã¿è¾¼ã¿ã‚’組ã¿æ›¿ãˆã‚‹" #: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp #: scene/gui/file_dialog.cpp msgid "Path:" -msgstr "Path:" +msgstr "パス:" #: editor/editor_autoload_settings.cpp #, fuzzy @@ -1153,7 +1150,6 @@ msgstr "ノードã®åå‰:" #: editor/editor_autoload_settings.cpp editor/editor_profiler.cpp #: editor/project_manager.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "Name" msgstr "åå‰" @@ -1197,7 +1193,7 @@ msgstr "ディレクトリをé¸ã¶" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "フォルダを作æˆã™ã‚‹" +msgstr "フォルダーを作æˆ" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -1236,9 +1232,8 @@ 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" @@ -1371,7 +1366,6 @@ msgstr "アセットを(å†ï¼‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆ" #: editor/editor_help.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Search Help" msgstr "ヘルプを検索" @@ -1550,7 +1544,7 @@ 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 #, fuzzy @@ -1579,9 +1573,8 @@ msgid "Requested file format unknown:" msgstr "ãã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯æœªçŸ¥ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã§ã™:" #: editor/editor_node.cpp -#, fuzzy msgid "Error while saving." -msgstr "ä¿å˜ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒèµ·ãã¾ã—ãŸ." +msgstr "ä¿å˜ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" #: editor/editor_node.cpp #, fuzzy @@ -1589,9 +1582,8 @@ msgid "Can't open '%s'." msgstr "'..'を処ç†ã§ãã¾ã›ã‚“" #: editor/editor_node.cpp -#, fuzzy msgid "Error while parsing '%s'." -msgstr "ä¿å˜ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒèµ·ãã¾ã—ãŸ." +msgstr "「%sã€ã®è§£æžä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." @@ -1603,9 +1595,8 @@ msgid "Missing '%s' or its dependencies." msgstr "シーン'%s' ã¯ä¾å˜é–¢ä¿‚ãŒå£Šã‚Œã¦ã„ã¾ã™:" #: editor/editor_node.cpp -#, fuzzy msgid "Error while loading '%s'." -msgstr "ä¿å˜ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒèµ·ãã¾ã—ãŸ." +msgstr "「%sã€ã®èªè¾¼ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" #: editor/editor_node.cpp msgid "Saving Scene" @@ -1924,14 +1915,12 @@ msgid "Exit the editor?" msgstr "エディターを終了ã—ã¾ã™ã‹ï¼Ÿ" #: editor/editor_node.cpp -#, fuzzy msgid "Open Project Manager?" -msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼" +msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’é–‹ãã¾ã™ã‹ï¼Ÿ" #: editor/editor_node.cpp -#, fuzzy msgid "Save & Quit" -msgstr "ファイルをä¿å˜" +msgstr "ファイルをä¿å˜ã—ã¦çµ‚了" #: editor/editor_node.cpp msgid "Save changes to the following scene(s) before quitting?" @@ -2194,7 +2183,7 @@ msgstr "ツール" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "終了ã—ã¦ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãƒªã‚¹ãƒˆã‚’é–‹ã" +msgstr "終了ã—ã¦ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆä¸€è¦§ã‚’é–‹ã" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -2334,7 +2323,6 @@ msgstr "クラス" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/project_settings_editor.cpp -#, fuzzy msgid "Search" msgstr "検索" @@ -2480,7 +2468,7 @@ msgstr "ベクトル定数を変更" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "インãƒãƒ¼ãƒˆï¼ˆå–ã‚Šè¾¼ã¿ï¼‰" +msgstr "インãƒãƒ¼ãƒˆ" #: editor/editor_node.cpp #, fuzzy @@ -3058,7 +3046,7 @@ msgstr "移動" #: editor/filesystem_dock.cpp editor/plugins/animation_tree_editor_plugin.cpp #: editor/project_manager.cpp msgid "Rename" -msgstr "åå‰ã‚’変更ã™ã‚‹" +msgstr "åå‰ã®å¤‰æ›´" #: editor/groups_editor.cpp #, fuzzy @@ -3705,12 +3693,10 @@ msgid "Connection error, please try again." msgstr "接続失敗 å†è©¦è¡Œã‚’" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Can't connect to host:" msgstr "ホストã«æŽ¥ç¶šã§ãã¾ã›ã‚“:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "No response from host:" msgstr "ホストã‹ã‚‰å¿œç”ãŒã‚ã‚Šã¾ã›ã‚“:" @@ -6655,9 +6641,8 @@ msgid "Please choose a 'project.godot' file." msgstr "'project.godot' ファイルをé¸æŠžã—ã¦ãã ã•ã„." #: editor/project_manager.cpp -#, fuzzy msgid "Please choose an empty folder." -msgstr "'project.godot' ファイルをé¸æŠžã—ã¦ãã ã•ã„." +msgstr "空ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠžã—ã¦ãã ã•ã„。" #: editor/project_manager.cpp msgid "Imported Project" @@ -6675,7 +6660,7 @@ msgstr "フォルダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" #: editor/project_manager.cpp msgid "There is already a folder in this path with the specified name." -msgstr "" +msgstr "ã“ã®ãƒ‘スã«ã¯ã€æŒ‡å®šã•ã‚ŒãŸåå‰ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ãŒæ—¢ã«å˜åœ¨ã—ã¾ã™ã€‚" #: editor/project_manager.cpp msgid "It would be a good idea to name your project." @@ -6709,9 +6694,8 @@ msgid "The following files failed extraction from package:" msgstr "以下ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’パッケージã‹ã‚‰æŠ½å‡ºã§ãã¾ã›ã‚“ã§ã—ãŸ:" #: editor/project_manager.cpp -#, fuzzy msgid "Rename Project" -msgstr "åç„¡ã—ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆ" +msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆåã®å¤‰æ›´" #: editor/project_manager.cpp msgid "New Game Project" @@ -6728,12 +6712,11 @@ msgstr "インãƒãƒ¼ãƒˆã—ã¦é–‹ã" #: editor/project_manager.cpp msgid "Create New Project" -msgstr "æ–°ã—ã„プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’作る" +msgstr "æ–°è¦ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’作æˆ" #: editor/project_manager.cpp -#, fuzzy msgid "Create & Edit" -msgstr "発光物を生æˆ" +msgstr "作æˆã—ã¦ç·¨é›†" #: editor/project_manager.cpp msgid "Install Project:" @@ -6745,14 +6728,12 @@ msgid "Install & Edit" msgstr "インストール" #: editor/project_manager.cpp -#, fuzzy msgid "Project Name:" msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆå:" #: editor/project_manager.cpp -#, fuzzy msgid "Create folder" -msgstr "フォルダを作æˆã™ã‚‹" +msgstr "フォルダを作æˆ" #: editor/project_manager.cpp msgid "Project Path:" @@ -6760,16 +6741,15 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘ス:" #: editor/project_manager.cpp msgid "Browse" -msgstr "ブラウズ" +msgstr "å‚照…" #: editor/project_manager.cpp msgid "Unnamed Project" msgstr "åç„¡ã—ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆ" #: editor/project_manager.cpp -#, fuzzy msgid "Can't open project" -msgstr "接続失敗." +msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’é–‹ã‘ã¾ã›ã‚“" #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" @@ -6797,19 +6777,17 @@ msgid "Are you sure to run more than one project?" msgstr "複数ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’本当ã«å®Ÿè¡Œã—ã¾ã™ã‹ï¼Ÿ" #: editor/project_manager.cpp -#, fuzzy msgid "Remove project from the list? (Folder contents will not be modified)" msgstr "" -"リストã‹ã‚‰ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’除去ã—ã¾ã™ã‹ï¼Ÿï¼ˆãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã¯å½±éŸ¿ã‚’å—ã‘ã¾" -"ã›ã‚“)" +"一覧ã‹ã‚‰ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’削除ã—ã¾ã™ã‹ï¼Ÿï¼ˆãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®å†…容ã¯å¤‰æ›´ã•ã‚Œã¾ã›ã‚“)" #: editor/project_manager.cpp msgid "" "Language changed.\n" "The UI will update next time the editor or project manager starts." msgstr "" -"言語ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸ.\n" -"エディタã¾ãŸã¯ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãƒžãƒã‚¸ãƒ£ãƒ¼å†é–‹æ™‚ã«UIãŒæ›´æ–°ã•ã‚Œã¾ã™." +"言語ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚\n" +"エディターã¾ãŸã¯ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼å†èµ·å‹•å¾Œã«UIãŒæ›´æ–°ã•ã‚Œã¾ã™ã€‚" #: editor/project_manager.cpp msgid "" @@ -6823,7 +6801,7 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼" #: editor/project_manager.cpp msgid "Project List" -msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã®ãƒªã‚¹ãƒˆ" +msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆä¸€è¦§" #: editor/project_manager.cpp msgid "Scan" @@ -6835,34 +6813,31 @@ msgstr "スã‚ャンã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž" #: editor/project_manager.cpp msgid "New Project" -msgstr "æ–°ã—ã„プãƒã‚¸ã‚§ã‚¯ãƒˆ" +msgstr "æ–°è¦ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆ" #: editor/project_manager.cpp -#, fuzzy msgid "Templates" -msgstr "é¸æŠžã—ã¦ã„ã‚‹ã‚‚ã®ã‚’削除" +msgstr "テンプレート" #: editor/project_manager.cpp msgid "Exit" msgstr "終了" #: editor/project_manager.cpp -#, fuzzy msgid "Restart Now" -msgstr "アニメーションを最åˆã‹ã‚‰å†ç”Ÿã™ã‚‹ :" +msgstr "今ã™ãå†èµ·å‹•" #: editor/project_manager.cpp -#, fuzzy msgid "Can't run project" -msgstr "接続失敗." +msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’実行ã§ãã¾ã›ã‚“" #: editor/project_manager.cpp msgid "" "You don't currently have any projects.\n" "Would you like to explore the official example projects in the Asset Library?" msgstr "" -"ã‚ãªãŸã¯ç¾åœ¨ã©ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚‚æŒã£ã¦ã„ã¾ã›ã‚“。\n" -"アセットライブラリã§å…¬å¼ã®ã‚µãƒ³ãƒ—ルプãƒã‚¸ã‚§ã‚¯ãƒˆã‚’探ã—ã¾ã—ょã†ã‹ï¼Ÿ" +"プãƒã‚¸ã‚§ã‚¯ãƒˆãŒä½•ã‚‚登録ã•ã‚Œã¦ã„ã¾ã›ã‚“。\n" +"アセットライブラリã§å…¬å¼ã®ã‚µãƒ³ãƒ—ルプãƒã‚¸ã‚§ã‚¯ãƒˆã‚’ãƒã‚§ãƒƒã‚¯ã—ã¾ã™ã‹ï¼Ÿ" #: editor/project_settings_editor.cpp #, fuzzy @@ -9050,7 +9025,7 @@ msgstr "è¦å‘Š!" #: scene/gui/dialogs.cpp msgid "Please Confirm..." -msgstr "確èªã—ã¦ãã ã•ã„。" +msgstr "確èª" #: scene/gui/file_dialog.cpp #, fuzzy @@ -9119,6 +9094,13 @@ msgstr "フォントèªã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã€‚" msgid "Invalid font size." msgstr "無効ãªãƒ•ã‚©ãƒ³ãƒˆ サイズã§ã™ã€‚" +#, fuzzy +#~ msgid "Previous" +#~ msgstr "以å‰ã®ã‚¿ãƒ–" + +#~ msgid "Next" +#~ msgstr "次" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "ä¸æ£ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ï¼ˆ '/' ã¨':'ã¯ä¸å¯ã§ã™ï¼‰." @@ -9147,9 +9129,6 @@ msgstr "無効ãªãƒ•ã‚©ãƒ³ãƒˆ サイズã§ã™ã€‚" #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "project.godotをプãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スã«ç”Ÿæˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "Next" -#~ msgstr "次" - #~ msgid "Not found!" #~ msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“!" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 575c14c97c..be6b540a9a 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -2,21 +2,20 @@ # 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. -# # Ch <ccwpc@hanmail.net>, 2017. # paijai 송 (fivejobi) <xotjq237@gmail.com>, 2018. +# pgyage3263 <pgyage3263@naver.com>, 2018. # Sun Kim <perplexingsun@gmail.com>, 2018. # TheRedPlanet <junmo.moon8@gmail.com>, 2018. # Xavier Cho <mysticfallband@gmail.com>, 2018. # 박한얼 (volzhs) <volzhs@gmail.com>, 2016-2018. # ì†¡íƒœì„ <xotjq237@gmail.com>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-05-27 04:39+0000\n" -"Last-Translator: ì†¡íƒœì„ <xotjq237@gmail.com>\n" +"PO-Revision-Date: 2018-06-07 16:40+0000\n" +"Last-Translator: pgyage3263 <pgyage3263@naver.com>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" "Language: ko\n" @@ -24,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-dev\n" +"X-Generator: Weblate 3.0\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5677,9 +5676,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" @@ -5960,9 +5958,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." @@ -6162,13 +6159,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!" @@ -8177,6 +8173,13 @@ msgstr "í°íŠ¸ 로딩 ì—러." msgid "Invalid font size." msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ í°íŠ¸ í¬ê¸°." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "ì´ì „ íƒ" + +#~ msgid "Next" +#~ msgstr "다ìŒ" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ ì•¡ì…˜ ('/' ë˜ëŠ” ':' ë¬¸ìž ì‚¬ìš© 불가)." @@ -8202,9 +8205,6 @@ msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ í°íŠ¸ í¬ê¸°." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "프로ì 트 ê²½ë¡œì— project.godot 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." -#~ msgid "Next" -#~ msgstr "다ìŒ" - #~ msgid "Not found!" #~ msgstr "ì°¾ì„ ìˆ˜ ì—†ìŒ!" diff --git a/editor/translations/lt.po b/editor/translations/lt.po index aaf6fc4499..bf4443627a 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -2,14 +2,12 @@ # 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. -# # Ignas Kiela <ignaskiela@super.lt>, 2017. -# Kornelijus <kornelijus.github@gmail.com>, 2017. -# +# Kornelijus <kornelijus.github@gmail.com>, 2017, 2018. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2017-11-27 00:48+0000\n" +"PO-Revision-Date: 2018-06-12 09:40+0000\n" "Last-Translator: Kornelijus <kornelijus.github@gmail.com>\n" "Language-Team: Lithuanian <https://hosted.weblate.org/projects/godot-engine/" "godot/lt/>\n" @@ -18,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=4; plural=n==1 ? 0 : n%10>=2 && (n%100<10 || n" "%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3;\n" -"X-Generator: Weblate 2.18-dev\n" +"X-Generator: Weblate 3.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2022,11 +2020,11 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" -msgstr "" +msgstr "BendruomenÄ—" #: editor/editor_node.cpp msgid "About" -msgstr "" +msgstr "Apie" #: editor/editor_node.cpp msgid "Play the project." diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 1637ef9725..e76053150c 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2,27 +2,27 @@ # 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. -# # Allan Nordhøy <epost@anotheragency.no>, 2017-2018. # Anonymous <GentleSaucepan@protonmail.com>, 2017. +# Elias <eliasnykrem@gmail.com>, 2018. # flesk <eivindkn@gmail.com>, 2017. +# Frank T. Rambol <frank@d-fect.com>, 2018. # Jørgen Aarmo Lund <jorgen.aarmo@gmail.com>, 2016. # NicolaiF <nico-fre@hotmail.com>, 2017-2018. # Norwegian Disaster <stian.furu.overbye@gmail.com>, 2017. # passeride <lukas@passeride.com>, 2017. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-03-22 03:38+0000\n" -"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n" +"PO-Revision-Date: 2018-06-22 08:31+0000\n" +"Last-Translator: Frank T. Rambol <frank@d-fect.com>\n" "Language-Team: Norwegian BokmÃ¥l <https://hosted.weblate.org/projects/godot-" "engine/godot/nb/>\n" "Language: nb\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 2.20-dev\n" +"X-Generator: Weblate 3.1-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -33,9 +33,8 @@ msgid "All Selection" msgstr "Alle valg" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Time" -msgstr "Anim Forandre Verdi" +msgstr "Anim Endre Nøkkelbildetid" #: editor/animation_editor.cpp msgid "Anim Change Transition" @@ -46,9 +45,8 @@ msgid "Anim Change Transform" msgstr "Anim Forandre Omforming" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Value" -msgstr "Anim Forandre Verdi" +msgstr "Anim Endre Nøkkelbildeverdi" #: editor/animation_editor.cpp msgid "Anim Change Call" @@ -99,9 +97,8 @@ msgid "Edit Node Curve" msgstr "Forandre Nodekurve" #: editor/animation_editor.cpp -#, fuzzy msgid "Edit Selection Curve" -msgstr "Forandre utvalgskurve" +msgstr "Rediger utvalgskurve" #: editor/animation_editor.cpp msgid "Anim Delete Keys" @@ -501,9 +498,8 @@ msgid "Connecting Signal:" msgstr "Kobler Til Signal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect '%s' from '%s'" -msgstr "Koble '%s' til '%s'" +msgstr "Koble '%s' fra '%s'" #: editor/connections_dialog.cpp msgid "Connect..." @@ -519,9 +515,8 @@ msgid "Signals" msgstr "Signaler" #: editor/create_dialog.cpp -#, fuzzy msgid "Change %s Type" -msgstr "Endre standard type" +msgstr "Endre %s type" #: editor/create_dialog.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -529,9 +524,8 @@ msgid "Change" msgstr "Forandre" #: editor/create_dialog.cpp -#, fuzzy msgid "Create New %s" -msgstr "Lag Ny" +msgstr "Lag ny %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -598,7 +592,7 @@ msgstr "Ressurs" #: editor/project_manager.cpp editor/project_settings_editor.cpp #: editor/script_create_dialog.cpp msgid "Path" -msgstr "Sti" +msgstr "Søkesti" #: editor/dependency_editor.cpp msgid "Dependencies:" @@ -642,9 +636,8 @@ msgstr "" "Fjern dem likevel? (kan ikke angres)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Cannot remove:" -msgstr "Kan ikke fjerne:\n" +msgstr "Kan ikke fjerne:" #: editor/dependency_editor.cpp msgid "Error loading:" @@ -729,9 +722,8 @@ msgid "Lead Developer" msgstr "Utviklingsleder" #: editor/editor_about.cpp -#, fuzzy msgid "Project Manager " -msgstr "Prosjektleder" +msgstr "Prosjektleder " #: editor/editor_about.cpp msgid "Developers" @@ -840,9 +832,8 @@ msgid "Rename Audio Bus" msgstr "Gi nytt navn til Audio Bus" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Change Audio Bus Volume" -msgstr "Veksle Audio Bus Solo" +msgstr "Endre Lydbuss Volum" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" @@ -885,7 +876,6 @@ msgid "Mute" msgstr "Demp" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Bypass" msgstr "OmgÃ¥" @@ -1131,9 +1121,8 @@ msgid "Packing" msgstr "Pakking" #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found:" -msgstr "Malfil ble ikke funnet:\n" +msgstr "Malfil ble ikke funnet:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" @@ -1344,19 +1333,18 @@ msgid "Description" msgstr "Beskrivelse" #: editor/editor_help.cpp -#, fuzzy msgid "Online Tutorials:" -msgstr "Online Dokumentasjon" +msgstr "Online dokumentasjon:" #: editor/editor_help.cpp -#, fuzzy msgid "" "There are currently no tutorials for this class, you can [color=$color][url=" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Det finnes i øyeblikket ingen beskrivelse av denne metoden. Hjelp til ved Ã¥ " -"[colour=$color][url=$url]bidra med en[/url][/color]!" +"Det finnes i øyeblikket ingen beskrivelse av denne metoden, men du kan " +"[colour=$color][url=$url]bidra med en[/url][/color] eller [color=$color][url=" +"$url2]be om en[/url][/color]." #: editor/editor_help.cpp msgid "Properties" @@ -1410,13 +1398,12 @@ msgid "Clear" msgstr "Tøm" #: editor/editor_log.cpp -#, fuzzy msgid "Clear Output" -msgstr "Output" +msgstr "Nullstill resultat" #: editor/editor_node.cpp msgid "Project export failed with error code %d." -msgstr "" +msgstr "Eksport av prosjektet mislyktes med feilkode %d." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" @@ -1428,9 +1415,8 @@ msgstr "Lagre Ressurs Som..." #: editor/editor_node.cpp editor/plugins/spatial_editor_plugin.cpp #: editor/scene_tree_dock.cpp -#, fuzzy msgid "I see..." -msgstr "Jeg ser..." +msgstr "Jeg forstÃ¥r..." #: editor/editor_node.cpp msgid "Can't open file for writing:" @@ -1453,9 +1439,8 @@ msgid "Error while parsing '%s'." msgstr "Error ved parsing av '%s'." #: editor/editor_node.cpp -#, fuzzy msgid "Unexpected end of file '%s'." -msgstr "Uventet ende av fil '%s'." +msgstr "Uventet slutt pÃ¥ fil '%s'." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." @@ -1482,13 +1467,12 @@ msgid "This operation can't be done without a tree root." msgstr "Denne operasjonen kan ikke gjennomføres uten en trerot." #: editor/editor_node.cpp -#, fuzzy msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" -"Kunne ikke lagre scene. Sannsynligvis avhengigheter (instanser) ikke kunne " -"oppfylles." +"Kunne ikke lagre scene. Sannsynligvis kunne ikke avhengigheter (instanser " +"eller arvinger) oppfylles." #: editor/editor_node.cpp msgid "Failed to load resource." @@ -1600,14 +1584,12 @@ msgid "Copy Resource" msgstr "Kopier Ressurs" #: editor/editor_node.cpp -#, fuzzy msgid "Make Built-In" -msgstr "Lag Innebygd" +msgstr "Lag innebygget" #: editor/editor_node.cpp -#, fuzzy msgid "Make Sub-Resources Unique" -msgstr "Gjør Underressurs Unik" +msgstr "Lag underressurser unike" #: editor/editor_node.cpp msgid "Open in Help" @@ -1628,14 +1610,13 @@ msgstr "" "'applikasjon'." #: editor/editor_node.cpp -#, fuzzy msgid "" "Selected scene '%s' does not exist, select a valid one?\n" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Valgte scene '%s' finnes ikke, velg en gyldig en?\n" -"Du kan endre dette senere under \"Prosjekt Innstillinger\" under kategorien " +"Den valgte scenen '%s' finnes ikke. Vil du velge en gyldig scene?\n" +"Du kan endre dette senere i \"Prosjektinnstillinger\" under kategorien " "'applikasjon'." #: editor/editor_node.cpp @@ -1933,7 +1914,7 @@ msgstr "MeshBibliotek..." #: editor/editor_node.cpp #, fuzzy msgid "TileSet..." -msgstr "TileSet..." +msgstr "TileSet…" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -1983,9 +1964,8 @@ msgid "Debug" msgstr "Debug" #: editor/editor_node.cpp -#, fuzzy msgid "Deploy with Remote Debug" -msgstr "Deploy med Ekstern Debug" +msgstr "Distribuer med ekstern feilsøking" #: editor/editor_node.cpp #, fuzzy @@ -2145,7 +2125,7 @@ msgstr "Pause scenen" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "Pause Scene" +msgstr "Sett scenen pÃ¥ pause" #: editor/editor_node.cpp msgid "Stop the scene." @@ -8214,12 +8194,19 @@ msgstr "" #: scene/resources/dynamic_font.cpp msgid "Error loading font." -msgstr "" +msgstr "Feil ved innlasting av font." #: scene/resources/dynamic_font.cpp msgid "Invalid font size." msgstr "Ugyldig fontstørrelse." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Forrige fane" + +#~ msgid "Next" +#~ msgstr "Neste" + #~ msgid "" #~ "Invalid version.txt format inside templates. Revision is not a valid " #~ "identifier." @@ -8230,9 +8217,6 @@ msgstr "Ugyldig fontstørrelse." #~ msgid "Can't write file." #~ msgstr "Kan ikke skrive fil." -#~ msgid "Next" -#~ msgstr "Neste" - #~ msgid "Not found!" #~ msgstr "Ikke funnet!" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 3bf8ab3a32..bfedf322b3 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -8272,6 +8272,13 @@ msgid "Invalid font size." msgstr "Ongeldige lettertype grootte." #, fuzzy +#~ msgid "Previous" +#~ msgstr "Vorig tabblad" + +#~ msgid "Next" +#~ msgstr "Volgende" + +#, fuzzy #~ msgid "Can't contain '/' or ':'" #~ msgstr "Kan niet verbinden met host:" @@ -8285,9 +8292,6 @@ msgstr "Ongeldige lettertype grootte." #~ msgid "Can't write file." #~ msgstr "Kan niet naar bestand schrijven." -#~ msgid "Next" -#~ msgstr "Volgende" - #~ msgid "Not found!" #~ msgstr "Niet gevonden!" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 1a597cee5a..5ca2760249 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.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. -# # 8-bit Pixel <dawdejw@gmail.com>, 2016. # Adam Wolanski <adam.wolanski94@gmail.com>, 2017. # Adrian WÄ™cÅ‚awski <weclawskiadrian@gmail.com>, 2016. @@ -25,11 +24,10 @@ # Sebastian Pasich <sebastian.pasich@gmail.com>, 2017. # siatek papieros <sbigneu@gmail.com>, 2016. # Zatherz <zatherz@linux.pl>, 2017. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-06-05 13:41+0000\n" +"PO-Revision-Date: 2018-06-22 08:31+0000\n" "Last-Translator: RM <synaptykq@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -38,7 +36,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 3.0\n" +"X-Generator: Weblate 3.1-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5354,7 +5352,7 @@ msgstr "Tryb skalowania (R)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Coords" -msgstr "Koordynaty lokalne" +msgstr "Local Coords" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Space Mode (%s)" @@ -8294,6 +8292,13 @@ msgstr "BÅ‚Ä…d Å‚adowania fonta." msgid "Invalid font size." msgstr "Niepoprawny rozmiar fonta." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Poprzednia zakÅ‚adka" + +#~ msgid "Next" +#~ msgstr "NastÄ™pny" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "NieprawidÅ‚owa akcja (wszystko oprócz '/' lub ':')." @@ -8319,9 +8324,6 @@ msgstr "Niepoprawny rozmiar fonta." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Nie znaleziono project.godot w Å›cieżce projektu." -#~ msgid "Next" -#~ msgstr "NastÄ™pny" - #~ msgid "Not found!" #~ msgstr "Nie znaleziono!" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 9880271a0d..6d26cbc500 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.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. -# # Allyson Souza <allyson_as@outlook.com>, 2017. # Anderson Araujo <anderson.araujoprog@gmail.com>, 2018. # António Sarmento <antonio.luis.sarmento@gmail.com>, 2016. @@ -24,14 +23,12 @@ # Renato Rotenberg <renato.rotenberg@gmail.com>, 2017. # Rodolfo R Gomes <rodolforg@gmail.com>, 2017-2018. # Tiago Almeida <thyagoeap@gmail.com>, 2017. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2018-05-20 21:41+0000\n" -"Last-Translator: Michael Alexsander Silva Dias <michaelalexsander@protonmail." -"com>\n" +"PO-Revision-Date: 2018-06-16 18:43+0000\n" +"Last-Translator: Rodolfo R Gomes <rodolforg@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -39,7 +36,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.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -525,7 +522,7 @@ msgstr "Conectar..." #: editor/connections_dialog.cpp #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Disconnect" -msgstr "Disconectar" +msgstr "Desconectar" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -3308,7 +3305,7 @@ msgstr "AnimationTree" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" -msgstr "Livrar" +msgstr "Livre" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" @@ -5717,9 +5714,8 @@ msgid "Options" msgstr "Opções" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "Tem,Muitas,Várias,Opções!" +msgstr "Tem,Muitas,Opções" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -6008,9 +6004,8 @@ msgid "Imported Project" msgstr "Projeto Importado" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nome do Projeto:" +msgstr "Nome do Projeto Inválido." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6212,13 +6207,12 @@ msgid "Mouse Button" msgstr "Botão do Mous" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" "Nome de ação inválido. Ele não pode estar vazio ou conter '/', ':', '=', " -"'\\' ou '\"'" +"'\\' ou '\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -8246,6 +8240,13 @@ msgstr "Erro ao carregar fonte." msgid "Invalid font size." msgstr "Tamanho de fonte inválido." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Guia anterior" + +#~ msgid "Next" +#~ msgstr "Próximo" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Ação Inválida (qualquer coisa serve, exceto '/' ou ':')." @@ -8272,9 +8273,6 @@ msgstr "Tamanho de fonte inválido." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Não foi possÃvel encontrar project.godot no caminho do projeto." -#~ msgid "Next" -#~ msgstr "Próximo" - #~ msgid "Not found!" #~ msgstr "Não encontrado!" diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index 0d6a1c27a5..71275cd19a 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.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. -# # António Sarmento <antonio.luis.sarmento@gmail.com>, 2016. # Carlos Vieira <carlos.vieira@gmail.com>, 2017. # João <joao@nogordio.com>, 2018. @@ -14,19 +13,18 @@ # Rueben Stevens <supercell03@gmail.com>, 2017. # SARDON <fabio3_Santos@hotmail.com>, 2017. # Vinicius Gonçalves <viniciusgoncalves21@gmail.com>, 2017. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-05-26 14:42+0000\n" -"Last-Translator: João <joao@nogordio.com>\n" +"PO-Revision-Date: 2018-06-10 01:02+0000\n" +"Last-Translator: João Lopes <linux-man@hotmail.com>\n" "Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_PT/>\n" "Language: pt_PT\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.0\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5697,9 +5695,8 @@ msgid "Options" msgstr "Opções" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "Tem,Muitos,Vários,Opções!" +msgstr "Tem,Muitas,Opções" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -5986,9 +5983,8 @@ msgid "Imported Project" msgstr "Projeto importado" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nome do Projeto:" +msgstr "Nome do Projeto Inválido." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6189,13 +6185,12 @@ msgid "Mouse Button" msgstr "Botão do rato" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" "Nome de ação inválido. Não pode ser vazio nem conter '/', ':', '=', '\\' ou " -"'\"'" +"'\"'." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -8224,6 +8219,13 @@ msgstr "Erro ao carregar letra." msgid "Invalid font size." msgstr "Tamanho de letra inválido." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Guia anterior" + +#~ msgid "Next" +#~ msgstr "Proximo" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Ação inválida (tudo menos '/' ou ':')." @@ -8249,9 +8251,6 @@ msgstr "Tamanho de letra inválido." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "ImpossÃvel encontrar project.godot no Caminho do Projeto." -#~ msgid "Next" -#~ msgstr "Proximo" - #~ msgid "Not found!" #~ msgstr "Não encontrado!" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 9358c958a0..eaf931092a 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -2,16 +2,15 @@ # 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. -# +# Calin Sopterean <csopterean@gmail.com>, 2018. # Filip <filipanton@tutanota.com>, 2018. # Nitroretro <nitroretro@protonmail.com>, 2018. # TigerxWood <TigerxWood@gmail.com>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-05-10 20:02+0000\n" -"Last-Translator: Nitroretro <nitroretro@protonmail.com>\n" +"PO-Revision-Date: 2018-06-20 20:43+0000\n" +"Last-Translator: Calin Sopterean <csopterean@gmail.com>\n" "Language-Team: Romanian <https://hosted.weblate.org/projects/godot-engine/" "godot/ro/>\n" "Language: ro\n" @@ -19,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" -"X-Generator: Weblate 3.0-dev\n" +"X-Generator: Weblate 3.1-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -257,7 +256,7 @@ msgstr "Pas (s):" #: editor/animation_editor.cpp msgid "Cursor step snap (in seconds)." -msgstr "Pas Bruscare Cursor (în secunde)." +msgstr "Pas de Cursor Snap (în secunde)." #: editor/animation_editor.cpp msgid "Enable/Disable looping in animation." @@ -550,7 +549,7 @@ msgstr "Potriviri:" #: editor/plugins/asset_library_editor_plugin.cpp editor/property_selector.cpp #: editor/script_editor_debugger.cpp msgid "Description:" -msgstr "DescripÈ›ie:" +msgstr "Descriere:" #: editor/dependency_editor.cpp msgid "Search Replacement For:" @@ -794,7 +793,7 @@ msgstr "Eroare la deschiderea fiÅŸierului pachet, nu este în format zip." #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" -msgstr "Decompresez Active" +msgstr "Decomprimare Asset-uri" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package Installed Successfully!" @@ -893,7 +892,7 @@ msgstr "ȘtergeÈ›i Efectul" #: editor/editor_audio_buses.cpp msgid "Audio" -msgstr "Audio" +msgstr "Sunet" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" @@ -921,15 +920,15 @@ msgstr "MutaÈ›i Pista Audio" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "SalvaÈ›i Pista Audio Șablon Ca..." +msgstr "SalvaÈ›i Schema Pistei Audio Ca..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." -msgstr "LocaÈ›ie pentru Noul Șablon..." +msgstr "LocaÈ›ie pentru Noua Schemă..." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "DeschideÈ›i Șablon Pistă Audio" +msgstr "Deschide Schema Pistei Audio" #: editor/editor_audio_buses.cpp msgid "There is no 'res://default_bus_layout.tres' file." @@ -937,7 +936,7 @@ msgstr "Nu există nici un fiÅŸier 'res://default_bus_layout.tres'." #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." -msgstr "FiÅŸier nevalid, nu un È™ablon de pistă audio." +msgstr "FiÅŸier nevalid, nu este o schemă de pistă audio." #: editor/editor_audio_buses.cpp msgid "Add Bus" @@ -945,7 +944,7 @@ msgstr "AdaugaÈ›i Pistă Audio" #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "CreaÅ£i un Șablon nou Pistă Audio." +msgstr "CreaÅ£i o Schemă nouă de Pistă Audio." #: editor/editor_audio_buses.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp @@ -954,7 +953,7 @@ msgstr "ÃŽncărcaÈ›i" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." -msgstr "ÃŽncărcaÅ£i un Șablon de Pistă Audio existent." +msgstr "ÃŽncărcaÅ£i o Schemă de Pistă Audio existentă." #: editor/editor_audio_buses.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -963,7 +962,7 @@ msgstr "SalvaÈ›i Ca" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "SalvaÅ£i acest Șablon Pistă Audio într-un fiÅŸier." +msgstr "SalvaÅ£i acestă Schemă de Pistă Audio într-un fiÅŸier." #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" @@ -971,7 +970,7 @@ msgstr "ÃŽncărcaÈ›i Implicit" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "ÃŽncărcat Șablonul Pistă Audio implicit." +msgstr "ÃŽncarcă Schema de Pistă Audio implicită." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1242,7 +1241,7 @@ msgstr "SurseScan" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" -msgstr "(Re)Importând Bunuri" +msgstr "(Re)Importând Asset-uri" #: editor/editor_help.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp @@ -1393,11 +1392,11 @@ msgstr "AfiÈ™are:" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "GoliÈ›i" +msgstr "Curăță" #: editor/editor_log.cpp msgid "Clear Output" -msgstr "GoliÈ›i AfiÈ™area" +msgstr "Curăță AfiÈ™area" #: editor/editor_node.cpp msgid "Project export failed with error code %d." @@ -1498,15 +1497,15 @@ msgstr "Eroare la încercarea de a salva schema!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "Șablon Editor implicit suprascris." +msgstr "Schemă implicită de editor suprascrisă." #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "Numele È™ablonului nu a fost găsit!" +msgstr "Numele schemei nu a fost găsit!" #: editor/editor_node.cpp msgid "Restored default layout to base settings." -msgstr "Restaurat È™ablonul implicit la setările de bază." +msgstr "S-a restaurat schema implictă la setările de bază." #: editor/editor_node.cpp msgid "" @@ -1597,7 +1596,7 @@ msgstr "DeschideÈ›i în Ajutor" #: editor/editor_node.cpp msgid "There is no defined scene to run." -msgstr "Nu există nici o scenă definită pentru a rula." +msgstr "Nu există nici o scenă definită pentru a execuÈ›ie." #: editor/editor_node.cpp msgid "" @@ -1681,288 +1680,306 @@ msgstr "Această operaÈ›ie nu se poate face fără o scenă." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "Exportă Librăria de Mesh-uri" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "" +msgstr "Această operaÈ›iune nu poate fi făcută fără un nod de bază." #: editor/editor_node.cpp msgid "Export Tile Set" -msgstr "" +msgstr "Exportă Setul de Plăci" #: editor/editor_node.cpp msgid "This operation can't be done without a selected node." -msgstr "" +msgstr "Această operaÈ›iune nu poate fi făcută fără un nod selectat." #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "" +msgstr "Scena curentă nu este salvată. Deschizi oricum?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "" +msgstr "Nu se poate reîncărca o scenă care nu a fost salvată niciodată." #: editor/editor_node.cpp msgid "Revert" -msgstr "" +msgstr "ÃŽntoarcere" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "" +msgstr "Această acÈ›iune nu poate fi recuperată. Te reîntorci oricum?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "" +msgstr "Execută Rapid Scena..." #: editor/editor_node.cpp msgid "Quit" -msgstr "" +msgstr "ÃŽnchidere" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "" +msgstr "IeÈ™i din editor?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "" +msgstr "Deschizi Managerul de Proiect?" #: editor/editor_node.cpp msgid "Save & Quit" -msgstr "" +msgstr "Salvează È™i ÃŽnchide" #: editor/editor_node.cpp msgid "Save changes to the following scene(s) before quitting?" msgstr "" +"Salvezi modificările făcute în urmatoarea(le) scenă(e) înainte să închizi?" #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" msgstr "" +"Salvezi modificările făcute în urmatoarea(le) scenă(e) înainte să deschizi " +"Managerul de Proiect?" #: editor/editor_node.cpp msgid "" "This option is deprecated. Situations where refresh must be forced are now " "considered a bug. Please report." msgstr "" +"Această opÈ›iune este depreciată. SituaÈ›iile în care reînprospătarea trebuie " +"forÈ›ată sunt acum considerate buguri. Te rugăm să raportezi." #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "" +msgstr "Alege o Scenă Principală" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" +"Nu se poate iniÈ›ializa plugin-ul la: '%s' analizarea configuraÈ›iei a eÈ™uat." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." msgstr "" +"Nu a putut fi găsit câmpul scriptului pentru plugin la: 'res://addons/%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "" +msgstr "Nu a putut fi încărcat scriptul add-on din calea: '%s'." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" +"Nu a putut fi încărcat scriptul add-on din calea: '%s' tipul de Bază nu este " +"EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" +"Nu a putut fi încărcat scriptul add-on din calea: '%s' Scriptul nu este în " +"modul unealtă." #: editor/editor_node.cpp msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" +"Scena '%s' nu a fost importată automat, deci ea nu poate fi modificată.\n" +"Ca să poÈ›i face modificări, o nouă scenă derivată poate fi creată." #: editor/editor_node.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Ugh" -msgstr "" +msgstr "Uh" #: editor/editor_node.cpp msgid "" "Error loading scene, it must be inside the project path. Use 'Import' to " "open the scene, then save it inside the project path." msgstr "" +"Eroare la încărcarea scenei, aceasta trebuie să fie în calea spre proiect. " +"FoloseÈ™te 'Importă' ca să deschizi scena, apoi salveaz-o în calea spre " +"proiect." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "" +msgstr "Scena '%s' are dependinÈ›e nefuncÈ›ionale:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" -msgstr "" +msgstr "Curăță Scenele Recente" #: editor/editor_node.cpp msgid "Save Layout" -msgstr "" +msgstr "Salvează Schema" #: editor/editor_node.cpp msgid "Delete Layout" -msgstr "" +msgstr "Șterge Schema" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "" +msgstr "Implicit" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "" +msgstr "ComutaÈ›i între Scene" #: editor/editor_node.cpp msgid "%d more files or folders" -msgstr "" +msgstr "%d mai multe fiÈ™iere sau foldere" #: editor/editor_node.cpp msgid "%d more folders" -msgstr "" +msgstr "%d mai multe foldere" #: editor/editor_node.cpp msgid "%d more files" -msgstr "" +msgstr "%d mai multe fiÈ™iere" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "" +msgstr "PoziÈ›ia Dock-ului" #: editor/editor_node.cpp msgid "Distraction Free Mode" -msgstr "" +msgstr "Modul Fără Distrageri" #: editor/editor_node.cpp msgid "Toggle distraction-free mode." -msgstr "" +msgstr "Comutează modul fără distrageri." #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "" +msgstr "Adaugă o nouă scenă." #: editor/editor_node.cpp msgid "Scene" -msgstr "" +msgstr "Scenă" #: editor/editor_node.cpp msgid "Go to previously opened scene." -msgstr "" +msgstr "Mergi la o scenă deschisă anterior." #: editor/editor_node.cpp msgid "Next tab" -msgstr "" +msgstr "Fila următoare" #: editor/editor_node.cpp msgid "Previous tab" -msgstr "" +msgstr "Fila anterioară" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "" +msgstr "Filtrează fiÈ™ierele..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "" +msgstr "OperaÈ›iuni cu fiÈ™iere tip scenă." #: editor/editor_node.cpp msgid "New Scene" -msgstr "" +msgstr "Scenă Nouă" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "" +msgstr "Scenă Derivată Nouă..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "" +msgstr "Deschide Scena..." #: editor/editor_node.cpp msgid "Save Scene" -msgstr "" +msgstr "Salvează Scena" #: editor/editor_node.cpp msgid "Save all Scenes" -msgstr "" +msgstr "Salvează toate Scenele" #: editor/editor_node.cpp msgid "Close Scene" -msgstr "" +msgstr "ÃŽnchide Scena" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" -msgstr "" +msgstr "Deschide Recente" #: editor/editor_node.cpp msgid "Convert To..." -msgstr "" +msgstr "ConverteÈ™te ÃŽn..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "Librărie_de_Structuri..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "" +msgstr "Set_de_Plăci..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Undo" -msgstr "" +msgstr "Revenire" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp msgid "Redo" -msgstr "" +msgstr "Reîntoarcere" #: editor/editor_node.cpp msgid "Revert Scene" -msgstr "" +msgstr "RestabileÈ™te Scena" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "" +msgstr "Proiect Divers sau unelte pentru scenă." #: editor/editor_node.cpp msgid "Project" -msgstr "" +msgstr "Proiect" #: editor/editor_node.cpp msgid "Project Settings" -msgstr "" +msgstr "Setări ale Proiectului" #: editor/editor_node.cpp msgid "Run Script" -msgstr "" +msgstr "Execută Scriptul" #: editor/editor_node.cpp editor/project_export.cpp msgid "Export" -msgstr "" +msgstr "Exportare" #: editor/editor_node.cpp msgid "Tools" -msgstr "" +msgstr "Unelte" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "" +msgstr "ÃŽnchide spre Lista Proiectului" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Debug" -msgstr "" +msgstr "Depanare" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" -msgstr "" +msgstr "Lansează cu Depanare la Distanță" #: editor/editor_node.cpp msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" +"Când exporÈ›i sau lansezi, executabilul rezultat va încerca să se conecteze " +"la IP-ul acestui computer pentru a putea fi depanat." #: editor/editor_node.cpp msgid "Small Deploy with Network FS" -msgstr "" +msgstr "Mini Lansare cu ReÈ›ea FS" #: editor/editor_node.cpp msgid "" @@ -1973,30 +1990,39 @@ msgid "" "On Android, deploy will use the USB cable for faster performance. This " "option speeds up testing for games with a large footprint." msgstr "" +"Când această opÈ›iune este activată, exportarea sau lansarea va produce un " +"executabil minimal.\n" +"Sistemul de fiÈ™iere va fi furnizat de la proiect la editor prin reÈ›ea.\n" +"Pe Android, lansarea va folosi cablul USB pentru performanță mai rapidă. " +"Această opÈ›iune accelerează testarea jocurilor cu o marime substanÈ›ială." #: editor/editor_node.cpp msgid "Visible Collision Shapes" -msgstr "" +msgstr "Forme de Coliziune Vizibile" #: editor/editor_node.cpp msgid "" "Collision shapes and raycast nodes (for 2D and 3D) will be visible on the " "running game if this option is turned on." msgstr "" +"Formele de coliziune si nodurile raycast (pentru 2D È™i 3D) vor fi vizibile " +"când jocul rulează dacă această opÈ›iune este activată." #: editor/editor_node.cpp msgid "Visible Navigation" -msgstr "" +msgstr "Navigare Vizibilă" #: editor/editor_node.cpp msgid "" "Navigation meshes and polygons will be visible on the running game if this " "option is turned on." msgstr "" +"Structurile de navigare È™i poligoanele vor fi vizibile când jocul rulează " +"dacă această opÈ›iune este activată." #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "" +msgstr "Sincronizează Modificările Scenei" #: editor/editor_node.cpp msgid "" @@ -2005,10 +2031,14 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" +"Când această opÈ›iune este activată, orice modificare facută în scenă din " +"editor va fi replicată în jocul care rulează.\n" +"Când această opÈ›iune este folosită de la distanță pe un dispozitiv, este " +"mult mai eficient dacă este folosit un sistem de fiÈ™iere în reÈ›ea." #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "" +msgstr "Sincronizează Modificările Scriptului" #: editor/editor_node.cpp msgid "" @@ -2017,844 +2047,861 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" +"Când această opÈ›iune este activată, orice script salvat ulterior va fi " +"reîncărcat în jocul care rulează.\n" +"Când această opÈ›iune este folosită de la distanță pe un dispozitiv, este " +"mult mai eficient dacă este folosit un sistem de fiÈ™iere în reÈ›ea." #: editor/editor_node.cpp msgid "Editor" -msgstr "" +msgstr "Editor" #: editor/editor_node.cpp editor/settings_config_dialog.cpp msgid "Editor Settings" -msgstr "" +msgstr "Setări ale Editorului" #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "" +msgstr "Schema Editorului" #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "" +msgstr "Comută în Ecran Complet" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" -msgstr "" +msgstr "Administrează Șabloanele de Export" #: editor/editor_node.cpp msgid "Help" -msgstr "" +msgstr "Ajutor" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Classes" -msgstr "" +msgstr "Clase" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/project_settings_editor.cpp msgid "Search" -msgstr "" +msgstr "Căutare" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Online Docs" -msgstr "" +msgstr "DocumentaÈ›ie Online" #: editor/editor_node.cpp msgid "Q&A" -msgstr "" +msgstr "ÃŽntrebări È™i Răspunsuri" #: editor/editor_node.cpp msgid "Issue Tracker" -msgstr "" +msgstr "Agent de Monitorizare al Problemelor" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" -msgstr "" +msgstr "Comunitate" #: editor/editor_node.cpp msgid "About" -msgstr "" +msgstr "Despre" #: editor/editor_node.cpp msgid "Play the project." -msgstr "" +msgstr "Rulează proiectul." #: editor/editor_node.cpp msgid "Play" -msgstr "" +msgstr "Rulează" #: editor/editor_node.cpp msgid "Pause the scene" -msgstr "" +msgstr "ÃŽntrerupe scena" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "" +msgstr "ÃŽntrerupere Scenă" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "" +msgstr "OpreÈ™te scena." #: editor/editor_node.cpp msgid "Stop" -msgstr "" +msgstr "OpreÈ™te" #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "" +msgstr "Rulează scena editată." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "" +msgstr "Rulează Scena" #: editor/editor_node.cpp msgid "Play custom scene" -msgstr "" +msgstr "Rulează scena personalizată" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "" +msgstr "Rulează Scena Personalizată" #: editor/editor_node.cpp msgid "Spins when the editor window repaints!" -msgstr "" +msgstr "Se roteÈ™te când ferestra editorului se recolorează!" #: editor/editor_node.cpp msgid "Update Always" -msgstr "" +msgstr "Actualizează ÃŽntotdeauna" #: editor/editor_node.cpp msgid "Update Changes" -msgstr "" +msgstr "Modificări ale Actualizării" #: editor/editor_node.cpp msgid "Disable Update Spinner" -msgstr "" +msgstr "Dezactivează Cercul de Actualizare" #: editor/editor_node.cpp msgid "Inspector" -msgstr "" +msgstr "Inspector" #: editor/editor_node.cpp msgid "Create a new resource in memory and edit it." -msgstr "" +msgstr "Creează o nouă resursă în memorie È™i editeaz-o." #: editor/editor_node.cpp msgid "Load an existing resource from disk and edit it." -msgstr "" +msgstr "ÃŽncarcă o resursă existentă de pe disc si editeaz-o." #: editor/editor_node.cpp msgid "Save the currently edited resource." -msgstr "" +msgstr "Salvează resursa editată curentă." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Save As..." -msgstr "" +msgstr "Salvează Ca..." #: editor/editor_node.cpp msgid "Go to the previous edited object in history." -msgstr "" +msgstr "Mergi la un obiect din istoric editat anterior." #: editor/editor_node.cpp msgid "Go to the next edited object in history." -msgstr "" +msgstr "Mergi la următorul obiect editat din istoric." #: editor/editor_node.cpp msgid "History of recently edited objects." -msgstr "" +msgstr "Istoricul obiectelor editate recent." #: editor/editor_node.cpp msgid "Object properties." -msgstr "" +msgstr "Proprietățile obiectului." #: editor/editor_node.cpp msgid "Changes may be lost!" -msgstr "" +msgstr "Modificările pot fi pierdute!" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "" +msgstr "Importă" #: editor/editor_node.cpp msgid "Node" -msgstr "" +msgstr "Nod" #: editor/editor_node.cpp msgid "FileSystem" -msgstr "" +msgstr "Sistemul De FiÈ™iere" #: editor/editor_node.cpp msgid "Output" -msgstr "" +msgstr "IeÈ™ire" #: editor/editor_node.cpp msgid "Don't Save" -msgstr "" +msgstr "Nu Salva" #: editor/editor_node.cpp msgid "Import Templates From ZIP File" -msgstr "" +msgstr "Importă Șabloane Dintr-o Arhivă ZIP" #: editor/editor_node.cpp editor/project_export.cpp msgid "Export Project" -msgstr "" +msgstr "Exportă Proiectul" #: editor/editor_node.cpp msgid "Export Library" -msgstr "" +msgstr "Exportă Librăria" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "" +msgstr "ContopeÈ™te Cu Existentul" #: editor/editor_node.cpp msgid "Password:" -msgstr "" +msgstr "Parola:" #: editor/editor_node.cpp msgid "Open & Run a Script" -msgstr "" +msgstr "Deschide È™i Execută un Script" #: editor/editor_node.cpp msgid "New Inherited" -msgstr "" +msgstr "Derivare Nouă" #: editor/editor_node.cpp msgid "Load Errors" -msgstr "" +msgstr "ÃŽncarcă Erorile" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Select" -msgstr "" +msgstr "Selectează" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "" +msgstr "Deschide Editorul 2D" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "" +msgstr "Deschide Editorul 3D" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "" +msgstr "Deschide Editorul de Scripturi" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "" +msgstr "Deschide Librăria de Asseturi" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "" +msgstr "Deschide Editorul următor" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "" +msgstr "Deschide Editorul anterior" #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "" +msgstr "Se creează Previzualizările Mesh-ului" #: editor/editor_plugin.cpp msgid "Thumbnail..." -msgstr "" +msgstr "Miniatură..." #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" -msgstr "" +msgstr "Pluginuri instalate:" #: editor/editor_plugin_settings.cpp msgid "Update" -msgstr "" +msgstr "Actualizare" #: editor/editor_plugin_settings.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Version:" -msgstr "" +msgstr "Versiune:" #: editor/editor_plugin_settings.cpp msgid "Author:" -msgstr "" +msgstr "Autor:" #: editor/editor_plugin_settings.cpp msgid "Status:" -msgstr "" +msgstr "Stare:" #: editor/editor_profiler.cpp msgid "Stop Profiling" -msgstr "" +msgstr "OpreÈ™te Profilarea" #: editor/editor_profiler.cpp msgid "Start Profiling" -msgstr "" +msgstr "PorneÈ™te Profilarea" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "Măsura:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "" +msgstr "Timpul Cadrului (sec)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" -msgstr "" +msgstr "Media Timpului (sec)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "" +msgstr "Cadru %" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "" +msgstr "Cadru Fizic %" #: editor/editor_profiler.cpp editor/script_editor_debugger.cpp msgid "Time:" -msgstr "" +msgstr "Timp:" #: editor/editor_profiler.cpp msgid "Inclusive" -msgstr "" +msgstr "Inclusiv" #: editor/editor_profiler.cpp msgid "Self" -msgstr "" +msgstr "Propriu" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "" +msgstr "Cadru #:" #: editor/editor_profiler.cpp msgid "Time" -msgstr "" +msgstr "Timp" #: editor/editor_profiler.cpp msgid "Calls" -msgstr "" +msgstr "Apeluri" #: editor/editor_run_native.cpp msgid "Select device from the list" -msgstr "" +msgstr "Selectează un dispozitiv din listă" #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" "Please add a runnable preset in the export menu." msgstr "" +"Nu a fost găsită nicio presetare de export care să poată rula pentru această " +"platformă.\n" +"Te rog adaugă o presetare de rulare în meniul pentru export." #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "" +msgstr "Scrie logica programului în metoda _run()." #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "" +msgstr "Acolo este o scenă deja editată." #: editor/editor_run_script.cpp msgid "Couldn't instance script:" -msgstr "" +msgstr "Nu s-a putut iniÈ›ializa scriptul:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "" +msgstr "Ai uitat cumva cuvântul 'unealtă'?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" -msgstr "" +msgstr "Nu a putut fi executat scriptul:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "" +msgstr "Ai uitat cumva metoda '_run' ?" #: editor/editor_settings.cpp msgid "Default (Same as Editor)" -msgstr "" +msgstr "Implicit (Asemănător ca Editor)" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "" +msgstr "Selectează Nodul(rile) pentru Importare" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "Calea Scenei:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "" +msgstr "Importă Din Nod:" #: editor/export_template_manager.cpp msgid "Re-Download" -msgstr "" +msgstr "Descarcă din nou" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "Dezinstalează" #: editor/export_template_manager.cpp msgid "(Installed)" -msgstr "" +msgstr "(Instalat)" #: editor/export_template_manager.cpp msgid "Download" -msgstr "" +msgstr "Descarcă" #: editor/export_template_manager.cpp msgid "(Missing)" -msgstr "" +msgstr "(LipseÈ™te)" #: editor/export_template_manager.cpp msgid "(Current)" -msgstr "" +msgstr "(Curent)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait..." -msgstr "" +msgstr "Se recuperează oglinzile, te rog aÈ™teaptă..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" -msgstr "" +msgstr "Elimini È™ablonul versiunea '%s'?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." -msgstr "" +msgstr "Nu se pot deschide È™abloanele de export zip." #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates." -msgstr "" +msgstr "Format nevalid versiune.txt în È™abloane." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "" +msgstr "Nu s-a găsit versiune.txt în È™abloane." #: editor/export_template_manager.cpp msgid "Error creating path for templates:" -msgstr "" +msgstr "Eroare la crearea căii pentru È™abloane:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" -msgstr "" +msgstr "Se extrag Șabloanele de Export" #: editor/export_template_manager.cpp msgid "Importing:" -msgstr "" +msgstr "Se importă:" #: editor/export_template_manager.cpp msgid "" "No download links found for this version. Direct download is only available " "for official releases." msgstr "" +"Niciun link pentru descărcare nu a fost găsit pentru această versiune. " +"Descărcarea directă este disponibilă numai pentru lansări oficiale." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve." -msgstr "" +msgstr "Nu se poate rezolva." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect." -msgstr "" +msgstr "Nu se poate face conexiunea." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response." -msgstr "" +msgstr "Niciun răspuns." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request Failed." -msgstr "" +msgstr "Cerere EÈ™uată." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Redirect Loop." -msgstr "" +msgstr "Buclă de RedirecÈ›ionare." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" +msgstr "A EÈ™uat:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "" +msgstr "Descărcare Completă." #: editor/export_template_manager.cpp msgid "Error requesting url: " -msgstr "" +msgstr "Eroare la solicitarea URL: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." -msgstr "" +msgstr "Se conectează la Oglinda..." #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "" +msgstr "Deconectat" #: editor/export_template_manager.cpp msgid "Resolving" -msgstr "" +msgstr "Se SoluÈ›ionează" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "Nu se poate SoluÈ›iona" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connecting..." -msgstr "" +msgstr "Conectare..." #: editor/export_template_manager.cpp msgid "Can't Connect" -msgstr "" +msgstr "Nu se poate Conecta" #: editor/export_template_manager.cpp msgid "Connected" -msgstr "" +msgstr "Conectat" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Requesting..." -msgstr "" +msgstr "Se Solicită..." #: editor/export_template_manager.cpp msgid "Downloading" -msgstr "" +msgstr "Se Descarcă" #: editor/export_template_manager.cpp msgid "Connection Error" -msgstr "" +msgstr "Eroare de Conexiune" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "" +msgstr "Eroare SSL Handshake" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "" +msgstr "Versiune Curentă:" #: editor/export_template_manager.cpp msgid "Installed Versions:" -msgstr "" +msgstr "Versiuni Instalate:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "" +msgstr "Instalează Din FiÈ™ier" #: editor/export_template_manager.cpp msgid "Remove Template" -msgstr "" +msgstr "Elimină Șablon" #: editor/export_template_manager.cpp msgid "Select template file" -msgstr "" +msgstr "Selectează fiÈ™ierul È™ablon" #: editor/export_template_manager.cpp msgid "Export Template Manager" -msgstr "" +msgstr "Exportă Managerul de Șabloane" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "" +msgstr "Descarcă Șabloane" #: editor/export_template_manager.cpp msgid "Select mirror from list: " -msgstr "" +msgstr "Selectează oglinda din listă: " #: editor/file_type_cache.cpp msgid "Can't open file_type_cache.cch for writing, not saving file type cache!" msgstr "" +"Nu se poate deschide file_type_cache.cch pentru scriere, nu se salvează " +"fiÈ™ierul tip cache!" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" msgstr "" +"Nu se poate naviga către '%s' pentru că nu a fost găsit în sistemul de " +"fiÈ™iere!" #: editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails" -msgstr "" +msgstr "Vizualizează articolele ca È™i o grilă de miniaturi" #: editor/filesystem_dock.cpp msgid "View items as a list" -msgstr "" +msgstr "Vizualizează articolele ca È™i o listă" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." msgstr "" +"Stare: Importarea fiÈ™ierului eÈ™uată. Te rog repară fiÈ™ierul È™i reimportă " +"manual." #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "Nu se poate muta/redenumi rădăcina resurselor." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "Nu se poate muta un director în el însuÈ™i." #: editor/filesystem_dock.cpp msgid "Error moving:" -msgstr "" +msgstr "Eroare mutând:" #: editor/filesystem_dock.cpp msgid "Error duplicating:" -msgstr "" +msgstr "Eroare duplicând:" #: editor/filesystem_dock.cpp msgid "Unable to update dependencies:" -msgstr "" +msgstr "Imposibil de actualizat dependinÈ›ele:" #: editor/filesystem_dock.cpp msgid "No name provided" -msgstr "" +msgstr "Niciun nume furnizat" #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters" -msgstr "" +msgstr "Numele furnizat conÈ›ine caractere nevalide" #: editor/filesystem_dock.cpp msgid "No name provided." -msgstr "" +msgstr "Niciun nume furnizat." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "Numele furnizat conÈ›ine caractere nevalide." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "Un fiÈ™ier sau un director cu acest nume există deja." #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "" +msgstr "Redenumind fiÈ™ierul:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "" +msgstr "Redenumind directorul:" #: editor/filesystem_dock.cpp msgid "Duplicating file:" -msgstr "" +msgstr "Duplicând fiÈ™ierul:" #: editor/filesystem_dock.cpp msgid "Duplicating folder:" -msgstr "" +msgstr "Duplicând directorul:" #: editor/filesystem_dock.cpp msgid "Expand all" -msgstr "" +msgstr "Extinde toate" #: editor/filesystem_dock.cpp msgid "Collapse all" -msgstr "" +msgstr "Restrânge toate" #: editor/filesystem_dock.cpp msgid "Rename..." -msgstr "" +msgstr "RedenumeÈ™te..." #: editor/filesystem_dock.cpp msgid "Move To..." -msgstr "" +msgstr "Mută ÃŽn..." #: editor/filesystem_dock.cpp msgid "Open Scene(s)" -msgstr "" +msgstr "Deschide Scena(ele)" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "Instanță" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." -msgstr "" +msgstr "Editează DependinÈ›ele..." #: editor/filesystem_dock.cpp msgid "View Owners..." -msgstr "" +msgstr "Vizualizează Proprietarii..." #: editor/filesystem_dock.cpp msgid "Duplicate..." -msgstr "" +msgstr "DuplicaÈ›i..." #: editor/filesystem_dock.cpp msgid "Previous Directory" -msgstr "" +msgstr "Directorul Anterior" #: editor/filesystem_dock.cpp msgid "Next Directory" -msgstr "" +msgstr "Directorul Urmator" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "" +msgstr "Rescanează Sistemul de FiÈ™iere" #: editor/filesystem_dock.cpp msgid "Toggle folder status as Favorite" -msgstr "" +msgstr "Marchează statutul directorului ca Favorit" #: editor/filesystem_dock.cpp msgid "Instance the selected scene(s) as child of the selected node." -msgstr "" +msgstr "InstanÈ›iază scena(ele) selectată ca un copil al nodului selectat." #: editor/filesystem_dock.cpp msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" +"Se Scanează FiÈ™ierele,\n" +"Te Rog AÈ™teaptă..." #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "Mută" #: editor/filesystem_dock.cpp editor/plugins/animation_tree_editor_plugin.cpp #: editor/project_manager.cpp msgid "Rename" -msgstr "" +msgstr "RedenumeÈ™te" #: editor/groups_editor.cpp msgid "Add to Group" -msgstr "" +msgstr "Adaugă în Grup" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "" +msgstr "Elimină din Grup" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "" +msgstr "Importă ca Scenă Simplă" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "" +msgstr "Importă cu AnimaÈ›ii Separate" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "" +msgstr "Importă cu Materiale Separate" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "" +msgstr "Importă cu Obiecte Separate" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "" +msgstr "Importă cu Obiecte+Materiale Separate" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "" +msgstr "Importă cu Obiecte+AnimaÈ›ii Separate" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "" +msgstr "Importă cu Materiale+AnimaÈ›ii Separate" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "" +msgstr "Importă cu Obiecte+Materiale+AnimaÈ›ii Separate" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "" +msgstr "Importă ca Scene Multiple" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "Importă ca Scene+Materiale Multiple" #: editor/import/resource_importer_scene.cpp #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "Importă Scena" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "" +msgstr "Se Importa Scena..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" -msgstr "" +msgstr "Se Genereaza Lightmaps" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "Se Generează pentru Mesh: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." -msgstr "" +msgstr "Se Execută un Script Personalizat..." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "Nu s-a putut încărca scriptul post-importare:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" -msgstr "" +msgstr "Script nevalid/nefuncÈ›ional pentru post-importare (vezi consola):" #: editor/import/resource_importer_scene.cpp msgid "Error running post-import script:" -msgstr "" +msgstr "Eroare la executarea scripyului post-importare:" #: editor/import/resource_importer_scene.cpp msgid "Saving..." -msgstr "" +msgstr "Se Salvează..." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "" +msgstr "Setează ca Implicit pentru '%s'" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "Curăță setarea Implicită pentru '%s'" #: editor/import_dock.cpp msgid " Files" -msgstr "" +msgstr " FiÈ™iere" #: editor/import_dock.cpp msgid "Import As:" -msgstr "" +msgstr "Importă Ca:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset..." -msgstr "" +msgstr "Presetare..." #: editor/import_dock.cpp msgid "Reimport" -msgstr "" +msgstr "Reimportă" #: editor/multi_node_edit.cpp msgid "MultiNode Set" -msgstr "" +msgstr "Set MultiNod" #: editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "Grupuri" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "" +msgstr "Selectează un Nod pentru a edita Semnalele È™i Grupurile." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Poly" -msgstr "" +msgstr "Crează Poligon" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly" -msgstr "" +msgstr "Editează Poligon" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "Inserează Punct" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "Editează Poligon (Elimină Punct)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Poly And Point" -msgstr "" +msgstr "Elimină Poligon Și Punct" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Create a new polygon from scratch" -msgstr "" +msgstr "Crează un nou poligon de la zero" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -2863,522 +2910,526 @@ msgid "" "Ctrl+LMB: Split Segment.\n" "RMB: Erase Point." msgstr "" +"Editează poligon existent:\n" +"LMB: Mută Punct.\n" +"Ctrl+LMB: Despică Segment.\n" +"RMB: Șterge Punct." #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Delete points" -msgstr "" +msgstr "Șterge puncte" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "" +msgstr "Comutează Auto-ExecuÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "Nume Nou AnimaÈ›ie:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Anim Nouă" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" -msgstr "" +msgstr "Schimbă Numele AnimaÈ›iei:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Delete Animation?" -msgstr "" +msgstr "Ștergi AnimaÈ›ia?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Elimină AnimaÈ›ia" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Invalid animation name!" -msgstr "" +msgstr "EROARE: Nume animaÈ›ie nevalid!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Animation name already exists!" -msgstr "" +msgstr "EROARE: Numele animaÈ›iei există deja!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "RedenumeÈ™te AnimaÈ›ia" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Animation" -msgstr "" +msgstr "Adaugă AnimaÈ›ia" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" -msgstr "" +msgstr "Amestecă Următoarea Schimbare" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "" +msgstr "Schimbă Timpul Amestecului" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "ÃŽncarcă AnimaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Duplicare AnimaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to copy!" -msgstr "" +msgstr "EROARE: Nicio copie a animaÈ›iei!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation resource on clipboard!" -msgstr "" +msgstr "EROARE: Nicio resursă de animaÈ›ie în clipboard!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "" +msgstr "AnimaÈ›ie Lipită" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "" +msgstr "LipeÈ™te AnimaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to edit!" -msgstr "" +msgstr "EROARE: Nicio animaÈ›ie pentru editare!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" -msgstr "" +msgstr "Rulează animaÈ›ia selectată în sens invers de la poziÈ›ia curentă. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "Rulează animaÈ›ia selectată în sens invers de la sfârÈ™it. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "OpreÈ™te rularea animaÈ›iei. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "Rulează animaÈ›ia selectată de la început. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "Rulează animaÈ›ia selectată de la poziÈ›ia curentă. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "PoziÈ›ia animaÈ›iei (în secunde)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "" +msgstr "Redimensionează rularea animaÈ›iei pentru nod." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create new animation in player." -msgstr "" +msgstr "Creează o nouă animaÈ›ie în player." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load animation from disk." -msgstr "" +msgstr "ÃŽncarcă animaÈ›ie de pe disc." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load an animation from disk." -msgstr "" +msgstr "ÃŽncarcă o animaÈ›ie de pe disc." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Save the current animation" -msgstr "" +msgstr "Salvează actuala animaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "" +msgstr "AfiÈ™ează o listă a animaÈ›iilor în player." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Auto-Execută la ÃŽncărcare" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Target Blend Times" -msgstr "" +msgstr "Editează Timpul de Amestecare al Èšintei" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "" +msgstr "Unelte AnimaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Copy Animation" -msgstr "" +msgstr "Copiză AnimaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning" -msgstr "" +msgstr "Onion Skinning" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "Activează Onion Skinning" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" -msgstr "" +msgstr "DirecÈ›ii" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Past" -msgstr "" +msgstr "Trecut" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "Viitor" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" -msgstr "" +msgstr "Adâncime" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "" +msgstr "1 pas" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" -msgstr "" +msgstr "2 paÈ™i" #: editor/plugins/animation_player_editor_plugin.cpp msgid "3 steps" -msgstr "" +msgstr "3 paÈ™i" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Doar DiferenÈ›e" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "ForÈ›ează Modulare Albă" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" -msgstr "" +msgstr "Include Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Creează AnimaÈ›ie Nouă" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Nume AnimaÈ›ie:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp msgid "Error!" -msgstr "" +msgstr "Eroare!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "" +msgstr "Timpi de Amestecare:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "" +msgstr "Următorul (Rând Automat):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" -msgstr "" +msgstr "Timpi de Amestecare Cross-AnimaÈ›ie" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "AnimaÈ›ie" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "New name:" -msgstr "" +msgstr "Nume nou:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Filters" -msgstr "" +msgstr "Editează Filtrele" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Scale:" -msgstr "" +msgstr "Dimensiune:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade In (s):" -msgstr "" +msgstr "Estompează (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade Out (s):" -msgstr "" +msgstr "Reliefează (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend" -msgstr "" +msgstr "Amestec" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix" -msgstr "" +msgstr "Mix" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Auto Restart:" -msgstr "" +msgstr "Restartare Automată:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Restart (s):" -msgstr "" +msgstr "Restartare (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Random Restart (s):" -msgstr "" +msgstr "Restartare Aleatorie (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Start!" -msgstr "" +msgstr "Start!" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Amount:" -msgstr "" +msgstr "Cantitate:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend:" -msgstr "" +msgstr "Amestec:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 0:" -msgstr "" +msgstr "Amestec 0:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 1:" -msgstr "" +msgstr "Amestec 1:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "X-Fade Time (s):" -msgstr "" +msgstr "Timp X-Decolorare (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Current:" -msgstr "" +msgstr "Curent:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Add Input" -msgstr "" +msgstr "Adaugă Intrare(Input)" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Clear Auto-Advance" -msgstr "" +msgstr "Curăță Auto-Avansarea" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Set Auto-Advance" -msgstr "" +msgstr "Setează Auto-Avansare" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Delete Input" -msgstr "" +msgstr "Șterge Intrare(Input)" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation tree is valid." -msgstr "" +msgstr "Arborele AnimaÈ›iei este valid." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation tree is invalid." -msgstr "" +msgstr "Arborele AnimaÈ›iei este nevalid." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation Node" -msgstr "" +msgstr "Nod de AnimaÈ›ie" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "OneShot Node" -msgstr "" +msgstr "Nod OneShot" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix Node" -msgstr "" +msgstr "Nod de Amestecare" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend2 Node" -msgstr "" +msgstr "Nod Amestec2" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend3 Node" -msgstr "" +msgstr "Nod Amestec3" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend4 Node" -msgstr "" +msgstr "Nod Amestec4" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeScale Node" -msgstr "" +msgstr "Nod DimensiuneTimp" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeSeek Node" -msgstr "" +msgstr "Nod CăutareTimp" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Transition Node" -msgstr "" +msgstr "Nod TranziÈ›ie" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Import Animations..." -msgstr "" +msgstr "Importă AnimaÈ›ii..." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Node Filters" -msgstr "" +msgstr "Editează Filtrele Nodurilor" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Filters..." -msgstr "" +msgstr "Filtre..." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "AnimationTree" -msgstr "" +msgstr "ArboreAnimaÈ›ie" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" -msgstr "" +msgstr "Gratuit" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" -msgstr "" +msgstr "ConÈ›inut:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "View Files" -msgstr "" +msgstr "Vizualizează FiÈ™ierele" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve hostname:" -msgstr "" +msgstr "Nu se poate rezolva numele gazdei:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connection error, please try again." -msgstr "" +msgstr "Eroare la conectare, te rog încearcă din nou." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect to host:" -msgstr "" +msgstr "Nu se poate conecta la gazda:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response from host:" -msgstr "" +msgstr "Nciun răspuns de la gazda:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, return code:" -msgstr "" +msgstr "Cerere eÈ™uată, cod returnat:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" -msgstr "" +msgstr "Cerere eÈ™uată, prea multe redirecÈ›ionări" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." -msgstr "" +msgstr "Hash eronat de descărcare, se presupune că fiÈ™ierul este falsificat." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Expected:" -msgstr "" +msgstr "AÈ™teptat:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Got:" -msgstr "" +msgstr "Primit:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed sha256 hash check" -msgstr "" +msgstr "Verificare hash sha256 eÈ™uată" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" -msgstr "" +msgstr "Eroare la Descărcarea Asset-ului:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Fetching:" -msgstr "" +msgstr "Se Preia(u):" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Resolving..." -msgstr "" +msgstr "Se Rezolvă..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Error making request" -msgstr "" +msgstr "Eroare la solicitare" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Idle" -msgstr "" +msgstr "Inactiv" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Retry" -msgstr "" +msgstr "Reîncearcă" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" -msgstr "" +msgstr "Eroare Descărcare" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download for this asset is already in progress!" -msgstr "" +msgstr "Descărcarea acestui asset rulează deja!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "first" -msgstr "" +msgstr "primul" #: editor/plugins/asset_library_editor_plugin.cpp msgid "prev" -msgstr "" +msgstr "anterior" #: editor/plugins/asset_library_editor_plugin.cpp msgid "next" -msgstr "" +msgstr "următorul" #: editor/plugins/asset_library_editor_plugin.cpp msgid "last" -msgstr "" +msgstr "ultimul" #: editor/plugins/asset_library_editor_plugin.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "All" -msgstr "" +msgstr "Toate" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/project_settings_editor.cpp msgid "Plugins" -msgstr "" +msgstr "Plugin-uri" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Sort:" -msgstr "" +msgstr "Sorare:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Reverse" -msgstr "" +msgstr "Revers" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/project_settings_editor.cpp msgid "Category:" -msgstr "" +msgstr "Categorie:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Site:" -msgstr "" +msgstr "Site:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Support..." -msgstr "" +msgstr "Suport..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Official" -msgstr "" +msgstr "Oficial" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Testing" -msgstr "" +msgstr "Se Testează" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" -msgstr "" +msgstr "FiÈ™ier ZIP cu Asset-uri" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -3386,135 +3437,144 @@ msgid "" "Save your scene (for images to be saved in the same dir), or pick a save " "path from the BakedLightmap properties." msgstr "" +"Nu se poate determina p cale de salvare pentru imaginile lightmap.\n" +"Salvează scena (imaginile vor fi salvate în acelasi director), sau alege o " +"cale de salvare din proprietățile BakedLightmap." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " "Light' flag is on." msgstr "" +"Nicio structură pentru procesare. Asigură-te că acestea conÈ›in un canal UV2 " +"È™i că opÈ›iunea 'Procesează Lumina' este pornită." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed creating lightmap images, make sure path is writable." msgstr "" +"Crearea imaginilor lightmap eÈ™uată, asigură-te că poate fi scrisă calea spre " +"ele." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" -msgstr "" +msgstr "Procesează Lightmaps" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" -msgstr "" +msgstr "Previzualizare" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "" +msgstr "Configurare Snap" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Offset:" -msgstr "" +msgstr "Compensare Grilă:" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Step:" -msgstr "" +msgstr "Pas Grilă:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" -msgstr "" +msgstr "Compensare RotaÈ›ie:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Step:" -msgstr "" +msgstr "Pas RotaÈ›ie:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Pivot" -msgstr "" +msgstr "Mută Pivot" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Action" -msgstr "" +msgstr "AcÈ›iune de Mutare" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move vertical guide" -msgstr "" +msgstr "Mută ghidul vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new vertical guide" -msgstr "" +msgstr "Creează un nou ghid vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Remove vertical guide" -msgstr "" +msgstr "Elimină ghidul vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move horizontal guide" -msgstr "" +msgstr "Mută ghidul orizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new horizontal guide" -msgstr "" +msgstr "Creează un nou ghid orizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Remove horizontal guide" -msgstr "" +msgstr "Elimină ghidul orizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new horizontal and vertical guides" -msgstr "" +msgstr "Creează ghizi noi orizontal È™i vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Edit IK Chain" -msgstr "" +msgstr "Editează LanÈ› IK" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Edit CanvasItem" -msgstr "" +msgstr "Editează ObiectulPânză" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" -msgstr "" +msgstr "Doar ancore" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors and Margins" -msgstr "" +msgstr "Modifică Ancorele È™i Limitele" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors" -msgstr "" +msgstr "Modifică Ancorele" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" -msgstr "" +msgstr "LipeÈ™te Postura" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Select Mode" -msgstr "" +msgstr "Mod Selectare" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag: Rotate" -msgstr "" +msgstr "Trage: Rotire" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move" -msgstr "" +msgstr "Alt+Trage: Mutare" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" +"Apasă 'v' pentru a Schimba Pivotul, 'Shift+v' pentru a Trage Pivotul (în " +"timpul miÈ™cării)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" -msgstr "" +msgstr "Alt+RMB: SelecÈ›ie adâncime listă" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Mode" -msgstr "" +msgstr "Mod Mutare" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate Mode" -msgstr "" +msgstr "Mod RotaÈ›ie" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -3522,560 +3582,566 @@ msgid "" "Show a list of all objects at the position clicked\n" "(same as Alt+RMB in select mode)." msgstr "" +"Arată o listă a tuturor obiectelor la poziÈ›ia clickului\n" +"(similar cu Alt+RMB în modul selectare)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Click to change object's rotation pivot." -msgstr "" +msgstr "Click pentru a modifica pivotul de rotaÈ›ie al obiectului." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Pan Mode" -msgstr "" +msgstr "Mod ÃŽn Jur" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Toggles snapping" -msgstr "" +msgstr "Comutare snapping" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Snap" -msgstr "" +msgstr "Utilizează Snap" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snapping options" -msgstr "" +msgstr "OpÈ›iuni Snapping" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to grid" -msgstr "" +msgstr "Snap pe grilă" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" -msgstr "" +msgstr "FoloseÈ™te RotaÈ›ia Snap" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Configure Snap..." -msgstr "" +msgstr "Configurare Snap..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap Relative" -msgstr "" +msgstr "Snap Relativ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Pixel Snap" -msgstr "" +msgstr "Utilizează Pixel Snap" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Smart snapping" -msgstr "" +msgstr "Snapping inteligent" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to parent" -msgstr "" +msgstr "Snap către părinte" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to node anchor" -msgstr "" +msgstr "Snap către ancora nodului" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to node sides" -msgstr "" +msgstr "Snap pe feÈ›ele nodului" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to other nodes" -msgstr "" +msgstr "Snap către alte noduri" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to guides" -msgstr "" +msgstr "Snap pe ghizi" #: 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 "" +msgstr "Imobilizează obiectul selectat (nu poate fi miÈ™cat)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Unlock the selected object (can be moved)." -msgstr "" +msgstr "Remobilizează obiectul selectat (poate fi miÈ™cat)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Makes sure the object's children are not selectable." -msgstr "" +msgstr "Asigură-te că nu pot fi selectaÈ›i copiii obiectului." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Restores the object's children's ability to be selected." -msgstr "" +msgstr "Restaurează abilitatea copiilor obiectului de a fi selectaÈ›i." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make Bones" -msgstr "" +msgstr "Creează Oase" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Bones" -msgstr "" +msgstr "Curăță Oasele" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Bones" -msgstr "" +msgstr "Arată Oasele" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" -msgstr "" +msgstr "Creează LanÈ› IK" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear IK Chain" -msgstr "" +msgstr "Curăță LanÈ›ul IK" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "" +msgstr "Perspectivă" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Show Grid" -msgstr "" +msgstr "Arată Grila" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" -msgstr "" +msgstr "Arată AsistenÈ›ii" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Rulers" -msgstr "" +msgstr "Arată Riglele" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Guides" -msgstr "" +msgstr "Arată Ghizii" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Origin" -msgstr "" +msgstr "Arată Originea" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Viewport" -msgstr "" +msgstr "Arată Fereastra de Lucru" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" -msgstr "" +msgstr "Centrează SelecÈ›ia" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" -msgstr "" +msgstr "ÃŽncadrează în Ecran SelecÈ›ia" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "" +msgstr "Schemă" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Keys" -msgstr "" +msgstr "Inserează Note" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" -msgstr "" +msgstr "Inserează Notă" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" -msgstr "" +msgstr "Inserează Notă (Melodii existente)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Copy Pose" -msgstr "" +msgstr "Copiază Postura" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Pose" -msgstr "" +msgstr "Curăță Postura" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag pivot from mouse position" -msgstr "" +msgstr "Trage pivotul de la poziÈ›ia mouse-ului" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set pivot at mouse position" -msgstr "" +msgstr "Setează pivotul la poziÈ›ia mouse-ului" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Multiply grid step by 2" -msgstr "" +msgstr "Multiplică pasul pe grilă cu 2" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Divide grid step by 2" -msgstr "" +msgstr "ÃŽmparte pasul pe grilă cu 2" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" -msgstr "" +msgstr "Adaugă %s" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Adding %s..." -msgstr "" +msgstr "Se adaugă %s..." #: editor/plugins/canvas_item_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Ok" -msgstr "" +msgstr "Bine" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Cannot instantiate multiple nodes without root." -msgstr "" +msgstr "Nu se pot instanÈ›ia noduri multiple fără o rădacină." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Create Node" -msgstr "" +msgstr "Creează Nod" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Error instancing scene from %s" -msgstr "" +msgstr "Eroare la instanÈ›ierea scenei din %s" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change default type" -msgstr "" +msgstr "Schimbă tipul implicit" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" "Drag & drop + Shift : Add node as sibling\n" "Drag & drop + Alt : Change node type" msgstr "" +"Trage & lasă + Shift: Adaugă nod ca È™i frate\n" +"Trage & lasă + Shift: Schimbă tipul nodului" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Create Poly3D" -msgstr "" +msgstr "Creează Poligon3D" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" -msgstr "" +msgstr "Setează Mâner" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Remove item %d?" -msgstr "" +msgstr "Elimini obiectul %d?" #: editor/plugins/cube_grid_theme_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Item" -msgstr "" +msgstr "Adaugă Obiect" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Remove Selected Item" -msgstr "" +msgstr "Elimină Obiectul Selectat" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import from Scene" -msgstr "" +msgstr "Importă din Scenă" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Update from Scene" -msgstr "" +msgstr "Actualizează din Scenă" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat0" -msgstr "" +msgstr "Plat0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat1" -msgstr "" +msgstr "Plat1" #: editor/plugins/curve_editor_plugin.cpp msgid "Ease in" -msgstr "" +msgstr "Facilitare în" #: editor/plugins/curve_editor_plugin.cpp msgid "Ease out" -msgstr "" +msgstr "Facilitare din" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" -msgstr "" +msgstr "PasOmogen" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Point" -msgstr "" +msgstr "Modifică Punctul Curbei" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Tangent" -msgstr "" +msgstr "Modifică Tangenta Curbei" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Curve Preset" -msgstr "" +msgstr "ÃŽncarcă Presetare a Curbei" #: editor/plugins/curve_editor_plugin.cpp msgid "Add point" -msgstr "" +msgstr "Adaugă punct" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove point" -msgstr "" +msgstr "Elimină punct" #: editor/plugins/curve_editor_plugin.cpp msgid "Left linear" -msgstr "" +msgstr "Stânga liniară" #: editor/plugins/curve_editor_plugin.cpp msgid "Right linear" -msgstr "" +msgstr "Dreapta liniară" #: editor/plugins/curve_editor_plugin.cpp msgid "Load preset" -msgstr "" +msgstr "ÃŽncarcă presetare" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" -msgstr "" +msgstr "Elimină Punctul Curbei" #: editor/plugins/curve_editor_plugin.cpp msgid "Toggle Curve Linear Tangent" -msgstr "" +msgstr "Comută Tangenta Liniară a Curbei" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" -msgstr "" +msgstr "Èšine apăsat Shift pentru a edita individual tangentele" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "" +msgstr "Procesează Sonda GI" #: editor/plugins/gradient_editor_plugin.cpp msgid "Add/Remove Color Ramp Point" -msgstr "" +msgstr "Adaugă/Elimină Punctul Rampei de Culori" #: editor/plugins/gradient_editor_plugin.cpp #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Modify Color Ramp" -msgstr "" +msgstr "Modifică Rampa de Culori" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" -msgstr "" +msgstr "Obiect %d" #: editor/plugins/item_list_editor_plugin.cpp msgid "Items" -msgstr "" +msgstr "Obiecte" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item List Editor" -msgstr "" +msgstr "Editor Lista de Obiect" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "" "No OccluderPolygon2D resource on this node.\n" "Create and assign one?" msgstr "" +"Nicio resursă OccluderPolygon2D în acest nod.\n" +"Vrei să creezi È™i să atribui una?" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" -msgstr "" +msgstr "Creează Poligon de Ocluziune" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create a new polygon from scratch." -msgstr "" +msgstr "Creează un nou poligon de la zero." #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit existing polygon:" -msgstr "" +msgstr "Editează poligonul existent:" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "LMB: Move Point." -msgstr "" +msgstr "LMB: MiÈ™că Punctul." #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Ctrl+LMB: Split Segment." -msgstr "" +msgstr "Ctrl+LMB: Despică Segmentul." #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "RMB: Erase Point." -msgstr "" +msgstr "RMB: Șterge Punctul." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "" +msgstr "Mesh-ul este gol!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "" +msgstr "Creează un Corp Static Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Convex Body" -msgstr "" +msgstr "Creează un Corp Static Convex" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" -msgstr "" +msgstr "Asta nu funcÈ›ionează în rădăcina scenei!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Shape" -msgstr "" +msgstr "Creează o Formă Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Shape" -msgstr "" +msgstr "Creează o Formă Convexă" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "" +msgstr "Creează un Mesh de Navigare" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "Mesh-ul conÈ›inut nu este de tipul ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "" +msgstr "Despachetarea UV a eÈ™uat, se poate ca mesh-ul să nu fie multiplu?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." -msgstr "" +msgstr "Niciun mesh de depanat." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Model has no UV in this layer" -msgstr "" +msgstr "Modelul nu are UV în acest strat" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "" +msgstr "MeshInstance nu are un Mesh!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" -msgstr "" +msgstr "Mesh-ul nu are o suprafață din care să se poată creea contururi!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "" +msgstr "Mesh-ul primitiv nu este de tipul PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" -msgstr "" +msgstr "Nu s-a putut creea un contur!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline" -msgstr "" +msgstr "Creează Contur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "" +msgstr "Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" -msgstr "" +msgstr "Creează un Corp Static Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Static Body" -msgstr "" +msgstr "Creează un Corp Static Convex" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" -msgstr "" +msgstr "Creează un Frate de Coliziune Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Collision Sibling" -msgstr "" +msgstr "Creează un Frate de Coliziune Convex" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." -msgstr "" +msgstr "Se Creează un Mesh de Contur..." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" -msgstr "" +msgstr "Vizionare UV1" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV2" -msgstr "" +msgstr "Vizionare UV2" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Unwrap UV2 for Lightmap/AO" -msgstr "" +msgstr "Despachetează UV2 pentru Lightmap/AO" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "" +msgstr "Creează Mesh de Contur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" -msgstr "" +msgstr "Dimensiunea Conturului:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." -msgstr "" +msgstr "Niciun mesh sursă specificată (È™i niciun MultiMesh setat în nod)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." -msgstr "" +msgstr "Niciun mesh sursă specificată (È™i MultiMesh nu conÈ›ine un Mesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "" +msgstr "Sursa mesh-ului nevalidă (cale nevalidă)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "" +msgstr "Sursa mesh-ului nevalidă (nu este un MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." -msgstr "" +msgstr "Sursa mesh-ului nevalidă (nu conÈ›ine nicio resursă Mesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." -msgstr "" +msgstr "Nicio sursă de suprafață specificată." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (invalid path)." -msgstr "" +msgstr "Sursa suprafeÈ›ei nevalidă (cale nevalidă)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no geometry)." -msgstr "" +msgstr "Sursa suprafeÈ›ei nevalidă (nu există geometrie)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no faces)." -msgstr "" +msgstr "Sursa suprafeÈ›ei nevalidă (nu există feÈ›e)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Parent has no solid faces to populate." -msgstr "" +msgstr "Părintele nu are feÈ›e solide pentru a fi populate." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Couldn't map area." -msgstr "" +msgstr "Nu s-a putut mapa zona." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "" +msgstr "Selectează un Mesh Sursă:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" -msgstr "" +msgstr "Selectează o Suprafață Èšintă:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate Surface" -msgstr "" +msgstr "Populează SuprafaÈ›a" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate MultiMesh" -msgstr "" +msgstr "Populează MultiMesh" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Target Surface:" -msgstr "" +msgstr "Suprafață Èšintă:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" -msgstr "" +msgstr "Mesh Sursă:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" -msgstr "" +msgstr "Axa-X" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Y-Axis" -msgstr "" +msgstr "Axa-Y" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Z-Axis" -msgstr "" +msgstr "Axa-Z" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" @@ -4091,7 +4157,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Scale:" -msgstr "" +msgstr "Dimensiune Aleatorie:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate" @@ -4103,11 +4169,11 @@ msgstr "" #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Bake the navigation mesh." -msgstr "" +msgstr "Procesează mesh-ul de navigare." #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "" +msgstr "Curăță mesh-ul de navigare." #: editor/plugins/navigation_mesh_generator.cpp msgid "Setting up Configuration..." @@ -4147,11 +4213,11 @@ msgstr "" #: editor/plugins/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." -msgstr "" +msgstr "Se converteÈ™te în mesh nativ de navigare..." #: editor/plugins/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "" +msgstr "Setup Generare Mesh de Navigare:" #: editor/plugins/navigation_mesh_generator.cpp msgid "Parsing Geometry..." @@ -4192,7 +4258,7 @@ msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" -msgstr "" +msgstr "Curăță Masca de Emisie" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -4246,7 +4312,7 @@ msgstr "" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "" +msgstr "Creează Puncte de Emisie Din Mesh" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" @@ -4411,7 +4477,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift+Ctrl: Scale" -msgstr "" +msgstr "Shift+Ctrl: Dimensiune" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Polygon" @@ -4423,7 +4489,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Scale Polygon" -msgstr "" +msgstr "Redimensionează Poligon" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -4443,16 +4509,16 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Clear UV" -msgstr "" +msgstr "Curăță UV" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap" -msgstr "" +msgstr "Snap" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "" +msgstr "Activează Snap" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" @@ -4513,7 +4579,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" -msgstr "" +msgstr "Curăță FiÈ™ierele Recente" #: editor/plugins/script_editor_plugin.cpp msgid "Close and save changes?" @@ -4629,7 +4695,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "" +msgstr "Execută" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" @@ -5219,7 +5285,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Mode (R)" -msgstr "" +msgstr "Mod Redimensionare (R)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Coords" @@ -5231,7 +5297,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Mode (%s)" -msgstr "" +msgstr "Mod Snap (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View" @@ -5291,7 +5357,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Tool Scale" -msgstr "" +msgstr "Unealtă Dimensiune" #: editor/plugins/spatial_editor_plugin.cpp msgid "Toggle Freelook" @@ -5348,19 +5414,19 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" -msgstr "" +msgstr "Setări Snap" #: editor/plugins/spatial_editor_plugin.cpp msgid "Translate Snap:" -msgstr "" +msgstr "Tradu Snap:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate Snap (deg.):" -msgstr "" +msgstr "RotaÈ›ie Snap (grade):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Snap (%):" -msgstr "" +msgstr "Dimensionare Snap (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" @@ -5392,7 +5458,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale (ratio):" -msgstr "" +msgstr "Dimensiune (raport):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Type" @@ -5488,7 +5554,7 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" -msgstr "" +msgstr "Mod Snap:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "<None>" @@ -5496,11 +5562,11 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Pixel Snap" -msgstr "" +msgstr "Pixel Snap" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "" +msgstr "Snap Grilă" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" @@ -5901,9 +5967,8 @@ msgid "Imported Project" msgstr "" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Nume nevalid." +msgstr "Nume de Proiect Nevalid." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6005,16 +6070,21 @@ msgid "" "Please edit the project and set the main scene in \"Project Settings\" under " "the \"Application\" category." msgstr "" +"Proiectul nu poate fi executat: nicio scenă principală nu a fost definită.\n" +"Te rog editează proiectul È™i setează o scenă principală în \"Setările " +"Proiectului\" din categoria \"AplicaÈ›ii\"." #: editor/project_manager.cpp msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" +"Nu se poate executa priectul: există Asset-uri care trebuie importate.\n" +"Te rog editează proiectul pentru a declanÈ™a importul iniÈ›ial." #: editor/project_manager.cpp msgid "Are you sure to run more than one project?" -msgstr "" +msgstr "EÈ™ti sigur că vrei să execuÈ›i acel proiect?" #: editor/project_manager.cpp msgid "Remove project from the list? (Folder contents will not be modified)" @@ -6066,13 +6136,16 @@ msgstr "" #: editor/project_manager.cpp msgid "Can't run project" -msgstr "" +msgstr "Proiectul nu poate fi executat" #: editor/project_manager.cpp msgid "" "You don't currently have any projects.\n" "Would you like to explore the official example projects in the Asset Library?" msgstr "" +"Deocamdată nu ai niciun proiect.\n" +"DoreÈ™ti să explorezi exemplele de proiecte oficiale din Librăria de Asset-" +"uri?" #: editor/project_settings_editor.cpp msgid "Key " @@ -6298,7 +6371,7 @@ msgstr "" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" -msgstr "" +msgstr "General" #: editor/project_settings_editor.cpp editor/property_editor.cpp msgid "Property:" @@ -6506,7 +6579,7 @@ msgstr "" #: editor/run_settings_dialog.cpp msgid "Run Mode:" -msgstr "" +msgstr "Modul de ExecuÈ›ie:" #: editor/run_settings_dialog.cpp msgid "Current Scene" @@ -6522,7 +6595,7 @@ msgstr "" #: editor/run_settings_dialog.cpp msgid "Scene Run Settings" -msgstr "" +msgstr "Setările de ExecuÈ›ie ale Scenei" #: editor/scene_tree_dock.cpp editor/script_create_dialog.cpp #: scene/gui/dialogs.cpp @@ -6627,7 +6700,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" -msgstr "" +msgstr "Curăță Derivarea" #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" @@ -6651,7 +6724,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Clear Script" -msgstr "" +msgstr "Curăță Scriptul" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -6689,7 +6762,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Clear a script for the selected node." -msgstr "" +msgstr "Curăță un script pentru nodul selectat." #: editor/scene_tree_dock.cpp msgid "Remote" @@ -6701,11 +6774,11 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance? (No Undo!)" -msgstr "" +msgstr "Curăță Derivarea? (Fără ÃŽntoarcere)" #: editor/scene_tree_dock.cpp msgid "Clear!" -msgstr "" +msgstr "Curăță!" #: editor/scene_tree_editor.cpp msgid "Toggle Spatial Visible" @@ -7197,7 +7270,7 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Snap View" -msgstr "" +msgstr "Perspectivă Snap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7249,7 +7322,7 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Clear Rotation" -msgstr "" +msgstr "Curăță RotaÈ›ia Cursorului" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Create Area" @@ -7265,7 +7338,7 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" -msgstr "" +msgstr "Curăță SelecÈ›ia" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Settings" @@ -7669,11 +7742,11 @@ msgstr "" #: platform/javascript/export/export.cpp msgid "Run in Browser" -msgstr "" +msgstr "Execută în Browser" #: platform/javascript/export/export.cpp msgid "Run exported HTML in the system's default browser." -msgstr "" +msgstr "Execută HTML-ul exportat în browserul prestabilit al sistemului." #: platform/javascript/export/export.cpp msgid "Could not write file:" @@ -8008,3 +8081,11 @@ msgstr "" #: scene/resources/dynamic_font.cpp msgid "Invalid font size." msgstr "" + +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Fila anterioară" + +#, fuzzy +#~ msgid "Next" +#~ msgstr "Fila următoare" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index 3a939ae94e..97c7284404 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -2,7 +2,7 @@ # 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. -# +# Ðркадий ÐÐ²Ð°Ñ <savvot@gmail.com>, 2018. # Artem Varaksa <aymfst@gmail.com>, 2018. # B10nicMachine <shumik1337@gmail.com>, 2017. # Chaosus89 <chaosus89@gmail.com>, 2018. @@ -14,14 +14,14 @@ # Maxim toby3d Lebedev <mail@toby3d.ru>, 2016. # outbools <drag4e@yandex.ru>, 2017. # pitchblack <pitchblack@mail.ru>, 2017. +# Sergey <maligin.serega2010@yandex.ru>, 2018. # Sergey Agarkov <zorgsoft@gmail.com>, 2017. -# Ðркадий ÐÐ²Ð°Ñ <savvot@gmail.com>, 2018. -# +# teriva <spirin.cos@yandex.ru>, 2018. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-05-22 17:41+0000\n" +"PO-Revision-Date: 2018-06-18 19:42+0000\n" "Last-Translator: ijet <my-ijet@mail.ru>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -31,7 +31,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-dev\n" +"X-Generator: Weblate 3.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2109,7 +2109,7 @@ msgstr "СиÑтема отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" -msgstr "ОбщеÑтвенные" +msgstr "СообщеÑтво" #: editor/editor_node.cpp msgid "About" @@ -3728,7 +3728,7 @@ msgstr "Показать окно проÑмотра" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" -msgstr "Центрировать на выбранном" +msgstr "Центрировать выбранное" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" @@ -5706,9 +5706,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" @@ -5991,9 +5990,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." @@ -6194,13 +6192,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!" @@ -8231,6 +8228,13 @@ msgstr "Ошибка загрузки шрифта." msgid "Invalid font size." msgstr "ÐедопуÑтимый размер шрифта." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ°" + +#~ msgid "Next" +#~ msgstr "Следующий" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "ÐедопуÑтимое название дейÑÑ‚Ð²Ð¸Ñ (подойдёт вÑÑ‘ кроме '/' или ':')." @@ -8257,9 +8261,6 @@ msgstr "ÐедопуÑтимый размер шрифта." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "ОтÑутÑтвует project.godot в папке проекта." -#~ msgid "Next" -#~ msgstr "Следующий" - #~ msgid "Not found!" #~ msgstr "Ðе найдено!" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 9a95848f70..9716dee696 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.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. -# # J08nY <johnenter@gmail.com>, 2016. -# +# MineGame 159 <minegame459@gmail.com>, 2018. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2016-06-25 14:16+0000\n" -"Last-Translator: J08nY <johnenter@gmail.com>\n" +"PO-Revision-Date: 2018-06-18 08:43+0000\n" +"Last-Translator: MineGame 159 <minegame459@gmail.com>\n" "Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/" "godot/sk/>\n" "Language: sk\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 2.7-dev\n" +"X-Generator: Weblate 3.0.1\n" #: editor/animation_editor.cpp msgid "Disabled" -msgstr "" +msgstr "Vypnuté" #: editor/animation_editor.cpp msgid "All Selection" @@ -28,11 +27,11 @@ msgstr "VÅ¡etky vybrané" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "" +msgstr "Animácia ZmeniÅ¥ Keyframe ÄŒas" #: editor/animation_editor.cpp msgid "Anim Change Transition" -msgstr "" +msgstr "Animácia zmeniÅ¥ prechod" #: editor/animation_editor.cpp msgid "Anim Change Transform" @@ -40,11 +39,12 @@ msgstr "" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Value" -msgstr "" +msgstr "Animácia ZmeniÅ¥ Keyframe Hodnotu" #: editor/animation_editor.cpp +#, fuzzy msgid "Anim Change Call" -msgstr "" +msgstr "Animácia ZmeniÅ¥ Hovor" #: editor/animation_editor.cpp msgid "Anim Add Track" @@ -68,7 +68,7 @@ msgstr "" #: editor/animation_editor.cpp msgid "Set Transitions to:" -msgstr "" +msgstr "NastaviÅ¥ prechody na:" #: editor/animation_editor.cpp msgid "Anim Track Rename" @@ -92,7 +92,7 @@ msgstr "" #: editor/animation_editor.cpp msgid "Edit Selection Curve" -msgstr "" +msgstr "UpraviÅ¥ výber krivky" #: editor/animation_editor.cpp msgid "Anim Delete Keys" @@ -101,20 +101,19 @@ msgstr "" #: editor/animation_editor.cpp editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "" +msgstr "DuplikovaÅ¥ výber" #: editor/animation_editor.cpp msgid "Duplicate Transposed" msgstr "" #: editor/animation_editor.cpp -#, fuzzy msgid "Remove Selection" -msgstr "VÅ¡etky vybrané" +msgstr "OdstrániÅ¥ výber" #: editor/animation_editor.cpp msgid "Continuous" -msgstr "" +msgstr "Priebežný" #: editor/animation_editor.cpp msgid "Discrete" @@ -134,19 +133,19 @@ msgstr "" #: editor/animation_editor.cpp msgid "Scale Selection" -msgstr "" +msgstr "ZmeniÅ¥ veľkosÅ¥ výberu" #: editor/animation_editor.cpp msgid "Scale From Cursor" -msgstr "" +msgstr "ZmeniÅ¥ veľkosÅ¥ od kurzora" #: editor/animation_editor.cpp msgid "Goto Next Step" -msgstr "" +msgstr "PrejsÅ¥ na ÄalÅ¡Ã krok" #: editor/animation_editor.cpp msgid "Goto Prev Step" -msgstr "" +msgstr "PrejsÅ¥ na predchádzajúci krok" #: editor/animation_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp @@ -159,23 +158,25 @@ msgstr "" #: editor/animation_editor.cpp msgid "In" -msgstr "" +msgstr "V" #: editor/animation_editor.cpp msgid "Out" -msgstr "" +msgstr "Von" #: editor/animation_editor.cpp +#, fuzzy msgid "In-Out" -msgstr "" +msgstr "V-Von" #: editor/animation_editor.cpp +#, fuzzy msgid "Out-In" -msgstr "" +msgstr "Von-V" #: editor/animation_editor.cpp msgid "Transitions" -msgstr "" +msgstr "Prechody" #: editor/animation_editor.cpp msgid "Optimize Animation" @@ -8050,7 +8051,7 @@ msgstr "" #: scene/resources/dynamic_font.cpp msgid "Invalid font size." -msgstr "" +msgstr "Nesprávna veľkosÅ¥ pÃsma." #, fuzzy #~ msgid "Can't write file." diff --git a/editor/translations/sl.po b/editor/translations/sl.po index a762d6f69b..0fe619654f 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -2,17 +2,15 @@ # 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. -# # matevž lapajne <sivar.lapajne@gmail.com>, 2016-2018. # Matjaž Vitas <matjaz.vitas@gmail.com>, 2017-2018. # Miha Komatar <miha.komatar@gmail.com>, 2018. # Simon Å ander <simon.sand3r@gmail.com>, 2017. # Yahara Octanis <yaharao55@gmail.com>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-06-05 19:27+0000\n" +"PO-Revision-Date: 2018-06-10 08:44+0000\n" "Last-Translator: matevž lapajne <sivar.lapajne@gmail.com>\n" "Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/" "godot/sl/>\n" @@ -21,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\n" +"X-Generator: Weblate 3.0.1-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2860,36 +2858,36 @@ msgstr "Skupine" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "" +msgstr "Za urejanje Signalov in Skupin izberi Gradnik." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Poly" -msgstr "" +msgstr "Ustvarite Poligon" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly" -msgstr "" +msgstr "Uredi Poligon" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "Ustavi ToÄko" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "Uredi Poligon (Odstrani ToÄko)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Poly And Point" -msgstr "" +msgstr "Odstrani Poligon in ToÄko" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Create a new polygon from scratch" -msgstr "" +msgstr "Ustvari nov poligon od zaÄetka" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -2898,6 +2896,10 @@ msgid "" "Ctrl+LMB: Split Segment.\n" "RMB: Erase Point." msgstr "" +"Uredi obstojeÄi poligon:\n" +"LMG: Premakni ToÄko.\n" +"Ctrl+LMG: Razdeli Älen.\n" +"DMG: ZbriÅ¡i ToÄko." #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Delete points" @@ -2905,154 +2907,154 @@ msgstr "IzbriÅ¡i toÄke" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "" +msgstr "Preklop funkcije Samodejno Predvajanje" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "Novo Ime Animacije:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Nova Animacija" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" -msgstr "" +msgstr "Spremeni Ime Animacije:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Delete Animation?" -msgstr "" +msgstr "IzbriÅ¡em animacijo?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Odstrani Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Invalid animation name!" -msgstr "" +msgstr "Napaka: Neveljavno ime animacije!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Animation name already exists!" -msgstr "" +msgstr "NAPAKA: Animacija s tem imenom že obstaja!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "Preimenuj Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Animation" -msgstr "" +msgstr "Dodaj Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" -msgstr "" +msgstr "Naslednjo MeÅ¡anje se je Spremenilo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "" +msgstr "Spremeni MeÅ¡alni ÄŒas" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "Naloži Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Podvoji Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to copy!" -msgstr "" +msgstr "NAPAKA: Ni animacije za kopiranje!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation resource on clipboard!" -msgstr "" +msgstr "NAPAKA: Ni animacije virov na odložiÅ¡Äu!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "" +msgstr "Prilepljena Animacija" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "" +msgstr "Prilepi animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to edit!" -msgstr "" +msgstr "NAPAKA: Ni animacije za urejanje!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" -msgstr "" +msgstr "Predvajaj izbrano animacijo nazaj od trenutnega položaja. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "Predvajaj izbrano animacijo nazaj od konca. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "Ustavi predvajanje animacije. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "Predvajaj izbrano animacijo od zaÄetka. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "Predvajaj izbrano animacijo iz trenutne pozicije. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "Mesto animacije (v sekundah)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "" +msgstr "Spremeni velikost predvajanja za gradnike globalno." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create new animation in player." -msgstr "" +msgstr "Ustvari novo animacijo v predvajalniku." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load animation from disk." -msgstr "" +msgstr "Naloži animacijo z diska." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load an animation from disk." -msgstr "" +msgstr "Naloži animacijo z diska." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Save the current animation" -msgstr "" +msgstr "Shrani trenutno animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "" +msgstr "Prikaži seznam animacij v predvajalniku." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Samodejno predvajaj ob nalaganju" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Target Blend Times" -msgstr "" +msgstr "Uredi Äas meÅ¡anice cilja" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "" +msgstr "Animacijska Orodja" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Copy Animation" -msgstr "" +msgstr "Kopiraj Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning" -msgstr "" +msgstr "Lupljenje ÄŒebule" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "OmogoÄi Lupljenje ÄŒebule" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -3060,35 +3062,35 @@ msgstr "Smeri" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Past" -msgstr "" +msgstr "Preteklost" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "Prihodnost" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" -msgstr "" +msgstr "Globina" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "" +msgstr "1 korak" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" -msgstr "" +msgstr "2 koraka" #: editor/plugins/animation_player_editor_plugin.cpp msgid "3 steps" -msgstr "" +msgstr "3 koraki" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Samo Razlike" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "Sile Bele Modulacije" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" @@ -3096,30 +3098,30 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Ustvari Novo Animacijo" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Ime Animacije:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp msgid "Error!" -msgstr "" +msgstr "Napaka!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "" +msgstr "ÄŒas MeÅ¡anja:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "" +msgstr "Naprej (Samodejna Razvrstitev):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" -msgstr "" +msgstr "Navzkrižna Animacija ÄŒasa MeÅ¡anice" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/canvas_item_editor_plugin.cpp @@ -3128,7 +3130,7 @@ msgstr "Animacija" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "New name:" -msgstr "" +msgstr "Novo ime:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Filters" @@ -3137,68 +3139,68 @@ msgstr "Uredi Filtre" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Scale:" -msgstr "" +msgstr "Prilagodi Velikost:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade In (s):" -msgstr "" +msgstr "Postopno Prikazovanje (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade Out (s):" -msgstr "" +msgstr "Postopno Izginevanje (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend" -msgstr "" +msgstr "ZmeÅ¡aj" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix" -msgstr "" +msgstr "MeÅ¡aj" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Auto Restart:" -msgstr "" +msgstr "Samodejni Ponovni Zagon:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Restart (s):" -msgstr "" +msgstr "Znova Zaženi (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Random Restart (s):" -msgstr "" +msgstr "NakljuÄno Zaženi (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Start!" -msgstr "" +msgstr "Zaženi!" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Amount:" -msgstr "" +msgstr "KoliÄina:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend:" -msgstr "" +msgstr "ZmeÅ¡aj:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 0:" -msgstr "" +msgstr "ZmeÅ¡aj 0:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 1:" -msgstr "" +msgstr "ZmeÅ¡aj 1:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "X-Fade Time (s):" -msgstr "" +msgstr "ÄŒas X-Bledenja (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Current:" -msgstr "" +msgstr "Trenutno:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Add Input" -msgstr "" +msgstr "Dodaj Vnos" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Clear Auto-Advance" @@ -3206,67 +3208,67 @@ msgstr "" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Set Auto-Advance" -msgstr "" +msgstr "Nastavi Samodejno-Napredovanje" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Delete Input" -msgstr "" +msgstr "IzbriÅ¡i Vnos" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation tree is valid." -msgstr "" +msgstr "Drevo animacije je veljavno." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation tree is invalid." -msgstr "" +msgstr "Drevo animacije ni veljavno." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation Node" -msgstr "" +msgstr "Animacijski Gradnik" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "OneShot Node" -msgstr "" +msgstr "Gradnik EnPoizkus" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix Node" -msgstr "" +msgstr "Gradnik MeÅ¡anica" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend2 Node" -msgstr "" +msgstr "Gradnik ZmeÅ¡aj2" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend3 Node" -msgstr "" +msgstr "Gradnik ZmeÅ¡aj3" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend4 Node" -msgstr "" +msgstr "Gradnik ZmeÅ¡aj4" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeScale Node" -msgstr "" +msgstr "Gradnik ÄŒasovnoMerilo" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeSeek Node" -msgstr "" +msgstr "Gradnik ÄŒasovniIskalnik" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Transition Node" -msgstr "" +msgstr "Gradnik Prehod" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Import Animations..." -msgstr "" +msgstr "Uvozi Animacije..." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Node Filters" -msgstr "" +msgstr "Uredi Gradnike Filtri" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Filters..." -msgstr "" +msgstr "Filtri..." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "AnimationTree" @@ -3274,67 +3276,67 @@ msgstr "AnimacijskoDrevo" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" -msgstr "" +msgstr "Prosto" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" -msgstr "" +msgstr "Vsebina:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "View Files" -msgstr "" +msgstr "Ogled datotek" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve hostname:" -msgstr "" +msgstr "Ne morem razreÅ¡iti imena gostitelja:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connection error, please try again." -msgstr "" +msgstr "Napaka pri povezavi, poskusi znova." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect to host:" -msgstr "" +msgstr "NemogoÄe se je povezati z gostiteljem:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response from host:" -msgstr "" +msgstr "Gostitelj se ne odziva:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, return code:" -msgstr "" +msgstr "Zahteva ni uspela, povratna koda:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" -msgstr "" +msgstr "Zahteva ni uspela, preveÄ preusmeritev" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." -msgstr "" +msgstr "Slab prenos hash kode, predvidevamo, da je bila datoteka spremenjena." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Expected:" -msgstr "" +msgstr "PriÄakovano:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Got:" -msgstr "" +msgstr "Dobil:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed sha256 hash check" -msgstr "" +msgstr "NeuspeÅ¡no preverjanje preizkusa sha256" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" -msgstr "" +msgstr "Napaka pri prenosu sredstev:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Fetching:" -msgstr "" +msgstr "Pridobivanje:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Resolving..." -msgstr "" +msgstr "RazreÅ¡evanje..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Error making request" @@ -8078,6 +8080,14 @@ msgstr "Napaka nalaganja pisave." msgid "Invalid font size." msgstr "Neveljavna velikost pisave." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "PrejÅ¡nji zavihek" + +#, fuzzy +#~ msgid "Next" +#~ msgstr "Naslednji zavihek" + #~ msgid "Not found!" #~ msgstr "Ni Zadetka!" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index fbfc998111..c838174131 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -8149,6 +8149,13 @@ msgstr "" msgid "Invalid font size." msgstr "Ðеважећа величина фонта." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Претходни таб" + +#~ msgid "Next" +#~ msgstr "Следеће" + #~ msgid "" #~ "Invalid version.txt format inside templates. Revision is not a valid " #~ "identifier." @@ -8159,9 +8166,6 @@ msgstr "Ðеважећа величина фонта." #~ msgid "Can't write file." #~ msgstr "ÐеуÑпех при запиÑивању датотеке." -#~ msgid "Next" -#~ msgstr "Следеће" - #~ msgid "Not found!" #~ msgstr "Ðије пронађено!" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index 1f1b6f1397..9ec654128a 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -3668,8 +3668,9 @@ msgid "first" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "prev" -msgstr "" +msgstr "förhandsgranska" #: editor/plugins/asset_library_editor_plugin.cpp msgid "next" @@ -8650,6 +8651,10 @@ msgstr "Fel vid laddning av font." msgid "Invalid font size." msgstr "Ogiltig teckenstorlek." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "FöregÃ¥ende flik" + #~ msgid "Next" #~ msgstr "Nästa" @@ -8685,10 +8690,6 @@ msgstr "Ogiltig teckenstorlek." #~ msgid "That's a BINGO!" #~ msgstr "Det är en BINGO!" -#, fuzzy -#~ msgid "preview" -#~ msgstr "förhandsgranska" - #~ msgid "Move Add Key" #~ msgstr "Flytta Lägg Till Nyckel" diff --git a/editor/translations/th.po b/editor/translations/th.po index f49b08d272..4db8459f1b 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -8077,6 +8077,13 @@ msgstr "ผิดพลาดขณะโหลดฟà¸à¸™à¸•à¹Œ" msgid "Invalid font size." msgstr "ขนาดฟà¸à¸™à¸•à¹Œà¸œà¸´à¸”พลาด" +#, fuzzy +#~ msgid "Previous" +#~ msgstr "à¹à¸—็บà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" + +#~ msgid "Next" +#~ msgstr "ต่à¸à¹„ป" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "ใช้ชื่à¸à¸™à¸µà¹‰à¹„ม่ได้ (มี '/' หรืภ':')" @@ -8100,9 +8107,6 @@ msgstr "ขนาดฟà¸à¸™à¸•à¹Œà¸œà¸´à¸”พลาด" #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "ไม่พบไฟล์ project.godot" -#~ msgid "Next" -#~ msgstr "ต่à¸à¹„ป" - #~ msgid "Not found!" #~ msgstr "ไม่พบ!" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 5be2415c0e..292cec4063 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -2,8 +2,8 @@ # 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. -# # Aprın Çor Tigin <kabusturk38@gmail.com>, 2016-2017. +# Aykut YILDIRIM <aykutyildirim@windowslive.com>, 2018. # Ceyhun Can Ulker <ceyhuncanu@gmail.com>, 2016. # Enes Kaya Öcal <ekayaocal@hotmail.com>, 2016. # Enescan Yerlikaya <enescanyerlikaya@gmail.com>, 2017. @@ -17,19 +17,18 @@ # razah <icnikerazah@gmail.com>, 2017-2018. # stnmycri <satenmeycri@gmail.com>, 2017-2018. # Yavuz Günay <yavuzgunay@gmail.com>, 2017. -# msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-06-05 05:45+0000\n" -"Last-Translator: Kaan Gül <qaantum@hotmail.com>\n" +"PO-Revision-Date: 2018-06-10 09:46+0000\n" +"Last-Translator: Aykut YILDIRIM <aykutyildirim@windowslive.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\n" +"X-Generator: Weblate 3.0.1-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5984,9 +5983,8 @@ msgid "Imported Project" msgstr "İçe Aktarılan Proje" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "Proje Adı:" +msgstr "Geçersiz Proje Adı." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -6191,6 +6189,7 @@ msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" +"Geçersiz iÅŸlem adı. BoÅŸ olamaz ve '/', ':', '=', '\\' veya '\"' içeremez." #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -7420,9 +7419,8 @@ msgid "Mono" msgstr "Tekli" #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy msgid "About C# support" -msgstr "C# hakkında destek" +msgstr "C# desteÄŸi hakkında" #: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" @@ -7995,12 +7993,11 @@ msgstr "ARVROrigin bir ARVRCamera çocuk düğümü gerektirir" #: scene/3d/baked_lightmap.cpp msgid "%d%%" -msgstr "" +msgstr "%d%%" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "(Time Left: %d:%02d s)" -msgstr "(Kalan Zaman:%d:%02d s)" +msgstr "(Kalan Zaman:%d:%02d sn)" #: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " @@ -8102,7 +8099,7 @@ msgstr "" #: scene/3d/scenario_fx.cpp msgid "WorldEnvironment needs an Environment resource." -msgstr "" +msgstr "WorldEnvironment bir Environment kaynağı gerektirir." #: scene/3d/scenario_fx.cpp msgid "" @@ -8116,6 +8113,8 @@ msgid "" "This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " "this environment's Background Mode to Canvas (for 2D scenes)." msgstr "" +"Bu WorldEnvironment yoksayıldı. (3B sahneler için) Bir Kamera ekleyin veya " +"(2B sahneler için) bu ortamın Arkaplan Kipini Canvas olarak ayarlayın." #: scene/3d/sprite_3d.cpp msgid "" @@ -8213,6 +8212,13 @@ msgstr "Yazıtipi yükleme hatası." msgid "Invalid font size." msgstr "Geçersiz yazıtipi boyutu." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "Önceki sekme" + +#~ msgid "Next" +#~ msgstr "Sonraki" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Geçersiz iÅŸlem (her ÅŸey ancak ÅŸu '/' ya da ÅŸuna ':' gider)." @@ -8238,9 +8244,6 @@ msgstr "Geçersiz yazıtipi boyutu." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Proje yolunda proje.godot alınamadı." -#~ msgid "Next" -#~ msgstr "Sonraki" - #~ msgid "Not found!" #~ msgstr "Bulunamadı!" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index 730d6a38ca..067c7be724 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.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. -# # Aleksandr <XpycT.TOP@gmail.com>, 2017. # Yuri Chornoivan <yurchor@ukr.net>, 2018. # Ðндрій Бандура <andriykopanytsia@gmail.com>, 2018. @@ -10,12 +9,11 @@ # МакÑим Якимчук <xpinovo@gmail.com>, 2018. # ÐœÐ°Ñ€Ñ Ð¯Ð¼Ð±Ð°Ñ€ <mjambarmeta@gmail.com>, 2017-2018. # ОлекÑандр Пилипчук <pilipchukap@rambler.ru>, 2018. -# msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" -"PO-Revision-Date: 2018-05-18 10:42+0000\n" -"Last-Translator: МакÑим Якимчук <xpinovo@gmail.com>\n" +"PO-Revision-Date: 2018-06-06 04:03+0000\n" +"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" "Language: uk\n" @@ -23,7 +21,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\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-dev\n" +"X-Generator: Weblate 3.0\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -5700,9 +5698,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" @@ -5989,9 +5986,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." @@ -6193,13 +6189,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!" @@ -8230,6 +8225,13 @@ msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ñƒ." msgid "Invalid font size." msgstr "Ðекоректний розмір шрифту." +#, fuzzy +#~ msgid "Previous" +#~ msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ°" + +#~ msgid "Next" +#~ msgstr "Далі" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Ðекоректна Ð´Ñ–Ñ (можна уÑе, окрім «/» або «:»)." @@ -8256,9 +8258,6 @@ msgstr "Ðекоректний розмір шрифту." #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ project.godot у каталозі проекту." -#~ msgid "Next" -#~ msgstr "Далі" - #~ msgid "Not found!" #~ msgstr "Ðе знайдено!" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 2ed1d729c7..6651bd170c 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -7967,3 +7967,7 @@ msgstr "Lá»—i tải font." #: scene/resources/dynamic_font.cpp msgid "Invalid font size." msgstr "KÃch thÆ°á»›c font không hợp lệ." + +#, fuzzy +#~ msgid "Previous" +#~ msgstr "ThÆ° mục trÆ°á»›c" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index b04de228dd..48e30ceab3 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.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. -# # 360119124 <360119124@qq.com>, 2018. # æŸ æª¬æ€æ‰‹ <lemonkiller@gmail.com>, 2018. # 纯æ´çš„å蛋 <tqj.zyy@gmail.com>, 2016. @@ -13,8 +12,9 @@ # dragonandy <dragonandy@foxmail.com>, 2017-2018. # Geequlim <geequlim@gmail.com>, 2016-2018. # jie Shi <meishijiemeimeimei@gmail.com>, 2018. +# Jingtian Pan <panjingtian@126.com>, 2018. # lalalaring <783482203@qq.com>, 2017. -# Luo Jun <vipsbpig@gmail.com>, 2016-2017. +# Luo Jun <vipsbpig@gmail.com>, 2016-2017, 2018. # oberon-tonya <360119124@qq.com>, 2016. # plumsky <x-wolf@163.com>, 2018. # Qichunren <whyruby@gmail.com>, 2017. @@ -25,13 +25,13 @@ # Youmu <konpaku.w@gmail.com>, 2017. # yuetian <18829280955@163.com>, 2018. # Zae Chao <zae.vito@live.com>, 2018. -# +# zwj36028 <23732399@qq.com>, 2018. msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2018-05-11 03:34+0000\n" -"Last-Translator: plumsky <x-wolf@163.com>\n" +"PO-Revision-Date: 2018-06-09 03:55+0000\n" +"Last-Translator: zwj36028 <23732399@qq.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -39,7 +39,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-dev\n" +"X-Generator: Weblate 3.0\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -1403,7 +1403,7 @@ 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!" @@ -2748,11 +2748,11 @@ msgstr "导入独立的物体和动画" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "导入独立的æ质和动画" +msgstr "与独立的æ质和动画一åŒå¯¼å…¥" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "导入独立的物体ã€æ质和动画" +msgstr "与独立的物体ã€æ质和动画一åŒå¯¼å…¥" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" @@ -3853,7 +3853,7 @@ msgstr "æŒ‰ä½ Shift å¯å•ç‹¬ç¼–辑切线" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "烘焙GI Probe" +msgstr "渲染GI Probe" #: editor/plugins/gradient_editor_plugin.cpp msgid "Add/Remove Color Ramp Point" @@ -5647,9 +5647,8 @@ msgid "Options" msgstr "选项" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "æœ‰ï¼Œå¾ˆå¤šï¼Œå‡ ä¸ªï¼Œé€‰é¡¹(Have,Many,Several,Options)ï¼" +msgstr "有,很多,选项" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -5929,9 +5928,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." @@ -6128,11 +6126,10 @@ msgid "Mouse Button" msgstr "é¼ æ ‡æŒ‰é”®" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." -msgstr "æ— æ•ˆçš„æ“作å称。它ä¸èƒ½æ˜¯ç©ºçš„也ä¸èƒ½åŒ…å« '/', ':', '=', '\\' 或者 '\"'" +msgstr "æ— æ•ˆçš„æ“作å称。它ä¸èƒ½æ˜¯ç©ºçš„也ä¸èƒ½åŒ…å« '/', ':', '=', '\\' 或者 '\"'。" #: editor/project_settings_editor.cpp msgid "Action '%s' already exists!" @@ -6388,7 +6385,7 @@ msgstr "地区é‡å®šå‘:" #: editor/project_settings_editor.cpp msgid "Locale" -msgstr "地区" +msgstr "区域" #: editor/project_settings_editor.cpp msgid "Locales Filter" @@ -7349,7 +7346,7 @@ msgstr "完æˆ" #: modules/mono/editor/godotsharp_editor.cpp msgid "Failed to create C# project." -msgstr "创建C#项目失败" +msgstr "创建C#项目失败。" #: modules/mono/editor/godotsharp_editor.cpp msgid "Mono" @@ -8100,6 +8097,13 @@ msgstr "åŠ è½½å—体出错。" msgid "Invalid font size." msgstr "å—体大å°éžæ³•ã€‚" +#, fuzzy +#~ msgid "Previous" +#~ msgstr "上一个目录" + +#~ msgid "Next" +#~ msgstr "下一项" + #~ msgid "Invalid action (anything goes but '/' or ':')." #~ msgstr "Actionåéžæ³•(ä¸å¾—包å«'/'或':')。" @@ -8123,9 +8127,6 @@ msgstr "å—体大å°éžæ³•ã€‚" #~ msgid "Couldn't get project.godot in the project path." #~ msgstr "æ— æ³•åœ¨é¡¹ç›®ç›®å½•ä¸‹æ‰¾åˆ°project.godot文件。" -#~ msgid "Next" -#~ msgstr "下一项" - #~ msgid "Not found!" #~ msgstr "未找到ï¼" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index 2a0941da8e..568390a7a8 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -8295,6 +8295,13 @@ msgid "Invalid font size." msgstr "無效å—åž‹" #, fuzzy +#~ msgid "Previous" +#~ msgstr "上一個tab" + +#~ msgid "Next" +#~ msgstr "下一個" + +#, fuzzy #~ msgid "Can't contain '/' or ':'" #~ msgstr "ä¸èƒ½é€£åˆ°ä¸»æ©Ÿï¼š" @@ -8302,9 +8309,6 @@ msgstr "無效å—åž‹" #~ msgid "Can't write file." #~ msgstr "無法新增資料夾" -#~ msgid "Next" -#~ msgstr "下一個" - #~ msgid "Not found!" #~ msgstr "找ä¸åˆ°!" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index c38ab9f25b..38b565a37f 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -3343,8 +3343,9 @@ msgid "first" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "prev" -msgstr "" +msgstr "é 覽:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "next" @@ -8122,6 +8123,10 @@ msgstr "讀å–å—體錯誤。" msgid "Invalid font size." msgstr "無效的å—體大å°ã€‚" +#, fuzzy +#~ msgid "Previous" +#~ msgstr "上個分é " + #~ msgid "Next" #~ msgstr "下一個" @@ -8140,10 +8145,6 @@ msgstr "無效的å—體大å°ã€‚" #~ msgid "Skip" #~ msgstr "è·³éŽ" -#, fuzzy -#~ msgid "preview" -#~ msgstr "é 覽:" - #~ msgid "List:" #~ msgstr "列表:" diff --git a/main/SCsub b/main/SCsub index e2bf03234f..0692175799 100644 --- a/main/SCsub +++ b/main/SCsub @@ -131,20 +131,20 @@ env.add_source_files(env.main_sources, "*.cpp") controller_databases = ["#main/gamecontrollerdb.txt", "#main/gamecontrollerdb_205.txt", "#main/gamecontrollerdb_204.txt", "#main/godotcontrollerdb.txt"] env.Depends("#main/default_controller_mappings.gen.cpp", controller_databases) -env.Command("#main/default_controller_mappings.gen.cpp", controller_databases, make_default_controller_mappings) +env.CommandNoCache("#main/default_controller_mappings.gen.cpp", controller_databases, make_default_controller_mappings) env.main_sources.append("#main/default_controller_mappings.gen.cpp") Export('env') env.Depends("#main/splash.gen.h", "#main/splash.png") -env.Command("#main/splash.gen.h", "#main/splash.png", make_splash) +env.CommandNoCache("#main/splash.gen.h", "#main/splash.png", make_splash) env.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png") -env.Command("#main/splash_editor.gen.h", "#main/splash_editor.png", make_splash_editor) +env.CommandNoCache("#main/splash_editor.gen.h", "#main/splash_editor.png", make_splash_editor) env.Depends("#main/app_icon.gen.h", "#main/app_icon.png") -env.Command("#main/app_icon.gen.h", "#main/app_icon.png", make_app_icon) +env.CommandNoCache("#main/app_icon.gen.h", "#main/app_icon.png", make_app_icon) SConscript('tests/SCsub') diff --git a/main/app_icon.png b/main/app_icon.png Binary files differindex 1d75cdc710..cf31af18a4 100644 --- a/main/app_icon.png +++ b/main/app_icon.png diff --git a/main/main.cpp b/main/main.cpp index 2e3c2f41b9..e2b3bb8e6f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -867,6 +867,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/allow_per_pixel_transparency", false); video_mode.use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", true); + OS::get_singleton()->_use_vsync = video_mode.use_vsync; + video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency", false); video_mode.layered_splash = GLOBAL_DEF("display/window/per_pixel_transparency_splash", false); diff --git a/main/splash.png b/main/splash.png Binary files differindex 34be46557f..32960db65f 100644 --- a/main/splash.png +++ b/main/splash.png diff --git a/main/splash_editor.png b/main/splash_editor.png Binary files differindex d8677f1749..f003995d6f 100644 --- a/main/splash_editor.png +++ b/main/splash_editor.png diff --git a/methods.py b/methods.py index 6dca826b2b..227a17d312 100644 --- a/methods.py +++ b/methods.py @@ -1329,3 +1329,8 @@ def add_program(env, name, sources, **args): program = env.Program(name, sources, **args) env.NoCache(program) return program + +def CommandNoCache(env, target, sources, command, **args): + result = env.Command(target, sources, command, **args) + env.NoCache(result) + return result diff --git a/misc/dist/appimage/AppRun b/misc/dist/appimage/AppRun deleted file mode 100755 index db3398a92a..0000000000 --- a/misc/dist/appimage/AppRun +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -HERE="$(dirname "$(readlink -f "${0}")")" -"${HERE}"/godot $@ diff --git a/misc/dist/appimage/godot.desktop b/misc/dist/appimage/godot.desktop deleted file mode 100644 index 545c491256..0000000000 --- a/misc/dist/appimage/godot.desktop +++ /dev/null @@ -1,9 +0,0 @@ -[Desktop Entry] -Name=Godot Engine -GenericName=Libre game engine -Comment=Multi-platform 2D and 3D game engine with a feature rich editor -Exec=godot -pm -Icon=godot -Terminal=false -Type=Application -Categories=Development;IDE; diff --git a/misc/dist/appimage/godot.png b/misc/dist/appimage/godot.png Binary files differdeleted file mode 100644 index e334f5fa78..0000000000 --- a/misc/dist/appimage/godot.png +++ /dev/null diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png Binary files differindex 6b9b10daae..1299ceaee5 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png Binary files differindex 50497496b7..604a7ba701 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png Binary files differindex 1c489de69f..bffb8c9fde 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png Binary files differindex d82dfce936..47826cd683 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png Binary files differindex 5120595df8..0f44a704b5 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png Binary files differindex cf6cf1347a..07ab777bc2 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png Binary files differindex 4eb167ae18..774b9c5bbf 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png Binary files differindex a9f951deac..fff36679c7 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png Binary files differindex 06d16412e2..0804519faa 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png Binary files differindex d70cab17be..833142222c 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png Binary files differindex f934971074..4c934c4a53 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png diff --git a/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png b/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png Binary files differindex 540bfb1c01..0c27fda8e7 100644 --- a/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png +++ b/misc/dist/uwp_template/Assets/SplashScreen.scale-100.png diff --git a/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png Binary files differindex 6e307e5eb8..96871f7413 100644 --- a/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png +++ b/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png diff --git a/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png Binary files differindex cb2516d7a0..96494b1020 100644 --- a/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png +++ b/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png diff --git a/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png Binary files differindex 6e14223e87..d21bc42009 100644 --- a/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png +++ b/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png diff --git a/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png Binary files differindex 0d4bd54da8..22a43cf95f 100644 --- a/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png +++ b/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png diff --git a/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png b/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png Binary files differindex 1501a09557..3960b0424b 100644 --- a/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png +++ b/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png diff --git a/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png b/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png Binary files differindex 593568e980..d836e113b1 100644 --- a/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png +++ b/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index ba27d6839d..5f13474d2c 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -2020,7 +2020,7 @@ void CSGPolygon::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees"); ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node"), "set_path_node", "get_path_node"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path"), "set_path_node", "get_path_node"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval"); ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 92fb41adf8..116a86b27b 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -13,6 +13,7 @@ gdn_env.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cp gdn_env.Append(CPPPATH=['#modules/gdnative/include/']) +SConscript("net/SCsub") SConscript("arvr/SCsub") SConscript("pluginscript/SCsub") @@ -196,7 +197,7 @@ def build_gdnative_api_struct(target, source, env): with open(source.path, 'w') as fd: fd.write(_build_gdnative_api_struct_source(api)) -_, gensource = gdn_env.Command(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'], +_, gensource = gdn_env.CommandNoCache(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'], 'gdnative_api.json', build_gdnative_api_struct) gdn_env.add_source_files(env.modules_sources, [gensource]) @@ -277,7 +278,7 @@ def build_gdnative_wrapper_code(target, source, env): if ARGUMENTS.get('gdnative_wrapper', False): #build wrapper code - gensource, = gdn_env.Command('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code) + gensource, = gdn_env.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code) gd_wrapper_env = env.Clone() gd_wrapper_env.Append(CPPPATH=['#modules/gdnative/include/']) diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py index 626e9239f8..c5b37d35b4 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -10,6 +10,7 @@ def get_doc_classes(): "GDNative", "GDNativeLibrary", "NativeScript", + "PacketPeerGDNative", "PluginScript", ] diff --git a/modules/gdnative/include/net/godot_net.h b/modules/gdnative/include/net/godot_net.h new file mode 100644 index 0000000000..bfa688592d --- /dev/null +++ b/modules/gdnative/include/net/godot_net.h @@ -0,0 +1,118 @@ +/*************************************************************************/ +/* godot_net.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 GODOT_NATIVENET_H +#define GODOT_NATIVENET_H + +#include <gdnative/gdnative.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// For future versions of the API we should only add new functions at the end of the structure and use the +// version info to detect whether a call is available + +// Use these to populate version in your plugin +#define GODOT_NET_API_MAJOR 3 +#define GODOT_NET_API_MINOR 1 + +typedef struct { + + godot_gdnative_api_version version; /* version of our API */ + godot_object *data; /* User reference */ + + /* This is StreamPeer */ + godot_error (*get_data)(void *user, uint8_t *p_buffer, int p_bytes); + godot_error (*get_partial_data)(void *user, uint8_t *p_buffer, int p_bytes, int &r_received); + godot_error (*put_data)(void *user, const uint8_t *p_data, int p_bytes); + godot_error (*put_partial_data)(void *user, const uint8_t *p_data, int p_bytes, int &r_sent); + + int (*get_available_bytes)(const void *user); + + void *next; /* For extension? */ +} godot_net_stream_peer; + +/* Binds a StreamPeerGDNative to the provided interface */ +void godot_net_bind_stream_peer(godot_object *p_obj, godot_net_stream_peer *p_interface); + +typedef struct { + godot_gdnative_api_version version; /* version of our API */ + + godot_object *data; /* User reference */ + + /* This is PacketPeer */ + godot_error (*get_packet)(void *, const uint8_t **, int &); + godot_error (*put_packet)(void *, const uint8_t *, int); + godot_int (*get_available_packet_count)(const void *); + godot_int (*get_max_packet_size)(const void *); + + void *next; /* For extension? */ +} godot_net_packet_peer; + +/* Binds a PacketPeerGDNative to the provided interface */ +void GDAPI godot_net_bind_packet_peer(godot_object *p_obj, const godot_net_packet_peer *); + +typedef struct { + godot_gdnative_api_version version; /* version of our API */ + + godot_object *data; /* User reference */ + + /* This is PacketPeer */ + godot_error (*get_packet)(void *, const uint8_t **, int &); + godot_error (*put_packet)(void *, const uint8_t *, int); + godot_int (*get_available_packet_count)(const void *); + godot_int (*get_max_packet_size)(const void *); + + /* This is NetworkedMultiplayerPeer */ + void (*set_transfer_mode)(void *, godot_int); + godot_int (*get_transfer_mode)(const void *); + // 0 = broadcast, 1 = server, <0 = all but abs(value) + void (*set_target_peer)(void *, godot_int); + godot_int (*get_packet_peer)(const void *); + godot_bool (*is_server)(const void *); + void (*poll)(void *); + // Must be > 0, 1 is for server + int32_t (*get_unique_id)(const void *); + void (*set_refuse_new_connections)(void *, godot_bool); + godot_bool (*is_refusing_new_connections)(const void *); + godot_int (*get_connection_status)(const void *); + + void *next; /* For extension? Or maybe not... */ +} godot_net_multiplayer_peer; + +/* Binds a MultiplayerPeerGDNative to the provided interface */ +void GDAPI godot_net_bind_multiplayer_peer(godot_object *p_obj, const godot_net_multiplayer_peer *); + +#ifdef __cplusplus +} +#endif + +#endif /* GODOT_NATIVENET_H */ diff --git a/modules/gdnative/net/SCsub b/modules/gdnative/net/SCsub new file mode 100644 index 0000000000..53f9271128 --- /dev/null +++ b/modules/gdnative/net/SCsub @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import os +import methods + +Import('env') +Import('env_modules') + +env_net_gdnative = env_modules.Clone() + +env_net_gdnative.Append(CPPPATH=['#modules/gdnative/include/']) +env_net_gdnative.add_source_files(env.modules_sources, '*.cpp') diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.cpp b/modules/gdnative/net/multiplayer_peer_gdnative.cpp new file mode 100644 index 0000000000..e2d710b5ad --- /dev/null +++ b/modules/gdnative/net/multiplayer_peer_gdnative.cpp @@ -0,0 +1,124 @@ +/*************************************************************************/ +/* multiplayer_peer_gdnative.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "multiplayer_peer_gdnative.h" + +MultiplayerPeerGDNative::MultiplayerPeerGDNative() { + interface = NULL; +} + +MultiplayerPeerGDNative::~MultiplayerPeerGDNative() { +} + +void MultiplayerPeerGDNative::set_native_multiplayer_peer(const godot_net_multiplayer_peer *p_interface) { + interface = p_interface; +} + +Error MultiplayerPeerGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->get_packet(interface->data, r_buffer, r_buffer_size); +} + +Error MultiplayerPeerGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size); +} + +int MultiplayerPeerGDNative::get_max_packet_size() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_max_packet_size(interface->data); +} + +int MultiplayerPeerGDNative::get_available_packet_count() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_available_packet_count(interface->data); +} + +/* NetworkedMultiplayerPeer */ +void MultiplayerPeerGDNative::set_transfer_mode(TransferMode p_mode) { + ERR_FAIL_COND(interface == NULL); + interface->set_transfer_mode(interface->data, (godot_int)p_mode); +} + +NetworkedMultiplayerPeer::TransferMode MultiplayerPeerGDNative::get_transfer_mode() const { + ERR_FAIL_COND_V(interface == NULL, TRANSFER_MODE_UNRELIABLE); + return (TransferMode)interface->get_transfer_mode(interface->data); +} + +void MultiplayerPeerGDNative::set_target_peer(int p_peer_id) { + ERR_FAIL_COND(interface == NULL); + interface->set_target_peer(interface->data, p_peer_id); +} + +int MultiplayerPeerGDNative::get_packet_peer() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_packet_peer(interface->data); +} + +bool MultiplayerPeerGDNative::is_server() const { + ERR_FAIL_COND_V(interface == NULL, false); + return interface->is_server(interface->data); +} + +void MultiplayerPeerGDNative::poll() { + ERR_FAIL_COND(interface == NULL); + interface->poll(interface->data); +} + +int MultiplayerPeerGDNative::get_unique_id() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_unique_id(interface->data); +} + +void MultiplayerPeerGDNative::set_refuse_new_connections(bool p_enable) { + ERR_FAIL_COND(interface == NULL); + interface->set_refuse_new_connections(interface->data, p_enable); +} + +bool MultiplayerPeerGDNative::is_refusing_new_connections() const { + ERR_FAIL_COND_V(interface == NULL, true); + return interface->is_refusing_new_connections(interface->data); +} + +NetworkedMultiplayerPeer::ConnectionStatus MultiplayerPeerGDNative::get_connection_status() const { + ERR_FAIL_COND_V(interface == NULL, CONNECTION_DISCONNECTED); + return (ConnectionStatus)interface->get_connection_status(interface->data); +} + +void MultiplayerPeerGDNative::_bind_methods() { +} + +extern "C" { + +void GDAPI godot_net_bind_multiplayer_peer(godot_object *p_obj, const godot_net_multiplayer_peer *p_impl) { + + ((MultiplayerPeerGDNative *)p_obj)->set_native_multiplayer_peer(p_impl); +} +} diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.h b/modules/gdnative/net/multiplayer_peer_gdnative.h new file mode 100644 index 0000000000..c8c95b3dd7 --- /dev/null +++ b/modules/gdnative/net/multiplayer_peer_gdnative.h @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* multiplayer_peer_gdnative.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 MULTIPLAYER_PEER_GDNATIVE_H +#define MULTIPLAYER_PEER_GDNATIVE_H + +#include "core/io/networked_multiplayer_peer.h" +#include "modules/gdnative/gdnative.h" +#include "modules/gdnative/include/net/godot_net.h" + +class MultiplayerPeerGDNative : public NetworkedMultiplayerPeer { + GDCLASS(MultiplayerPeerGDNative, NetworkedMultiplayerPeer) + +protected: + static void _bind_methods(); + const godot_net_multiplayer_peer *interface; + +public: + MultiplayerPeerGDNative(); + ~MultiplayerPeerGDNative(); + + /* Sets the interface implementation from GDNative */ + void set_native_multiplayer_peer(const godot_net_multiplayer_peer *p_impl); + + /* Specific to PacketPeer */ + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); + virtual int get_max_packet_size() const; + virtual int get_available_packet_count() const; + + /* Specific to NetworkedMultiplayerPeer */ + virtual void set_transfer_mode(TransferMode p_mode); + virtual TransferMode get_transfer_mode() const; + virtual void set_target_peer(int p_peer_id); + + virtual int get_packet_peer() const; + + virtual bool is_server() const; + + virtual void poll(); + + virtual int get_unique_id() const; + + virtual void set_refuse_new_connections(bool p_enable); + virtual bool is_refusing_new_connections() const; + + virtual ConnectionStatus get_connection_status() const; +}; + +#endif // MULTIPLAYER_PEER_GDNATIVE_H diff --git a/modules/gdnative/net/packet_peer_gdnative.cpp b/modules/gdnative/net/packet_peer_gdnative.cpp new file mode 100644 index 0000000000..ceae79edc0 --- /dev/null +++ b/modules/gdnative/net/packet_peer_gdnative.cpp @@ -0,0 +1,73 @@ +/*************************************************************************/ +/* packet_peer_gdnative.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "packet_peer_gdnative.h" + +PacketPeerGDNative::PacketPeerGDNative() { + interface = NULL; +} + +PacketPeerGDNative::~PacketPeerGDNative() { +} + +void PacketPeerGDNative::set_native_packet_peer(const godot_net_packet_peer *p_impl) { + interface = p_impl; +} + +void PacketPeerGDNative::_bind_methods() { +} + +Error PacketPeerGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->get_packet(interface->data, r_buffer, r_buffer_size); +} + +Error PacketPeerGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size); +} + +int PacketPeerGDNative::get_max_packet_size() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_max_packet_size(interface->data); +} + +int PacketPeerGDNative::get_available_packet_count() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_available_packet_count(interface->data); +} + +extern "C" { + +void GDAPI godot_net_bind_packet_peer(godot_object *p_obj, const godot_net_packet_peer *p_impl) { + + ((PacketPeerGDNative *)p_obj)->set_native_packet_peer(p_impl); +} +} diff --git a/modules/gdnative/net/packet_peer_gdnative.h b/modules/gdnative/net/packet_peer_gdnative.h new file mode 100644 index 0000000000..71814177ed --- /dev/null +++ b/modules/gdnative/net/packet_peer_gdnative.h @@ -0,0 +1,59 @@ +/*************************************************************************/ +/* packet_peer_gdnative.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 PACKET_PEER_GDNATIVE_H +#define PACKET_PEER_GDNATIVE_H + +#include "core/io/packet_peer.h" +#include "modules/gdnative/gdnative.h" +#include "modules/gdnative/include/net/godot_net.h" + +class PacketPeerGDNative : public PacketPeer { + GDCLASS(PacketPeerGDNative, PacketPeer) + +protected: + static void _bind_methods(); + const godot_net_packet_peer *interface; + +public: + PacketPeerGDNative(); + ~PacketPeerGDNative(); + + /* Sets the interface implementation from GDNative */ + void set_native_packet_peer(const godot_net_packet_peer *p_impl); + + /* Specific to PacketPeer */ + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); + virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); + virtual int get_max_packet_size() const; + virtual int get_available_packet_count() const; +}; + +#endif // PACKET_PEER_GDNATIVE_H diff --git a/modules/gdnative/net/register_types.cpp b/modules/gdnative/net/register_types.cpp new file mode 100644 index 0000000000..c3fb4d8008 --- /dev/null +++ b/modules/gdnative/net/register_types.cpp @@ -0,0 +1,43 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "register_types.h" +#include "multiplayer_peer_gdnative.h" +#include "packet_peer_gdnative.h" +#include "stream_peer_gdnative.h" + +void register_net_types() { + ClassDB::register_class<MultiplayerPeerGDNative>(); + ClassDB::register_class<PacketPeerGDNative>(); + ClassDB::register_class<StreamPeerGDNative>(); +} + +void unregister_net_types() { +} diff --git a/modules/gdnative/net/register_types.h b/modules/gdnative/net/register_types.h new file mode 100644 index 0000000000..9545a2ba8f --- /dev/null +++ b/modules/gdnative/net/register_types.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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. */ +/*************************************************************************/ + +void register_net_types(); +void unregister_net_types(); diff --git a/modules/gdnative/net/stream_peer_gdnative.cpp b/modules/gdnative/net/stream_peer_gdnative.cpp new file mode 100644 index 0000000000..4d1f2ec9a5 --- /dev/null +++ b/modules/gdnative/net/stream_peer_gdnative.cpp @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* stream_peer_gdnative.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "stream_peer_gdnative.h" + +StreamPeerGDNative::StreamPeerGDNative() { + interface = NULL; +} + +StreamPeerGDNative::~StreamPeerGDNative() { +} + +void StreamPeerGDNative::set_native_stream_peer(godot_net_stream_peer *p_interface) { + interface = p_interface; +} + +void StreamPeerGDNative::_bind_methods() { +} + +Error StreamPeerGDNative::put_data(const uint8_t *p_data, int p_bytes) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->put_data(interface->data, p_data, p_bytes)); +} + +Error StreamPeerGDNative::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->put_partial_data(interface->data, p_data, p_bytes, r_sent)); +} + +Error StreamPeerGDNative::get_data(uint8_t *p_buffer, int p_bytes) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->get_data(interface->data, p_buffer, p_bytes)); +} + +Error StreamPeerGDNative::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) { + ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED); + return (Error)(interface->get_partial_data(interface->data, p_buffer, p_bytes, r_received)); +} + +int StreamPeerGDNative::get_available_bytes() const { + ERR_FAIL_COND_V(interface == NULL, 0); + return interface->get_available_bytes(interface->data); +} + +extern "C" { + +void GDAPI godot_net_bind_stream_peer(godot_object *p_obj, godot_net_stream_peer *p_interface) { + ((StreamPeerGDNative *)p_obj)->set_native_stream_peer(p_interface); +} +} diff --git a/modules/gdnative/net/stream_peer_gdnative.h b/modules/gdnative/net/stream_peer_gdnative.h new file mode 100644 index 0000000000..654234e6ab --- /dev/null +++ b/modules/gdnative/net/stream_peer_gdnative.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/* stream_peer_gdnative.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 STREAM_PEER_GDNATIVE_H +#define STREAM_PEER_GDNATIVE_H + +#include "core/io/stream_peer.h" +#include "modules/gdnative/gdnative.h" +#include "modules/gdnative/include/net/godot_net.h" + +class StreamPeerGDNative : public StreamPeer { + + GDCLASS(StreamPeerGDNative, StreamPeer); + +protected: + static void _bind_methods(); + godot_net_stream_peer *interface; + +public: + StreamPeerGDNative(); + ~StreamPeerGDNative(); + + /* Sets the interface implementation from GDNative */ + void set_native_stream_peer(godot_net_stream_peer *p_interface); + + /* Specific to StreamPeer */ + Error put_data(const uint8_t *p_data, int p_bytes); + Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent); + Error get_data(uint8_t *p_buffer, int p_bytes); + Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received); + int get_available_bytes() const; +}; + +#endif // STREAM_PEER_GDNATIVE_H diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index a0b6fbeb75..d18297f2f8 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -38,6 +38,7 @@ #include "arvr/register_types.h" #include "nativescript/register_types.h" +#include "net/register_types.h" #include "pluginscript/register_types.h" #include "core/engine.h" @@ -321,6 +322,7 @@ void register_gdnative_types() { GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall); + register_net_types(); register_arvr_types(); register_nativescript_types(); register_pluginscript_types(); @@ -379,6 +381,7 @@ void unregister_gdnative_types() { unregister_pluginscript_types(); unregister_nativescript_types(); unregister_arvr_types(); + unregister_net_types(); memdelete(GDNativeCallRegistry::singleton); diff --git a/modules/mono/SCsub b/modules/mono/SCsub index a1dfcf6377..03e187e5b0 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -127,15 +127,24 @@ def find_msbuild_windows(): if not mono_root: raise RuntimeError('Cannot find mono root directory') + framework_path = os.path.join(mono_root, 'lib', 'mono', '4.5') + + mono_bin_dir = os.path.join(mono_root, 'bin') + + msbuild_mono = os.path.join(mono_bin_dir, 'msbuild.bat') + + if os.path.isfile(msbuild_mono): + mono_msbuild_env = { + 'CscToolExe': os.path.join(mono_bin_dir, 'csc.bat'), + 'VbcToolExe': os.path.join(mono_bin_dir, 'vbc.bat'), + 'FscToolExe': os.path.join(mono_bin_dir, 'fsharpc.bat') + } + return (msbuild_mono, framework_path, mono_msbuild_env) + msbuild_tools_path = monoreg.find_msbuild_tools_path_reg() if msbuild_tools_path: - return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), os.path.join(mono_root, 'lib', 'mono', '4.5')) - else: - msbuild_mono = os.path.join(mono_root, 'bin', 'msbuild.bat') - - if os.path.isfile(msbuild_mono): - return (msbuild_mono, '') + return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), framework_path, {}) return None @@ -145,14 +154,21 @@ def mono_build_solution(source, target, env): import mono_reg_utils as monoreg from shutil import copyfile - framework_path_override = '' + framework_path = '' + + msbuild_env = os.environ.copy() + + # Needed when running from Developer Command Prompt for VS + if 'PLATFORM' in msbuild_env: + del msbuild_env['PLATFORM'] if os.name == 'nt': msbuild_info = find_msbuild_windows() if msbuild_info is None: raise RuntimeError('Cannot find MSBuild executable') msbuild_path = msbuild_info[0] - framework_path_override = msbuild_info[1] + framework_path = msbuild_info[1] + msbuild_env.update(msbuild_info[2]) else: msbuild_path = find_msbuild_unix('msbuild') if msbuild_path is None: @@ -183,14 +199,8 @@ def mono_build_solution(source, target, env): '/p:Configuration=' + build_config, ] - if framework_path_override: - msbuild_args += ['/p:FrameworkPathOverride=' + framework_path_override] - - msbuild_env = os.environ.copy() - - # Needed when running from Developer Command Prompt for VS - if 'PLATFORM' in msbuild_env: - del msbuild_env['PLATFORM'] + if framework_path: + msbuild_args += ['/p:FrameworkPathOverride=' + framework_path] try: subprocess.check_call(msbuild_args, env=msbuild_env) diff --git a/modules/mono/config.py b/modules/mono/config.py index 8b52d77f80..ebf8512fb6 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -4,7 +4,7 @@ import os import sys import subprocess -from SCons.Script import BoolVariable, Dir, Environment, PathVariable, Variables +from SCons.Script import BoolVariable, Dir, Environment, File, PathVariable, SCons, Variables monoreg = imp.load_source('mono_reg_utils', 'modules/mono/mono_reg_utils.py') @@ -42,13 +42,24 @@ def copy_file(src_dir, dst_dir, name): copyfile(src_path, dst_path) +def custom_path_is_dir_create(key, val, env): + """Validator to check if Path is a directory, creating it if it does not exist. + Similar to PathIsDirCreate, except it uses SCons.Script.Dir() and + SCons.Script.File() in order to support the '#' top level directory token. + """ + # Dir constructor will throw an error if the path points to a file + fsDir = Dir(val) + if not fsDir.exists: + os.makedirs(fsDir.abspath) + + def configure(env): env.use_ptrcall = True env.add_module_version_string("mono") envvars = Variables() envvars.Add(BoolVariable('mono_static', 'Statically link mono', False)) - envvars.Add(PathVariable('mono_assemblies_output_dir', 'Path to the assemblies output directory', '#bin', PathVariable.PathIsDirCreate)) + envvars.Add(PathVariable('mono_assemblies_output_dir', 'Path to the assemblies output directory', '#bin', custom_path_is_dir_create)) envvars.Update(env) bits = env['bits'] @@ -135,6 +146,22 @@ def configure(env): if os.getenv('MONO64_PREFIX'): mono_root = os.getenv('MONO64_PREFIX') + # We can't use pkg-config to link mono statically, + # but we can still use it to find the mono root directory + if not mono_root and mono_static: + def pkgconfig_try_find_mono_root(): + tmpenv = Environment() + tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH')) + tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L') + for hint_dir in tmpenv['LIBPATH']: + name_found = find_file_in_dir(hint_dir, mono_lib_names, prefix='lib', extension=sharedlib_ext) + if name_found and os.path.isdir(os.path.join(hint_dir, '..', 'include', 'mono-2.0')): + return os.path.join(hint_dir, '..') + return '' + mono_root = pkgconfig_try_find_mono_root() + if not mono_root: + raise RuntimeError('Building with mono_static=yes, but failed to find the mono prefix with pkg-config. Specify one manually') + if mono_root: mono_lib_path = os.path.join(mono_root, 'lib') @@ -175,8 +202,7 @@ def configure(env): copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll') else: - if mono_static: - raise RuntimeError('mono-static: Not supported with pkg-config. Specify a mono prefix manually') + assert not mono_static env.ParseConfig('pkg-config monosgen-2 --cflags --libs') diff --git a/modules/websocket/lws_helper.h b/modules/websocket/lws_helper.h index a850a545d3..a4920c3d54 100644 --- a/modules/websocket/lws_helper.h +++ b/modules/websocket/lws_helper.h @@ -30,6 +30,9 @@ #ifndef LWS_HELPER_H #define LWS_HELPER_H +#define LWS_BUF_SIZE 65536 +#define LWS_PACKET_SIZE LWS_BUF_SIZE + #include "core/io/stream_peer.h" #include "core/os/os.h" #include "core/reference.h" @@ -124,6 +127,7 @@ static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, /* LWS protocol structs */ ref->lws_structs = (struct lws_protocols *)memalloc(sizeof(struct lws_protocols) * (len + 2)); + memset(ref->lws_structs, 0, sizeof(struct lws_protocols) * (len + 2)); CharString strings = p_names.join(",").ascii(); int str_len = strings.length(); @@ -145,13 +149,15 @@ static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, structs_ptr[0].name = "http-only"; structs_ptr[0].callback = p_callback; structs_ptr[0].per_session_data_size = data_size; - structs_ptr[0].rx_buffer_size = 0; + structs_ptr[0].rx_buffer_size = LWS_BUF_SIZE; + structs_ptr[0].tx_packet_size = LWS_PACKET_SIZE; /* add user defined protocols */ for (i = 0; i < len; i++) { structs_ptr[i + 1].name = (const char *)&names_ptr[pos]; structs_ptr[i + 1].callback = p_callback; structs_ptr[i + 1].per_session_data_size = data_size; - structs_ptr[i + 1].rx_buffer_size = 0; + structs_ptr[i + 1].rx_buffer_size = LWS_BUF_SIZE; + structs_ptr[i + 1].tx_packet_size = LWS_PACKET_SIZE; pos += pnr[i].ascii().length() + 1; names_ptr[pos - 1] = '\0'; } diff --git a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png Binary files differindex 94bc406416..372b763ec5 100644 --- a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png +++ b/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png diff --git a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png Binary files differindex ef6fe4e836..c61c440636 100644 --- a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png +++ b/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png Binary files differindex 29c4a7b8fc..6ad9b43117 100644 --- a/platform/android/java/res/drawable/icon.png +++ b/platform/android/java/res/drawable/icon.png diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index 90848e6a90..8a2d789dc5 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -32,6 +32,7 @@ package org.godotengine.godot; import android.R; import android.app.Activity; +import android.content.pm.ConfigurationInfo; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; @@ -246,9 +247,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } }; - public void onVideoInit(boolean use_gl2) { + public void onVideoInit() { - //mView = new GodotView(getApplication(),io,use_gl2); + boolean use_gl3 = getGLESVersionCode() >= 0x00030000; + + //mView = new GodotView(getApplication(),io,use_gl3); //setContentView(mView); layout = new FrameLayout(this); @@ -261,7 +264,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(getApplication(), io, use_gl2, use_32_bits, this); + mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, this); layout.addView(mView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); edittext.setView(mView); io.setEdit(edittext); @@ -338,6 +341,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC return Godot._self; } + public int getGLESVersionCode() { + ActivityManager am = (ActivityManager)Godot.getInstance().getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo(); + return deviceInfo.reqGlEsVersion; + } + private String[] getCommandLine() { InputStream is; try { diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 579c06f76b..e6240ad9e9 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -614,6 +614,7 @@ static jmethodID _hideKeyboard = 0; static jmethodID _setScreenOrientation = 0; static jmethodID _getUniqueID = 0; static jmethodID _getSystemDir = 0; +static jmethodID _getGLESVersionCode = 0; static jmethodID _playVideo = 0; static jmethodID _isVideoPlaying = 0; static jmethodID _pauseVideo = 0; @@ -685,6 +686,11 @@ static String _get_system_dir(int p_dir) { return String(env->GetStringUTFChars(s, NULL)); } +static int _get_gles_version_code() { + JNIEnv *env = ThreadAndroid::get_env(); + return env->CallIntMethod(_godot_instance, _getGLESVersionCode); +} + static void _hide_vk() { JNIEnv *env = ThreadAndroid::get_env(); @@ -764,9 +770,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en godot_io = gob; - _on_video_init = env->GetMethodID(cls, "onVideoInit", "(Z)V"); + _on_video_init = env->GetMethodID(cls, "onVideoInit", "()V"); _setKeepScreenOn = env->GetMethodID(cls, "setKeepScreenOn", "(Z)V"); _alertDialog = env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V"); + _getGLESVersionCode = env->GetMethodID(cls, "getGLESVersionCode", "()I"); jclass clsio = env->FindClass("org/godotengine/godot/Godot"); if (cls) { @@ -800,16 +807,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en AudioDriverAndroid::setup(gob); } - os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); + os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _get_gles_version_code, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); os_android->set_need_reload_hooks(p_need_reload_hook); char wd[500]; getcwd(wd, 500); - //video driver is determined here, because once initialized, it can't be changed - // String vd = ProjectSettings::get_singleton()->get("display/driver"); - - env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true); + env->CallVoidMethod(_godot_instance, _on_video_init); } static void _initialize_java_modules() { diff --git a/platform/android/logo.png b/platform/android/logo.png Binary files differindex fcf684c026..ba2a0e366a 100644 --- a/platform/android/logo.png +++ b/platform/android/logo.png diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index fc41adeb76..9188f09f21 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -32,6 +32,7 @@ #include "core/io/file_access_buffered_fa.h" #include "core/project_settings.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" @@ -125,13 +126,20 @@ void OS_Android::set_opengl_extensions(const char *p_gl_extensions) { Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { - use_gl2 = p_video_driver != 1; + bool use_gl3 = get_gl_version_code_func() >= 0x00030000; + use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3"); + use_gl2 = !use_gl3; if (gfx_init_func) gfx_init_func(gfx_init_ud, use_gl2); - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); + if (use_gl2) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + } visual_server = memnew(VisualServerRaster); /* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { @@ -684,7 +692,7 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) { return false; } -OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) { +OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) { use_apk_expansion = p_use_apk_expansion; default_videomode.width = 800; @@ -706,6 +714,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI get_screen_dpi_func = p_get_screen_dpi_func; get_unique_id_func = p_get_unique_id; get_system_dir_func = p_get_sdir_func; + get_gl_version_code_func = p_get_gl_version_func; video_play_func = p_video_play_func; video_is_playing_func = p_video_is_playing_func; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index d2457e538d..ac901d4832 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -58,6 +58,7 @@ typedef void (*ShowVirtualKeyboardFunc)(const String &); typedef void (*HideVirtualKeyboardFunc)(); typedef void (*SetScreenOrientationFunc)(int); typedef String (*GetSystemDirFunc)(int); +typedef int (*GetGLVersionCodeFunc)(); typedef void (*VideoPlayFunc)(const String &); typedef bool (*VideoIsPlayingFunc)(); @@ -126,6 +127,7 @@ private: SetScreenOrientationFunc set_screen_orientation_func; GetUniqueIDFunc get_unique_id_func; GetSystemDirFunc get_system_dir_func; + GetGLVersionCodeFunc get_gl_version_code_func; VideoPlayFunc video_play_func; VideoIsPlayingFunc video_is_playing_func; @@ -239,7 +241,7 @@ public: void joy_connection_changed(int p_device, bool p_connected, String p_name); virtual bool _check_internal_feature_support(const String &p_feature); - OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion); + OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion); ~OS_Android(); }; diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png Binary files differindex e53f8e9da5..b687c9ac31 100644 --- a/platform/android/run_icon.png +++ b/platform/android/run_icon.png diff --git a/platform/haiku/logo.png b/platform/haiku/logo.png Binary files differindex d5d98e4cc6..a2d8e242a6 100644 --- a/platform/haiku/logo.png +++ b/platform/haiku/logo.png diff --git a/platform/iphone/logo.png b/platform/iphone/logo.png Binary files differindex 8dd718524c..405b6f93ca 100644 --- a/platform/iphone/logo.png +++ b/platform/iphone/logo.png diff --git a/platform/javascript/logo.png b/platform/javascript/logo.png Binary files differindex ce911180ac..36832d93ba 100644 --- a/platform/javascript/logo.png +++ b/platform/javascript/logo.png diff --git a/platform/javascript/run_icon.png b/platform/javascript/run_icon.png Binary files differindex dedee6f479..574abb0150 100644 --- a/platform/javascript/run_icon.png +++ b/platform/javascript/run_icon.png diff --git a/platform/osx/logo.png b/platform/osx/logo.png Binary files differindex 93c6890e85..62086fc415 100644 --- a/platform/osx/logo.png +++ b/platform/osx/logo.png diff --git a/platform/server/logo.png b/platform/server/logo.png Binary files differindex 5e98ac26ec..8666ada9ca 100644 --- a/platform/server/logo.png +++ b/platform/server/logo.png diff --git a/platform/windows/logo.png b/platform/windows/logo.png Binary files differindex 4376abd563..f06b463850 100644 --- a/platform/windows/logo.png +++ b/platform/windows/logo.png diff --git a/platform/x11/logo.png b/platform/x11/logo.png Binary files differindex 1cc93b46ac..078654b757 100644 --- a/platform/x11/logo.png +++ b/platform/x11/logo.png diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index d7f042b4fe..2bc85f76c9 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1954,6 +1954,7 @@ void OS_X11::process_xevents() { // to be able to send relative motion events. Point2i pos(event.xmotion.x, event.xmotion.y); +#ifdef TOUCH_ENABLED // Avoidance of spurious mouse motion (see handling of touch) bool filter = false; // Adding some tolerance to match better Point2i to Vector2 @@ -1965,6 +1966,7 @@ void OS_X11::process_xevents() { if (filter) { break; } +#endif if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -2527,17 +2529,23 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c void OS_X11::release_rendering_thread() { +#if defined(OPENGL_ENABLED) context_gl->release_current(); +#endif } void OS_X11::make_rendering_thread() { +#if defined(OPENGL_ENABLED) context_gl->make_current(); +#endif } void OS_X11::swap_buffers() { +#if defined(OPENGL_ENABLED) context_gl->swap_buffers(); +#endif } void OS_X11::alert(const String &p_alert, const String &p_title) { @@ -2631,8 +2639,10 @@ String OS_X11::get_joy_guid(int p_device) const { } void OS_X11::_set_use_vsync(bool p_enable) { +#if defined(OPENGL_ENABLED) if (context_gl) - return context_gl->set_use_vsync(p_enable); + context_gl->set_use_vsync(p_enable); +#endif } /* bool OS_X11::is_vsync_enabled() const { diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 329382c034..7d5360c0e4 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -158,8 +158,8 @@ void Joint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint2D::set_exclude_nodes_from_collision); ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a"), "set_node_a", "get_node_a"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b"), "set_node_b", "get_node_b"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_a", "get_node_a"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_b", "get_node_b"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); } diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 4d6ebc81c3..81ed3c63c3 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -649,7 +649,7 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-1440,1440,0.1"), "set_texture_rotation_degrees", "get_texture_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation"); ADD_GROUP("Skeleton", ""); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton"), "set_skeleton", "get_skeleton"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton"); ADD_GROUP("Invert", "invert_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert"); diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index da764e032b..63c3d78dfd 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -201,7 +201,7 @@ void RemoteTransform2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_update_scale", "update_remote_scale"), &RemoteTransform2D::set_update_scale); ClassDB::bind_method(D_METHOD("get_update_scale"), &RemoteTransform2D::get_update_scale); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path"), "set_remote_node", "get_remote_node"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_remote_node", "get_remote_node"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_coordinates"), "set_use_global_coordinates", "get_use_global_coordinates"); ADD_GROUP("Update", "update_"); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 98275510d6..1d60037287 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -708,7 +708,7 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { rect_cache_dirty = true; } -void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q) { +void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update) { Quadrant &q = Q->get(); if (!q.dirty_list.in_list()) @@ -719,7 +719,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q) { pending_update = true; if (!is_inside_tree()) return; - _update_dirty_quadrants(); + + if (update) { + _update_dirty_quadrants(); + } } void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose) { @@ -727,6 +730,11 @@ void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_ set_cell(p_pos.x, p_pos.y, p_tile, p_flip_x, p_flip_y, p_transpose); } +void TileMap::set_celld(const Vector2 &p_pos, const Dictionary &p_data) { + + set_cell(p_pos.x, p_pos.y, p_data["id"], p_data["flip_h"], p_data["flip_y"], p_data["transpose"], p_data["auto_coord"]); +} + void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, Vector2 p_autotile_coord) { PosKey pk(p_x, p_y); @@ -1016,8 +1024,9 @@ void TileMap::_recreate_quadrants() { } Q->get().cells.insert(E->key()); - _make_quadrant_dirty(Q); + _make_quadrant_dirty(Q, false); } + _update_dirty_quadrants(); } void TileMap::_clear_quadrants() { @@ -1612,6 +1621,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cell", "x", "y", "tile", "flip_x", "flip_y", "transpose", "autotile_coord"), &TileMap::set_cell, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(Vector2())); ClassDB::bind_method(D_METHOD("set_cellv", "position", "tile", "flip_x", "flip_y", "transpose"), &TileMap::set_cellv, DEFVAL(false), DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("set_celld", "data"), &TileMap::set_celld); ClassDB::bind_method(D_METHOD("get_cell", "x", "y"), &TileMap::get_cell); ClassDB::bind_method(D_METHOD("get_cellv", "position"), &TileMap::get_cellv); ClassDB::bind_method(D_METHOD("is_cell_x_flipped", "x", "y"), &TileMap::is_cell_x_flipped); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 07947004b3..3ddb143f4a 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -188,7 +188,7 @@ private: Map<PosKey, Quadrant>::Element *_create_quadrant(const PosKey &p_qk); void _erase_quadrant(Map<PosKey, Quadrant>::Element *Q); - void _make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q); + void _make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update = true); void _recreate_quadrants(); void _clear_quadrants(); void _update_dirty_quadrants(); @@ -241,6 +241,7 @@ public: void set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord); Vector2 get_cell_autotile_coord(int p_x, int p_y) const; + void set_celld(const Vector2 &p_pos, const Dictionary &p_data); void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false); int get_cellv(const Vector2 &p_pos) const; diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index 001c58ea76..4bff26a200 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -73,7 +73,10 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const { ERR_FAIL_NULL_V(arvr_server, Vector3()); Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - ERR_FAIL_COND_V(arvr_interface.is_null(), Vector3()); + if (arvr_interface.is_null()) { + // we might be in the editor or have VR turned off, just call superclass + return Camera::project_local_ray_normal(p_pos); + } if (!is_inside_tree()) { ERR_EXPLAIN("Camera is not inside scene."); @@ -98,7 +101,10 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { ERR_FAIL_NULL_V(arvr_server, Vector2()); Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - ERR_FAIL_COND_V(arvr_interface.is_null(), Vector2()); + if (arvr_interface.is_null()) { + // we might be in the editor or have VR turned off, just call superclass + return Camera::unproject_position(p_pos); + } if (!is_inside_tree()) { ERR_EXPLAIN("Camera is not inside scene."); @@ -127,7 +133,10 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point) const { ERR_FAIL_NULL_V(arvr_server, Vector3()); Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - ERR_FAIL_COND_V(arvr_interface.is_null(), Vector3()); + if (arvr_interface.is_null()) { + // we might be in the editor or have VR turned off, just call superclass + return Camera::project_position(p_point); + } if (!is_inside_tree()) { ERR_EXPLAIN("Camera is not inside scene."); @@ -157,7 +166,10 @@ Vector<Plane> ARVRCamera::get_frustum() const { ERR_FAIL_NULL_V(arvr_server, Vector<Plane>()); Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - ERR_FAIL_COND_V(arvr_interface.is_null(), Vector<Plane>()); + if (arvr_interface.is_null()) { + // we might be in the editor or have VR turned off, just call superclass + return Camera::get_frustum(); + } ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>()); diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index 80bae911d4..e836a6154a 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -371,7 +371,7 @@ void MeshInstance::_bind_methods() { ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton"), "set_skeleton_path", "get_skeleton_path"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path"); } MeshInstance::MeshInstance() { diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp index b2d10006f7..c7a002e675 100644 --- a/scene/3d/physics_joint.cpp +++ b/scene/3d/physics_joint.cpp @@ -154,8 +154,8 @@ void Joint::_bind_methods() { ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint::set_exclude_nodes_from_collision); ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint::get_exclude_nodes_from_collision); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a"), "set_node_a", "get_node_a"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b"), "set_node_b", "get_node_b"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject"), "set_node_a", "get_node_a"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject"), "set_node_b", "get_node_b"); ADD_PROPERTY(PropertyInfo(Variant::INT, "solver/priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision/exclude_nodes"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp index afb85f7314..2156e24cd0 100644 --- a/scene/3d/remote_transform.cpp +++ b/scene/3d/remote_transform.cpp @@ -194,7 +194,7 @@ void RemoteTransform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_update_scale", "update_remote_scale"), &RemoteTransform::set_update_scale); ClassDB::bind_method(D_METHOD("get_update_scale"), &RemoteTransform::get_update_scale); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path"), "set_remote_node", "get_remote_node"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Spatial"), "set_remote_node", "get_remote_node"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_coordinates"), "set_use_global_coordinates", "get_use_global_coordinates"); ADD_GROUP("Update", "update_"); diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp new file mode 100644 index 0000000000..d3d2870c3f --- /dev/null +++ b/scene/animation/animation_blend_space_1d.cpp @@ -0,0 +1,294 @@ +#include "animation_blend_space_1d.h" + +void AnimationNodeBlendSpace1D::set_tree(AnimationTree *p_player) { + + AnimationRootNode::set_tree(p_player); + + for(int i=0;i<blend_points_used;i++) { + blend_points[i].node->set_tree(p_player); + } + +} + +void AnimationNodeBlendSpace1D::_validate_property(PropertyInfo &property) const { + if (property.name.begins_with("blend_point_")) { + String left = property.name.get_slicec('/', 0); + int idx = left.get_slicec('_', 2).to_int(); + if (idx >= blend_points_used) { + property.usage = 0; + } + } + AnimationRootNode::_validate_property(property); +} + +void AnimationNodeBlendSpace1D::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace1D::add_blend_point, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace1D::set_blend_point_position); + ClassDB::bind_method(D_METHOD("get_blend_point_position", "point"), &AnimationNodeBlendSpace1D::get_blend_point_position); + ClassDB::bind_method(D_METHOD("set_blend_point_node", "point", "node"), &AnimationNodeBlendSpace1D::set_blend_point_node); + ClassDB::bind_method(D_METHOD("get_blend_point_node", "point"), &AnimationNodeBlendSpace1D::get_blend_point_node); + ClassDB::bind_method(D_METHOD("remove_blend_point", "point"), &AnimationNodeBlendSpace1D::remove_blend_point); + ClassDB::bind_method(D_METHOD("get_blend_point_count"), &AnimationNodeBlendSpace1D::get_blend_point_count); + + ClassDB::bind_method(D_METHOD("set_min_space", "min_space"), &AnimationNodeBlendSpace1D::set_min_space); + ClassDB::bind_method(D_METHOD("get_min_space"), &AnimationNodeBlendSpace1D::get_min_space); + + ClassDB::bind_method(D_METHOD("set_max_space", "max_space"), &AnimationNodeBlendSpace1D::set_max_space); + ClassDB::bind_method(D_METHOD("get_max_space"), &AnimationNodeBlendSpace1D::get_max_space); + + ClassDB::bind_method(D_METHOD("set_snap", "snap"), &AnimationNodeBlendSpace1D::set_snap); + ClassDB::bind_method(D_METHOD("get_snap"), &AnimationNodeBlendSpace1D::get_snap); + + ClassDB::bind_method(D_METHOD("set_blend_pos", "pos"), &AnimationNodeBlendSpace1D::set_blend_pos); + ClassDB::bind_method(D_METHOD("get_blend_pos"), &AnimationNodeBlendSpace1D::get_blend_pos); + + ClassDB::bind_method(D_METHOD("set_value_label", "text"), &AnimationNodeBlendSpace1D::set_value_label); + ClassDB::bind_method(D_METHOD("get_value_label"), &AnimationNodeBlendSpace1D::get_value_label); + + ClassDB::bind_method(D_METHOD("_add_blend_point", "index", "node"), &AnimationNodeBlendSpace1D::_add_blend_point); + + for (int i = 0; i < MAX_BLEND_POINTS; i++) { + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "_add_blend_point", "get_blend_point_node", i); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i); + } + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "blend_pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_blend_pos", "get_blend_pos"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "value_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_value_label", "get_value_label"); +} + +void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index) { + ERR_FAIL_COND(blend_points_used >= MAX_BLEND_POINTS); + ERR_FAIL_COND(p_node.is_null()); + ERR_FAIL_COND(p_node->get_parent().is_valid()); + ERR_FAIL_COND(p_at_index < -1 || p_at_index > blend_points_used); + + if (p_at_index == -1 || p_at_index == blend_points_used) { + p_at_index = blend_points_used; + } else { + for (int i = blend_points_used - 1; i > p_at_index; i++) { + blend_points[i] = blend_points[i - 1]; + } + } + + blend_points[p_at_index].node = p_node; + blend_points[p_at_index].position = p_position; + + blend_points[p_at_index].node->set_parent(this); + blend_points[p_at_index].node->set_tree(get_tree()); + + blend_points_used++; +} + +void AnimationNodeBlendSpace1D::set_blend_point_position(int p_point, float p_position) { + ERR_FAIL_INDEX(p_point, blend_points_used); + + blend_points[p_point].position = p_position; +} + +void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node) { + ERR_FAIL_INDEX(p_point, blend_points_used); + ERR_FAIL_COND(p_node.is_null()); + + if (blend_points[p_point].node.is_valid()) { + blend_points[p_point].node->set_parent(NULL); + blend_points[p_point].node->set_tree(NULL); + } + + blend_points[p_point].node = p_node; + blend_points[p_point].node->set_parent(this); + blend_points[p_point].node->set_tree(get_tree()); +} + +float AnimationNodeBlendSpace1D::get_blend_point_position(int p_point) const { + ERR_FAIL_INDEX_V(p_point, blend_points_used, 0); + return blend_points[p_point].position; +} + +Ref<AnimationRootNode> AnimationNodeBlendSpace1D::get_blend_point_node(int p_point) const { + ERR_FAIL_INDEX_V(p_point, blend_points_used, Ref<AnimationRootNode>()); + return blend_points[p_point].node; +} + +void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) { + ERR_FAIL_INDEX(p_point, blend_points_used); + + blend_points[p_point].node->set_parent(NULL); + blend_points[p_point].node->set_tree(NULL); + + for (int i = p_point; i < blend_points_used - 1; i++) { + blend_points[i] = blend_points[i + 1]; + } + + blend_points_used--; +} + +int AnimationNodeBlendSpace1D::get_blend_point_count() const { + + return blend_points_used; +} + +void AnimationNodeBlendSpace1D::set_min_space(float p_min) { + min_space = p_min; + + if (min_space >= max_space) { + min_space = max_space - 1; + } +} + +float AnimationNodeBlendSpace1D::get_min_space() const { + return min_space; +} + +void AnimationNodeBlendSpace1D::set_max_space(float p_max) { + max_space = p_max; + + if (max_space <= min_space) { + max_space = min_space + 1; + } +} + +float AnimationNodeBlendSpace1D::get_max_space() const { + return max_space; +} + +void AnimationNodeBlendSpace1D::set_snap(float p_snap) { + snap = p_snap; +} + +float AnimationNodeBlendSpace1D::get_snap() const { + return snap; +} + +void AnimationNodeBlendSpace1D::set_blend_pos(float p_pos) { + blend_pos = p_pos; +} + +float AnimationNodeBlendSpace1D::get_blend_pos() const { + return blend_pos; +} + +void AnimationNodeBlendSpace1D::set_value_label(const String &p_label) { + value_label = p_label; +} + +String AnimationNodeBlendSpace1D::get_value_label() const { + return value_label; +} + +void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node) { + if (p_index == blend_points_used) { + add_blend_point(p_node, 0); + } else { + set_blend_point_node(p_index, p_node); + } +} + +float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) { + + if (blend_points_used == 0) { + return 0.0; + } + + if (blend_points_used == 1) { + // only one point available, just play that animation + return blend_node(blend_points[0].node, p_time, p_seek, 1.0, FILTER_IGNORE, false); + } + + float weights[MAX_BLEND_POINTS] = {}; + + int point_lower = -1; + float pos_lower = 0.0; + int point_higher = -1; + float pos_higher = 0.0; + + // find the closest two points to blend between + for (int i = 0; i < blend_points_used; i++) { + + float pos = blend_points[i].position; + + if (pos <= blend_pos) { + if (point_lower == -1) { + point_lower = i; + pos_lower = pos; + } else if ((blend_pos - pos) < (blend_pos - pos_lower)) { + point_lower = i; + pos_lower = pos; + } + } else { + if (point_higher == -1) { + point_higher = i; + pos_higher = pos; + } else if ((pos - blend_pos) < (pos_higher - blend_pos)) { + point_higher = i; + pos_higher = pos; + } + } + } + + // fill in weights + + if (point_lower == -1) { + // we are on the left side, no other point to the left + // we just play the next point. + + weights[point_higher] = 1.0; + } else if (point_higher == -1) { + // we are on the right side, no other point to the right + // we just play the previous point + + weights[point_lower] = 1.0; + } else { + + // we are between two points. + // figure out weights, then blend the animations + + float distance_between_points = pos_higher - pos_lower; + + float current_pos_inbetween = blend_pos - pos_lower; + + float blend_percentage = current_pos_inbetween / distance_between_points; + + float blend_lower = 1.0 - blend_percentage; + float blend_higher = blend_percentage; + + weights[point_lower] = blend_lower; + weights[point_higher] = blend_higher; + } + + // actually blend the animations now + + float max_time_remaining = 0.0; + + for (int i = 0; i < blend_points_used; i++) { + float remaining = blend_node(blend_points[i].node, p_time, p_seek, weights[i], FILTER_IGNORE, false); + + max_time_remaining = MAX(max_time_remaining, remaining); + } + + return max_time_remaining; +} + +String AnimationNodeBlendSpace1D::get_caption() const { + return "BlendSpace1D"; +} + +AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() { + + blend_points_used = 0; + max_space = 1; + min_space = -1; + + snap = 0.1; + value_label = "value"; +} + +AnimationNodeBlendSpace1D::~AnimationNodeBlendSpace1D() { + + for (int i = 0; i < blend_points_used; i++) { + blend_points[i].node->set_parent(this); + blend_points[i].node->set_tree(get_tree()); + } +} diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h new file mode 100644 index 0000000000..774894ef4b --- /dev/null +++ b/scene/animation/animation_blend_space_1d.h @@ -0,0 +1,71 @@ +#ifndef ANIMATION_BLEND_SPACE_1D_H +#define ANIMATION_BLEND_SPACE_1D_H + +#include "scene/animation/animation_tree.h" + +class AnimationNodeBlendSpace1D : public AnimationRootNode { + GDCLASS(AnimationNodeBlendSpace1D, AnimationRootNode) + + enum { + MAX_BLEND_POINTS = 64 + }; + + struct BlendPoint { + Ref<AnimationRootNode> node; + float position; + }; + + BlendPoint blend_points[MAX_BLEND_POINTS]; + int blend_points_used; + + float blend_pos; + + float max_space; + float min_space; + + float snap; + + String value_label; + + void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); + +protected: + virtual void _validate_property(PropertyInfo &property) const; + static void _bind_methods(); + +public: + + virtual void set_tree(AnimationTree *p_player); + + void add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index = -1); + void set_blend_point_position(int p_point, float p_position); + void set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node); + + float get_blend_point_position(int p_point) const; + Ref<AnimationRootNode> get_blend_point_node(int p_point) const; + void remove_blend_point(int p_point); + int get_blend_point_count() const; + + void set_min_space(float p_min); + float get_min_space() const; + + void set_max_space(float p_max); + float get_max_space() const; + + void set_snap(float p_snap); + float get_snap() const; + + void set_blend_pos(float p_pos); + float get_blend_pos() const; + + void set_value_label(const String &p_label); + String get_value_label() const; + + float process(float p_time, bool p_seek); + String get_caption() const; + + AnimationNodeBlendSpace1D(); + ~AnimationNodeBlendSpace1D(); +}; + +#endif // ANIMATION_BLEND_SPACE_1D_H diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp new file mode 100644 index 0000000000..82db647124 --- /dev/null +++ b/scene/animation/animation_blend_space_2d.cpp @@ -0,0 +1,567 @@ +#include "animation_blend_space_2d.h" +#include "math/delaunay.h" + +void AnimationNodeBlendSpace2D::set_tree(AnimationTree *p_player) { + AnimationRootNode::set_tree(p_player); + + for(int i=0;i<blend_points_used;i++) { + blend_points[i].node->set_tree(p_player); + } +} + + +void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index) { + ERR_FAIL_COND(blend_points_used >= MAX_BLEND_POINTS); + ERR_FAIL_COND(p_node.is_null()); + ERR_FAIL_COND(p_node->get_parent().is_valid()); + ERR_FAIL_COND(p_at_index < -1 || p_at_index > blend_points_used); + + if (p_at_index == -1 || p_at_index == blend_points_used) { + p_at_index = blend_points_used; + } else { + for (int i = blend_points_used - 1; i > p_at_index; i--) { + blend_points[i] = blend_points[i - 1]; + } + for (int i = 0; i < triangles.size(); i++) { + for (int j = 0; j < 3; j++) { + if (triangles[i].points[j] >= p_at_index) { + triangles[i].points[j]++; + } + } + } + } + blend_points[p_at_index].node = p_node; + blend_points[p_at_index].position = p_position; + + blend_points[p_at_index].node->set_parent(this); + blend_points[p_at_index].node->set_tree(get_tree()); + blend_points_used++; + + if (auto_triangles) { + trianges_dirty = true; + } +} + +void AnimationNodeBlendSpace2D::set_blend_point_position(int p_point, const Vector2 &p_position) { + ERR_FAIL_INDEX(p_point, blend_points_used); + blend_points[p_point].position = p_position; + if (auto_triangles) { + trianges_dirty = true; + } +} +void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node) { + ERR_FAIL_INDEX(p_point, blend_points_used); + ERR_FAIL_COND(p_node.is_null()); + + if (blend_points[p_point].node.is_valid()) { + blend_points[p_point].node->set_parent(NULL); + blend_points[p_point].node->set_tree(NULL); + } + blend_points[p_point].node = p_node; + blend_points[p_point].node->set_parent(this); + blend_points[p_point].node->set_tree(get_tree()); +} +Vector2 AnimationNodeBlendSpace2D::get_blend_point_position(int p_point) const { + ERR_FAIL_INDEX_V(p_point, blend_points_used, Vector2()); + return blend_points[p_point].position; +} +Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_point) const { + ERR_FAIL_INDEX_V(p_point, blend_points_used, Ref<AnimationRootNode>()); + return blend_points[p_point].node; +} +void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) { + ERR_FAIL_INDEX(p_point, blend_points_used); + + blend_points[p_point].node->set_parent(NULL); + blend_points[p_point].node->set_tree(NULL); + + for (int i = 0; i < triangles.size(); i++) { + bool erase = false; + for (int j = 0; j < 3; j++) { + if (triangles[i].points[j] == p_point) { + erase = true; + break; + } else if (triangles[i].points[j] > p_point) { + triangles[i].points[j]--; + } + } + if (erase) { + triangles.remove(i); + + i--; + } + } + + for (int i = p_point; i < blend_points_used - 1; i++) { + blend_points[i] = blend_points[i + 1]; + } + blend_points_used--; +} + +int AnimationNodeBlendSpace2D::get_blend_point_count() const { + + return blend_points_used; +} + +bool AnimationNodeBlendSpace2D::has_triangle(int p_x, int p_y, int p_z) const { + + ERR_FAIL_INDEX_V(p_x, blend_points_used, false); + ERR_FAIL_INDEX_V(p_y, blend_points_used, false); + ERR_FAIL_INDEX_V(p_z, blend_points_used, false); + + BlendTriangle t; + t.points[0] = p_x; + t.points[1] = p_y; + t.points[2] = p_z; + + SortArray<int> sort; + sort.sort(t.points, 3); + + for (int i = 0; i < triangles.size(); i++) { + bool all_equal = true; + for (int j = 0; j < 3; j++) { + if (triangles[i].points[j] != t.points[j]) { + all_equal = false; + break; + } + } + if (all_equal) + return true; + } + + return false; +} + +void AnimationNodeBlendSpace2D::add_triangle(int p_x, int p_y, int p_z, int p_at_index) { + + ERR_FAIL_INDEX(p_x, blend_points_used); + ERR_FAIL_INDEX(p_y, blend_points_used); + ERR_FAIL_INDEX(p_z, blend_points_used); + + _update_triangles(); + + BlendTriangle t; + t.points[0] = p_x; + t.points[1] = p_y; + t.points[2] = p_z; + + SortArray<int> sort; + sort.sort(t.points, 3); + + for (int i = 0; i < triangles.size(); i++) { + bool all_equal = true; + for (int j = 0; j < 3; j++) { + if (triangles[i].points[j] != t.points[j]) { + all_equal = false; + break; + } + } + ERR_FAIL_COND(all_equal); + } + + if (p_at_index == -1 || p_at_index == triangles.size()) { + triangles.push_back(t); + } else { + triangles.insert(p_at_index, t); + } +} +int AnimationNodeBlendSpace2D::get_triangle_point(int p_triangle, int p_point) { + + _update_triangles(); + + ERR_FAIL_INDEX_V(p_point, 3, -1); + ERR_FAIL_INDEX_V(p_triangle, triangles.size(), -1); + return triangles[p_triangle].points[p_point]; +} +void AnimationNodeBlendSpace2D::remove_triangle(int p_triangle) { + ERR_FAIL_INDEX(p_triangle, triangles.size()); + + triangles.remove(p_triangle); +} + +int AnimationNodeBlendSpace2D::get_triangle_count() const { + return triangles.size(); +} + +void AnimationNodeBlendSpace2D::set_min_space(const Vector2 &p_min) { + + min_space = p_min; + if (min_space.x >= max_space.x) { + min_space.x = max_space.x - 1; + } + if (min_space.y >= max_space.y) { + min_space.y = max_space.y - 1; + } +} +Vector2 AnimationNodeBlendSpace2D::get_min_space() const { + return min_space; +} + +void AnimationNodeBlendSpace2D::set_max_space(const Vector2 &p_max) { + + max_space = p_max; + if (max_space.x <= min_space.x) { + max_space.x = min_space.x + 1; + } + if (max_space.y <= min_space.y) { + max_space.y = min_space.y + 1; + } +} +Vector2 AnimationNodeBlendSpace2D::get_max_space() const { + return max_space; +} + +void AnimationNodeBlendSpace2D::set_snap(const Vector2 &p_snap) { + snap = p_snap; +} +Vector2 AnimationNodeBlendSpace2D::get_snap() const { + return snap; +} + +void AnimationNodeBlendSpace2D::set_blend_position(const Vector2 &p_pos) { + blend_pos = p_pos; +} +Vector2 AnimationNodeBlendSpace2D::get_blend_position() const { + return blend_pos; +} + +void AnimationNodeBlendSpace2D::set_x_label(const String &p_label) { + x_label = p_label; +} +String AnimationNodeBlendSpace2D::get_x_label() const { + return x_label; +} + +void AnimationNodeBlendSpace2D::set_y_label(const String &p_label) { + y_label = p_label; +} +String AnimationNodeBlendSpace2D::get_y_label() const { + return y_label; +} + +void AnimationNodeBlendSpace2D::_add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node) { + if (p_index == blend_points_used) { + add_blend_point(p_node, Vector2()); + } else { + set_blend_point_node(p_index, p_node); + } +} + +void AnimationNodeBlendSpace2D::_set_triangles(const Vector<int> &p_triangles) { + + if (auto_triangles) + return; + ERR_FAIL_COND(p_triangles.size() % 3 != 0); + for (int i = 0; i < p_triangles.size(); i += 3) { + add_triangle(p_triangles[i + 0], p_triangles[i + 1], p_triangles[i + 2]); + } +} + +Vector<int> AnimationNodeBlendSpace2D::_get_triangles() const { + + Vector<int> t; + if (auto_triangles && trianges_dirty) + return t; + + t.resize(triangles.size() * 3); + for (int i = 0; i < triangles.size(); i++) { + t[i * 3 + 0] = triangles[i].points[0]; + t[i * 3 + 1] = triangles[i].points[1]; + t[i * 3 + 2] = triangles[i].points[2]; + } + return t; +} + +void AnimationNodeBlendSpace2D::_update_triangles() { + + if (!auto_triangles || !trianges_dirty) + return; + + trianges_dirty = false; + triangles.clear(); + if (blend_points_used < 3) + return; + + Vector<Vector2> points; + points.resize(blend_points_used); + for (int i = 0; i < blend_points_used; i++) { + points[i] = blend_points[i].position; + } + + Vector<Delaunay2D::Triangle> triangles = Delaunay2D::triangulate(points); + + for (int i = 0; i < triangles.size(); i++) { + add_triangle(triangles[i].points[0], triangles[i].points[1], triangles[i].points[2]); + } +} + +Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) { + + _update_triangles(); + + if (triangles.size() == 0) + return Vector2(); + + Vector2 best_point; + bool first = true; + + for (int i = 0; i < triangles.size(); i++) { + Vector2 points[3]; + for (int j = 0; j < 3; j++) { + points[j] = get_blend_point_position(get_triangle_point(i, j)); + } + + if (Geometry::is_point_in_triangle(p_point, points[0], points[1], points[2])) { + + return p_point; + } + + for (int j = 0; j < 3; j++) { + Vector2 s[2] = { + points[j], + points[(j + 1) % 3] + }; + Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, s); + if (first || closest.distance_to(p_point) < best_point.distance_to(p_point)) { + best_point = closest; + first = false; + } + } + } + + return best_point; +} + +void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights) { + + if (p_pos.distance_squared_to(p_points[0]) < CMP_EPSILON2) { + r_weights[0] = 1; + r_weights[1] = 0; + r_weights[2] = 0; + return; + } + if (p_pos.distance_squared_to(p_points[1]) < CMP_EPSILON2) { + r_weights[0] = 0; + r_weights[1] = 1; + r_weights[2] = 0; + return; + } + if (p_pos.distance_squared_to(p_points[2]) < CMP_EPSILON2) { + r_weights[0] = 0; + r_weights[1] = 0; + r_weights[2] = 1; + return; + } + + Vector2 v0 = p_points[1] - p_points[0]; + Vector2 v1 = p_points[2] - p_points[0]; + Vector2 v2 = p_pos - p_points[0]; + + float d00 = v0.dot(v0); + float d01 = v0.dot(v1); + float d11 = v1.dot(v1); + float d20 = v2.dot(v0); + float d21 = v2.dot(v1); + float denom = (d00 * d11 - d01 * d01); + if (denom == 0) { + r_weights[0] = 1; + r_weights[1] = 0; + r_weights[2] = 0; + return; + } + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + + r_weights[0] = u; + r_weights[1] = v; + r_weights[2] = w; +} + +float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { + + _update_triangles(); + + if (triangles.size() == 0) + return 0; + + Vector2 best_point; + bool first = true; + int blend_triangle = -1; + float blend_weights[3] = { 0, 0, 0 }; + + for (int i = 0; i < triangles.size(); i++) { + Vector2 points[3]; + for (int j = 0; j < 3; j++) { + points[j] = get_blend_point_position(get_triangle_point(i, j)); + } + + if (Geometry::is_point_in_triangle(blend_pos, points[0], points[1], points[2])) { + + blend_triangle = i; + _blend_triangle(blend_pos, points, blend_weights); + break; + } + + for (int j = 0; j < 3; j++) { + Vector2 s[2] = { + points[j], + points[(j + 1) % 3] + }; + Vector2 closest = Geometry::get_closest_point_to_segment_2d(blend_pos, s); + if (first || closest.distance_to(blend_pos) < best_point.distance_to(blend_pos)) { + best_point = closest; + blend_triangle = i; + first = false; + float d = s[0].distance_to(s[1]); + if (d == 0.0) { + blend_weights[j] = 1.0; + blend_weights[(j + 1) % 3] = 0.0; + blend_weights[(j + 2) % 3] = 0.0; + } else { + float c = s[0].distance_to(closest) / d; + + blend_weights[j] = 1.0 - c; + blend_weights[(j + 1) % 3] = c; + blend_weights[(j + 2) % 3] = 0.0; + } + } + } + } + + ERR_FAIL_COND_V(blend_triangle == -1, 0); //should never reach here + + int triangle_points[3]; + for (int j = 0; j < 3; j++) { + triangle_points[j] = get_triangle_point(blend_triangle, j); + } + + first = true; + float mind; + for (int i = 0; i < blend_points_used; i++) { + + bool found = false; + for (int j = 0; j < 3; j++) { + if (i == triangle_points[j]) { + //blend with the given weight + float t = blend_node(blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false); + if (first || t < mind) { + mind = t; + first = false; + } + found = true; + break; + } + } + + if (!found) { + //ignore + blend_node(blend_points[i].node, p_time, p_seek, 0, FILTER_IGNORE, false); + } + } + return mind; +} + +String AnimationNodeBlendSpace2D::get_caption() const { + return "BlendSpace2D"; +} + +void AnimationNodeBlendSpace2D::_validate_property(PropertyInfo &property) const { + if (property.name.begins_with("blend_point_")) { + String left = property.name.get_slicec('/', 0); + int idx = left.get_slicec('_', 2).to_int(); + if (idx >= blend_points_used) { + property.usage = 0; + } + } + AnimationRootNode::_validate_property(property); +} + +void AnimationNodeBlendSpace2D::set_auto_triangles(bool p_enable) { + auto_triangles = p_enable; + if (auto_triangles) { + trianges_dirty = true; + } +} + +bool AnimationNodeBlendSpace2D::get_auto_triangles() const { + return auto_triangles; +} + +void AnimationNodeBlendSpace2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace2D::set_blend_point_position); + ClassDB::bind_method(D_METHOD("get_blend_point_position", "point"), &AnimationNodeBlendSpace2D::get_blend_point_position); + ClassDB::bind_method(D_METHOD("set_blend_point_node", "point", "node"), &AnimationNodeBlendSpace2D::set_blend_point_node); + ClassDB::bind_method(D_METHOD("get_blend_point_node", "point"), &AnimationNodeBlendSpace2D::get_blend_point_node); + ClassDB::bind_method(D_METHOD("remove_blend_point", "point"), &AnimationNodeBlendSpace2D::remove_blend_point); + ClassDB::bind_method(D_METHOD("get_blend_point_count"), &AnimationNodeBlendSpace2D::get_blend_point_count); + + ClassDB::bind_method(D_METHOD("add_triangle", "x", "y", "z", "at_index"), &AnimationNodeBlendSpace2D::add_triangle, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("get_triangle_point", "triangle", "point"), &AnimationNodeBlendSpace2D::get_triangle_point); + ClassDB::bind_method(D_METHOD("remove_triangle", "triangle"), &AnimationNodeBlendSpace2D::remove_triangle); + ClassDB::bind_method(D_METHOD("get_triangle_count"), &AnimationNodeBlendSpace2D::get_triangle_count); + + ClassDB::bind_method(D_METHOD("set_min_space", "min_space"), &AnimationNodeBlendSpace2D::set_min_space); + ClassDB::bind_method(D_METHOD("get_min_space"), &AnimationNodeBlendSpace2D::get_min_space); + + ClassDB::bind_method(D_METHOD("set_max_space", "max_space"), &AnimationNodeBlendSpace2D::set_max_space); + ClassDB::bind_method(D_METHOD("get_max_space"), &AnimationNodeBlendSpace2D::get_max_space); + + ClassDB::bind_method(D_METHOD("set_snap", "snap"), &AnimationNodeBlendSpace2D::set_snap); + ClassDB::bind_method(D_METHOD("get_snap"), &AnimationNodeBlendSpace2D::get_snap); + + ClassDB::bind_method(D_METHOD("set_blend_position", "pos"), &AnimationNodeBlendSpace2D::set_blend_position); + ClassDB::bind_method(D_METHOD("get_blend_position"), &AnimationNodeBlendSpace2D::get_blend_position); + + ClassDB::bind_method(D_METHOD("set_x_label", "text"), &AnimationNodeBlendSpace2D::set_x_label); + ClassDB::bind_method(D_METHOD("get_x_label"), &AnimationNodeBlendSpace2D::get_x_label); + + ClassDB::bind_method(D_METHOD("set_y_label", "text"), &AnimationNodeBlendSpace2D::set_y_label); + ClassDB::bind_method(D_METHOD("get_y_label"), &AnimationNodeBlendSpace2D::get_y_label); + + ClassDB::bind_method(D_METHOD("_add_blend_point", "index", "node"), &AnimationNodeBlendSpace2D::_add_blend_point); + + ClassDB::bind_method(D_METHOD("_set_triangles", "triangles"), &AnimationNodeBlendSpace2D::_set_triangles); + ClassDB::bind_method(D_METHOD("_get_triangles"), &AnimationNodeBlendSpace2D::_get_triangles); + + ClassDB::bind_method(D_METHOD("set_auto_triangles", "enable"), &AnimationNodeBlendSpace2D::set_auto_triangles); + ClassDB::bind_method(D_METHOD("get_auto_triangles"), &AnimationNodeBlendSpace2D::get_auto_triangles); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_auto_triangles", "get_auto_triangles"); + + for (int i = 0; i < MAX_BLEND_POINTS; i++) { + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "_add_blend_point", "get_blend_point_node", i); + ADD_PROPERTYI(PropertyInfo(Variant::VECTOR2, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i); + } + + ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_triangles", "_get_triangles"); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "blend_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_blend_position", "get_blend_position"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "x_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_x_label", "get_x_label"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "y_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_y_label", "get_y_label"); +} + +AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() { + + auto_triangles = true; + blend_points_used = 0; + max_space = Vector2(1, 1); + min_space = Vector2(-1, -1); + snap = Vector2(0.1, 0.1); + x_label = "x"; + y_label = "y"; + trianges_dirty = false; +} + +AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() { + + for (int i = 0; i < blend_points_used; i++) { + blend_points[i].node->set_parent(this); + blend_points[i].node->set_tree(get_tree()); + } +} diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h new file mode 100644 index 0000000000..4778299df1 --- /dev/null +++ b/scene/animation/animation_blend_space_2d.h @@ -0,0 +1,97 @@ +#ifndef ANIMATION_BLEND_SPACE_2D_H +#define ANIMATION_BLEND_SPACE_2D_H + +#include "scene/animation/animation_tree.h" + +class AnimationNodeBlendSpace2D : public AnimationRootNode { + GDCLASS(AnimationNodeBlendSpace2D, AnimationRootNode) + + enum { + MAX_BLEND_POINTS = 64 + }; + + struct BlendPoint { + Ref<AnimationRootNode> node; + Vector2 position; + }; + + BlendPoint blend_points[MAX_BLEND_POINTS]; + int blend_points_used; + + struct BlendTriangle { + int points[3]; + }; + + Vector<BlendTriangle> triangles; + + Vector2 blend_pos; + Vector2 max_space; + Vector2 min_space; + Vector2 snap; + String x_label; + String y_label; + + void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); + void _set_triangles(const Vector<int> &p_triangles); + Vector<int> _get_triangles() const; + + void _blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights); + + bool auto_triangles; + bool trianges_dirty; + + void _update_triangles(); + +protected: + virtual void _validate_property(PropertyInfo &property) const; + static void _bind_methods(); + +public: + + virtual void set_tree(AnimationTree *p_player); + + void add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index = -1); + void set_blend_point_position(int p_point, const Vector2 &p_position); + void set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node); + Vector2 get_blend_point_position(int p_point) const; + Ref<AnimationRootNode> get_blend_point_node(int p_point) const; + void remove_blend_point(int p_point); + int get_blend_point_count() const; + + bool has_triangle(int p_x, int p_y, int p_z) const; + void add_triangle(int p_x, int p_y, int p_z, int p_at_index = -1); + int get_triangle_point(int p_triangle, int p_point); + void remove_triangle(int p_triangle); + int get_triangle_count() const; + + void set_min_space(const Vector2 &p_min); + Vector2 get_min_space() const; + + void set_max_space(const Vector2 &p_max); + Vector2 get_max_space() const; + + void set_snap(const Vector2 &p_snap); + Vector2 get_snap() const; + + void set_blend_position(const Vector2 &p_pos); + Vector2 get_blend_position() const; + + void set_x_label(const String &p_label); + String get_x_label() const; + + void set_y_label(const String &p_label); + String get_y_label() const; + + virtual float process(float p_time, bool p_seek); + virtual String get_caption() const; + + Vector2 get_closest_point(const Vector2 &p_point); + + void set_auto_triangles(bool p_enable); + bool get_auto_triangles() const; + + AnimationNodeBlendSpace2D(); + ~AnimationNodeBlendSpace2D(); +}; + +#endif // ANIMATION_BLEND_SPACE_2D_H diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index a266e69bcb..946a1246ff 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -16,7 +16,7 @@ float AnimationNodeAnimation::get_playback_time() const { void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const { if (property.name == "animation") { - AnimationGraphPlayer *gp = get_graph_player(); + AnimationTree *gp = get_tree(); if (gp && gp->has_node(gp->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); if (ap) { @@ -36,6 +36,8 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const { } } } + + AnimationRootNode::_validate_property(property); } float AnimationNodeAnimation::process(float p_time, bool p_seek) { @@ -46,8 +48,9 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) { Ref<Animation> anim = ap->get_animation(animation); if (!anim.is_valid()) { - if (get_tree().is_valid()) { - String name = get_tree()->get_node_name(Ref<AnimationNodeAnimation>(this)); + Ref<AnimationNodeBlendTree> tree = get_parent(); + if (tree.is_valid()) { + String name = tree->get_node_name(Ref<AnimationNodeAnimation>(this)); make_invalid(vformat(RTR("On BlendTree node '%s', animation not found: '%s'"), name, animation)); } else { @@ -308,33 +311,33 @@ AnimationNodeOneShot::AnimationNodeOneShot() { //////////////////////////////////////////////// -void AnimationNodeAdd::set_amount(float p_amount) { +void AnimationNodeAdd2::set_amount(float p_amount) { amount = p_amount; } -float AnimationNodeAdd::get_amount() const { +float AnimationNodeAdd2::get_amount() const { return amount; } -String AnimationNodeAdd::get_caption() const { - return "Add"; +String AnimationNodeAdd2::get_caption() const { + return "Add2"; } -void AnimationNodeAdd::set_use_sync(bool p_sync) { +void AnimationNodeAdd2::set_use_sync(bool p_sync) { sync = p_sync; } -bool AnimationNodeAdd::is_using_sync() const { +bool AnimationNodeAdd2::is_using_sync() const { return sync; } -bool AnimationNodeAdd::has_filter() const { +bool AnimationNodeAdd2::has_filter() const { return true; } -float AnimationNodeAdd::process(float p_time, bool p_seek) { +float AnimationNodeAdd2::process(float p_time, bool p_seek) { float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync); @@ -342,19 +345,19 @@ float AnimationNodeAdd::process(float p_time, bool p_seek) { return rem0; } -void AnimationNodeAdd::_bind_methods() { +void AnimationNodeAdd2::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd::set_amount); - ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd::get_amount); + ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd2::set_amount); + ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd2::get_amount); - ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd::set_use_sync); - ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd::is_using_sync); + ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync); + ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync); ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_amount", "get_amount"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync"); } -AnimationNodeAdd::AnimationNodeAdd() { +AnimationNodeAdd2::AnimationNodeAdd2() { add_input("in"); add_input("add"); @@ -362,6 +365,63 @@ AnimationNodeAdd::AnimationNodeAdd() { sync = false; } +//////////////////////////////////////////////// + +void AnimationNodeAdd3::set_amount(float p_amount) { + amount = p_amount; +} + +float AnimationNodeAdd3::get_amount() const { + return amount; +} + +String AnimationNodeAdd3::get_caption() const { + return "Add3"; +} +void AnimationNodeAdd3::set_use_sync(bool p_sync) { + + sync = p_sync; +} + +bool AnimationNodeAdd3::is_using_sync() const { + + return sync; +} + +bool AnimationNodeAdd3::has_filter() const { + + return true; +} + +float AnimationNodeAdd3::process(float p_time, bool p_seek) { + + blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync); + float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); + blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_PASS, !sync); + + return rem0; +} + +void AnimationNodeAdd3::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd3::set_amount); + ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd3::get_amount); + + ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync); + ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_amount", "get_amount"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync"); +} + +AnimationNodeAdd3::AnimationNodeAdd3() { + + add_input("-add"); + add_input("in"); + add_input("+add"); + amount = 0; + sync = false; +} ///////////////////////////////////////////// void AnimationNodeBlend2::set_amount(float p_amount) { @@ -596,7 +656,9 @@ void AnimationNodeTransition::set_current(int p_current) { return; ERR_FAIL_INDEX(p_current, enabled_inputs); - if (get_tree().is_valid() && current >= 0) { + Ref<AnimationNodeBlendTree> tree = get_parent(); + + if (tree.is_valid() && current >= 0) { prev = current; prev_xfading = xfade; prev_time = time; @@ -692,6 +754,8 @@ void AnimationNodeTransition::_validate_property(PropertyInfo &property) const { } } } + + AnimationNode::_validate_property(property); } void AnimationNodeTransition::_bind_methods() { @@ -754,14 +818,14 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod ERR_FAIL_COND(nodes.has(p_name)); ERR_FAIL_COND(p_node.is_null()); - ERR_FAIL_COND(p_node->tree != NULL); - ERR_FAIL_COND(p_node->player != NULL); + ERR_FAIL_COND(p_node->get_parent().is_valid()); + ERR_FAIL_COND(p_node->get_tree() != NULL); ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); ERR_FAIL_COND(String(p_name).find("/") != -1); nodes[p_name] = p_node; - p_node->tree = this; - p_node->player = player; + p_node->set_parent(this); + p_node->set_tree(get_tree()); emit_changed(); } @@ -796,8 +860,8 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) { for (int i = 0; i < node->get_input_count(); i++) { node->set_input_connection(i, StringName()); } - node->tree = NULL; - node->player = NULL; + node->set_parent(NULL); + node->set_tree(NULL); } nodes.erase(p_name); @@ -958,13 +1022,13 @@ Vector2 AnimationNodeBlendTree::get_graph_offset() const { return graph_offset; } -void AnimationNodeBlendTree::set_graph_player(AnimationGraphPlayer *p_player) { +void AnimationNodeBlendTree::set_tree(AnimationTree *p_player) { - AnimationNode::set_graph_player(p_player); + AnimationNode::set_tree(p_player); for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) { Ref<AnimationNode> node = E->get(); - node->set_graph_player(p_player); + node->set_tree(p_player); } } @@ -1092,14 +1156,14 @@ AnimationNodeBlendTree::AnimationNodeBlendTree() { Ref<AnimationNodeOutput> output; output.instance(); output->set_position(Vector2(300, 150)); - output->tree = this; + output->set_parent(this); nodes["output"] = output; } AnimationNodeBlendTree::~AnimationNodeBlendTree() { for (Map<StringName, Ref<AnimationNode> >::Element *E = nodes.front(); E; E = E->next()) { - E->get()->tree = NULL; - E->get()->player = NULL; + E->get()->set_parent(NULL); + E->get()->set_tree(NULL); } } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 68afdf04b3..e86cc2e823 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -1,11 +1,11 @@ #ifndef ANIMATION_BLEND_TREE_H #define ANIMATION_BLEND_TREE_H -#include "scene/animation/animation_graph_player.h" +#include "scene/animation/animation_tree.h" -class AnimationNodeAnimation : public AnimationNode { +class AnimationNodeAnimation : public AnimationRootNode { - GDCLASS(AnimationNodeAnimation, AnimationNode); + GDCLASS(AnimationNodeAnimation, AnimationRootNode); StringName animation; @@ -94,8 +94,8 @@ public: VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode) -class AnimationNodeAdd : public AnimationNode { - GDCLASS(AnimationNodeAdd, AnimationNode); +class AnimationNodeAdd2 : public AnimationNode { + GDCLASS(AnimationNodeAdd2, AnimationNode); float amount; bool sync; @@ -115,7 +115,31 @@ public: virtual bool has_filter() const; virtual float process(float p_time, bool p_seek); - AnimationNodeAdd(); + AnimationNodeAdd2(); +}; + +class AnimationNodeAdd3 : public AnimationNode { + GDCLASS(AnimationNodeAdd3, AnimationNode); + + float amount; + bool sync; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + void set_amount(float p_amount); + float get_amount() const; + + void set_use_sync(bool p_sync); + bool is_using_sync() const; + + virtual bool has_filter() const; + virtual float process(float p_time, bool p_seek); + + AnimationNodeAdd3(); }; class AnimationNodeBlend2 : public AnimationNode { @@ -266,8 +290,8 @@ public: ///// -class AnimationNodeBlendTree : public AnimationNode { - GDCLASS(AnimationNodeBlendTree, AnimationNode) +class AnimationNodeBlendTree : public AnimationRootNode { + GDCLASS(AnimationNodeBlendTree, AnimationRootNode) Map<StringName, Ref<AnimationNode> > nodes; @@ -318,7 +342,7 @@ public: void set_graph_offset(const Vector2 &p_graph_offset); Vector2 get_graph_offset() const; - virtual void set_graph_player(AnimationGraphPlayer *p_player); + virtual void set_tree(AnimationTree *p_player); AnimationNodeBlendTree(); ~AnimationNodeBlendTree(); }; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp new file mode 100644 index 0000000000..c5ad980806 --- /dev/null +++ b/scene/animation/animation_node_state_machine.cpp @@ -0,0 +1,790 @@ +#include "animation_node_state_machine.h" + +///////////////////////////////////////////////// + +void AnimationNodeStateMachineTransition::set_switch_mode(SwitchMode p_mode) { + + switch_mode = p_mode; +} + +AnimationNodeStateMachineTransition::SwitchMode AnimationNodeStateMachineTransition::get_switch_mode() const { + + return switch_mode; +} + +void AnimationNodeStateMachineTransition::set_auto_advance(bool p_enable) { + auto_advance = p_enable; +} + +bool AnimationNodeStateMachineTransition::has_auto_advance() const { + return auto_advance; +} + +void AnimationNodeStateMachineTransition::set_xfade_time(float p_xfade) { + + ERR_FAIL_COND(p_xfade < 0); + xfade = p_xfade; + emit_changed(); +} + +float AnimationNodeStateMachineTransition::get_xfade_time() const { + return xfade; +} + +void AnimationNodeStateMachineTransition::set_disabled(bool p_disabled) { + disabled = p_disabled; + emit_changed(); +} + +bool AnimationNodeStateMachineTransition::is_disabled() const { + return disabled; +} + +void AnimationNodeStateMachineTransition::set_priority(int p_priority) { + priority = p_priority; + emit_changed(); +} + +int AnimationNodeStateMachineTransition::get_priority() const { + return priority; +} + +void AnimationNodeStateMachineTransition::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_switch_mode", "mode"), &AnimationNodeStateMachineTransition::set_switch_mode); + ClassDB::bind_method(D_METHOD("get_switch_mode"), &AnimationNodeStateMachineTransition::get_switch_mode); + + ClassDB::bind_method(D_METHOD("set_auto_advance", "auto_advance"), &AnimationNodeStateMachineTransition::set_auto_advance); + ClassDB::bind_method(D_METHOD("has_auto_advance"), &AnimationNodeStateMachineTransition::has_auto_advance); + + ClassDB::bind_method(D_METHOD("set_xfade_time", "secs"), &AnimationNodeStateMachineTransition::set_xfade_time); + ClassDB::bind_method(D_METHOD("get_xfade_time"), &AnimationNodeStateMachineTransition::get_xfade_time); + + ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &AnimationNodeStateMachineTransition::set_disabled); + ClassDB::bind_method(D_METHOD("is_disabled"), &AnimationNodeStateMachineTransition::is_disabled); + + ClassDB::bind_method(D_METHOD("set_priority", "priority"), &AnimationNodeStateMachineTransition::set_priority); + ClassDB::bind_method(D_METHOD("get_priority"), &AnimationNodeStateMachineTransition::get_priority); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); + + BIND_CONSTANT(SWITCH_MODE_IMMEDIATE); + BIND_CONSTANT(SWITCH_MODE_SYNC); + BIND_CONSTANT(SWITCH_MODE_AT_END); +} + +AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() { + + switch_mode = SWITCH_MODE_IMMEDIATE; + auto_advance = false; + xfade = 0; + disabled = false; + priority = 1; +} + +/////////////////////////////////////////////////////// +void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node) { + + ERR_FAIL_COND(states.has(p_name)); + ERR_FAIL_COND(p_node.is_null()); + ERR_FAIL_COND(p_node->get_parent().is_valid()); + ERR_FAIL_COND(p_node->get_tree() != NULL); + ERR_FAIL_COND(String(p_name).find("/") != -1); + states[p_name] = p_node; + + p_node->set_parent(this); + p_node->set_tree(get_tree()); + + emit_changed(); +} + +Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const { + + ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>()); + + return states[p_name]; +} + +StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_node) const { + for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) { + if (E->get() == p_node) { + return E->key(); + } + } + + ERR_FAIL_V(StringName()); +} + +bool AnimationNodeStateMachine::has_node(const StringName &p_name) const { + return states.has(p_name); +} +void AnimationNodeStateMachine::remove_node(const StringName &p_name) { + + ERR_FAIL_COND(!states.has(p_name)); + + { + //erase node connections + Ref<AnimationNode> node = states[p_name]; + for (int i = 0; i < node->get_input_count(); i++) { + node->set_input_connection(i, StringName()); + } + node->set_parent(NULL); + node->set_tree(NULL); + } + + states.erase(p_name); + path.erase(p_name); + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == p_name || transitions[i].to == p_name) { + transitions.remove(i); + i--; + } + } + + if (start_node == p_name) { + start_node = StringName(); + } + + if (end_node == p_name) { + end_node = StringName(); + } + + if (playing && current == p_name) { + stop(); + } + emit_changed(); +} + +void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) { + + ERR_FAIL_COND(!states.has(p_name)); + ERR_FAIL_COND(states.has(p_new_name)); + + states[p_new_name] = states[p_name]; + states.erase(p_name); + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == p_name) { + transitions[i].from = p_new_name; + } + + if (transitions[i].to == p_name) { + transitions[i].to = p_new_name; + } + } + + if (start_node == p_name) { + start_node = p_new_name; + } + + if (end_node == p_name) { + end_node = p_new_name; + } + + if (playing && current == p_name) { + current = p_new_name; + } + + path.clear(); //clear path +} + +void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { + + List<StringName> nodes; + for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) { + nodes.push_back(E->key()); + } + nodes.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) { + r_nodes->push_back(E->get()); + } +} + +bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const StringName &p_to) const { + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == p_from && transitions[i].to == p_to) + return true; + } + return false; +} + +int AnimationNodeStateMachine::find_transition(const StringName &p_from, const StringName &p_to) const { + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == p_from && transitions[i].to == p_to) + return i; + } + return -1; +} + +void AnimationNodeStateMachine::add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition) { + + ERR_FAIL_COND(p_from == p_to); + ERR_FAIL_COND(!states.has(p_from)); + ERR_FAIL_COND(!states.has(p_to)); + ERR_FAIL_COND(p_transition.is_null()); + + for (int i = 0; i < transitions.size(); i++) { + ERR_FAIL_COND(transitions[i].from == p_from && transitions[i].to == p_to); + } + + Transition tr; + tr.from = p_from; + tr.to = p_to; + tr.transition = p_transition; + + transitions.push_back(tr); +} + +Ref<AnimationNodeStateMachineTransition> AnimationNodeStateMachine::get_transition(int p_transition) const { + ERR_FAIL_INDEX_V(p_transition, transitions.size(), Ref<AnimationNodeStateMachineTransition>()); + return transitions[p_transition].transition; +} +StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const { + + ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName()); + return transitions[p_transition].from; +} +StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const { + + ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName()); + return transitions[p_transition].to; +} + +int AnimationNodeStateMachine::get_transition_count() const { + + return transitions.size(); +} +void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) { + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == p_from && transitions[i].to == p_to) { + transitions.remove(i); + return; + } + } + + if (playing) { + path.clear(); + } +} + +void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) { + + transitions.remove(p_transition); + if (playing) { + path.clear(); + } +} + +void AnimationNodeStateMachine::set_start_node(const StringName &p_node) { + + ERR_FAIL_COND(p_node != StringName() && !states.has(p_node)); + start_node = p_node; +} + +String AnimationNodeStateMachine::get_start_node() const { + + return start_node; +} + +void AnimationNodeStateMachine::set_end_node(const StringName &p_node) { + + ERR_FAIL_COND(p_node != StringName() && !states.has(p_node)); + end_node = p_node; +} + +String AnimationNodeStateMachine::get_end_node() const { + + return end_node; +} + +void AnimationNodeStateMachine::set_graph_offset(const Vector2 &p_offset) { + graph_offset = p_offset; +} + +Vector2 AnimationNodeStateMachine::get_graph_offset() const { + return graph_offset; +} + +float AnimationNodeStateMachine::process(float p_time, bool p_seek) { + + //if not playing and it can restart, then restart + if (!playing) { + if (start_node) { + start(start_node); + } else { + return 0; + } + } + + bool do_start = (p_seek && p_time == 0) || play_start || current == StringName(); + + if (do_start) { + + if (start_node != StringName() && p_seek && p_time == 0) { + current = start_node; + } + + len_current = blend_node(states[current], 0, true, 1.0, FILTER_IGNORE, false); + pos_current = 0; + loops_current = 0; + play_start = false; + } + + float fade_blend = 1.0; + + if (fading_from != StringName()) { + + if (!p_seek) { + fading_pos += p_time; + } + fade_blend = MIN(1.0, fading_pos / fading_time); + if (fade_blend >= 1.0) { + fading_from = StringName(); + } + } + + float rem = blend_node(states[current], p_time, p_seek, fade_blend, FILTER_IGNORE, false); + + if (fading_from != StringName()) { + + blend_node(states[fading_from], p_time, p_seek, 1.0 - fade_blend, FILTER_IGNORE, false); + } + + //guess playback position + if (rem > len_current) { // weird but ok + len_current = rem; + } + + { //advance and loop check + + float next_pos = len_current - rem; + + if (next_pos < pos_current) { + loops_current++; + } + pos_current = next_pos; //looped + } + + //find next + StringName next; + float next_xfade = 0; + AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE; + + if (path.size()) { + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == current && transitions[i].to == path[0]) { + next_xfade = transitions[i].transition->get_xfade_time(); + switch_mode = transitions[i].transition->get_switch_mode(); + next = path[0]; + } + } + } else { + float priority_best = 1e20; + int auto_advance_to = -1; + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == current && transitions[i].transition->has_auto_advance()) { + + if (transitions[i].transition->get_priority() < priority_best) { + auto_advance_to = i; + } + } + } + + if (auto_advance_to != -1) { + next = transitions[auto_advance_to].to; + next_xfade = transitions[auto_advance_to].transition->get_xfade_time(); + switch_mode = transitions[auto_advance_to].transition->get_switch_mode(); + } + } + + //if next, see when to transition + if (next != StringName()) { + + bool goto_next = false; + + if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE) { + goto_next = fading_from == StringName(); + } else { + goto_next = next_xfade >= (len_current - pos_current) || loops_current > 0; + if (loops_current > 0) { + next_xfade = 0; + } + } + + if (goto_next) { //loops should be used because fade time may be too small or zero and animation may have looped + + if (next_xfade) { + //time to fade, baby + fading_from = current; + fading_time = next_xfade; + fading_pos = 0; + } else { + fading_from = StringName(); + fading_pos = 0; + } + + if (path.size()) { //if it came from path, remove path + path.remove(0); + } + current = next; + if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_SYNC) { + len_current = blend_node(states[current], 0, true, 0, FILTER_IGNORE, false); + pos_current = MIN(pos_current, len_current); + blend_node(states[current], pos_current, true, 0, FILTER_IGNORE, false); + + } else { + len_current = blend_node(states[current], 0, true, 0, FILTER_IGNORE, false); + pos_current = 0; + } + + rem = len_current; //so it does not show 0 on transition + loops_current = 0; + } + } + + //compute time left for transitions by using the end node + + if (end_node != StringName() && end_node != current) { + + rem = blend_node(states[end_node], 0, true, 0, FILTER_IGNORE, false); + } + + return rem; +} + +bool AnimationNodeStateMachine::travel(const StringName &p_state) { + ERR_FAIL_COND_V(!playing, false); + ERR_FAIL_COND_V(!states.has(p_state), false); + ERR_FAIL_COND_V(!states.has(current), false); + + path.clear(); //a new one will be needed + + if (current == p_state) + return true; //nothing to do + + loops_current = 0; // reset loops, so fade does not happen immediately + + Vector2 current_pos = states[current]->get_position(); + Vector2 target_pos = states[p_state]->get_position(); + + Map<StringName, AStarCost> cost_map; + + List<int> open_list; + + //build open list + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from == current) { + open_list.push_back(i); + float cost = states[transitions[i].to]->get_position().distance_to(current_pos); + cost *= transitions[i].transition->get_priority(); + AStarCost ap; + ap.prev = current; + ap.distance = cost; + cost_map[transitions[i].to] = ap; + + if (transitions[i].to == p_state) { //prematurely found it! :D + path.push_back(p_state); + return true; + } + } + } + + //begin astar + bool found_route = false; + while (!found_route) { + + if (open_list.size() == 0) { + return false; //no path found + } + + //find the last cost transition + List<int>::Element *least_cost_transition = NULL; + float least_cost = 1e20; + + for (List<int>::Element *E = open_list.front(); E; E = E->next()) { + + float cost = cost_map[transitions[E->get()].to].distance; + cost += states[transitions[E->get()].to]->get_position().distance_to(target_pos); + + if (cost < least_cost) { + least_cost_transition = E; + } + } + + StringName transition_prev = transitions[least_cost_transition->get()].from; + StringName transition = transitions[least_cost_transition->get()].to; + + for (int i = 0; i < transitions.size(); i++) { + if (transitions[i].from != transition || transitions[i].to == transition_prev) { + continue; //not interested on those + } + + float distance = states[transitions[i].from]->get_position().distance_to(states[transitions[i].to]->get_position()); + distance *= transitions[i].transition->get_priority(); + distance += cost_map[transitions[i].from].distance; + + if (cost_map.has(transitions[i].to)) { + //oh this was visited already, can we win the cost? + if (distance < cost_map[transitions[i].to].distance) { + cost_map[transitions[i].to].distance = distance; + cost_map[transitions[i].to].prev = transitions[i].from; + } + } else { + //add to open list + AStarCost ac; + ac.prev = transitions[i].from; + ac.distance = distance; + cost_map[transitions[i].to] = ac; + + open_list.push_back(i); + + if (transitions[i].to == p_state) { + found_route = true; + break; + } + } + } + + if (found_route) { + break; + } + + open_list.erase(least_cost_transition); + } + + //make path + StringName at = p_state; + while (at != current) { + path.push_back(at); + at = cost_map[at].prev; + } + + path.invert(); + + return true; +} + +void AnimationNodeStateMachine::start(const StringName &p_state) { + + ERR_FAIL_COND(!states.has(p_state)); + path.clear(); + current = p_state; + playing = true; + play_start = true; +} +void AnimationNodeStateMachine::stop() { + playing = false; + play_start = false; + current = StringName(); +} +bool AnimationNodeStateMachine::is_playing() const { + + return playing; +} +StringName AnimationNodeStateMachine::get_current_node() const { + if (!playing) { + return StringName(); + } + + return current; +} + +StringName AnimationNodeStateMachine::get_blend_from_node() const { + if (!playing) { + return StringName(); + } + + return fading_from; +} + +float AnimationNodeStateMachine::get_current_play_pos() const { + return pos_current; +} +float AnimationNodeStateMachine::get_current_length() const { + return len_current; +} + +Vector<StringName> AnimationNodeStateMachine::get_travel_path() const { + return path; +} +String AnimationNodeStateMachine::get_caption() const { + return "StateMachine"; +} + +void AnimationNodeStateMachine::_notification(int p_what) { +} + +void AnimationNodeStateMachine::set_tree(AnimationTree *p_player) { + + AnimationNode::set_tree(p_player); + + for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) { + Ref<AnimationRootNode> node = E->get(); + node->set_tree(p_player); + } +} + +bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_value) { + + String name = p_name; + if (name.begins_with("states/")) { + String node_name = name.get_slicec('/', 1); + String what = name.get_slicec('/', 2); + + if (what == "node") { + Ref<AnimationNode> anode = p_value; + if (anode.is_valid()) { + add_node(node_name, p_value); + } + return true; + } + + if (what == "position") { + + if (states.has(node_name)) { + states[node_name]->set_position(p_value); + } + return true; + } + } else if (name == "transitions") { + + Array trans = p_value; + ERR_FAIL_COND_V(trans.size() % 3 != 0, false); + + for (int i = 0; i < trans.size(); i += 3) { + add_transition(trans[i], trans[i + 1], trans[i + 2]); + } + return true; + } else if (name == "start_node") { + set_start_node(p_value); + return true; + } else if (name == "end_node") { + set_end_node(p_value); + return true; + } else if (name == "graph_offset") { + set_graph_offset(p_value); + return true; + } + + return false; +} + +bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) const { + + String name = p_name; + if (name.begins_with("states/")) { + String node_name = name.get_slicec('/', 1); + String what = name.get_slicec('/', 2); + + if (what == "node") { + if (states.has(node_name)) { + r_ret = states[node_name]; + return true; + } + } + + if (what == "position") { + + if (states.has(node_name)) { + r_ret = states[node_name]->get_position(); + return true; + } + } + } else if (name == "transitions") { + Array trans; + trans.resize(transitions.size() * 3); + + for (int i = 0; i < transitions.size(); i++) { + trans[i * 3 + 0] = transitions[i].from; + trans[i * 3 + 1] = transitions[i].to; + trans[i * 3 + 2] = transitions[i].transition; + } + + r_ret = trans; + return true; + } else if (name == "start_node") { + r_ret = get_start_node(); + return true; + } else if (name == "end_node") { + r_ret = get_end_node(); + return true; + } else if (name == "graph_offset") { + r_ret = get_graph_offset(); + return true; + } + + return false; +} +void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const { + + List<StringName> names; + for (Map<StringName, Ref<AnimationRootNode> >::Element *E = states.front(); E; E = E->next()) { + names.push_back(E->key()); + } + names.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + String name = E->get(); + p_list->push_back(PropertyInfo(Variant::OBJECT, "states/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + p_list->push_back(PropertyInfo(Variant::VECTOR2, "states/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + } + + p_list->push_back(PropertyInfo(Variant::ARRAY, "transitions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING, "start_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING, "end_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); +} + +void AnimationNodeStateMachine::_bind_methods() { + + ClassDB::bind_method(D_METHOD("add_node", "name", "node"), &AnimationNodeStateMachine::add_node); + ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeStateMachine::get_node); + ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeStateMachine::remove_node); + ClassDB::bind_method(D_METHOD("rename_node", "name", "new_name"), &AnimationNodeStateMachine::rename_node); + ClassDB::bind_method(D_METHOD("has_node", "name"), &AnimationNodeStateMachine::has_node); + ClassDB::bind_method(D_METHOD("get_node_name", "node"), &AnimationNodeStateMachine::get_node_name); + + ClassDB::bind_method(D_METHOD("has_transition", "from", "to"), &AnimationNodeStateMachine::add_transition); + ClassDB::bind_method(D_METHOD("add_transition", "from", "to", "transition"), &AnimationNodeStateMachine::add_transition); + ClassDB::bind_method(D_METHOD("get_transition", "idx"), &AnimationNodeStateMachine::get_transition); + ClassDB::bind_method(D_METHOD("get_transition_from", "idx"), &AnimationNodeStateMachine::get_transition_from); + ClassDB::bind_method(D_METHOD("get_transition_to", "idx"), &AnimationNodeStateMachine::get_transition_to); + ClassDB::bind_method(D_METHOD("get_transition_count"), &AnimationNodeStateMachine::get_transition_count); + ClassDB::bind_method(D_METHOD("remove_transition_by_index", "idx"), &AnimationNodeStateMachine::remove_transition_by_index); + ClassDB::bind_method(D_METHOD("remove_transition", "from", "to"), &AnimationNodeStateMachine::remove_transition); + + ClassDB::bind_method(D_METHOD("set_start_node", "name"), &AnimationNodeStateMachine::set_start_node); + ClassDB::bind_method(D_METHOD("get_start_node"), &AnimationNodeStateMachine::get_start_node); + + ClassDB::bind_method(D_METHOD("set_end_node", "name"), &AnimationNodeStateMachine::set_end_node); + ClassDB::bind_method(D_METHOD("get_end_node"), &AnimationNodeStateMachine::get_end_node); + + ClassDB::bind_method(D_METHOD("set_graph_offset", "name"), &AnimationNodeStateMachine::set_graph_offset); + ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset); + + ClassDB::bind_method(D_METHOD("travel", "to_node"), &AnimationNodeStateMachine::travel); + ClassDB::bind_method(D_METHOD("start", "node"), &AnimationNodeStateMachine::start); + ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachine::stop); + ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachine::is_playing); + ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachine::get_current_node); + ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachine::get_travel_path); +} + +AnimationNodeStateMachine::AnimationNodeStateMachine() { + + play_start = false; + + playing = false; + len_current = 0; + + fading_time = 0; +} diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h new file mode 100644 index 0000000000..e7357e09ea --- /dev/null +++ b/scene/animation/animation_node_state_machine.h @@ -0,0 +1,142 @@ +#ifndef ANIMATION_NODE_STATE_MACHINE_H +#define ANIMATION_NODE_STATE_MACHINE_H + +#include "scene/animation/animation_tree.h" + +class AnimationNodeStateMachineTransition : public Resource { + GDCLASS(AnimationNodeStateMachineTransition, Resource) +public: + enum SwitchMode { + SWITCH_MODE_IMMEDIATE, + SWITCH_MODE_SYNC, + SWITCH_MODE_AT_END, + }; + +private: + SwitchMode switch_mode; + bool auto_advance; + float xfade; + bool disabled; + int priority; + +protected: + static void _bind_methods(); + +public: + void set_switch_mode(SwitchMode p_mode); + SwitchMode get_switch_mode() const; + + void set_auto_advance(bool p_enable); + bool has_auto_advance() const; + + void set_xfade_time(float p_xfade); + float get_xfade_time() const; + + void set_disabled(bool p_disabled); + bool is_disabled() const; + + void set_priority(int p_priority); + int get_priority() const; + + AnimationNodeStateMachineTransition(); +}; + +VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::SwitchMode) + +class AnimationNodeStateMachine : public AnimationRootNode { + + GDCLASS(AnimationNodeStateMachine, AnimationRootNode); + +private: + Map<StringName, Ref<AnimationRootNode> > states; + + struct Transition { + + StringName from; + StringName to; + Ref<AnimationNodeStateMachineTransition> transition; + }; + + struct AStarCost { + float distance; + StringName prev; + }; + + Vector<Transition> transitions; + + float len_total; + + float len_current; + float pos_current; + int loops_current; + + bool play_start; + StringName start_node; + StringName end_node; + + Vector2 graph_offset; + + StringName current; + + StringName fading_from; + float fading_time; + float fading_pos; + + Vector<StringName> path; + bool playing; + +protected: + void _notification(int p_what); + static void _bind_methods(); + + 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; + +public: + void add_node(const StringName &p_name, Ref<AnimationNode> p_node); + Ref<AnimationNode> get_node(const StringName &p_name) const; + void remove_node(const StringName &p_name); + void rename_node(const StringName &p_name, const StringName &p_new_name); + bool has_node(const StringName &p_name) const; + StringName get_node_name(const Ref<AnimationNode> &p_node) const; + void get_node_list(List<StringName> *r_nodes) const; + + bool has_transition(const StringName &p_from, const StringName &p_to) const; + int find_transition(const StringName &p_from, const StringName &p_to) const; + void add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition); + Ref<AnimationNodeStateMachineTransition> get_transition(int p_transition) const; + StringName get_transition_from(int p_transition) const; + StringName get_transition_to(int p_transition) const; + int get_transition_count() const; + void remove_transition_by_index(int p_transition); + void remove_transition(const StringName &p_from, const StringName &p_to); + + void set_start_node(const StringName &p_node); + String get_start_node() const; + + void set_end_node(const StringName &p_node); + String get_end_node() const; + + void set_graph_offset(const Vector2 &p_offset); + Vector2 get_graph_offset() const; + + virtual float process(float p_time, bool p_seek); + virtual String get_caption() const; + + bool travel(const StringName &p_state); + void start(const StringName &p_state); + void stop(); + bool is_playing() const; + StringName get_current_node() const; + StringName get_blend_from_node() const; + Vector<StringName> get_travel_path() const; + float get_current_play_pos() const; + float get_current_length() const; + + virtual void set_tree(AnimationTree *p_player); + + AnimationNodeStateMachine(); +}; + +#endif // ANIMATION_NODE_STATE_MACHINE_H diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 06aaeddf18..a4322bf713 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -419,14 +419,26 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float pa->capture = pa->object->get_indexed(pa->subpath); } - if (a->track_get_key_count(i) == 0) + int key_count = a->track_get_key_count(i); + if (key_count == 0) continue; //eeh not worth it float first_key_time = a->track_get_key_time(i, 0); + float transition = 1.0; + int first_key = 0; + + if (first_key_time == 0.0) { + //ignore, use for transition + if (key_count == 1) + continue; //with one key we cant do anything + transition = a->track_get_key_transition(i, 0); + first_key_time = a->track_get_key_time(i, 1); + first_key = 1; + } if (p_time < first_key_time) { - float c = p_time / first_key_time; - Variant first_value = a->track_get_key_value(i, 0); + float c = Math::ease(p_time / first_key_time, transition); + Variant first_value = a->track_get_key_value(i, first_key); Variant interp_value; Variant::interpolate(pa->capture, first_value, c, interp_value); diff --git a/scene/animation/animation_graph_player.cpp b/scene/animation/animation_tree.cpp index ee9621dc1a..011c4eb470 100644 --- a/scene/animation/animation_graph_player.cpp +++ b/scene/animation/animation_tree.cpp @@ -1,4 +1,4 @@ -#include "animation_graph_player.h" +#include "animation_tree.h" #include "animation_blend_tree.h" #include "core/method_bind_ext.gen.inc" #include "engine.h" @@ -14,8 +14,13 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time, if (animation.is_null()) { - String name = get_tree()->get_node_name(Ref<AnimationNodeAnimation>(this)); - make_invalid(vformat(RTR("In node '%s', invalid animation: '%s'."), name, p_animation)); + Ref<AnimationNodeBlendTree> btree = get_parent(); + if (btree.is_valid()) { + String name = btree->get_node_name(Ref<AnimationNodeAnimation>(this)); + make_invalid(vformat(RTR("In node '%s', invalid animation: '%s'."), name, p_animation)); + } else { + make_invalid(vformat(RTR("Invalid animation: '%s'."), p_animation)); + } return; } @@ -51,14 +56,16 @@ void AnimationNode::make_invalid(const String &p_reason) { float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) { ERR_FAIL_INDEX_V(p_input, inputs.size(), 0); ERR_FAIL_COND_V(!state, 0); - ERR_FAIL_COND_V(!get_graph_player(), 0); //should not happen, but used to catch bugs + ERR_FAIL_COND_V(!get_tree(), 0); //should not happen, but used to catch bugs + + Ref<AnimationNodeBlendTree> tree = get_parent(); - if (!tree && get_graph_player()->get_graph_root().ptr() != this) { + if (!tree.is_valid() && get_tree()->get_tree_root().ptr() != this) { make_invalid(RTR("Can't blend input because node is not in a tree")); return 0; } - ERR_FAIL_COND_V(!tree, 0); //should not happen + ERR_FAIL_COND_V(!tree.is_valid(), 0); //should not happen StringName anim_name = inputs[p_input].connected_to; @@ -66,7 +73,7 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p if (node.is_null()) { - String name = get_tree()->get_node_name(Ref<AnimationNodeAnimation>(this)); + String name = tree->get_node_name(Ref<AnimationNodeAnimation>(this)); make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), name)); return 0; } @@ -197,10 +204,10 @@ String AnimationNode::get_input_name(int p_input) { float AnimationNode::get_input_activity(int p_input) const { ERR_FAIL_INDEX_V(p_input, inputs.size(), 0); - if (!get_graph_player()) + if (!get_tree()) return 0; - if (get_graph_player()->get_last_process_pass() != inputs[p_input].last_pass) { + if (get_tree()->get_last_process_pass() != inputs[p_input].last_pass) { return 0; } return inputs[p_input].activity; @@ -218,10 +225,17 @@ void AnimationNode::set_input_connection(int p_input, const StringName &p_connec } String AnimationNode::get_caption() const { + + if (get_script_instance()) { + return get_script_instance()->call("get_caption"); + } + return "Node"; } void AnimationNode::add_input(const String &p_name) { + //root nodes cant add inputs + ERR_FAIL_COND(Object::cast_to<AnimationRootNode>(this) != NULL) Input input; ERR_FAIL_COND(p_name.find(".") != -1 || p_name.find("/") != -1); input.name = p_name; @@ -244,15 +258,26 @@ void AnimationNode::remove_input(int p_index) { emit_changed(); } -Ref<AnimationNodeBlendTree> AnimationNode::get_tree() const { - if (tree) { - return Ref<AnimationNodeBlendTree>(tree); +void AnimationNode::_set_parent(Object *p_parent) { + set_parent(Object::cast_to<AnimationNode>(p_parent)); +} + +void AnimationNode::set_parent(AnimationNode *p_parent) { + parent = p_parent; //do not use ref because parent contains children + if (get_script_instance()) { + get_script_instance()->call("_parent_set", p_parent); + } +} + +Ref<AnimationNode> AnimationNode::get_parent() const { + if (parent) { + return Ref<AnimationNode>(parent); } - return Ref<AnimationNodeBlendTree>(); + return Ref<AnimationNode>(); } -AnimationGraphPlayer *AnimationNode::get_graph_player() const { +AnimationTree *AnimationNode::get_tree() const { return player; } @@ -303,8 +328,11 @@ Vector2 AnimationNode::get_position() const { return position; } -void AnimationNode::set_graph_player(AnimationGraphPlayer *p_player) { +void AnimationNode::set_tree(AnimationTree *p_player) { + if (player != NULL && p_player == NULL) { + emit_signal("removed_from_graph"); + } player = p_player; } @@ -359,11 +387,19 @@ void AnimationNode::_bind_methods() { ClassDB::bind_method(D_METHOD("blend_node", "node", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true)); ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("set_parent", "parent"), &AnimationNode::_set_parent); + ClassDB::bind_method(D_METHOD("get_parent"), &AnimationNode::get_parent); + ClassDB::bind_method(D_METHOD("get_tree"), &AnimationNode::get_tree); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_filter_enabled", "is_filter_enabled"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters"); BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::REAL, "time"), PropertyInfo(Variant::BOOL, "seek"))); + BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "has_filter")); + BIND_VMETHOD(MethodInfo("_parent_set", PropertyInfo(Variant::OBJECT, "parent"))); + ADD_SIGNAL(MethodInfo("removed_from_graph")); BIND_ENUM_CONSTANT(FILTER_IGNORE); BIND_ENUM_CONSTANT(FILTER_PASS); BIND_ENUM_CONSTANT(FILTER_STOP); @@ -373,7 +409,7 @@ void AnimationNode::_bind_methods() { AnimationNode::AnimationNode() { state = NULL; - tree = NULL; + parent = NULL; player = NULL; set_local_to_scene(true); filter_enabled = false; @@ -381,10 +417,10 @@ AnimationNode::AnimationNode() { //////////////////// -void AnimationGraphPlayer::set_graph_root(const Ref<AnimationNode> &p_root) { +void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) { if (root.is_valid()) { - root->set_graph_player(NULL); + root->set_tree(NULL); } if (p_root.is_valid()) { ERR_EXPLAIN("root node already set to another player"); @@ -393,17 +429,17 @@ void AnimationGraphPlayer::set_graph_root(const Ref<AnimationNode> &p_root) { root = p_root; if (root.is_valid()) { - root->set_graph_player(this); + root->set_tree(this); } update_configuration_warning(); } -Ref<AnimationNode> AnimationGraphPlayer::get_graph_root() const { +Ref<AnimationNode> AnimationTree::get_tree_root() const { return root; } -void AnimationGraphPlayer::set_active(bool p_active) { +void AnimationTree::set_active(bool p_active) { if (active == p_active) return; @@ -430,12 +466,12 @@ void AnimationGraphPlayer::set_active(bool p_active) { } } -bool AnimationGraphPlayer::is_active() const { +bool AnimationTree::is_active() const { return active; } -void AnimationGraphPlayer::set_process_mode(AnimationProcessMode p_mode) { +void AnimationTree::set_process_mode(AnimationProcessMode p_mode) { if (process_mode == p_mode) return; @@ -452,20 +488,20 @@ void AnimationGraphPlayer::set_process_mode(AnimationProcessMode p_mode) { } } -AnimationGraphPlayer::AnimationProcessMode AnimationGraphPlayer::get_process_mode() const { +AnimationTree::AnimationProcessMode AnimationTree::get_process_mode() const { return process_mode; } -void AnimationGraphPlayer::_node_removed(Node *p_node) { +void AnimationTree::_node_removed(Node *p_node) { cache_valid = false; } -bool AnimationGraphPlayer::_update_caches(AnimationPlayer *player) { +bool AnimationTree::_update_caches(AnimationPlayer *player) { setup_pass++; if (!player->has_node(player->get_root())) { - ERR_PRINT("AnimationGraphPlayer: AnimationPlayer root is invalid."); + ERR_PRINT("AnimationTree: AnimationPlayer root is invalid."); set_active(false); return false; } @@ -500,7 +536,7 @@ bool AnimationGraphPlayer::_update_caches(AnimationPlayer *player) { Node *child = parent->get_node_and_resource(path, resource, leftover_path); if (!child) { - ERR_PRINTS("AnimationGraphPlayer: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'"); + ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'"); continue; } @@ -530,7 +566,7 @@ bool AnimationGraphPlayer::_update_caches(AnimationPlayer *player) { Spatial *spatial = Object::cast_to<Spatial>(child); if (!spatial) { - ERR_PRINTS("AnimationGraphPlayer: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'"); + ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'"); continue; } @@ -649,7 +685,7 @@ bool AnimationGraphPlayer::_update_caches(AnimationPlayer *player) { return true; } -void AnimationGraphPlayer::_clear_caches() { +void AnimationTree::_clear_caches() { const NodePath *K = NULL; while ((K = track_cache.next(K))) { @@ -661,19 +697,20 @@ void AnimationGraphPlayer::_clear_caches() { cache_valid = false; } -void AnimationGraphPlayer::_process_graph(float p_delta) { +void AnimationTree::_process_graph(float p_delta) { //check all tracks, see if they need modification + root_motion_transform = Transform(); if (!root.is_valid()) { - ERR_PRINT("AnimationGraphPlayer: root AnimationNode is not set, disabling playback."); + ERR_PRINT("AnimationTree: root AnimationNode is not set, disabling playback."); set_active(false); cache_valid = false; return; } if (!has_node(animation_player)) { - ERR_PRINT("AnimationGraphPlayer: no valid AnimationPlayer path set, disabling playback"); + ERR_PRINT("AnimationTree: no valid AnimationPlayer path set, disabling playback"); set_active(false); cache_valid = false; return; @@ -682,7 +719,7 @@ void AnimationGraphPlayer::_process_graph(float p_delta) { AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player)); if (!player) { - ERR_PRINT("AnimationGraphPlayer: path points to a node not an AnimationPlayer, disabling playback"); + ERR_PRINT("AnimationTree: path points to a node not an AnimationPlayer, disabling playback"); set_active(false); cache_valid = false; return; @@ -753,6 +790,8 @@ void AnimationGraphPlayer::_process_graph(float p_delta) { continue; //may happen should not } + track->root_motion = root_motion_track == path; + ERR_CONTINUE(!state.track_map.has(path)); int blend_idx = state.track_map[path]; @@ -769,29 +808,85 @@ void AnimationGraphPlayer::_process_graph(float p_delta) { TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); - Vector3 loc; - Quat rot; - Vector3 scale; - - Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale); - //ERR_CONTINUE(err!=OK); //used for testing, should be removed - - scale -= Vector3(1.0, 1.0, 1.0); //helps make it work properly with Add nodes - - if (err != OK) - continue; - if (t->process_pass != process_pass) { t->process_pass = process_pass; t->loc = Vector3(); t->rot = Quat(); + t->rot_blend_accum = 0; t->scale = Vector3(); } - t->loc = t->loc.linear_interpolate(loc, blend); - t->rot = t->rot.slerp(rot, blend); - t->scale = t->scale.linear_interpolate(scale, blend); + if (track->root_motion) { + + float prev_time = time - delta; + if (prev_time < 0) { + if (!a->has_loop()) { + prev_time = 0; + } else { + prev_time = a->get_length() + prev_time; + } + } + + Vector3 loc[2]; + Quat rot[2]; + Vector3 scale[2]; + + if (prev_time > time) { + + Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]); + if (err != OK) { + continue; + } + + a->transform_track_interpolate(i, a->get_length(), &loc[1], &rot[1], &scale[1]); + + t->loc += (loc[1] - loc[0]) * blend; + t->scale += (scale[1] - scale[0]) * blend; + Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); + t->rot = (t->rot * q).normalized(); + + prev_time = 0; + } + + Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]); + if (err != OK) { + continue; + } + + a->transform_track_interpolate(i, time, &loc[1], &rot[1], &scale[1]); + + t->loc += (loc[1] - loc[0]) * blend; + t->scale += (scale[1] - scale[0]) * blend; + Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); + t->rot = (t->rot * q).normalized(); + + prev_time = 0; + + } else { + Vector3 loc; + Quat rot; + Vector3 scale; + + Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale); + //ERR_CONTINUE(err!=OK); //used for testing, should be removed + + scale -= Vector3(1.0, 1.0, 1.0); //helps make it work properly with Add nodes + + if (err != OK) + continue; + + t->loc = t->loc.linear_interpolate(loc, blend); + if (t->rot_blend_accum==0) { + t->rot = rot; + t->rot_blend_accum = blend; + } else { + float rot_total = t->rot_blend_accum + blend; + t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized(); + t->rot_blend_accum = rot_total; + } + t->scale = t->scale.linear_interpolate(scale, blend); + } } break; case Animation::TYPE_VALUE: { @@ -1042,11 +1137,18 @@ void AnimationGraphPlayer::_process_graph(float p_delta) { Transform xform; xform.origin = t->loc; - t->scale += Vector3(1.0, 1.0, 1.0); //helps make it work properly with Add nodes + t->scale += Vector3(1.0, 1.0, 1.0); //helps make it work properly with Add nodes and root motion xform.basis.set_quat_scale(t->rot, t->scale); - if (t->skeleton && t->bone_idx >= 0) { + if (t->root_motion) { + + root_motion_transform = xform; + + if (t->skeleton && t->bone_idx >= 0) { + root_motion_transform = (t->skeleton->get_bone_rest(t->bone_idx) * root_motion_transform) * t->skeleton->get_bone_rest(t->bone_idx).affine_inverse(); + } + } else if (t->skeleton && t->bone_idx >= 0) { t->skeleton->set_bone_pose(t->bone_idx, xform); @@ -1076,7 +1178,7 @@ void AnimationGraphPlayer::_process_graph(float p_delta) { } } -void AnimationGraphPlayer::_notification(int p_what) { +void AnimationTree::_notification(int p_what) { if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) { _process_graph(get_physics_process_delta_time()); @@ -1091,29 +1193,29 @@ void AnimationGraphPlayer::_notification(int p_what) { } } -void AnimationGraphPlayer::set_animation_player(const NodePath &p_player) { +void AnimationTree::set_animation_player(const NodePath &p_player) { animation_player = p_player; update_configuration_warning(); } -NodePath AnimationGraphPlayer::get_animation_player() const { +NodePath AnimationTree::get_animation_player() const { return animation_player; } -bool AnimationGraphPlayer::is_state_invalid() const { +bool AnimationTree::is_state_invalid() const { return !state.valid; } -String AnimationGraphPlayer::get_invalid_state_reason() const { +String AnimationTree::get_invalid_state_reason() const { return state.invalid_reasons; } -uint64_t AnimationGraphPlayer::get_last_process_pass() const { +uint64_t AnimationTree::get_last_process_pass() const { return process_pass; } -String AnimationGraphPlayer::get_configuration_warning() const { +String AnimationTree::get_configuration_warning() const { String warning = Node::get_configuration_warning(); @@ -1157,28 +1259,49 @@ String AnimationGraphPlayer::get_configuration_warning() const { return warning; } -void AnimationGraphPlayer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationGraphPlayer::set_active); - ClassDB::bind_method(D_METHOD("is_active"), &AnimationGraphPlayer::is_active); +void AnimationTree::set_root_motion_track(const NodePath &p_track) { + root_motion_track = p_track; +} + +NodePath AnimationTree::get_root_motion_track() const { + return root_motion_track; +} + +Transform AnimationTree::get_root_motion_transform() const { + return root_motion_transform; +} + +void AnimationTree::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationTree::set_active); + ClassDB::bind_method(D_METHOD("is_active"), &AnimationTree::is_active); + + ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root); + ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root); + + ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationTree::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationTree::get_process_mode); + + ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player); + ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player); + + ClassDB::bind_method(D_METHOD("set_root_motion_track", "path"), &AnimationTree::set_root_motion_track); + ClassDB::bind_method(D_METHOD("get_root_motion_track"), &AnimationTree::get_root_motion_track); - ClassDB::bind_method(D_METHOD("set_graph_root", "root"), &AnimationGraphPlayer::set_graph_root); - ClassDB::bind_method(D_METHOD("get_graph_root"), &AnimationGraphPlayer::get_graph_root); + ClassDB::bind_method(D_METHOD("get_root_motion_transform"), &AnimationTree::get_root_motion_transform); - ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationGraphPlayer::set_process_mode); - ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationGraphPlayer::get_process_mode); - ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationGraphPlayer::set_animation_player); - ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationGraphPlayer::get_animation_player); - ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationGraphPlayer::_node_removed); + ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "graph_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNodeBlendTree", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_graph_root", "get_graph_root"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player"), "set_animation_player", "get_animation_player"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_tree_root", "get_tree_root"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player",PROPERTY_HINT_NODE_PATH_VALID_TYPES,"AnimationPlayer"), "set_animation_player", "get_animation_player"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); + ADD_GROUP("Root Motion", "root_motion_"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track"); } -AnimationGraphPlayer::AnimationGraphPlayer() { +AnimationTree::AnimationTree() { process_mode = ANIMATION_PROCESS_IDLE; active = false; @@ -1187,7 +1310,7 @@ AnimationGraphPlayer::AnimationGraphPlayer() { started = true; } -AnimationGraphPlayer::~AnimationGraphPlayer() { +AnimationTree::~AnimationTree() { if (root.is_valid()) { root->player = NULL; } diff --git a/scene/animation/animation_graph_player.h b/scene/animation/animation_tree.h index 6487a48f34..540c36437a 100644 --- a/scene/animation/animation_graph_player.h +++ b/scene/animation/animation_tree.h @@ -8,7 +8,7 @@ class AnimationNodeBlendTree; class AnimationPlayer; -class AnimationGraphPlayer; +class AnimationTree; class AnimationNode : public Resource { GDCLASS(AnimationNode, Resource) @@ -32,7 +32,7 @@ public: float process_input(int p_input, float p_time, bool p_seek, float p_blend); - friend class AnimationGraphPlayer; + friend class AnimationTree; struct AnimationState { @@ -61,9 +61,8 @@ public: void _pre_update_animations(HashMap<NodePath, int> *track_map); Vector2 position; - friend class AnimationNodeBlendTree; - AnimationNodeBlendTree *tree; - AnimationGraphPlayer *player; + AnimationNode *parent; + AnimationTree *player; float _blend_node(Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, float *r_max = NULL); @@ -83,13 +82,17 @@ protected: void _validate_property(PropertyInfo &property) const; + void _set_parent(Object *p_parent); + public: - Ref<AnimationNodeBlendTree> get_tree() const; - virtual void set_graph_player(AnimationGraphPlayer *p_player); - AnimationGraphPlayer *get_graph_player() const; + void set_parent(AnimationNode *p_parent); + Ref<AnimationNode> get_parent() const; + virtual void set_tree(AnimationTree *p_player); + AnimationTree *get_tree() const; AnimationPlayer *get_player() const; virtual float process(float p_time, bool p_seek); + virtual String get_caption() const; int get_input_count() const; String get_input_name(int p_input); @@ -101,8 +104,6 @@ public: void set_input_name(int p_input, const String &p_name); void remove_input(int p_index); - virtual String get_caption() const; - void set_filter_path(const NodePath &p_path, bool p_enable); bool is_path_filtered(const NodePath &p_path) const; @@ -119,8 +120,15 @@ public: VARIANT_ENUM_CAST(AnimationNode::FilterAction) -class AnimationGraphPlayer : public Node { - GDCLASS(AnimationGraphPlayer, Node) +//root node does not allow inputs +class AnimationRootNode : public AnimationNode { + GDCLASS(AnimationRootNode, AnimationNode) +public: + AnimationRootNode() {} +}; + +class AnimationTree : public Node { + GDCLASS(AnimationTree, Node) public: enum AnimationProcessMode { ANIMATION_PROCESS_PHYSICS, @@ -129,6 +137,8 @@ public: private: struct TrackCache { + + bool root_motion; uint64_t setup_pass; uint64_t process_pass; Animation::TrackType type; @@ -136,6 +146,7 @@ private: ObjectID object_id; TrackCache() { + root_motion = false; setup_pass = 0; process_pass = 0; object = NULL; @@ -150,6 +161,7 @@ private: int bone_idx; Vector3 loc; Quat rot; + float rot_blend_accum; Vector3 scale; TrackCacheTransform() { @@ -229,13 +241,16 @@ private: bool started; + NodePath root_motion_track; + Transform root_motion_transform; + protected: void _notification(int p_what); static void _bind_methods(); public: - void set_graph_root(const Ref<AnimationNode> &p_root); - Ref<AnimationNode> get_graph_root() const; + void set_tree_root(const Ref<AnimationNode> &p_root); + Ref<AnimationNode> get_tree_root() const; void set_active(bool p_active); bool is_active() const; @@ -251,11 +266,16 @@ public: bool is_state_invalid() const; String get_invalid_state_reason() const; + void set_root_motion_track(const NodePath &p_track); + NodePath get_root_motion_track() const; + + Transform get_root_motion_transform() const; + uint64_t get_last_process_pass() const; - AnimationGraphPlayer(); - ~AnimationGraphPlayer(); + AnimationTree(); + ~AnimationTree(); }; -VARIANT_ENUM_CAST(AnimationGraphPlayer::AnimationProcessMode) +VARIANT_ENUM_CAST(AnimationTree::AnimationProcessMode) #endif // ANIMATION_GRAPH_PLAYER_H diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 143684bdf9..026215508b 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -1814,7 +1814,7 @@ void AnimationTreePlayer::_bind_methods() { ADD_GROUP("Playback", "playback_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player"), "set_master_player", "get_master_player"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_master_player", "get_master_player"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp new file mode 100644 index 0000000000..8443995720 --- /dev/null +++ b/scene/animation/root_motion_view.cpp @@ -0,0 +1,163 @@ +#include "root_motion_view.h" +#include "scene/animation/animation_tree.h" +#include "scene/resources/material.h" +void RootMotionView::set_animation_path(const NodePath &p_path) { + path = p_path; + first = true; +} + +NodePath RootMotionView::get_animation_path() const { + return path; +} + +void RootMotionView::set_color(const Color &p_color) { + color = p_color; + first = true; +} + +Color RootMotionView::get_color() const { + return color; +} + +void RootMotionView::set_cell_size(float p_size) { + cell_size = p_size; + first = true; +} + +float RootMotionView::get_cell_size() const { + return cell_size; +} + +void RootMotionView::set_radius(float p_radius) { + radius = p_radius; + first = true; +} + +float RootMotionView::get_radius() const { + return radius; +} + +void RootMotionView::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE) { + + VS::get_singleton()->immediate_set_material(immediate, SpatialMaterial::get_material_rid_for_2d(false, true, false, false, false)); + first = true; + } + + if (p_what == NOTIFICATION_INTERNAL_PROCESS || p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { + Transform transform; + + if (has_node(path)) { + + Node *node = get_node(path); + + AnimationTree *tree = Object::cast_to<AnimationTree>(node); + if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) { + if (is_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { + set_process_internal(false); + set_physics_process_internal(true); + } + + if (is_physics_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_IDLE) { + set_process_internal(true); + set_physics_process_internal(false); + } + + transform = tree->get_root_motion_transform(); + } + } + + if (!first && transform == Transform()) { + return; + } + + first = false; + + transform.orthonormalize(); //dont want scale, too imprecise + transform.affine_invert(); + + accumulated = accumulated * transform; + accumulated.origin.x = Math::fposmod(accumulated.origin.x, cell_size); + accumulated.origin.y = Math::fposmod(accumulated.origin.y, cell_size); + accumulated.origin.z = Math::fposmod(accumulated.origin.z, cell_size); + + VS::get_singleton()->immediate_clear(immediate); + + int cells_in_radius = int((radius / cell_size) + 1.0); + + VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_LINES); + for (int i = -cells_in_radius; i < cells_in_radius; i++) { + for (int j = -cells_in_radius; j < cells_in_radius; j++) { + + Vector3 from(i * cell_size, 0, j * cell_size); + Vector3 from_i((i + 1) * cell_size, 0, j * cell_size); + Vector3 from_j(i * cell_size, 0, (j + 1) * cell_size); + from = accumulated.xform(from); + from_i = accumulated.xform(from_i); + from_j = accumulated.xform(from_j); + + Color c = color, c_i = color, c_j = color; + c.a *= MAX(0, 1.0 - from.length() / radius); + c_i.a *= MAX(0, 1.0 - from_i.length() / radius); + c_j.a *= MAX(0, 1.0 - from_j.length() / radius); + + VS::get_singleton()->immediate_color(immediate, c); + VS::get_singleton()->immediate_vertex(immediate, from); + + VS::get_singleton()->immediate_color(immediate, c_i); + VS::get_singleton()->immediate_vertex(immediate, from_i); + + VS::get_singleton()->immediate_color(immediate, c); + VS::get_singleton()->immediate_vertex(immediate, from); + + VS::get_singleton()->immediate_color(immediate, c_j); + VS::get_singleton()->immediate_vertex(immediate, from_j); + } + } + + VS::get_singleton()->immediate_end(immediate); + } +} + +AABB RootMotionView::get_aabb() const { + + return AABB(Vector3(-radius, 0, -radius), Vector3(radius * 2, 0.001, radius * 2)); +} +PoolVector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const { + return PoolVector<Face3>(); +} + +void RootMotionView::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_animation_path", "path"), &RootMotionView::set_animation_path); + ClassDB::bind_method(D_METHOD("get_animation_path"), &RootMotionView::get_animation_path); + + ClassDB::bind_method(D_METHOD("set_color", "color"), &RootMotionView::set_color); + ClassDB::bind_method(D_METHOD("get_color"), &RootMotionView::get_color); + + ClassDB::bind_method(D_METHOD("set_cell_size", "size"), &RootMotionView::set_cell_size); + ClassDB::bind_method(D_METHOD("get_cell_size"), &RootMotionView::get_cell_size); + + ClassDB::bind_method(D_METHOD("set_radius", "size"), &RootMotionView::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &RootMotionView::get_radius); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationTree"), "set_animation_path", "get_animation_path"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius"); +} + +RootMotionView::RootMotionView() { + radius = 10; + cell_size = 1; + set_process_internal(true); + immediate = VisualServer::get_singleton()->immediate_create(); + set_base(immediate); + color = Color(0.5, 0.5, 1.0); +} + +RootMotionView::~RootMotionView() { + set_base(RID()); + VisualServer::get_singleton()->free(immediate); +} diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h new file mode 100644 index 0000000000..65e9ff480b --- /dev/null +++ b/scene/animation/root_motion_view.h @@ -0,0 +1,43 @@ +#ifndef ROOT_MOTION_VIEW_H +#define ROOT_MOTION_VIEW_H + +#include "scene/3d/visual_instance.h" + +class RootMotionView : public VisualInstance { + GDCLASS(RootMotionView, VisualInstance) +public: + RID immediate; + NodePath path; + float cell_size; + float radius; + bool use_in_game; + Color color; + bool first; + + Transform accumulated; + +private: + void _notification(int p_what); + static void _bind_methods(); + +public: + void set_animation_path(const NodePath &p_path); + NodePath get_animation_path() const; + + void set_color(const Color &p_path); + Color get_color() const; + + void set_cell_size(float p_size); + float get_cell_size() const; + + void set_radius(float p_radius); + float get_radius() const; + + virtual AABB get_aabb() const; + virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + + RootMotionView(); + ~RootMotionView(); +}; + +#endif // ROOT_MOTION_VIEW_H diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index a738687a70..18a0cd13d9 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2888,12 +2888,12 @@ void Control::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip"); ADD_GROUP("Focus", "focus_"); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_left"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_LEFT); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT); - ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM); - ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next"), "set_focus_next", "get_focus_next"); - ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous"), "set_focus_previous", "get_focus_previous"); + ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_left", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_LEFT); + ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP); + ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT); + ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM); + ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_next", "get_focus_next"); + ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_previous", "get_focus_previous"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode"); ADD_GROUP("Mouse", "mouse_"); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1236aea2dd..a894b82a94 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -144,7 +144,7 @@ void ViewportTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene); ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path"), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport"), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); } ViewportTexture::ViewportTexture() { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index b455fa3511..55aa0024c8 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -63,10 +63,14 @@ #include "scene/2d/tile_map.h" #include "scene/2d/visibility_notifier_2d.h" #include "scene/2d/y_sort.h" +#include "scene/animation/animation_blend_space_1d.h" +#include "scene/animation/animation_blend_space_2d.h" #include "scene/animation/animation_blend_tree.h" -#include "scene/animation/animation_graph_player.h" +#include "scene/animation/animation_node_state_machine.h" #include "scene/animation/animation_player.h" +#include "scene/animation/animation_tree.h" #include "scene/animation/animation_tree_player.h" +#include "scene/animation/root_motion_view.h" #include "scene/animation/tween.h" #include "scene/audio/audio_player.h" #include "scene/gui/box_container.h" @@ -384,13 +388,22 @@ void register_scene_types() { ClassDB::register_class<NavigationMesh>(); ClassDB::register_class<Navigation>(); - ClassDB::register_class<AnimationGraphPlayer>(); + ClassDB::register_class<RootMotionView>(); + ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor + + ClassDB::register_class<AnimationTree>(); ClassDB::register_class<AnimationNode>(); + ClassDB::register_class<AnimationRootNode>(); ClassDB::register_class<AnimationNodeBlendTree>(); + ClassDB::register_class<AnimationNodeBlendSpace1D>(); + ClassDB::register_class<AnimationNodeBlendSpace2D>(); + ClassDB::register_class<AnimationNodeStateMachine>(); + ClassDB::register_class<AnimationNodeStateMachineTransition>(); ClassDB::register_class<AnimationNodeOutput>(); ClassDB::register_class<AnimationNodeOneShot>(); ClassDB::register_class<AnimationNodeAnimation>(); - ClassDB::register_class<AnimationNodeAdd>(); + ClassDB::register_class<AnimationNodeAdd2>(); + ClassDB::register_class<AnimationNodeAdd3>(); ClassDB::register_class<AnimationNodeBlend2>(); ClassDB::register_class<AnimationNodeBlend3>(); ClassDB::register_class<AnimationNodeTimeScale>(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index fe4d687c23..3185fb6768 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -134,8 +134,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { int um = d["update"]; if (um < 0) um = 0; - else if (um > 2) - um = 2; + else if (um > 3) + um = 3; vt->update_mode = UpdateMode(um); } diff --git a/scene/resources/default_theme/arrow_down.png b/scene/resources/default_theme/arrow_down.png Binary files differindex fc837d120a..bfb87a4761 100644 --- a/scene/resources/default_theme/arrow_down.png +++ b/scene/resources/default_theme/arrow_down.png diff --git a/scene/resources/default_theme/arrow_right.png b/scene/resources/default_theme/arrow_right.png Binary files differindex ebe6e26ace..1e4c8e5529 100644 --- a/scene/resources/default_theme/arrow_right.png +++ b/scene/resources/default_theme/arrow_right.png diff --git a/scene/resources/default_theme/background.png b/scene/resources/default_theme/background.png Binary files differindex 03cfab1de3..6c5f43e3ce 100644 --- a/scene/resources/default_theme/background.png +++ b/scene/resources/default_theme/background.png diff --git a/scene/resources/default_theme/base_green.png b/scene/resources/default_theme/base_green.png Binary files differindex d03d6f08d8..03a5b313d7 100644 --- a/scene/resources/default_theme/base_green.png +++ b/scene/resources/default_theme/base_green.png diff --git a/scene/resources/default_theme/button_disabled.png b/scene/resources/default_theme/button_disabled.png Binary files differindex d75e76989d..708748dfe9 100644 --- a/scene/resources/default_theme/button_disabled.png +++ b/scene/resources/default_theme/button_disabled.png diff --git a/scene/resources/default_theme/button_focus.png b/scene/resources/default_theme/button_focus.png Binary files differindex 44e354be95..70e16b953b 100644 --- a/scene/resources/default_theme/button_focus.png +++ b/scene/resources/default_theme/button_focus.png diff --git a/scene/resources/default_theme/button_hover.png b/scene/resources/default_theme/button_hover.png Binary files differindex 6e609f435f..ef226e3caf 100644 --- a/scene/resources/default_theme/button_hover.png +++ b/scene/resources/default_theme/button_hover.png diff --git a/scene/resources/default_theme/button_normal.png b/scene/resources/default_theme/button_normal.png Binary files differindex 92482aaf28..7d0bd16221 100644 --- a/scene/resources/default_theme/button_normal.png +++ b/scene/resources/default_theme/button_normal.png diff --git a/scene/resources/default_theme/checked.png b/scene/resources/default_theme/checked.png Binary files differindex 93e291a29e..bde031b6a2 100644 --- a/scene/resources/default_theme/checked.png +++ b/scene/resources/default_theme/checked.png diff --git a/scene/resources/default_theme/checker_bg.png b/scene/resources/default_theme/checker_bg.png Binary files differindex f58dfed29c..3eff2f0e08 100644 --- a/scene/resources/default_theme/checker_bg.png +++ b/scene/resources/default_theme/checker_bg.png diff --git a/scene/resources/default_theme/close.png b/scene/resources/default_theme/close.png Binary files differindex 5ac6357dcd..4d4ac4a551 100644 --- a/scene/resources/default_theme/close.png +++ b/scene/resources/default_theme/close.png diff --git a/scene/resources/default_theme/close_hl.png b/scene/resources/default_theme/close_hl.png Binary files differindex 5ac6357dcd..4d4ac4a551 100644 --- a/scene/resources/default_theme/close_hl.png +++ b/scene/resources/default_theme/close_hl.png diff --git a/scene/resources/default_theme/color_picker_sample.png b/scene/resources/default_theme/color_picker_sample.png Binary files differindex b145a3e384..e6ec28d307 100644 --- a/scene/resources/default_theme/color_picker_sample.png +++ b/scene/resources/default_theme/color_picker_sample.png diff --git a/scene/resources/default_theme/dosfont.png b/scene/resources/default_theme/dosfont.png Binary files differindex 814d2e9060..e2739b94ea 100644 --- a/scene/resources/default_theme/dosfont.png +++ b/scene/resources/default_theme/dosfont.png diff --git a/scene/resources/default_theme/dropdown.png b/scene/resources/default_theme/dropdown.png Binary files differindex 3a6a2ed778..b5d9ffbbb4 100644 --- a/scene/resources/default_theme/dropdown.png +++ b/scene/resources/default_theme/dropdown.png diff --git a/scene/resources/default_theme/error_icon.png b/scene/resources/default_theme/error_icon.png Binary files differindex f291362350..7741d00749 100644 --- a/scene/resources/default_theme/error_icon.png +++ b/scene/resources/default_theme/error_icon.png diff --git a/scene/resources/default_theme/focus.png b/scene/resources/default_theme/focus.png Binary files differindex 5d37028f2d..f51ea89e8f 100644 --- a/scene/resources/default_theme/focus.png +++ b/scene/resources/default_theme/focus.png diff --git a/scene/resources/default_theme/frame_focus.png b/scene/resources/default_theme/frame_focus.png Binary files differindex 9170db38ed..1b24ba47d8 100644 --- a/scene/resources/default_theme/frame_focus.png +++ b/scene/resources/default_theme/frame_focus.png diff --git a/scene/resources/default_theme/full_panel_bg.png b/scene/resources/default_theme/full_panel_bg.png Binary files differindex 7f02dc7259..85f753cc13 100644 --- a/scene/resources/default_theme/full_panel_bg.png +++ b/scene/resources/default_theme/full_panel_bg.png diff --git a/scene/resources/default_theme/graph_node_breakpoint.png b/scene/resources/default_theme/graph_node_breakpoint.png Binary files differindex 0e36f31bd4..e18c6f42e1 100644 --- a/scene/resources/default_theme/graph_node_breakpoint.png +++ b/scene/resources/default_theme/graph_node_breakpoint.png diff --git a/scene/resources/default_theme/graph_node_close.png b/scene/resources/default_theme/graph_node_close.png Binary files differindex 144a8b9c4c..5c962ae1c6 100644 --- a/scene/resources/default_theme/graph_node_close.png +++ b/scene/resources/default_theme/graph_node_close.png diff --git a/scene/resources/default_theme/graph_node_comment.png b/scene/resources/default_theme/graph_node_comment.png Binary files differindex f2d6daa259..cdec1d1eac 100644 --- a/scene/resources/default_theme/graph_node_comment.png +++ b/scene/resources/default_theme/graph_node_comment.png diff --git a/scene/resources/default_theme/graph_node_comment_focus.png b/scene/resources/default_theme/graph_node_comment_focus.png Binary files differindex a4b7b5a618..472a6b6f53 100644 --- a/scene/resources/default_theme/graph_node_comment_focus.png +++ b/scene/resources/default_theme/graph_node_comment_focus.png diff --git a/scene/resources/default_theme/graph_node_default.png b/scene/resources/default_theme/graph_node_default.png Binary files differindex e3a220301f..359bbdc205 100644 --- a/scene/resources/default_theme/graph_node_default.png +++ b/scene/resources/default_theme/graph_node_default.png diff --git a/scene/resources/default_theme/graph_node_default_focus.png b/scene/resources/default_theme/graph_node_default_focus.png Binary files differindex 9972b07593..204dd16ac0 100644 --- a/scene/resources/default_theme/graph_node_default_focus.png +++ b/scene/resources/default_theme/graph_node_default_focus.png diff --git a/scene/resources/default_theme/graph_node_position.png b/scene/resources/default_theme/graph_node_position.png Binary files differindex 7ec15e2ff4..24c2759be6 100644 --- a/scene/resources/default_theme/graph_node_position.png +++ b/scene/resources/default_theme/graph_node_position.png diff --git a/scene/resources/default_theme/graph_node_selected.png b/scene/resources/default_theme/graph_node_selected.png Binary files differindex f76c9703dd..cc4eb7f753 100644 --- a/scene/resources/default_theme/graph_node_selected.png +++ b/scene/resources/default_theme/graph_node_selected.png diff --git a/scene/resources/default_theme/graph_port.png b/scene/resources/default_theme/graph_port.png Binary files differindex 9d5082cfdb..f33ae3baf3 100644 --- a/scene/resources/default_theme/graph_port.png +++ b/scene/resources/default_theme/graph_port.png diff --git a/scene/resources/default_theme/hseparator.png b/scene/resources/default_theme/hseparator.png Binary files differindex 99609ac118..d4fd71ace5 100644 --- a/scene/resources/default_theme/hseparator.png +++ b/scene/resources/default_theme/hseparator.png diff --git a/scene/resources/default_theme/hslider_bg.png b/scene/resources/default_theme/hslider_bg.png Binary files differindex 9c2a2df62a..b402bd370d 100644 --- a/scene/resources/default_theme/hslider_bg.png +++ b/scene/resources/default_theme/hslider_bg.png diff --git a/scene/resources/default_theme/hslider_grabber.png b/scene/resources/default_theme/hslider_grabber.png Binary files differindex 2acd33879a..d273b491ee 100644 --- a/scene/resources/default_theme/hslider_grabber.png +++ b/scene/resources/default_theme/hslider_grabber.png diff --git a/scene/resources/default_theme/hslider_grabber_disabled.png b/scene/resources/default_theme/hslider_grabber_disabled.png Binary files differindex 0d75182b8f..dddd1a468e 100644 --- a/scene/resources/default_theme/hslider_grabber_disabled.png +++ b/scene/resources/default_theme/hslider_grabber_disabled.png diff --git a/scene/resources/default_theme/hslider_grabber_hl.png b/scene/resources/default_theme/hslider_grabber_hl.png Binary files differindex f8a011e64b..e3defb3610 100644 --- a/scene/resources/default_theme/hslider_grabber_hl.png +++ b/scene/resources/default_theme/hslider_grabber_hl.png diff --git a/scene/resources/default_theme/hslider_tick.png b/scene/resources/default_theme/hslider_tick.png Binary files differindex f7afd78529..1ba19c37a1 100644 --- a/scene/resources/default_theme/hslider_tick.png +++ b/scene/resources/default_theme/hslider_tick.png diff --git a/scene/resources/default_theme/hsplit_bg.png b/scene/resources/default_theme/hsplit_bg.png Binary files differindex 7dd1d48b29..a5749f6d5c 100644 --- a/scene/resources/default_theme/hsplit_bg.png +++ b/scene/resources/default_theme/hsplit_bg.png diff --git a/scene/resources/default_theme/hsplitter.png b/scene/resources/default_theme/hsplitter.png Binary files differindex 71a3914d7e..2287753c9d 100644 --- a/scene/resources/default_theme/hsplitter.png +++ b/scene/resources/default_theme/hsplitter.png diff --git a/scene/resources/default_theme/icon_add.png b/scene/resources/default_theme/icon_add.png Binary files differindex fa675045bc..eccb69b363 100644 --- a/scene/resources/default_theme/icon_add.png +++ b/scene/resources/default_theme/icon_add.png diff --git a/scene/resources/default_theme/icon_close.png b/scene/resources/default_theme/icon_close.png Binary files differindex 5ac6357dcd..4d4ac4a551 100644 --- a/scene/resources/default_theme/icon_close.png +++ b/scene/resources/default_theme/icon_close.png diff --git a/scene/resources/default_theme/icon_color_pick.png b/scene/resources/default_theme/icon_color_pick.png Binary files differindex 15679a9558..46953febb8 100644 --- a/scene/resources/default_theme/icon_color_pick.png +++ b/scene/resources/default_theme/icon_color_pick.png diff --git a/scene/resources/default_theme/icon_folder.png b/scene/resources/default_theme/icon_folder.png Binary files differindex cc05e98ebb..d1b308e88d 100644 --- a/scene/resources/default_theme/icon_folder.png +++ b/scene/resources/default_theme/icon_folder.png diff --git a/scene/resources/default_theme/icon_parent_folder.png b/scene/resources/default_theme/icon_parent_folder.png Binary files differindex 47fee1ad81..35d218722e 100644 --- a/scene/resources/default_theme/icon_parent_folder.png +++ b/scene/resources/default_theme/icon_parent_folder.png diff --git a/scene/resources/default_theme/icon_play.png b/scene/resources/default_theme/icon_play.png Binary files differindex 864e4e4fb9..b9ed6e6d5b 100644 --- a/scene/resources/default_theme/icon_play.png +++ b/scene/resources/default_theme/icon_play.png diff --git a/scene/resources/default_theme/icon_reload.png b/scene/resources/default_theme/icon_reload.png Binary files differindex 9303fabb9c..bec5f3f4f9 100644 --- a/scene/resources/default_theme/icon_reload.png +++ b/scene/resources/default_theme/icon_reload.png diff --git a/scene/resources/default_theme/icon_snap_grid.png b/scene/resources/default_theme/icon_snap_grid.png Binary files differindex 44db9bdfdc..0680317d86 100644 --- a/scene/resources/default_theme/icon_snap_grid.png +++ b/scene/resources/default_theme/icon_snap_grid.png diff --git a/scene/resources/default_theme/icon_stop.png b/scene/resources/default_theme/icon_stop.png Binary files differindex 1f194d0e14..0c1371ceb9 100644 --- a/scene/resources/default_theme/icon_stop.png +++ b/scene/resources/default_theme/icon_stop.png diff --git a/scene/resources/default_theme/icon_zoom_less.png b/scene/resources/default_theme/icon_zoom_less.png Binary files differindex 888ddc995d..03119c60ca 100644 --- a/scene/resources/default_theme/icon_zoom_less.png +++ b/scene/resources/default_theme/icon_zoom_less.png diff --git a/scene/resources/default_theme/icon_zoom_more.png b/scene/resources/default_theme/icon_zoom_more.png Binary files differindex fa675045bc..31467ec3de 100644 --- a/scene/resources/default_theme/icon_zoom_more.png +++ b/scene/resources/default_theme/icon_zoom_more.png diff --git a/scene/resources/default_theme/icon_zoom_reset.png b/scene/resources/default_theme/icon_zoom_reset.png Binary files differindex 953ae47d24..cac68c09fa 100644 --- a/scene/resources/default_theme/icon_zoom_reset.png +++ b/scene/resources/default_theme/icon_zoom_reset.png diff --git a/scene/resources/default_theme/line_edit.png b/scene/resources/default_theme/line_edit.png Binary files differindex bf2b91f1be..2b0c506f34 100644 --- a/scene/resources/default_theme/line_edit.png +++ b/scene/resources/default_theme/line_edit.png diff --git a/scene/resources/default_theme/line_edit_disabled.png b/scene/resources/default_theme/line_edit_disabled.png Binary files differindex a0fa505e4c..69d78febd9 100644 --- a/scene/resources/default_theme/line_edit_disabled.png +++ b/scene/resources/default_theme/line_edit_disabled.png diff --git a/scene/resources/default_theme/line_edit_focus.png b/scene/resources/default_theme/line_edit_focus.png Binary files differindex e66d7b60e3..1d74b74068 100644 --- a/scene/resources/default_theme/line_edit_focus.png +++ b/scene/resources/default_theme/line_edit_focus.png diff --git a/scene/resources/default_theme/logo.png b/scene/resources/default_theme/logo.png Binary files differindex 2161402438..d0ef9d8aa7 100644 --- a/scene/resources/default_theme/logo.png +++ b/scene/resources/default_theme/logo.png diff --git a/scene/resources/default_theme/mini_checkerboard.png b/scene/resources/default_theme/mini_checkerboard.png Binary files differindex 3e53183847..d8279bda80 100644 --- a/scene/resources/default_theme/mini_checkerboard.png +++ b/scene/resources/default_theme/mini_checkerboard.png diff --git a/scene/resources/default_theme/option_arrow.png b/scene/resources/default_theme/option_arrow.png Binary files differindex 007de16bfa..40590fd60a 100644 --- a/scene/resources/default_theme/option_arrow.png +++ b/scene/resources/default_theme/option_arrow.png diff --git a/scene/resources/default_theme/option_button_disabled.png b/scene/resources/default_theme/option_button_disabled.png Binary files differindex ce727d56e1..1961b673cd 100644 --- a/scene/resources/default_theme/option_button_disabled.png +++ b/scene/resources/default_theme/option_button_disabled.png diff --git a/scene/resources/default_theme/option_button_focus.png b/scene/resources/default_theme/option_button_focus.png Binary files differindex c76d91287e..402670f9a2 100644 --- a/scene/resources/default_theme/option_button_focus.png +++ b/scene/resources/default_theme/option_button_focus.png diff --git a/scene/resources/default_theme/option_button_hover.png b/scene/resources/default_theme/option_button_hover.png Binary files differindex fd1e987ceb..826fe1c9ca 100644 --- a/scene/resources/default_theme/option_button_hover.png +++ b/scene/resources/default_theme/option_button_hover.png diff --git a/scene/resources/default_theme/option_button_normal.png b/scene/resources/default_theme/option_button_normal.png Binary files differindex 9d7fb98d1c..2dadb40338 100644 --- a/scene/resources/default_theme/option_button_normal.png +++ b/scene/resources/default_theme/option_button_normal.png diff --git a/scene/resources/default_theme/option_button_pressed.png b/scene/resources/default_theme/option_button_pressed.png Binary files differindex 28b1d93468..68796f9d85 100644 --- a/scene/resources/default_theme/option_button_pressed.png +++ b/scene/resources/default_theme/option_button_pressed.png diff --git a/scene/resources/default_theme/panel_bg.png b/scene/resources/default_theme/panel_bg.png Binary files differindex 320819ad6d..b496e2177e 100644 --- a/scene/resources/default_theme/panel_bg.png +++ b/scene/resources/default_theme/panel_bg.png diff --git a/scene/resources/default_theme/popup_bg.png b/scene/resources/default_theme/popup_bg.png Binary files differindex 63f5994441..023029f936 100644 --- a/scene/resources/default_theme/popup_bg.png +++ b/scene/resources/default_theme/popup_bg.png diff --git a/scene/resources/default_theme/popup_bg_disabled.png b/scene/resources/default_theme/popup_bg_disabled.png Binary files differindex 611d949380..8eab5f27bc 100644 --- a/scene/resources/default_theme/popup_bg_disabled.png +++ b/scene/resources/default_theme/popup_bg_disabled.png diff --git a/scene/resources/default_theme/popup_checked.png b/scene/resources/default_theme/popup_checked.png Binary files differindex a24e0543c0..b7b05640e1 100644 --- a/scene/resources/default_theme/popup_checked.png +++ b/scene/resources/default_theme/popup_checked.png diff --git a/scene/resources/default_theme/popup_hover.png b/scene/resources/default_theme/popup_hover.png Binary files differindex 85d4e48475..bdb6ae8bd0 100644 --- a/scene/resources/default_theme/popup_hover.png +++ b/scene/resources/default_theme/popup_hover.png diff --git a/scene/resources/default_theme/popup_unchecked.png b/scene/resources/default_theme/popup_unchecked.png Binary files differindex c1137e6fbf..ff922335c3 100644 --- a/scene/resources/default_theme/popup_unchecked.png +++ b/scene/resources/default_theme/popup_unchecked.png diff --git a/scene/resources/default_theme/popup_window.png b/scene/resources/default_theme/popup_window.png Binary files differindex 59362a8ffd..174a29ef45 100644 --- a/scene/resources/default_theme/popup_window.png +++ b/scene/resources/default_theme/popup_window.png diff --git a/scene/resources/default_theme/progress_bar.png b/scene/resources/default_theme/progress_bar.png Binary files differindex bf81e3adea..057557e567 100644 --- a/scene/resources/default_theme/progress_bar.png +++ b/scene/resources/default_theme/progress_bar.png diff --git a/scene/resources/default_theme/progress_fill.png b/scene/resources/default_theme/progress_fill.png Binary files differindex 3a34dfdda6..e39bb2a021 100644 --- a/scene/resources/default_theme/progress_fill.png +++ b/scene/resources/default_theme/progress_fill.png diff --git a/scene/resources/default_theme/radio_checked.png b/scene/resources/default_theme/radio_checked.png Binary files differindex 95d472022f..0ce575c15f 100644 --- a/scene/resources/default_theme/radio_checked.png +++ b/scene/resources/default_theme/radio_checked.png diff --git a/scene/resources/default_theme/radio_unchecked.png b/scene/resources/default_theme/radio_unchecked.png Binary files differindex 7f0535c3a4..fe5bcf6ab1 100644 --- a/scene/resources/default_theme/radio_unchecked.png +++ b/scene/resources/default_theme/radio_unchecked.png diff --git a/scene/resources/default_theme/reference_border.png b/scene/resources/default_theme/reference_border.png Binary files differindex 96219676bf..6a680f393c 100644 --- a/scene/resources/default_theme/reference_border.png +++ b/scene/resources/default_theme/reference_border.png diff --git a/scene/resources/default_theme/scroll_bg.png b/scene/resources/default_theme/scroll_bg.png Binary files differindex cefadb2c08..fb151a48b1 100644 --- a/scene/resources/default_theme/scroll_bg.png +++ b/scene/resources/default_theme/scroll_bg.png diff --git a/scene/resources/default_theme/scroll_button_down.png b/scene/resources/default_theme/scroll_button_down.png Binary files differindex caeac9b286..1df4ef5b6b 100644 --- a/scene/resources/default_theme/scroll_button_down.png +++ b/scene/resources/default_theme/scroll_button_down.png diff --git a/scene/resources/default_theme/scroll_button_down_hl.png b/scene/resources/default_theme/scroll_button_down_hl.png Binary files differindex 48036e0297..ba79087393 100644 --- a/scene/resources/default_theme/scroll_button_down_hl.png +++ b/scene/resources/default_theme/scroll_button_down_hl.png diff --git a/scene/resources/default_theme/scroll_button_left.png b/scene/resources/default_theme/scroll_button_left.png Binary files differindex 3b50938d97..e430cb4673 100644 --- a/scene/resources/default_theme/scroll_button_left.png +++ b/scene/resources/default_theme/scroll_button_left.png diff --git a/scene/resources/default_theme/scroll_button_left_hl.png b/scene/resources/default_theme/scroll_button_left_hl.png Binary files differindex b3d348c24f..2a6ef17a34 100644 --- a/scene/resources/default_theme/scroll_button_left_hl.png +++ b/scene/resources/default_theme/scroll_button_left_hl.png diff --git a/scene/resources/default_theme/scroll_button_right.png b/scene/resources/default_theme/scroll_button_right.png Binary files differindex 1c622a41ad..4f61687aa4 100644 --- a/scene/resources/default_theme/scroll_button_right.png +++ b/scene/resources/default_theme/scroll_button_right.png diff --git a/scene/resources/default_theme/scroll_button_right_hl.png b/scene/resources/default_theme/scroll_button_right_hl.png Binary files differindex 108796ca02..10e2722509 100644 --- a/scene/resources/default_theme/scroll_button_right_hl.png +++ b/scene/resources/default_theme/scroll_button_right_hl.png diff --git a/scene/resources/default_theme/scroll_button_up.png b/scene/resources/default_theme/scroll_button_up.png Binary files differindex 2c8238ae4c..f425412f50 100644 --- a/scene/resources/default_theme/scroll_button_up.png +++ b/scene/resources/default_theme/scroll_button_up.png diff --git a/scene/resources/default_theme/scroll_button_up_hl.png b/scene/resources/default_theme/scroll_button_up_hl.png Binary files differindex 4283bd114a..615a236c52 100644 --- a/scene/resources/default_theme/scroll_button_up_hl.png +++ b/scene/resources/default_theme/scroll_button_up_hl.png diff --git a/scene/resources/default_theme/scroll_grabber.png b/scene/resources/default_theme/scroll_grabber.png Binary files differindex 1d625a9b7b..732725a28f 100644 --- a/scene/resources/default_theme/scroll_grabber.png +++ b/scene/resources/default_theme/scroll_grabber.png diff --git a/scene/resources/default_theme/scroll_grabber_hl.png b/scene/resources/default_theme/scroll_grabber_hl.png Binary files differindex 99eb24b7e7..006cfa3361 100644 --- a/scene/resources/default_theme/scroll_grabber_hl.png +++ b/scene/resources/default_theme/scroll_grabber_hl.png diff --git a/scene/resources/default_theme/scroll_grabber_pressed.png b/scene/resources/default_theme/scroll_grabber_pressed.png Binary files differindex a46d242ddd..f4886158fa 100644 --- a/scene/resources/default_theme/scroll_grabber_pressed.png +++ b/scene/resources/default_theme/scroll_grabber_pressed.png diff --git a/scene/resources/default_theme/selection.png b/scene/resources/default_theme/selection.png Binary files differindex 501877a8b4..7d1c985b35 100644 --- a/scene/resources/default_theme/selection.png +++ b/scene/resources/default_theme/selection.png diff --git a/scene/resources/default_theme/selection_oof.png b/scene/resources/default_theme/selection_oof.png Binary files differindex 9594fe0913..2da0538389 100644 --- a/scene/resources/default_theme/selection_oof.png +++ b/scene/resources/default_theme/selection_oof.png diff --git a/scene/resources/default_theme/spinbox_updown.png b/scene/resources/default_theme/spinbox_updown.png Binary files differindex b40b1e9fd2..74fab19f34 100644 --- a/scene/resources/default_theme/spinbox_updown.png +++ b/scene/resources/default_theme/spinbox_updown.png diff --git a/scene/resources/default_theme/submenu.png b/scene/resources/default_theme/submenu.png Binary files differindex ec727eecf1..8f7de446d4 100644 --- a/scene/resources/default_theme/submenu.png +++ b/scene/resources/default_theme/submenu.png diff --git a/scene/resources/default_theme/tab.png b/scene/resources/default_theme/tab.png Binary files differindex 3e4d792a48..895daa65e2 100644 --- a/scene/resources/default_theme/tab.png +++ b/scene/resources/default_theme/tab.png diff --git a/scene/resources/default_theme/tab_behind.png b/scene/resources/default_theme/tab_behind.png Binary files differindex 12f07c3a91..2803d9db65 100644 --- a/scene/resources/default_theme/tab_behind.png +++ b/scene/resources/default_theme/tab_behind.png diff --git a/scene/resources/default_theme/tab_close.png b/scene/resources/default_theme/tab_close.png Binary files differindex 20d9b5c810..af2775a132 100644 --- a/scene/resources/default_theme/tab_close.png +++ b/scene/resources/default_theme/tab_close.png diff --git a/scene/resources/default_theme/tab_container_bg.png b/scene/resources/default_theme/tab_container_bg.png Binary files differindex 92482aaf28..7d0bd16221 100644 --- a/scene/resources/default_theme/tab_container_bg.png +++ b/scene/resources/default_theme/tab_container_bg.png diff --git a/scene/resources/default_theme/tab_current.png b/scene/resources/default_theme/tab_current.png Binary files differindex 7289e032da..520d147217 100644 --- a/scene/resources/default_theme/tab_current.png +++ b/scene/resources/default_theme/tab_current.png diff --git a/scene/resources/default_theme/tab_menu.png b/scene/resources/default_theme/tab_menu.png Binary files differindex 148b64b8aa..fa4421a28a 100644 --- a/scene/resources/default_theme/tab_menu.png +++ b/scene/resources/default_theme/tab_menu.png diff --git a/scene/resources/default_theme/tab_menu_hl.png b/scene/resources/default_theme/tab_menu_hl.png Binary files differindex 148b64b8aa..fa4421a28a 100644 --- a/scene/resources/default_theme/tab_menu_hl.png +++ b/scene/resources/default_theme/tab_menu_hl.png diff --git a/scene/resources/default_theme/toggle_off.png b/scene/resources/default_theme/toggle_off.png Binary files differindex 71cd64b001..64b51c8c9d 100644 --- a/scene/resources/default_theme/toggle_off.png +++ b/scene/resources/default_theme/toggle_off.png diff --git a/scene/resources/default_theme/toggle_on.png b/scene/resources/default_theme/toggle_on.png Binary files differindex 6ea1b589c7..f0c699c181 100644 --- a/scene/resources/default_theme/toggle_on.png +++ b/scene/resources/default_theme/toggle_on.png diff --git a/scene/resources/default_theme/tool_button_pressed.png b/scene/resources/default_theme/tool_button_pressed.png Binary files differindex bcf70b486d..5494475792 100644 --- a/scene/resources/default_theme/tool_button_pressed.png +++ b/scene/resources/default_theme/tool_button_pressed.png diff --git a/scene/resources/default_theme/tooltip_bg.png b/scene/resources/default_theme/tooltip_bg.png Binary files differindex eca0675a98..07b7d942ca 100644 --- a/scene/resources/default_theme/tooltip_bg.png +++ b/scene/resources/default_theme/tooltip_bg.png diff --git a/scene/resources/default_theme/tree_bg.png b/scene/resources/default_theme/tree_bg.png Binary files differindex 839a6a272a..2b0c506f34 100644 --- a/scene/resources/default_theme/tree_bg.png +++ b/scene/resources/default_theme/tree_bg.png diff --git a/scene/resources/default_theme/tree_bg_disabled.png b/scene/resources/default_theme/tree_bg_disabled.png Binary files differindex a0fa505e4c..69d78febd9 100644 --- a/scene/resources/default_theme/tree_bg_disabled.png +++ b/scene/resources/default_theme/tree_bg_disabled.png diff --git a/scene/resources/default_theme/tree_bg_focus.png b/scene/resources/default_theme/tree_bg_focus.png Binary files differindex 692cf71926..aadc6b0db4 100644 --- a/scene/resources/default_theme/tree_bg_focus.png +++ b/scene/resources/default_theme/tree_bg_focus.png diff --git a/scene/resources/default_theme/tree_cursor.png b/scene/resources/default_theme/tree_cursor.png Binary files differindex 94d2a08818..2b8722d066 100644 --- a/scene/resources/default_theme/tree_cursor.png +++ b/scene/resources/default_theme/tree_cursor.png diff --git a/scene/resources/default_theme/tree_cursor_unfocus.png b/scene/resources/default_theme/tree_cursor_unfocus.png Binary files differindex 3f023bbabe..bfaebbea85 100644 --- a/scene/resources/default_theme/tree_cursor_unfocus.png +++ b/scene/resources/default_theme/tree_cursor_unfocus.png diff --git a/scene/resources/default_theme/tree_title.png b/scene/resources/default_theme/tree_title.png Binary files differindex b0ddcffbbe..e5f3f49695 100644 --- a/scene/resources/default_theme/tree_title.png +++ b/scene/resources/default_theme/tree_title.png diff --git a/scene/resources/default_theme/tree_title_pressed.png b/scene/resources/default_theme/tree_title_pressed.png Binary files differindex 746d10039e..35e2bb3008 100644 --- a/scene/resources/default_theme/tree_title_pressed.png +++ b/scene/resources/default_theme/tree_title_pressed.png diff --git a/scene/resources/default_theme/unchecked.png b/scene/resources/default_theme/unchecked.png Binary files differindex d6f790cbc2..8c818af755 100644 --- a/scene/resources/default_theme/unchecked.png +++ b/scene/resources/default_theme/unchecked.png diff --git a/scene/resources/default_theme/updown.png b/scene/resources/default_theme/updown.png Binary files differindex 916284a3cf..56f81921e8 100644 --- a/scene/resources/default_theme/updown.png +++ b/scene/resources/default_theme/updown.png diff --git a/scene/resources/default_theme/vseparator.png b/scene/resources/default_theme/vseparator.png Binary files differindex 498768c05b..51e79f3ac5 100644 --- a/scene/resources/default_theme/vseparator.png +++ b/scene/resources/default_theme/vseparator.png diff --git a/scene/resources/default_theme/vslider_bg.png b/scene/resources/default_theme/vslider_bg.png Binary files differindex 8d9ead3c5a..ba3244e3e5 100644 --- a/scene/resources/default_theme/vslider_bg.png +++ b/scene/resources/default_theme/vslider_bg.png diff --git a/scene/resources/default_theme/vslider_grabber.png b/scene/resources/default_theme/vslider_grabber.png Binary files differindex afc490be45..6c6bf93e68 100644 --- a/scene/resources/default_theme/vslider_grabber.png +++ b/scene/resources/default_theme/vslider_grabber.png diff --git a/scene/resources/default_theme/vslider_grabber_disabled.png b/scene/resources/default_theme/vslider_grabber_disabled.png Binary files differindex c830359f45..49cced5055 100644 --- a/scene/resources/default_theme/vslider_grabber_disabled.png +++ b/scene/resources/default_theme/vslider_grabber_disabled.png diff --git a/scene/resources/default_theme/vslider_grabber_hl.png b/scene/resources/default_theme/vslider_grabber_hl.png Binary files differindex 548972e115..28774fdbf8 100644 --- a/scene/resources/default_theme/vslider_grabber_hl.png +++ b/scene/resources/default_theme/vslider_grabber_hl.png diff --git a/scene/resources/default_theme/vslider_tick.png b/scene/resources/default_theme/vslider_tick.png Binary files differindex 873ebb00d8..bde788b563 100644 --- a/scene/resources/default_theme/vslider_tick.png +++ b/scene/resources/default_theme/vslider_tick.png diff --git a/scene/resources/default_theme/vsplit_bg.png b/scene/resources/default_theme/vsplit_bg.png Binary files differindex 7dd1d48b29..a5749f6d5c 100644 --- a/scene/resources/default_theme/vsplit_bg.png +++ b/scene/resources/default_theme/vsplit_bg.png diff --git a/scene/resources/default_theme/vsplitter.png b/scene/resources/default_theme/vsplitter.png Binary files differindex ec5542bf69..dde1f390df 100644 --- a/scene/resources/default_theme/vsplitter.png +++ b/scene/resources/default_theme/vsplitter.png diff --git a/scene/resources/default_theme/window_resizer.png b/scene/resources/default_theme/window_resizer.png Binary files differindex ed51968c4e..b06e6f5366 100644 --- a/scene/resources/default_theme/window_resizer.png +++ b/scene/resources/default_theme/window_resizer.png diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 43a225b370..b7abb07f43 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -1715,7 +1715,7 @@ void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInter float width = (2.0 * z_near) / camera_matrix.matrix[0][0]; float x_shift = width * camera_matrix.matrix[2][0]; float height = (2.0 * z_near) / camera_matrix.matrix[1][1]; - float y_shift = width * camera_matrix.matrix[2][1]; + float y_shift = height * camera_matrix.matrix[2][1]; // printf("Eye_dist = %f, Near = %f, Far = %f, Width = %f, Shift = %f\n", eye_dist, z_near, z_far, width, x_shift); @@ -1735,10 +1735,10 @@ void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInter float z_shift = (left_near / slope) - z_near; // - figure out new vertical near plane size (this will be slightly oversized thanks to our z-shift) - float top_near = (height + y_shift) * 0.5; - top_near += y_shift * z_shift; - float bottom_near = -(height - y_shift) * 0.5; - bottom_near -= y_shift * z_shift; + float top_near = (height - y_shift) * 0.5; + top_near += (top_near / z_near) * z_shift; + float bottom_near = -(height + y_shift) * 0.5; + bottom_near += (bottom_near / z_near) * z_shift; // printf("Left_near = %f, Left_far = %f, Top_near = %f, Bottom_near = %f, Z_shift = %f\n", left_near, left_far, top_near, bottom_near, z_shift); |