diff options
29 files changed, 600 insertions, 263 deletions
diff --git a/.gitignore b/.gitignore index 315dc7950f..d27b8b2b4b 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,8 @@ build/ bld/ [Bb]in/ [Oo]bj/ +*.debug +*.dSYM # MSTest test Results [Tt]est[Rr]esult*/ diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index be486a86a3..bc7ea47762 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -87,6 +87,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy path_found = true; //first match must have priority } else if (assign == "type") { r_path_and_type.type = value; + } else if (assign == "importer") { + r_path_and_type.importer = value; } else if (assign == "valid") { if (r_valid) { *r_valid = value; @@ -184,6 +186,29 @@ bool ResourceFormatImporter::can_be_imported(const String &p_path) const { return ResourceFormatLoader::recognize_path(p_path); } +int ResourceFormatImporter::get_import_order(const String &p_path) const { + + Ref<ResourceImporter> importer; + + if (FileAccess::exists(p_path + ".import")) { + + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err == OK) { + importer = get_importer_by_name(pat.importer); + } + } else { + + importer = get_importer_by_extension(p_path.get_extension().to_lower()); + } + + if (importer.is_valid()) + return importer->get_import_order(); + + return 0; +} + bool ResourceFormatImporter::handles_type(const String &p_type) const { for (Set<Ref<ResourceImporter> >::Element *E = importers.front(); E; E = E->next()) { @@ -291,7 +316,7 @@ void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> return ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types); } -Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) { +Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) const { for (Set<Ref<ResourceImporter> >::Element *E = importers.front(); E; E = E->next()) { if (E->get()->get_importer_name() == p_name) { @@ -315,7 +340,7 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi } } -Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) { +Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const { Ref<ResourceImporter> importer; float priority = 0; diff --git a/core/io/resource_import.h b/core/io/resource_import.h index b10255fbab..28489b5d34 100644 --- a/core/io/resource_import.h +++ b/core/io/resource_import.h @@ -38,6 +38,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { struct PathAndType { String path; String type; + String importer; }; Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const; @@ -58,14 +59,15 @@ public: virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual bool can_be_imported(const String &p_path) const; + virtual int get_import_order(const String &p_path) const; String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); void add_importer(const Ref<ResourceImporter> &p_importer) { importers.insert(p_importer); } void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } - Ref<ResourceImporter> get_importer_by_name(const String &p_name); - Ref<ResourceImporter> get_importer_by_extension(const String &p_extension); + Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; + Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const; void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers); String get_import_base_path(const String &p_for_file) const; @@ -82,6 +84,7 @@ public: virtual String get_save_extension() const = 0; virtual String get_resource_type() const = 0; virtual float get_priority() const { return 1.0; } + virtual int get_import_order() const { return 0; } struct ImportOption { PropertyInfo option; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 4f266df43e..89cb4a22c2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -308,6 +308,31 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l } } +int ResourceLoader::get_import_order(const String &p_path) { + + String path = _path_remap(p_path); + + String local_path; + if (path.is_rel_path()) + local_path = "res://" + path; + else + local_path = ProjectSettings::get_singleton()->localize_path(path); + + for (int i = 0; i < loader_count; i++) { + + if (!loader[i]->recognize_path(local_path)) + continue; + /* + if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) + continue; + */ + + return loader[i]->get_import_order(p_path); + } + + return 0; +} + bool ResourceLoader::is_import_valid(const String &p_path) { String path = _path_remap(p_path); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index a71a568569..5deffbca1a 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -67,6 +67,7 @@ public: virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map) { return OK; } virtual bool is_import_valid(const String &p_path) const { return true; } + virtual int get_import_order(const String &p_path) const { return 0; } virtual ~ResourceFormatLoader() {} }; @@ -110,6 +111,7 @@ public: static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); static bool is_import_valid(const String &p_path); + static int get_import_order(const String &p_path); static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; } diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 5d47936679..1c5a4ce8d0 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -164,50 +164,50 @@ bool Variant::booleanize() const { return; \ } -#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case INT: _RETURN(p_a._data.m_type m_op p_b._data._int); \ - case REAL: _RETURN(p_a._data.m_type m_op p_b._data._real); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \ + if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \ + \ + _RETURN_FAIL \ + }; + +#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \ + if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \ + if (p_b.type == NIL) _RETURN(!p_b.type m_op NIL); \ + \ + _RETURN_FAIL \ }; #ifdef DEBUG_ENABLED #define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \ CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case INT: { \ - if (p_b._data._int == 0) { \ - r_valid = false; \ - _RETURN("Division By Zero"); \ - } \ - _RETURN(p_a._data.m_type / p_b._data._int); \ + if (p_b.type == INT) { \ + if (p_b._data._int == 0) { \ + r_valid = false; \ + _RETURN("Division By Zero"); \ } \ - case REAL: { \ - if (p_b._data._real == 0) { \ - r_valid = false; \ - _RETURN("Division By Zero"); \ - } \ - _RETURN(p_a._data.m_type / p_b._data._real); \ + _RETURN(p_a._data.m_type / p_b._data._int); \ + } \ + if (p_b.type == REAL) { \ + if (p_b._data._real == 0) { \ + r_valid = false; \ + _RETURN("Division By Zero"); \ } \ - default: {} \ + _RETURN(p_a._data.m_type / p_b._data._real); \ } \ - r_valid = false; \ - return; \ + \ + _RETURN_FAIL \ }; #else -#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case INT: _RETURN(p_a._data.m_type / p_b._data._int); \ - case REAL: _RETURN(p_a._data.m_type / p_b._data._real); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == INT) _RETURN(p_a._data.m_type / p_b._data._int); \ + if (p_b.type == REAL) _RETURN(p_a._data.m_type / p_b._data._real); \ + \ + _RETURN_FAIL \ }; #endif @@ -221,55 +221,65 @@ bool Variant::booleanize() const { _RETURN(p_a._data.m_type); \ }; -#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case INT: _RETURN(p_a._data.m_type m_op p_b._data._int); \ - case REAL: _RETURN(p_a._data.m_type m_op p_b._data._real); \ - case VECTOR2: _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \ - case VECTOR3: _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \ + if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \ + if (p_b.type == VECTOR2) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \ + if (p_b.type == VECTOR3) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \ + \ + _RETURN_FAIL \ + }; + +#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \ + if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \ + \ + _RETURN_FAIL \ }; -#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case STRING: _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \ - case NODE_PATH: _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ + if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ + \ + _RETURN_FAIL \ }; -#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case STRING: _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ - case NODE_PATH: _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ + if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ + if (p_b.type == NIL) _RETURN(!p_b.type m_op NIL); \ + \ + _RETURN_FAIL \ }; #define DEFAULT_OP_LOCALMEM_REV(m_prefix, m_op_name, m_name, m_op, m_type) \ CASE_TYPE(m_prefix, m_op_name, m_name) { \ if (p_b.type == m_name) \ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const m_type *>(p_a._data._mem)); \ - r_valid = false; \ - return; \ + \ + _RETURN_FAIL \ }; #define DEFAULT_OP_LOCALMEM(m_prefix, m_op_name, m_name, m_op, m_type) \ CASE_TYPE(m_prefix, m_op_name, m_name) { \ if (p_b.type == m_name) \ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ - r_valid = false; \ - return; \ + \ + _RETURN_FAIL \ + }; + +#define DEFAULT_OP_LOCALMEM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == m_name) \ + _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ + if (p_b.type == NIL) \ + _RETURN(!p_b.type m_op NIL); \ + \ + _RETURN_FAIL \ }; #define DEFAULT_OP_LOCALMEM_NEG(m_prefix, m_op_name, m_name, m_type) \ @@ -282,38 +292,47 @@ bool Variant::booleanize() const { _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem)); \ } -#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - switch (p_b.type) { \ - case m_name: _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ - case INT: _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \ - case REAL: _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._real); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == m_name) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ + if (p_b.type == INT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \ + if (p_b.type == REAL) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._real); \ + \ + _RETURN_FAIL \ } -#define DEFAULT_OP_PTR(m_op, m_name, m_sub) \ - case m_name: { \ - switch (p_b.type) { \ - case m_name: _RETURN(p_a._data.m_sub m_op p_b._data.m_sub); \ - default: {} \ - } \ - r_valid = false; \ - return; \ +#define DEFAULT_OP_PTR(m_op, m_name, m_sub) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == m_name) \ + _RETURN(p_a._data.m_sub m_op p_b._data.m_sub); \ + \ + _RETURN_FAIL \ } #define DEFAULT_OP_PTRREF(m_prefix, m_op_name, m_name, m_op, m_sub) \ CASE_TYPE(m_prefix, m_op_name, m_name) { \ if (p_b.type == m_name) \ _RETURN(*p_a._data.m_sub m_op *p_b._data.m_sub); \ - r_valid = false; \ - return; \ + \ + _RETURN_FAIL \ } -#define DEFAULT_OP_ARRAY_EQ(m_prefix, m_op_name, m_name, m_type) \ - DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, !=, !=, true, false, false) +#define DEFAULT_OP_PTRREF_NULL(m_prefix, m_op_name, m_name, m_op, m_sub) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == m_name) \ + _RETURN(*p_a._data.m_sub m_op *p_b._data.m_sub); \ + if (p_b.type == NIL) \ + _RETURN(!p_b.type m_op NIL); \ + \ + _RETURN_FAIL \ + } + +#define DEFAULT_OP_ARRAY_EQ(m_prefix, m_op_name, m_name, m_type) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + if (p_b.type == NIL) \ + _RETURN(false) \ + DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, !=, !=, true, false, false) \ + } #define DEFAULT_OP_ARRAY_LT(m_prefix, m_op_name, m_name, m_type) \ DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, <, !=, false, a_len < array_b.size(), true) @@ -321,38 +340,39 @@ bool Variant::booleanize() const { #define DEFAULT_OP_ARRAY_GT(m_prefix, m_op_name, m_name, m_type) \ DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, >, !=, false, a_len < array_b.size(), true) -#define DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ - CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_a.type != p_b.type) { \ - r_valid = false; \ - return; \ - } \ - const PoolVector<m_type> &array_a = *reinterpret_cast<const PoolVector<m_type> *>(p_a._data._mem); \ - const PoolVector<m_type> &array_b = *reinterpret_cast<const PoolVector<m_type> *>(p_b._data._mem); \ - \ - int a_len = array_a.size(); \ - if (a_len m_opa array_b.size()) { \ - _RETURN(m_ret_s); \ - } else { \ - \ - PoolVector<m_type>::Read ra = array_a.read(); \ - PoolVector<m_type>::Read rb = array_b.read(); \ - \ - for (int i = 0; i < a_len; i++) { \ - if (ra[i] m_opb rb[i]) \ - _RETURN(m_ret_f); \ - } \ - \ - _RETURN(m_ret_def); \ - } \ +#define DEFAULT_OP_ARRAY_OP(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ + CASE_TYPE(m_prefix, m_op_name, m_name) { \ + DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ + } + +#define DEFAULT_OP_ARRAY_OP_BODY(m_prefix, m_op_name, m_name, m_type, m_opa, m_opb, m_ret_def, m_ret_s, m_ret_f) \ + if (p_a.type != p_b.type) \ + _RETURN_FAIL \ + \ + const PoolVector<m_type> &array_a = *reinterpret_cast<const PoolVector<m_type> *>(p_a._data._mem); \ + const PoolVector<m_type> &array_b = *reinterpret_cast<const PoolVector<m_type> *>(p_b._data._mem); \ + \ + int a_len = array_a.size(); \ + if (a_len m_opa array_b.size()) { \ + _RETURN(m_ret_s); \ + } else { \ + \ + PoolVector<m_type>::Read ra = array_a.read(); \ + PoolVector<m_type>::Read rb = array_b.read(); \ + \ + for (int i = 0; i < a_len; i++) { \ + if (ra[i] m_opb rb[i]) \ + _RETURN(m_ret_f); \ + } \ + \ + _RETURN(m_ret_def); \ } #define DEFAULT_OP_ARRAY_ADD(m_prefix, m_op_name, m_name, m_type) \ CASE_TYPE(m_prefix, m_op_name, m_name) { \ - if (p_a.type != p_b.type) { \ - r_valid = false; \ - _RETURN(NIL); \ - } \ + if (p_a.type != p_b.type) \ + _RETURN_FAIL; \ + \ const PoolVector<m_type> &array_a = *reinterpret_cast<const PoolVector<m_type> *>(p_a._data._mem); \ const PoolVector<m_type> &array_b = *reinterpret_cast<const PoolVector<m_type> *>(p_b._data._mem); \ PoolVector<m_type> sum = array_a; \ @@ -372,12 +392,17 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, if (p_b.type == NIL) _RETURN(true); if (p_b.type == OBJECT) _RETURN(p_b._get_obj().obj == NULL); - _RETURN_FAIL; + + _RETURN(false); } CASE_TYPE(math, OP_EQUAL, BOOL) { - if (p_b.type != BOOL) + if (p_b.type != BOOL) { + if (p_b.type == NIL) + _RETURN(false); _RETURN_FAIL; + } + _RETURN(p_a._data._bool == p_b._data._bool); } @@ -386,12 +411,16 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, _RETURN((p_a._get_obj().obj == p_b._get_obj().obj)); if (p_b.type == NIL) _RETURN(p_a._get_obj().obj == NULL); + _RETURN_FAIL; } CASE_TYPE(math, OP_EQUAL, DICTIONARY) { - if (p_b.type != DICTIONARY) + if (p_b.type != DICTIONARY) { + if (p_b.type == NIL) + _RETURN(false); _RETURN_FAIL; + } const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem); const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem); @@ -400,9 +429,11 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, } CASE_TYPE(math, OP_EQUAL, ARRAY) { - if (p_b.type != ARRAY) + if (p_b.type != ARRAY) { + if (p_b.type == NIL) + _RETURN(false); _RETURN_FAIL; - + } const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem); const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem); @@ -418,21 +449,21 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, _RETURN(true); } - DEFAULT_OP_NUM(math, OP_EQUAL, INT, ==, _int); - DEFAULT_OP_NUM(math, OP_EQUAL, REAL, ==, _real); - DEFAULT_OP_STR(math, OP_EQUAL, STRING, ==, String); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, VECTOR2, ==, Vector2); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, RECT2, ==, Rect2); - DEFAULT_OP_PTRREF(math, OP_EQUAL, TRANSFORM2D, ==, _transform2d); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, VECTOR3, ==, Vector3); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, PLANE, ==, Plane); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, QUAT, ==, Quat); - DEFAULT_OP_PTRREF(math, OP_EQUAL, RECT3, ==, _rect3); - DEFAULT_OP_PTRREF(math, OP_EQUAL, BASIS, ==, _basis); - DEFAULT_OP_PTRREF(math, OP_EQUAL, TRANSFORM, ==, _transform); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, COLOR, ==, Color); - DEFAULT_OP_STR(math, OP_EQUAL, NODE_PATH, ==, NodePath); - DEFAULT_OP_LOCALMEM(math, OP_EQUAL, _RID, ==, RID); + DEFAULT_OP_NUM_NULL(math, OP_EQUAL, INT, ==, _int); + DEFAULT_OP_NUM_NULL(math, OP_EQUAL, REAL, ==, _real); + DEFAULT_OP_STR_NULL(math, OP_EQUAL, STRING, ==, String); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR2, ==, Vector2); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, RECT2, ==, Rect2); + DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM2D, ==, _transform2d); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3, ==, Vector3); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, PLANE, ==, Plane); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, QUAT, ==, Quat); + DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, RECT3, ==, _rect3); + DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, BASIS, ==, _basis); + DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM, ==, _transform); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, COLOR, ==, Color); + DEFAULT_OP_STR_NULL(math, OP_EQUAL, NODE_PATH, ==, NodePath); + DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, _RID, ==, RID); DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_BYTE_ARRAY, uint8_t); DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_INT_ARRAY, int); @@ -448,12 +479,18 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, if (p_b.type == NIL) _RETURN(false); if (p_b.type == OBJECT) _RETURN(p_b._get_obj().obj != NULL); - _RETURN_FAIL; + + _RETURN(true); } CASE_TYPE(math, OP_NOT_EQUAL, BOOL) { - if (p_b.type != BOOL) + if (p_b.type != BOOL) { + if (p_b.type == NIL) + _RETURN(true); + _RETURN_FAIL; + } + _RETURN(p_a._data._bool != p_b._data._bool); } @@ -462,12 +499,16 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, _RETURN((p_a._get_obj().obj != p_b._get_obj().obj)); if (p_b.type == NIL) _RETURN(p_a._get_obj().obj != NULL); + _RETURN_FAIL; } CASE_TYPE(math, OP_NOT_EQUAL, DICTIONARY) { - if (p_b.type != DICTIONARY) + if (p_b.type != DICTIONARY) { + if (p_b.type == NIL) + _RETURN(true); _RETURN_FAIL; + } const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem); const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem); @@ -476,8 +517,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, } CASE_TYPE(math, OP_NOT_EQUAL, ARRAY) { - if (p_b.type != ARRAY) + if (p_b.type != ARRAY) { + if (p_b.type == NIL) + _RETURN(true); + _RETURN_FAIL; + } const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem); const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem); @@ -494,21 +539,21 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, _RETURN(true); } - DEFAULT_OP_NUM(math, OP_NOT_EQUAL, INT, !=, _int); - DEFAULT_OP_NUM(math, OP_NOT_EQUAL, REAL, !=, _real); - DEFAULT_OP_STR(math, OP_NOT_EQUAL, STRING, !=, String); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, VECTOR2, !=, Vector2); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, RECT2, !=, Rect2); - DEFAULT_OP_PTRREF(math, OP_NOT_EQUAL, TRANSFORM2D, !=, _transform2d); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, VECTOR3, !=, Vector3); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, PLANE, !=, Plane); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, QUAT, !=, Quat); - DEFAULT_OP_PTRREF(math, OP_NOT_EQUAL, RECT3, !=, _rect3); - DEFAULT_OP_PTRREF(math, OP_NOT_EQUAL, BASIS, !=, _basis); - DEFAULT_OP_PTRREF(math, OP_NOT_EQUAL, TRANSFORM, !=, _transform); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, COLOR, !=, Color); - DEFAULT_OP_STR(math, OP_NOT_EQUAL, NODE_PATH, !=, NodePath); - DEFAULT_OP_LOCALMEM(math, OP_NOT_EQUAL, _RID, !=, RID); + DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, INT, !=, _int); + DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, REAL, !=, _real); + DEFAULT_OP_STR_NULL(math, OP_NOT_EQUAL, STRING, !=, String); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR2, !=, Vector2); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, RECT2, !=, Rect2); + DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM2D, !=, _transform2d); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3, !=, Vector3); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, PLANE, !=, Plane); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, QUAT, !=, Quat); + DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, RECT3, !=, _rect3); + DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, BASIS, !=, _basis); + DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM, !=, _transform); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, COLOR, !=, Color); + DEFAULT_OP_STR_NULL(math, OP_NOT_EQUAL, NODE_PATH, !=, NodePath); + DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, _RID, !=, RID); CASE_TYPE(math, OP_NOT_EQUAL, POOL_BYTE_ARRAY); CASE_TYPE(math, OP_NOT_EQUAL, POOL_INT_ARRAY); diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index 0ced30bda6..05319e926c 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -1,8 +1,54 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorImportPlugin" inherits="Reference" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Registers a custom resource importer in the editor. Use the class to parse any file and import it as a new resource type. </brief_description> <description> + EditorImportPlugins provide a way to extend the editor's resource import functionality. Use them to import resources from custom files or to provide alternatives to the editor's existing importers. Register your [EditorPlugin] with [method EditorPlugin.add_import_plugin]. + + EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extension] and [method get_resource_type]). They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].import[/code] directory. + + + Below is an example EditorImportPlugin that imports a [Mesh] from a file with the extension ".special" or ".spec": + [codeblock] + tool + extends EditorImportPlugin + + func get_importer_name(): + return "my.special.plugin" + + func get_visible_name(): + return "Special Mesh Importer" + + func get_recognized_extensions(): + return ["special", "spec"] + + func get_save_extension(): + return "mesh" + + func get_resource_type(): + return "Mesh" + + func get_preset_count(): + return 1 + + func get_preset_name(i): + return "Default" + + func get_import_optons(i): + return [{"name": "my_option", "default_value": false}] + + func load(src, dst, opts, r_platform_variants, r_gen_files): + var f = File.new() + if f.open(src, File.READ) != OK: + return FAILED + + var mesh = Mesh.new() + + var save = dst + "." + get_save_extension() + ResourceSaver.save(file, mesh) + return OK + [/codeblock] </description> <tutorials> </tutorials> @@ -15,12 +61,14 @@ <argument index="0" name="preset" type="int"> </argument> <description> + Get the options and default values for the preset at this index. Returns an Array of Dictionaries with the following keys: "name", "default_value", "property_hint" (optional), "hint_string" (optional), "usage" (optional). </description> </method> <method name="get_importer_name" qualifiers="virtual"> <return type="String"> </return> <description> + Get the unique name of the importer. </description> </method> <method name="get_option_visibility" qualifiers="virtual"> @@ -37,6 +85,7 @@ <return type="int"> </return> <description> + Get the number of initial presets defined by the plugin. Use [method get_import_options] to get the default options for the preset and [method get_preset_name] to get the name of the preset. </description> </method> <method name="get_preset_name" qualifiers="virtual"> @@ -45,30 +94,35 @@ <argument index="0" name="preset" type="int"> </argument> <description> + Get the name of the options preset at this index. </description> </method> <method name="get_recognized_extensions" qualifiers="virtual"> <return type="Array"> </return> <description> + Get the list of file extensions to associate with this loader (case insensitive). e.g. ["obj"]. </description> </method> <method name="get_resource_type" qualifiers="virtual"> <return type="String"> </return> <description> + Get the godot resource type associated with this loader. e.g. "Mesh" or "Animation". </description> </method> <method name="get_save_extension" qualifiers="virtual"> <return type="String"> </return> <description> + Get the extension used to save this resource in the [code].import[/code] directory. </description> </method> <method name="get_visible_name" qualifiers="virtual"> <return type="String"> </return> <description> + Get the name to display in the import window. </description> </method> <method name="import" qualifiers="virtual"> diff --git a/editor/collada/collada.cpp b/editor/collada/collada.cpp index 4986d97e8f..2d49840683 100644 --- a/editor/collada/collada.cpp +++ b/editor/collada/collada.cpp @@ -1918,7 +1918,7 @@ void Collada::_parse_animation(XMLParser &parser) { for (int j = 0; j < key_count; j++) { track.keys[j].data.resize(output_len); for (int k = 0; k < output_len; k++) - track.keys[j].data[k] = output[l + j * stride + k]; //super weird but should work + track.keys[j].data[k] = output[l + j * stride + k]; //super weird but should work: } if (sampler.has("INTERPOLATION")) { diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 6e12a8fd02..481f2a8179 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1498,10 +1498,22 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { importing = true; EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size()); + + Vector<ImportFile> files; + for (int i = 0; i < p_files.size(); i++) { - pr.step(p_files[i].get_file(), i); + ImportFile ifile; + ifile.path = p_files[i]; + ifile.order = ResourceFormatImporter::get_singleton()->get_import_order(p_files[i]); + files.push_back(ifile); + } + + files.sort(); + + for (int i = 0; i < files.size(); i++) { + pr.step(files[i].path.get_file(), i); - _reimport_file(p_files[i]); + _reimport_file(files[i].path); } _save_filesystem_cache(); diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index cee3219b43..ebcc091b0a 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -206,6 +206,14 @@ class EditorFileSystem : public Node { Vector<String> _get_dependencies(const String &p_path); + struct ImportFile { + String path; + int order; + bool operator<(const ImportFile &p_if) const { + return order < p_if.order; + } + }; + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index eb72fdf64b..4de1c32fe7 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -584,6 +584,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("interface/theme/border_size", 1); set("interface/theme/use_graph_node_headers", false); hints["interface/theme/border_size"] = PropertyInfo(Variant::INT, "interface/theme/border_size", PROPERTY_HINT_RANGE, "0,2,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + set("interface/theme/additional_spacing", 0); + hints["interface/theme/additional_spacing"] = PropertyInfo(Variant::REAL, "interface/theme/additional_spacing", PROPERTY_HINT_RANGE, "0,5,0.1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); set("interface/theme/custom_theme", ""); hints["interface/theme/custom_theme"] = PropertyInfo(Variant::STRING, "interface/theme/custom_theme", PROPERTY_HINT_GLOBAL_FILE, "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); @@ -663,35 +665,47 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("editors/3d/default_z_near", 0.1); set("editors/3d/default_z_far", 500.0); - set("editors/3d/navigation_scheme", 0); - hints["editors/3d/navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/navigation_scheme", PROPERTY_HINT_ENUM, "Godot,Maya,Modo"); - set("editors/3d/zoom_style", 0); - hints["editors/3d/zoom_style"] = PropertyInfo(Variant::INT, "editors/3d/zoom_style", PROPERTY_HINT_ENUM, "Vertical, Horizontal"); - set("editors/3d/orbit_modifier", 0); - hints["editors/3d/orbit_modifier"] = PropertyInfo(Variant::INT, "editors/3d/orbit_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); - set("editors/3d/pan_modifier", 1); - hints["editors/3d/pan_modifier"] = PropertyInfo(Variant::INT, "editors/3d/pan_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); - set("editors/3d/zoom_modifier", 4); - hints["editors/3d/zoom_modifier"] = PropertyInfo(Variant::INT, "editors/3d/zoom_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); - set("editors/3d/emulate_numpad", false); - set("editors/3d/emulate_3_button_mouse", false); - set("editors/3d/warped_mouse_panning", true); - - set("editors/3d/orbit_sensitivity", 0.4); - - set("editors/3d/orbit_inertia", 0.2); - hints["editors/3d/orbit_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/orbit_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); - - set("editors/3d/freelook_inertia", 0.2); - hints["editors/3d/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); - - set("editors/3d/freelook_base_speed", 0.5); - hints["editors/3d/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.1"); - - set("editors/3d/freelook_activation_modifier", 0); - hints["editors/3d/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); - - set("editors/3d/freelook_modifier_speed_factor", 5.0); + // navigation + set("editors/3d/navigation/navigation_scheme", 0); + hints["editors/3d/navigation/navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/navigation/navigation_scheme", PROPERTY_HINT_ENUM, "Godot,Maya,Modo"); + set("editors/3d/navigation/zoom_style", 0); + hints["editors/3d/navigation/zoom_style"] = PropertyInfo(Variant::INT, "editors/3d/navigation/zoom_style", PROPERTY_HINT_ENUM, "Vertical, Horizontal"); + + set("editors/3d/navigation/emulate_3_button_mouse", false); + set("editors/3d/navigation/orbit_modifier", 3); + hints["editors/3d/navigation/orbit_modifier"] = PropertyInfo(Variant::INT, "editors/3d/navigation/orbit_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); + set("editors/3d/navigation/pan_modifier", 1); + hints["editors/3d/navigation/pan_modifier"] = PropertyInfo(Variant::INT, "editors/3d/navigation/pan_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); + set("editors/3d/navigation/zoom_modifier", 4); + hints["editors/3d/navigation/zoom_modifier"] = PropertyInfo(Variant::INT, "editors/3d/navigation/zoom_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); + + // set("editors/3d/navigation/emulate_numpad", false); not used at the moment + set("editors/3d/navigation/warped_mouse_panning", true); + + // navigation feel + set("editors/3d/navigation_feel/orbit_sensitivity", 0.4); + hints["editors/3d/navigation_feel/orbit_sensitivity"] = PropertyInfo(Variant::REAL, "editors/3d/navigation_feel/orbit_sensitivity", PROPERTY_HINT_RANGE, "0.0, 2, 0.01"); + + set("editors/3d/navigation_feel/orbit_inertia", 0.15); + hints["editors/3d/navigation_feel/orbit_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/navigation_feel/orbit_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + set("editors/3d/navigation_feel/translation_inertia", 0.15); + hints["editors/3d/navigation_feel/translation_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/navigation_feel/translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + set("editors/3d/navigation_feel/zoom_inertia", 0.1); + hints["editors/3d/navigation_feel/zoom_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/navigation_feel/zoom_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + set("editors/3d/navigation_feel/manipulation_orbit_inertia", 0.1); + hints["editors/3d/navigation_feel/manipulation_orbit_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/navigation_feel/manipulation_orbit_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + set("editors/3d/navigation_feel/manipulation_translation_inertia", 0.1); + hints["editors/3d/navigation_feel/manipulation_translation_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/navigation_feel/manipulation_translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + + // freelook + set("editors/3d/freelook/freelook_inertia", 0.1); + hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + set("editors/3d/freelook/freelook_base_speed", 0.5); + hints["editors/3d/freelook/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.1"); + set("editors/3d/freelook/freelook_activation_modifier", 0); + hints["editors/3d/freelook/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); + set("editors/3d/freelook/freelook_modifier_speed_factor", 3.0); + hints["editors/3d/freelook/freelook_modifier_speed_factor"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_modifier_speed_factor", PROPERTY_HINT_RANGE, "0.0, 10.0, 0.1"); set("editors/2d/bone_width", 5); set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9)); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 4aa1ccaa81..a4f2368794 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -345,11 +345,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_default->set_draw_center(true); // Button and widgets - Ref<StyleBoxFlat> style_widget = style_default->duplicate(); + const float extra_spacing = EDITOR_DEF("interface/theme/additional_spacing", 0.0); + Ref<StyleBoxFlat> style_widget = style_default->duplicate(); + style_widget->set_default_margin(MARGIN_LEFT, (extra_spacing + 6) * EDSCALE); + style_widget->set_default_margin(MARGIN_TOP, (extra_spacing + default_margin_size) * EDSCALE); + style_widget->set_default_margin(MARGIN_RIGHT, (extra_spacing + 6) * EDSCALE); + style_widget->set_default_margin(MARGIN_BOTTOM, (extra_spacing + default_margin_size) * EDSCALE); style_widget->set_bg_color(dark_color_1); - style_widget->set_default_margin(MARGIN_LEFT, 6 * EDSCALE); - style_widget->set_default_margin(MARGIN_RIGHT, 6 * EDSCALE); style_widget->set_border_color_all(dark_color_2); Ref<StyleBoxFlat> style_widget_disabled = style_widget->duplicate(); @@ -381,7 +384,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Tabs const int tab_default_margin_side = 10 * EDSCALE; - Ref<StyleBoxFlat> style_tab_selected = style_default->duplicate(); + Ref<StyleBoxFlat> style_tab_selected = style_widget->duplicate(); style_tab_selected->set_border_width_all(border_width); style_tab_selected->set_border_width(MARGIN_BOTTOM, 0); style_tab_selected->set_border_color_all(dark_color_3); @@ -404,7 +407,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("Focus", "EditorStyles", style_focus); // Menu - Ref<StyleBoxEmpty> style_menu = style_empty; + Ref<StyleBoxFlat> style_menu = style_widget->duplicate(); + style_menu->set_draw_center(false); + style_menu->set_border_width_all(0); theme->set_stylebox("panel", "PanelContainer", style_menu); theme->set_stylebox("MenuPanel", "EditorStyles", style_menu); @@ -416,13 +421,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("PlayButtonPanel", "EditorStyles", style_empty); //make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4)); //MenuButton - Ref<StyleBoxFlat> style_menu_hover_border = style_default->duplicate(); + Ref<StyleBoxFlat> style_menu_hover_border = style_widget->duplicate(); style_menu_hover_border->set_draw_center(false); style_menu_hover_border->set_border_width_all(0); style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width); style_menu_hover_border->set_border_color_all(accent_color); - Ref<StyleBoxFlat> style_menu_hover_bg = style_default->duplicate(); + Ref<StyleBoxFlat> style_menu_hover_bg = style_widget->duplicate(); style_menu_hover_bg->set_border_width_all(0); style_menu_hover_bg->set_bg_color(dark_color_1); @@ -517,7 +522,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons")); theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons")); - + theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size) * EDSCALE); // Tree & ItemList background Ref<StyleBoxFlat> style_tree_bg = style_default->duplicate(); style_tree_bg->set_bg_color(dark_color_1); @@ -537,6 +542,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("custom_button_font_highlight", "Tree", font_color_hl); theme->set_color("font_color", "Tree", font_color); theme->set_color("font_color_selected", "Tree", font_color); + theme->set_constant("vseparation", "Tree", (extra_spacing + default_margin_size) * EDSCALE); Ref<StyleBoxFlat> style_tree_btn = style_default->duplicate(); style_tree_btn->set_bg_color(contrast_color_1); @@ -592,7 +598,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("selected", "ItemList", style_tree_selected); theme->set_stylebox("bg_focus", "ItemList", style_focus); theme->set_stylebox("bg", "ItemList", style_itemlist_bg); - theme->set_constant("vseparation", "ItemList", 5 * EDSCALE); + theme->set_constant("vseparation", "ItemList", (extra_spacing + default_margin_size) * EDSCALE); theme->set_color("font_color", "ItemList", font_color); // Tabs & TabContainer @@ -840,6 +846,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("resizer", "GraphNode", theme->get_icon("GuiResizer", "EditorIcons")); theme->set_icon("port", "GraphNode", theme->get_icon("GuiGraphNodePort", "EditorIcons")); + // GridContainer + theme->set_constant("vseperation", "GridContainer", (extra_spacing + default_margin_size) * EDSCALE); + // FileDialog theme->set_color("files_disabled", "FileDialog", font_color_disabled); diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index b1991d755b..6ef1758363 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -381,6 +381,9 @@ Error ColladaImport::_create_material(const String &p_target) { String texfile = effect.get_texture_path(effect.diffuse.texture, collada); if (texfile != "") { + if (texfile.begins_with("/")) { + texfile = texfile.replace_first("/", "res://"); + } Ref<Texture> texture = ResourceLoader::load(texfile, "Texture"); if (texture.is_valid()) { @@ -402,6 +405,10 @@ Error ColladaImport::_create_material(const String &p_target) { String texfile = effect.get_texture_path(effect.specular.texture, collada); if (texfile != "") { + if (texfile.begins_with("/")) { + texfile = texfile.replace_first("/", "res://"); + } + Ref<Texture> texture = ResourceLoader::load(texfile, "Texture"); if (texture.is_valid()) { material->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture); @@ -425,6 +432,10 @@ Error ColladaImport::_create_material(const String &p_target) { String texfile = effect.get_texture_path(effect.emission.texture, collada); if (texfile != "") { + if (texfile.begins_with("/")) { + texfile = texfile.replace_first("/", "res://"); + } + Ref<Texture> texture = ResourceLoader::load(texfile, "Texture"); if (texture.is_valid()) { @@ -451,6 +462,10 @@ Error ColladaImport::_create_material(const String &p_target) { String texfile = effect.get_texture_path(effect.bump.texture, collada); if (texfile != "") { + if (texfile.begins_with("/")) { + texfile = texfile.replace_first("/", "res://"); + } + Ref<Texture> texture = ResourceLoader::load(texfile, "Texture"); if (texture.is_valid()) { material->set_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING, true); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index b448ab8920..6d5ff822ef 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -114,7 +114,7 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const } int ResourceImporterScene::get_preset_count() const { - return 6; + return PRESET_MAX; } String ResourceImporterScene::get_preset_name(int p_idx) const { @@ -955,9 +955,9 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in } bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS || p_preset == PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS; - bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS; + bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS; bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; - bool animations_out = p_preset == PRESET_SEPARATE_ANIMATIONS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS; + bool animations_out = p_preset == PRESET_SEPARATE_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS; r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0)); @@ -966,7 +966,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_on_reimport"), materials_out ? true : false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/compress"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? true : false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? 1 : 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index c3a66aa8b8..9c7e791719 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -96,6 +96,7 @@ class ResourceImporterScene : public ResourceImporter { PRESET_MULTIPLE_SCENES, PRESET_MULTIPLE_SCENES_AND_MATERIALS, + PRESET_MAX }; void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner); @@ -118,6 +119,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; + virtual int get_import_order() const { return 100; } //after everything void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 28de1ad940..bb25576007 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2577,6 +2577,8 @@ void CanvasItemEditor::_draw_bones() { } void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_xform) { + ERR_FAIL_COND(!p_node); + RID viewport_ci = viewport->get_canvas_item(); Transform2D transform_ci = p_xform; @@ -2605,6 +2607,8 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p } void CanvasItemEditor::_build_bones_list(Node *p_node) { + ERR_FAIL_COND(!p_node); + for (int i = 0; i < p_node->get_child_count(); i++) { _build_bones_list(p_node->get_child(i)); } @@ -2626,6 +2630,8 @@ void CanvasItemEditor::_build_bones_list(Node *p_node) { } void CanvasItemEditor::_get_encompassing_rect(Node *p_node, Rect2 &r_rect, const Transform2D &p_xform) { + ERR_FAIL_COND(!p_node); + for (int i = 0; i < p_node->get_child_count(); i++) { _get_encompassing_rect(p_node->get_child(i), r_rect, p_xform); } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 6b485aab7c..008dcac2c1 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -77,11 +77,13 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { camera->set_perspective(get_fov(), get_znear(), get_zfar()); //when not being manipulated, move softly - float free_orbit_inertia = EDITOR_DEF("editors/3d/free_orbit_inertia", 0.15); - float free_translation_inertia = EDITOR_DEF("editors/3d/free_translation_inertia", 0.15); + float free_orbit_inertia = EDITOR_DEF("editors/3d/navigation_feel/orbit_inertia", 0.15); + float free_translation_inertia = EDITOR_DEF("editors/3d/navigation_feel/translation_inertia", 0.15); //when being manipulated, move more quickly - float manip_orbit_inertia = EDITOR_DEF("editors/3d/manipulation_orbit_inertia", 0.075); - float manip_translation_inertia = EDITOR_DEF("editors/3d/manipulation_translation_inertia", 0.075); + float manip_orbit_inertia = EDITOR_DEF("editors/3d/navigation_feel/manipulation_orbit_inertia", 0.1); + float manip_translation_inertia = EDITOR_DEF("editors/3d/navigation_feel/manipulation_translation_inertia", 0.1); + + float zoom_inertia = EDITOR_DEF("editors/3d/navigation_feel/zoom_inertia", 0.1); //determine if being manipulated bool manipulated = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); @@ -96,7 +98,7 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia))); - camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / translation_inertia))); + camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia))); if (p_interp_delta == 0 || is_freelook_active()) { camera_cursor = cursor; @@ -465,7 +467,6 @@ void SpatialEditorViewport::_select_region() { Vector<Plane> frustum; Vector3 cam_pos = _get_camera_position(); - Set<Ref<SpatialEditorGizmo> > found_gizmos; for (int i = 0; i < 4; i++) { @@ -485,6 +486,9 @@ void SpatialEditorViewport::_select_region() { frustum.push_back(far); Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario()); + Vector<Spatial *> selected; + + Node *edited_scene = get_tree()->get_edited_scene_root(); for (int i = 0; i < instances.size(); i++) { @@ -497,11 +501,14 @@ void SpatialEditorViewport::_select_region() { if (!seg.is_valid()) continue; - if (found_gizmos.has(seg)) - continue; + Spatial *root_sp = sp; + while (root_sp && root_sp != edited_scene && root_sp->get_owner() != edited_scene && !edited_scene->is_editable_instance(root_sp->get_owner())) { + root_sp = Object::cast_to<Spatial>(root_sp->get_owner()); + } - if (seg->intersect_frustum(camera, frustum)) - _select(sp, true, false); + if (selected.find(root_sp) == -1) + if (seg->intersect_frustum(camera, frustum)) + _select(root_sp, true, false); } } @@ -797,20 +804,20 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> b = p_event; if (b.is_valid()) { - + float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor(); switch (b->get_button_index()) { case BUTTON_WHEEL_UP: { - scale_cursor_distance(is_freelook_active() ? ZOOM_MULTIPLIER : 1.0 / ZOOM_MULTIPLIER); + scale_cursor_distance(is_freelook_active() ? zoom_factor : 1.0 / zoom_factor); } break; case BUTTON_WHEEL_DOWN: { - scale_cursor_distance(is_freelook_active() ? 1.0 / ZOOM_MULTIPLIER : ZOOM_MULTIPLIER); + scale_cursor_distance(is_freelook_active() ? 1.0 / zoom_factor : zoom_factor); } break; case BUTTON_RIGHT: { - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); if (b->is_pressed() && _edit.gizmo.is_valid()) { //restore @@ -856,7 +863,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (b->is_pressed()) { int mod = _get_key_modifier(b); - if (mod == _get_key_modifier_setting("editors/3d/freelook_activation_modifier")) { + if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) { freelook_active = true; } } else { @@ -908,7 +915,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (b->is_pressed()) { - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) { break; } @@ -1117,7 +1124,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { _gizmo_select(_edit.mouse_pos, true); } - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); NavigationMode nav_mode = NAVIGATION_NONE; if (_edit.gizmo.is_valid()) { @@ -1440,11 +1447,11 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { int mod = _get_key_modifier(m); - if (mod == _get_key_modifier_setting("editors/3d/pan_modifier")) + if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) nav_mode = NAVIGATION_PAN; - else if (mod == _get_key_modifier_setting("editors/3d/zoom_modifier")) + else if (mod == _get_key_modifier_setting("editors/3d/navigation/zoom_modifier")) nav_mode = NAVIGATION_ZOOM; - else if (mod == _get_key_modifier_setting("editors/3d/orbit_modifier")) + else if (mod == _get_key_modifier_setting("editors/3d/navigation/orbit_modifier")) nav_mode = NAVIGATION_ORBIT; } else if (nav_scheme == NAVIGATION_MAYA) { @@ -1452,16 +1459,16 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { nav_mode = NAVIGATION_PAN; } - } else if (EditorSettings::get_singleton()->get("editors/3d/emulate_3_button_mouse")) { + } else if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_3_button_mouse")) { // Handle trackpad (no external mouse) use case int mod = _get_key_modifier(m); if (mod) { - if (mod == _get_key_modifier_setting("editors/3d/pan_modifier")) + if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) nav_mode = NAVIGATION_PAN; - else if (mod == _get_key_modifier_setting("editors/3d/zoom_modifier")) + else if (mod == _get_key_modifier_setting("editors/3d/navigation/zoom_modifier")) nav_mode = NAVIGATION_ZOOM; - else if (mod == _get_key_modifier_setting("editors/3d/orbit_modifier")) + else if (mod == _get_key_modifier_setting("editors/3d/navigation/orbit_modifier")) nav_mode = NAVIGATION_ORBIT; } } @@ -1494,7 +1501,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (nav_scheme == NAVIGATION_MAYA && m->get_shift()) zoom_speed *= zoom_speed_modifier; - NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int(); + NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/navigation/zoom_style").operator int(); if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) { if (m->get_relative().x > 0) scale_cursor_distance(1 - m->get_relative().x * zoom_speed); @@ -1512,7 +1519,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { case NAVIGATION_ORBIT: { Point2i relative = _get_warped_mouse_motion(m); - real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/orbit_sensitivity"); + real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); cursor.x_rot += relative.y * radians_per_pixel; @@ -1531,7 +1538,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (!orthogonal) { Point2i relative = _get_warped_mouse_motion(m); - real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/orbit_sensitivity"); + real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); cursor.x_rot += relative.y * radians_per_pixel; @@ -1668,7 +1675,7 @@ void SpatialEditorViewport::scale_cursor_distance(real_t scale) { Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const { Point2i relative; - if (bool(EDITOR_DEF("editors/3d/warped_mouse_panning", false))) { + if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) { relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect()); } else { relative = p_ev_mouse_motion->get_relative(); @@ -1722,10 +1729,10 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { speed_modifier = true; } - real_t inertia = EDITOR_DEF("editors/3d/freelook_inertia", 0.2); + real_t inertia = EDITOR_DEF("editors/3d/freelook/freelook_inertia", 0.1); inertia = MAX(0, inertia); - const real_t base_speed = EDITOR_DEF("editors/3d/freelook_base_speed", 0.5); - const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook_modifier_speed_factor", 5); + const real_t base_speed = EDITOR_DEF("editors/3d/freelook/freelook_base_speed", 0.5); + const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook/freelook_modifier_speed_factor", 3); real_t speed = base_speed * cursor.distance; if (speed_modifier) diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 9c7ea506aa..450c9f4b3c 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -211,9 +211,10 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material, instances.push_back(ins); } -void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh) { +void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds) { collision_mesh = p_tmesh; + collision_mesh_bounds = p_bounds; } void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) { @@ -359,6 +360,29 @@ bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera, const Vector< return false; } + if (collision_mesh_bounds.size != Vector3(0.0, 0.0, 0.0)) { + Transform t = spatial_node->get_global_transform(); + const Plane *p = p_frustum.ptr(); + int fc = p_frustum.size(); + + Vector3 mins = t.xform(collision_mesh_bounds.get_position()); + Vector3 max = t.xform(collision_mesh_bounds.get_position() + collision_mesh_bounds.get_size()); + + bool any_out = false; + + for (int j = 0; j < fc; j++) { + + if (p[j].distance_to(mins) > 0 || p[j].distance_to(max) > 0) { + + any_out = true; + break; + } + } + + if (!any_out) + return true; + } + return false; } @@ -637,7 +661,7 @@ void EditorSpatialGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard"), &EditorSpatialGizmo::add_lines, DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorSpatialGizmo::add_collision_segments); - ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorSpatialGizmo::add_collision_triangles); + ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles", "bounds"), &EditorSpatialGizmo::add_collision_triangles); ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1)); ClassDB::bind_method(D_METHOD("add_handles", "handles", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node); @@ -1249,8 +1273,10 @@ void MeshInstanceSpatialGizmo::redraw() { return; //none Ref<TriangleMesh> tm = m->generate_triangle_mesh(); - if (tm.is_valid()) - add_collision_triangles(tm); + if (tm.is_valid()) { + Rect3 aabb; + add_collision_triangles(tm, aabb); + } } MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) { diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h index d63a804055..afe64c723c 100644 --- a/editor/spatial_editor_gizmos.h +++ b/editor/spatial_editor_gizmos.h @@ -78,6 +78,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo { Vector<Vector3> collision_segments; Ref<TriangleMesh> collision_mesh; + Rect3 collision_mesh_bounds; struct Handle { Vector3 pos; @@ -99,7 +100,7 @@ protected: void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false); void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID()); void add_collision_segments(const Vector<Vector3> &p_lines); - void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); + void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds = Rect3()); void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1); void add_handles(const Vector<Vector3> &p_handles, bool p_billboard = false, bool p_secondary = false); void add_solid_box(Ref<Material> &p_material, Vector3 size); diff --git a/main/main.cpp b/main/main.cpp index 04375666a9..1f7418ba2a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -990,8 +990,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) { #endif } +#ifdef TOOLS_ENABLED Ref<Image> icon = memnew(Image(app_icon_png)); OS::get_singleton()->set_icon(icon); +#endif } MAIN_PRINT("Main: DCC"); @@ -1082,6 +1084,7 @@ bool Main::start() { ERR_FAIL_COND_V(!_start_success, false); + bool hasicon = false; bool editor = false; String doc_tool; List<String> removal_docs; @@ -1519,8 +1522,10 @@ bool Main::start() { if (iconpath != "") { Ref<Image> icon; icon.instance(); - if (icon->load(iconpath) == OK) + if (icon->load(iconpath) == OK) { OS::get_singleton()->set_icon(icon); + hasicon = true; + } } } } @@ -1537,6 +1542,11 @@ bool Main::start() { #endif } + if (!hasicon) { + Ref<Image> icon = memnew(Image(app_icon_png)); + OS::get_singleton()->set_icon(icon); + } + OS::get_singleton()->set_main_loop(main_loop); return true; diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index c0e003a3d2..61ee32d2dd 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -21,7 +21,7 @@ def can_build(): def get_opts(): return [ - ('debug_release', 'Add debug symbols to release version', 'no') + ('debug_symbols', 'Add debug symbols to release version (yes/no/full)', 'yes') ] @@ -36,16 +36,21 @@ def configure(env): ## Build type if (env["target"] == "release"): - if (env["debug_release"] == "yes"): + env.Prepend(CCFLAGS=['-O3', '-ffast-math']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): env.Prepend(CCFLAGS=['-g2']) - else: - env.Prepend(CCFLAGS=['-O3', '-ffast-math']) elif (env["target"] == "release_debug"): env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "debug"): - env.Prepend(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) ## Architecture diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 5b2de54535..27bffbe80e 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -1,7 +1,11 @@ #!/usr/bin/env python +import os Import('env') +def make_debug(target, source, env): + os.system('dsymutil %s -o %s.dSYM' % (target[0], target[0])) + files = [ 'crash_handler_osx.mm', 'os_osx.mm', @@ -13,8 +17,7 @@ files = [ 'power_osx.cpp', ] -prog = env.Program('#bin/godot', files) -if (env['target'] == "debug" or env['target'] == "release_debug"): - # Build the .dSYM file for atos - action = "dsymutil " + File(prog)[0].path + " -o " + File(prog)[0].path + ".dSYM" - env.AddPostAction(prog, action) +binary = env.Program('#bin/godot', files) +if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": + env.AddPostAction(binary, make_debug) + diff --git a/platform/osx/detect.py b/platform/osx/detect.py index d3ebdfe992..24302b5ff9 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -22,6 +22,7 @@ def get_opts(): return [ ('osxcross_sdk', 'OSXCross SDK version', 'darwin14'), + ('debug_symbols', 'Add debug symbols to release version (yes/no/full)', 'yes'), ] @@ -36,10 +37,18 @@ def configure(env): ## Build type if (env["target"] == "release"): - env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-fomit-frame-pointer', '-ftree-vectorize', '-msse2']) + env.Prepend(CCFLAGS=['-O3', '-ffast-math', '-fomit-frame-pointer', '-ftree-vectorize', '-msse2']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "release_debug"): env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) diff --git a/platform/windows/SCsub b/platform/windows/SCsub index b56a5c6a80..fd041e096e 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -1,7 +1,12 @@ #!/usr/bin/env python +import os Import('env') +def make_debug_mingw(target, source, env): + os.system('objcopy --only-keep-debug %s %s.debug' % (target[0], target[0])) + os.system('strip --strip-debug --strip-unneeded %s' % (target[0])) + os.system('objcopy --add-gnu-debuglink=%s.debug %s' % (target[0], target[0])) common_win = [ "context_gl_win.cpp", @@ -22,10 +27,14 @@ obj = env.RES(restarget, 'godot_res.rc') common_win.append(obj) -env.Program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"]) +binary = env.Program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"]) # Microsoft Visual Studio Project Generation if (env['vsproj']) == "yes": env.vs_srcs = env.vs_srcs + ["platform/windows/godot_win.cpp"] for x in common_win: env.vs_srcs = env.vs_srcs + ["platform/windows/" + str(x)] + +if not os.getenv("VCINSTALLDIR"): + if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": + env.AddPostAction(binary, make_debug_mingw) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 5bd9a78f49..65eb51a2f3 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -64,6 +64,7 @@ def get_opts(): return [ ('mingw_prefix_32', 'MinGW prefix (Win32)', mingw32), ('mingw_prefix_64', 'MinGW prefix (Win64)', mingw64), + ('debug_symbols', 'Add debug symbols to release version (yes/no/full)', 'yes') ] @@ -213,11 +214,20 @@ def configure(env): env.Append(LINKFLAGS=['-Wl,--subsystem,windows']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) + elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-g', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) ## Compiler configuration diff --git a/platform/x11/SCsub b/platform/x11/SCsub index 62717f3221..aabc49149f 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -1,7 +1,12 @@ #!/usr/bin/env python +import os Import('env') +def make_debug(target, source, env): + os.system('objcopy --only-keep-debug %s %s.debug' % (target[0], target[0])) + os.system('strip --strip-debug --strip-unneeded %s' % (target[0])) + os.system('objcopy --add-gnu-debuglink=%s.debug %s' % (target[0], target[0])) common_x11 = [ "context_gl_x11.cpp", @@ -12,4 +17,6 @@ common_x11 = [ "power_x11.cpp", ] -env.Program('#bin/godot', ['godot_x11.cpp'] + common_x11) +binary = env.Program('#bin/godot', ['godot_x11.cpp'] + common_x11) +if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": + env.AddPostAction(binary, make_debug) diff --git a/platform/x11/detect.py b/platform/x11/detect.py index d61175da60..efd388e44f 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -44,7 +44,6 @@ def can_build(): return True - def get_opts(): return [ @@ -55,7 +54,7 @@ def get_opts(): ('use_lto', 'Use link time optimization', 'no'), ('pulseaudio', 'Detect & use pulseaudio', 'yes'), ('udev', 'Use udev for gamepad connection callbacks', 'no'), - ('debug_release', 'Add debug symbols to release version', 'no'), + ('debug_symbols', 'Add debug symbols to release version (yes/no/full)', 'yes') ] @@ -77,16 +76,20 @@ def configure(env): # -O3 -ffast-math is identical to -Ofast. We need to split it out so we can selectively disable # -ffast-math in code for which it generates wrong results. env.Prepend(CCFLAGS=['-O3', '-ffast-math']) - if (env["debug_release"] == "yes"): + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "release_debug"): env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED']) - if (env["debug_release"] == "yes"): + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "debug"): - env.Prepend(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index c0299f1c26..599c0d2278 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -708,6 +708,16 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); } + + if (!p_enabled && !get_borderless_window()) { + // put decorations back if the window wasn't suppoesed to be borderless + Hints hints; + Atom property; + hints.flags = 2; + hints.decorations = 1; + property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); + } } int OS_X11::get_screen_count() const { diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index b2d87c8f35..1ee76a4216 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -560,8 +560,23 @@ void DynamicFontAtSize::_update_char(CharType p_char) { int ofs = ((i + tex_y + rect_margin) * tex.texture_size + j + tex_x + rect_margin) * 2; ERR_FAIL_COND(ofs >= tex.imgdata.size()); - wr[ofs + 0] = 255; //grayscale as 1 - wr[ofs + 1] = slot->bitmap.buffer[i * slot->bitmap.width + j]; + switch (slot->bitmap.pixel_mode) { + case FT_PIXEL_MODE_MONO: { + int byte = i * slot->bitmap.pitch + (j >> 3); + int bit = 1 << (7 - (j % 8)); + wr[ofs + 0] = 255; //grayscale as 1 + wr[ofs + 1] = slot->bitmap.buffer[byte] & bit ? 255 : 0; + } break; + case FT_PIXEL_MODE_GRAY: + wr[ofs + 0] = 255; //grayscale as 1 + wr[ofs + 1] = slot->bitmap.buffer[i * slot->bitmap.pitch + j]; + break; + // TODO: FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_BGRA + default: + ERR_EXPLAIN("Font uses unsupported pixel format: " + itos(slot->bitmap.pixel_mode)); + ERR_FAIL(); + break; + } } } } |