diff options
Diffstat (limited to 'modules')
19 files changed, 638 insertions, 63 deletions
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index cbf30c8a2e..37e45cfff8 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -142,6 +142,9 @@ bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) co btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { + if (m_count >= m_resultMax) + return cp.getDistance(); + if (cp.getDistance() <= 0) { PhysicsDirectSpaceState::ShapeResult &result = m_results[m_count]; @@ -165,7 +168,7 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con ++m_count; } - return m_count < m_resultMax; + return cp.getDistance(); } bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 669b2c3f0c..5e736c1856 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -264,6 +264,7 @@ RigidBodyBullet::RigidBodyBullet() : can_sleep(true), force_integration_callback(NULL), isTransformChanged(false), + previousActiveState(true), maxCollisionsDetection(0), collisionsCount(0), maxAreasWhereIam(10), @@ -287,6 +288,7 @@ RigidBodyBullet::RigidBodyBullet() : for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { areasWhereIam[i] = NULL; } + btBody->setSleepingThresholds(0.2, 0.2); } RigidBodyBullet::~RigidBodyBullet() { @@ -337,7 +339,7 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) { void RigidBodyBullet::dispatch_callbacks() { /// The check isTransformChanged is necessary in order to call integrated forces only when the first transform is sent - if (btBody->isActive() && force_integration_callback && isTransformChanged) { + if ((btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) { BulletPhysicsDirectBodyState *bodyDirect = BulletPhysicsDirectBodyState::get_singleton(this); @@ -364,6 +366,8 @@ void RigidBodyBullet::dispatch_callbacks() { /// Lock axis btBody->setLinearVelocity(btBody->getLinearVelocity() * btBody->getLinearFactor()); btBody->setAngularVelocity(btBody->getAngularVelocity() * btBody->getAngularFactor()); + + previousActiveState = btBody->isActive(); } void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) { @@ -580,7 +584,8 @@ Variant RigidBodyBullet::get_state(PhysicsServer::BodyState p_state) const { void RigidBodyBullet::apply_central_impulse(const Vector3 &p_impulse) { btVector3 btImpu; G_TO_B(p_impulse, btImpu); - btBody->activate(); + if (Vector3() != p_impulse) + btBody->activate(); btBody->applyCentralImpulse(btImpu); } @@ -589,14 +594,16 @@ void RigidBodyBullet::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impul btVector3 btPos; G_TO_B(p_impulse, btImpu); G_TO_B(p_pos, btPos); - btBody->activate(); + if (Vector3() != p_impulse) + btBody->activate(); btBody->applyImpulse(btImpu, btPos); } void RigidBodyBullet::apply_torque_impulse(const Vector3 &p_impulse) { btVector3 btImp; G_TO_B(p_impulse, btImp); - btBody->activate(); + if (Vector3() != p_impulse) + btBody->activate(); btBody->applyTorqueImpulse(btImp); } @@ -605,28 +612,32 @@ void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_pos) btVector3 btPos; G_TO_B(p_force, btForce); G_TO_B(p_pos, btPos); - btBody->activate(); + if (Vector3() != p_force) + btBody->activate(); btBody->applyForce(btForce, btPos); } void RigidBodyBullet::apply_central_force(const Vector3 &p_force) { btVector3 btForce; G_TO_B(p_force, btForce); - btBody->activate(); + if (Vector3() != p_force) + btBody->activate(); btBody->applyCentralForce(btForce); } void RigidBodyBullet::apply_torque(const Vector3 &p_torque) { btVector3 btTorq; G_TO_B(p_torque, btTorq); - btBody->activate(); + if (Vector3() != p_torque) + btBody->activate(); btBody->applyTorque(btTorq); } void RigidBodyBullet::set_applied_force(const Vector3 &p_force) { btVector3 btVec = btBody->getTotalTorque(); - btBody->activate(); + if (Vector3() != p_force) + btBody->activate(); btBody->clearForces(); btBody->applyTorque(btVec); @@ -644,7 +655,8 @@ Vector3 RigidBodyBullet::get_applied_force() const { void RigidBodyBullet::set_applied_torque(const Vector3 &p_torque) { btVector3 btVec = btBody->getTotalForce(); - btBody->activate(); + if (Vector3() != p_torque) + btBody->activate(); btBody->clearForces(); btBody->applyCentralForce(btVec); @@ -711,7 +723,8 @@ bool RigidBodyBullet::is_continuous_collision_detection_enabled() const { void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) { btVector3 btVec; G_TO_B(p_velocity, btVec); - btBody->activate(); + if (Vector3() != p_velocity) + btBody->activate(); btBody->setLinearVelocity(btVec); } @@ -724,7 +737,8 @@ Vector3 RigidBodyBullet::get_linear_velocity() const { void RigidBodyBullet::set_angular_velocity(const Vector3 &p_velocity) { btVector3 btVec; G_TO_B(p_velocity, btVec); - btBody->activate(); + if (Vector3() != p_velocity) + btBody->activate(); btBody->setAngularVelocity(btVec); } @@ -833,6 +847,9 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { void RigidBodyBullet::reload_space_override_modificator() { + if (!is_active()) + return; + Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude()); real_t newLinearDamp(linearDamp); real_t newAngularDamp(angularDamp); diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index c0eb148e24..c3b72172d9 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -207,6 +207,7 @@ private: bool isScratchedSpaceOverrideModificator; bool isTransformChanged; + bool previousActiveState; // Last check state ForceIntegrationCallback *force_integration_callback; diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index fd11c8d094..4e73ebfb9d 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -3,12 +3,12 @@ Import('env') gdn_env = env.Clone() - -gdn_env.add_source_files(env.modules_sources, "gd_native_library_editor.cpp") gdn_env.add_source_files(env.modules_sources, "gdnative.cpp") gdn_env.add_source_files(env.modules_sources, "register_types.cpp") gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp") gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp") +gdn_env.add_source_files(env.modules_sources, "gdnative_library_singleton_editor.cpp") +gdn_env.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cpp") gdn_env.Append(CPPPATH=['#modules/gdnative/include/']) diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp new file mode 100644 index 0000000000..1e638ab702 --- /dev/null +++ b/modules/gdnative/gdnative_library_editor_plugin.cpp @@ -0,0 +1,423 @@ +/*************************************************************************/ +/* gdnative_library_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef TOOLS_ENABLED +#include "gdnative_library_editor_plugin.h" +#include "gdnative.h" + +void GDNativeLibraryEditor::edit(Ref<GDNativeLibrary> p_library) { + library = p_library; + Ref<ConfigFile> config = p_library->get_config_file(); + + for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { + for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) { + + String target = E->key() + "." + it->get(); + TargetConfig ecfg; + ecfg.library = config->get_value("entry", target, ""); + ecfg.dependencies = config->get_value("dependencies", target, Array()); + entry_configs[target] = ecfg; + } + } + + _update_tree(); +} + +void GDNativeLibraryEditor::_bind_methods() { + + ClassDB::bind_method("_on_item_button", &GDNativeLibraryEditor::_on_item_button); + ClassDB::bind_method("_on_library_selected", &GDNativeLibraryEditor::_on_library_selected); + ClassDB::bind_method("_on_dependencies_selected", &GDNativeLibraryEditor::_on_dependencies_selected); + ClassDB::bind_method("_on_filter_selected", &GDNativeLibraryEditor::_on_filter_selected); + ClassDB::bind_method("_on_item_collapsed", &GDNativeLibraryEditor::_on_item_collapsed); + ClassDB::bind_method("_on_item_activated", &GDNativeLibraryEditor::_on_item_activated); + ClassDB::bind_method("_on_create_new_entry", &GDNativeLibraryEditor::_on_create_new_entry); +} + +void GDNativeLibraryEditor::_update_tree() { + + tree->clear(); + TreeItem *root = tree->create_item(); + + for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { + + if (showing_platform != E->key() && showing_platform != "All") + continue; + + TreeItem *platform = tree->create_item(root); + platform->set_text(0, E->get().name); + platform->set_metadata(0, E->get().library_extension); + + platform->set_custom_bg_color(0, get_color("prop_category", "Editor")); + platform->set_custom_bg_color(1, get_color("prop_category", "Editor")); + platform->set_custom_bg_color(2, get_color("prop_category", "Editor")); + platform->set_selectable(0, false); + platform->set_expand_right(0, true); + + for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) { + + String target = E->key() + "." + it->get(); + TreeItem *bit = tree->create_item(platform); + + bit->set_text(0, it->get()); + bit->set_metadata(0, target); + bit->set_selectable(0, false); + bit->set_custom_bg_color(0, get_color("prop_subsection", "Editor")); + + bit->add_button(1, get_icon("Folder", "EditorIcons"), BUTTON_SELECT_LIBRARY, false, TTR("Select the dynamic library for this entry")); + String file = entry_configs[target].library; + if (!file.empty()) { + bit->add_button(1, get_icon("Clear", "EditorIcons"), BUTTON_CLEAR_LIBRARY, false, TTR("Clear")); + } + bit->set_text(1, file); + + bit->add_button(2, get_icon("Folder", "EditorIcons"), BUTTON_SELECT_DEPENDENCES, false, TTR("Select dependencies of the library for this entry")); + Array files = entry_configs[target].dependencies; + if (files.size()) { + bit->add_button(2, get_icon("Clear", "EditorIcons"), BUTTON_CLEAR_DEPENDENCES, false, TTR("Clear")); + } + bit->set_text(2, Variant(files)); + + bit->add_button(3, get_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP, false, TTR("Move Up")); + bit->add_button(3, get_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN, false, TTR("Move Down")); + bit->add_button(3, get_icon("Remove", "EditorIcons"), BUTTON_ERASE_ENTRY, false, TTR("Remove current entry")); + } + + TreeItem *new_arch = tree->create_item(platform); + new_arch->set_text(0, TTR("Double click to create a new entry")); + new_arch->set_text_align(0, TreeItem::ALIGN_CENTER); + new_arch->set_custom_color(0, get_color("accent_color", "Editor")); + new_arch->set_expand_right(0, true); + new_arch->set_metadata(1, E->key()); + + platform->set_collapsed(collapsed_items.find(E->get().name) != NULL); + } +} + +void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) { + + String target = Object::cast_to<TreeItem>(item)->get_metadata(0); + String platform = target.substr(0, target.find(".")); + String entry = target.substr(platform.length() + 1, target.length()); + String section = (id == BUTTON_SELECT_DEPENDENCES || id == BUTTON_CLEAR_DEPENDENCES) ? "dependencies" : "entry"; + + if (id == BUTTON_SELECT_LIBRARY || id == BUTTON_SELECT_DEPENDENCES) { + + EditorFileDialog::Mode mode = EditorFileDialog::MODE_OPEN_FILE; + if (id == BUTTON_SELECT_DEPENDENCES) + mode = EditorFileDialog::MODE_OPEN_FILES; + + file_dialog->set_meta("target", target); + file_dialog->set_meta("section", section); + file_dialog->clear_filters(); + file_dialog->add_filter(Object::cast_to<TreeItem>(item)->get_parent()->get_metadata(0)); + file_dialog->set_mode(mode); + file_dialog->popup_centered_ratio(); + + } else if (id == BUTTON_CLEAR_LIBRARY) { + _set_target_value(section, target, ""); + } else if (id == BUTTON_CLEAR_DEPENDENCES) { + _set_target_value(section, target, Array()); + } else if (id == BUTTON_ERASE_ENTRY) { + _erase_entry(platform, entry); + } else if (id == BUTTON_MOVE_UP || id == BUTTON_MOVE_DOWN) { + _move_entry(platform, entry, id); + } +} + +void GDNativeLibraryEditor::_on_library_selected(const String &file) { + + _set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), file); +} + +void GDNativeLibraryEditor::_on_dependencies_selected(const PoolStringArray &files) { + + _set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), files); +} + +void GDNativeLibraryEditor::_on_filter_selected(int id) { + + showing_platform = filter->get_item_metadata(id); + _update_tree(); +} + +void GDNativeLibraryEditor::_on_item_collapsed(Object *p_item) { + + TreeItem *item = Object::cast_to<TreeItem>(p_item); + String name = item->get_text(0); + + if (item->is_collapsed()) { + collapsed_items.insert(name); + } else if (Set<String>::Element *e = collapsed_items.find(name)) { + collapsed_items.erase(e); + } +} + +void GDNativeLibraryEditor::_on_item_activated() { + + TreeItem *item = tree->get_selected(); + if (item && tree->get_selected_column() == 0 && item->get_metadata(0).get_type() == Variant::NIL) { + new_architecture_dialog->set_meta("platform", item->get_metadata(1)); + new_architecture_dialog->popup_centered(); + } +} + +void GDNativeLibraryEditor::_on_create_new_entry() { + + String platform = new_architecture_dialog->get_meta("platform"); + String entry = new_architecture_input->get_text().strip_edges(); + if (!entry.empty()) { + platforms[platform].entries.push_back(entry); + _update_tree(); + } +} + +void GDNativeLibraryEditor::_set_target_value(const String §ion, const String &target, Variant file) { + if (section == "entry") + entry_configs[target].library = file; + else if (section == "dependencies") + entry_configs[target].dependencies = file; + _translate_to_config_file(); + _update_tree(); +} + +void GDNativeLibraryEditor::_erase_entry(const String &platform, const String &entry) { + + if (platforms.has(platform)) { + if (List<String>::Element *E = platforms[platform].entries.find(entry)) { + + String target = platform + "." + entry; + Ref<ConfigFile> config = library->get_config_file(); + + platforms[platform].entries.erase(E); + _set_target_value("entry", target, ""); + _set_target_value("dependencies", target, Array()); + _translate_to_config_file(); + _update_tree(); + } + } +} + +void GDNativeLibraryEditor::_move_entry(const String &platform, const String &entry, int dir) { + if (List<String>::Element *E = platforms[platform].entries.find(entry)) { + if (E->prev() && dir == BUTTON_MOVE_UP) { + platforms[platform].entries.insert_before(E->prev(), E->get()); + platforms[platform].entries.erase(E); + } else if (E->next() && dir == BUTTON_MOVE_DOWN) { + platforms[platform].entries.insert_after(E->next(), E->get()); + platforms[platform].entries.erase(E); + } + _translate_to_config_file(); + _update_tree(); + } +} + +void GDNativeLibraryEditor::_translate_to_config_file() { + + if (!library.is_null()) { + + Ref<ConfigFile> config = library->get_config_file(); + config->erase_section("entry"); + config->erase_section("dependencies"); + + for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { + for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) { + + String target = E->key() + "." + it->get(); + if (entry_configs[target].library.empty() && entry_configs[target].dependencies.empty()) + continue; + + config->set_value("entry", target, entry_configs[target].library); + config->set_value("dependencies", target, entry_configs[target].dependencies); + } + } + + library->_change_notify(); + } +} + +GDNativeLibraryEditor::GDNativeLibraryEditor() { + + showing_platform = "All"; + + { // Define platforms + NativePlatformConfig platform_windows; + platform_windows.name = "Windows"; + platform_windows.entries.push_back("64"); + platform_windows.entries.push_back("32"); + platform_windows.library_extension = "*.dll"; + platforms["Windows"] = platform_windows; + + NativePlatformConfig platform_linux; + platform_linux.name = "Linux/X11"; + platform_linux.entries.push_back("64"); + platform_linux.entries.push_back("32"); + platform_linux.library_extension = "*.so"; + platforms["X11"] = platform_linux; + + NativePlatformConfig platform_osx; + platform_osx.name = "Mac OSX"; + platform_osx.entries.push_back("64"); + platform_osx.entries.push_back("32"); + platform_osx.library_extension = "*.dylib"; + platforms["OSX"] = platform_osx; + + NativePlatformConfig platform_haiku; + platform_haiku.name = "Haiku"; + platform_haiku.entries.push_back("64"); + platform_haiku.entries.push_back("32"); + platform_haiku.library_extension = "*.so"; + platforms["Haiku"] = platform_haiku; + + NativePlatformConfig platform_uwp; + platform_uwp.name = "Windows Universal"; + platform_uwp.entries.push_back("arm"); + platform_uwp.entries.push_back("x86"); + platform_uwp.entries.push_back("x64"); + platform_uwp.library_extension = "*.dll"; + platforms["UWP"] = platform_uwp; + + NativePlatformConfig platform_android; + platform_android.name = "Android"; + platform_android.entries.push_back("armeabi-v7a"); + platform_android.entries.push_back("arm64-v8a"); + platform_android.entries.push_back("x86"); + platform_android.entries.push_back("x86_64"); + platform_android.library_extension = "*.so"; + platforms["Android"] = platform_android; + + // TODO: Javascript platform is not supported yet + // NativePlatformConfig platform_html5; + // platform_html5.name = "HTML5"; + // platform_html5.library_extension = "*.wasm"; + // platforms["Javascript"] = platform_html5; + + NativePlatformConfig platform_ios; + platform_ios.name = "iOS"; + platform_ios.entries.push_back("armv7"); + platform_ios.entries.push_back("arm64"); + platform_ios.library_extension = "*.dylib"; + platforms["iOS"] = platform_ios; + } + + VBoxContainer *container = memnew(VBoxContainer); + add_child(container); + container->set_anchors_and_margins_preset(PRESET_WIDE); + + HBoxContainer *hbox = memnew(HBoxContainer); + container->add_child(hbox); + Label *label = memnew(Label); + label->set_text(TTR("Platform:")); + hbox->add_child(label); + filter = memnew(OptionButton); + hbox->add_child(filter); + filter->set_h_size_flags(SIZE_EXPAND_FILL); + + int idx = 0; + filter->add_item(TTR("All"), idx); + filter->set_item_metadata(idx, "All"); + idx += 1; + for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { + filter->add_item(E->get().name, idx); + filter->set_item_metadata(idx, E->key()); + idx += 1; + } + filter->connect("item_selected", this, "_on_filter_selected"); + + tree = memnew(Tree); + container->add_child(tree); + tree->set_v_size_flags(SIZE_EXPAND_FILL); + tree->set_hide_root(true); + tree->set_column_titles_visible(true); + tree->set_columns(4); + tree->set_column_expand(0, false); + tree->set_column_min_width(0, int(200 * EDSCALE)); + tree->set_column_title(0, TTR("Platform")); + tree->set_column_title(1, TTR("Dynamic Library")); + tree->set_column_title(2, TTR("Dependencies")); + tree->set_column_expand(3, false); + tree->set_column_min_width(3, int(110 * EDSCALE)); + tree->connect("button_pressed", this, "_on_item_button"); + tree->connect("item_collapsed", this, "_on_item_collapsed"); + tree->connect("item_activated", this, "_on_item_activated"); + + file_dialog = memnew(EditorFileDialog); + file_dialog->set_access(EditorFileDialog::ACCESS_RESOURCES); + file_dialog->set_resizable(true); + add_child(file_dialog); + file_dialog->connect("file_selected", this, "_on_library_selected"); + file_dialog->connect("files_selected", this, "_on_dependencies_selected"); + + new_architecture_dialog = memnew(ConfirmationDialog); + add_child(new_architecture_dialog); + new_architecture_dialog->set_title(TTR("Add an architecture entry")); + new_architecture_input = memnew(LineEdit); + new_architecture_dialog->add_child(new_architecture_input); + new_architecture_dialog->set_custom_minimum_size(Vector2(300, 80) * EDSCALE); + new_architecture_input->set_anchors_and_margins_preset(PRESET_HCENTER_WIDE, PRESET_MODE_MINSIZE, 5 * EDSCALE); + new_architecture_dialog->get_ok()->connect("pressed", this, "_on_create_new_entry"); +} + +void GDNativeLibraryEditorPlugin::edit(Object *p_node) { + + if (Object::cast_to<GDNativeLibrary>(p_node)) { + library_editor->edit(Object::cast_to<GDNativeLibrary>(p_node)); + library_editor->show(); + } else + library_editor->hide(); +} + +bool GDNativeLibraryEditorPlugin::handles(Object *p_node) const { + + return p_node->is_class("GDNativeLibrary"); +} + +void GDNativeLibraryEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + button->show(); + EditorNode::get_singleton()->make_bottom_panel_item_visible(library_editor); + + } else { + if (library_editor->is_visible_in_tree()) + EditorNode::get_singleton()->hide_bottom_panel(); + button->hide(); + } +} + +GDNativeLibraryEditorPlugin::GDNativeLibraryEditorPlugin(EditorNode *p_node) { + + library_editor = memnew(GDNativeLibraryEditor); + library_editor->set_custom_minimum_size(Size2(0, 250 * EDSCALE)); + button = p_node->add_bottom_panel_item(TTR("GDNativeLibrary"), library_editor); + button->hide(); +} + +#endif diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h new file mode 100644 index 0000000000..1fa6a0c945 --- /dev/null +++ b/modules/gdnative/gdnative_library_editor_plugin.h @@ -0,0 +1,113 @@ +/*************************************************************************/ +/* gdnative_library_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef GDNATIVE_LIBRARY_EDITOR_PLUGIN_H +#define GDNATIVE_LIBRARY_EDITOR_PLUGIN_H + +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" +#include "gdnative.h" + +class GDNativeLibraryEditor : public Control { + + GDCLASS(GDNativeLibraryEditor, Control); + + struct NativePlatformConfig { + String name; + String library_extension; + List<String> entries; + }; + + struct TargetConfig { + String library; + Array dependencies; + }; + + enum ItemButton { + BUTTON_SELECT_LIBRARY, + BUTTON_CLEAR_LIBRARY, + BUTTON_SELECT_DEPENDENCES, + BUTTON_CLEAR_DEPENDENCES, + BUTTON_ERASE_ENTRY, + BUTTON_MOVE_UP, + BUTTON_MOVE_DOWN, + }; + + Tree *tree; + OptionButton *filter; + EditorFileDialog *file_dialog; + ConfirmationDialog *new_architecture_dialog; + LineEdit *new_architecture_input; + Set<String> collapsed_items; + + String showing_platform; + Ref<GDNativeLibrary> library; + Map<String, NativePlatformConfig> platforms; + Map<String, TargetConfig> entry_configs; + +protected: + static void _bind_methods(); + void _update_tree(); + void _on_item_button(Object *item, int column, int id); + void _on_library_selected(const String &file); + void _on_dependencies_selected(const PoolStringArray &files); + void _on_filter_selected(int id); + void _on_item_collapsed(Object *item); + void _on_item_activated(); + void _on_create_new_entry(); + void _set_target_value(const String §ion, const String &target, Variant file); + void _erase_entry(const String &platform, const String &entry); + void _move_entry(const String &platform, const String &entry, int dir); + void _translate_to_config_file(); + +public: + void edit(Ref<GDNativeLibrary> p_library); + + GDNativeLibraryEditor(); +}; + +class GDNativeLibraryEditorPlugin : public EditorPlugin { + + GDCLASS(GDNativeLibraryEditorPlugin, EditorPlugin); + + GDNativeLibraryEditor *library_editor; + EditorNode *editor; + Button *button; + +public: + virtual String get_name() const { return "GDNativeLibrary"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + GDNativeLibraryEditorPlugin(EditorNode *p_node); +}; +#endif +#endif // GDNATIVE_LIBRARY_EDITOR_PLUGIN_H diff --git a/modules/gdnative/gd_native_library_editor.cpp b/modules/gdnative/gdnative_library_singleton_editor.cpp index fda5dcdcad..2ad497fcad 100644 --- a/modules/gdnative/gd_native_library_editor.cpp +++ b/modules/gdnative/gdnative_library_singleton_editor.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_native_library_editor.cpp */ +/* gdnative_library_singleton_editor.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #ifdef TOOLS_ENABLED -#include "gd_native_library_editor.h" - +#include "gdnative_library_singleton_editor.h" #include "gdnative.h" -void GDNativeLibraryEditor::_find_gdnative_singletons(EditorFileSystemDirectory *p_dir, const Set<String> &enabled_list) { +void GDNativeLibrarySingletonEditor::_find_gdnative_singletons(EditorFileSystemDirectory *p_dir, const Set<String> &enabled_list) { // check children @@ -65,7 +64,7 @@ void GDNativeLibraryEditor::_find_gdnative_singletons(EditorFileSystemDirectory } } -void GDNativeLibraryEditor::_update_libraries() { +void GDNativeLibrarySingletonEditor::_update_libraries() { updating = true; libraries->clear(); @@ -88,7 +87,7 @@ void GDNativeLibraryEditor::_update_libraries() { updating = false; } -void GDNativeLibraryEditor::_item_edited() { +void GDNativeLibrarySingletonEditor::_item_edited() { if (updating) return; @@ -119,7 +118,7 @@ void GDNativeLibraryEditor::_item_edited() { } } -void GDNativeLibraryEditor::_notification(int p_what) { +void GDNativeLibrarySingletonEditor::_notification(int p_what) { if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { if (is_visible_in_tree()) { @@ -128,12 +127,12 @@ void GDNativeLibraryEditor::_notification(int p_what) { } } -void GDNativeLibraryEditor::_bind_methods() { +void GDNativeLibrarySingletonEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_item_edited"), &GDNativeLibraryEditor::_item_edited); + ClassDB::bind_method(D_METHOD("_item_edited"), &GDNativeLibrarySingletonEditor::_item_edited); } -GDNativeLibraryEditor::GDNativeLibraryEditor() { +GDNativeLibrarySingletonEditor::GDNativeLibrarySingletonEditor() { libraries = memnew(Tree); libraries->set_columns(2); libraries->set_column_titles_visible(true); diff --git a/modules/gdnative/gd_native_library_editor.h b/modules/gdnative/gdnative_library_singleton_editor.h index a11c4620dd..ee1a32c5a5 100644 --- a/modules/gdnative/gd_native_library_editor.h +++ b/modules/gdnative/gdnative_library_singleton_editor.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gd_native_library_editor.h */ +/* gdnative_library_singleton_editor.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -34,7 +34,7 @@ #include "editor/editor_file_system.h" #include "editor/project_settings_editor.h" -class GDNativeLibraryEditor : public VBoxContainer { +class GDNativeLibrarySingletonEditor : public VBoxContainer { Tree *libraries; bool updating; @@ -48,7 +48,7 @@ protected: static void _bind_methods(); public: - GDNativeLibraryEditor(); + GDNativeLibrarySingletonEditor(); }; #endif diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 1cb35ec006..bd9bae5294 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -45,7 +45,8 @@ #ifdef TOOLS_ENABLED #include "editor/editor_node.h" -#include "gd_native_library_editor.h" +#include "gdnative_library_editor_plugin.h" +#include "gdnative_library_singleton_editor.h" // Class used to discover singleton gdnative files static void actual_discoverer_handler(); @@ -267,7 +268,7 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty static void editor_init_callback() { - GDNativeLibraryEditor *library_editor = memnew(GDNativeLibraryEditor); + GDNativeLibrarySingletonEditor *library_editor = memnew(GDNativeLibrarySingletonEditor); library_editor->set_name(TTR("GDNative")); ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(library_editor); @@ -278,6 +279,8 @@ static void editor_init_callback() { export_plugin.instance(); EditorExport::get_singleton()->add_export_plugin(export_plugin); + + EditorNode::get_singleton()->add_editor_plugin(memnew(GDNativeLibraryEditorPlugin(EditorNode::get_singleton()))); } #endif diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 1860176f0c..0b73cbfc6d 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -475,16 +475,17 @@ bool GridMap::_octant_update(const OctantKey &p_key) { xform.basis.set_orthogonal_index(c.rot); xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); + if (baked_meshes.size() == 0) { + if (theme->get_item_mesh(c.item).is_valid()) { + if (!multimesh_items.has(c.item)) { + multimesh_items[c.item] = List<Pair<Transform, IndexKey> >(); + } - if (theme->get_item_mesh(c.item).is_valid()) { - if (!multimesh_items.has(c.item)) { - multimesh_items[c.item] = List<Pair<Transform, IndexKey> >(); + Pair<Transform, IndexKey> p; + p.first = xform; + p.second = E->get(); + multimesh_items[c.item].push_back(p); } - - Pair<Transform, IndexKey> p; - p.first = xform; - p.second = E->get(); - multimesh_items[c.item].push_back(p); } Vector<MeshLibrary::ShapeData> shapes = theme->get_item_shapes(c.item); diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp index 9a1efb4423..d5819a4ca3 100644 --- a/modules/mono/editor/csharp_project.cpp +++ b/modules/mono/editor/csharp_project.cpp @@ -54,7 +54,7 @@ String generate_core_api_project(const String &p_dir, const Vector<String> &p_fi ERR_FAIL_V(String()); } - return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : ""; + return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); } String generate_editor_api_project(const String &p_dir, const String &p_core_dll_path, const Vector<String> &p_files) { @@ -75,7 +75,7 @@ String generate_editor_api_project(const String &p_dir, const String &p_core_dll ERR_FAIL_V(String()); } - return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : ""; + return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); } String generate_game_project(const String &p_dir, const String &p_name, const Vector<String> &p_files) { @@ -96,7 +96,7 @@ String generate_game_project(const String &p_dir, const String &p_name, const Ve ERR_FAIL_V(String()); } - return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : ""; + return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); } void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) { diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index 1bc1e8a515..1e61646769 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -50,9 +50,9 @@ GodotSharpEditor *GodotSharpEditor::singleton = NULL; bool GodotSharpEditor::_create_project_solution() { - EditorProgress pr("create_csharp_solution", "Generating solution...", 2); + EditorProgress pr("create_csharp_solution", TTR("Generating solution..."), 2); - pr.step("Generating C# project..."); + pr.step(TTR("Generating C# project...")); String path = OS::get_singleton()->get_resource_dir(); String name = ProjectSettings::get_singleton()->get("application/config/name"); @@ -67,7 +67,7 @@ bool GodotSharpEditor::_create_project_solution() { NETSolution solution(name); if (!solution.set_path(path)) { - show_error_dialog("Failed to create solution."); + show_error_dialog(TTR("Failed to create solution.")); return false; } @@ -79,7 +79,7 @@ bool GodotSharpEditor::_create_project_solution() { Error sln_error = solution.save(); if (sln_error != OK) { - show_error_dialog("Failed to save solution."); + show_error_dialog(TTR("Failed to save solution.")); return false; } @@ -89,13 +89,13 @@ bool GodotSharpEditor::_create_project_solution() { if (!GodotSharpBuilds::make_api_sln(GodotSharpBuilds::API_EDITOR)) return false; - pr.step("Done"); + pr.step(TTR("Done")); // Here, after all calls to progress_task_step call_deferred("_remove_create_sln_menu_option"); } else { - show_error_dialog("Failed to create C# project."); + show_error_dialog(TTR("Failed to create C# project.")); } return true; @@ -194,14 +194,14 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { error_dialog = memnew(AcceptDialog); editor->get_gui_base()->add_child(error_dialog); - bottom_panel_btn = editor->add_bottom_panel_item("Mono", memnew(MonoBottomPanel(editor))); + bottom_panel_btn = editor->add_bottom_panel_item(TTR("Mono"), memnew(MonoBottomPanel(editor))); godotsharp_builds = memnew(GodotSharpBuilds); editor->add_child(memnew(MonoReloadNode)); menu_button = memnew(MenuButton); - menu_button->set_text("Mono"); + menu_button->set_text(TTR("Mono")); menu_popup = menu_button->get_popup(); String sln_path = GodotSharpDirs::get_project_sln_path(); @@ -209,7 +209,7 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { if (!FileAccess::exists(sln_path) || !FileAccess::exists(csproj_path)) { bottom_panel_btn->hide(); - menu_popup->add_item("Create C# solution", MENU_CREATE_SLN); + menu_popup->add_item(TTR("Create C# solution"), MENU_CREATE_SLN); } menu_popup->connect("id_pressed", this, "_menu_option_pressed"); diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index 31dc09856a..be714026ad 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -197,7 +197,7 @@ MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { panel_builds_tab->add_child(toolbar_hbc); ToolButton *build_project_btn = memnew(ToolButton); - build_project_btn->set_text("Build Project"); + build_project_btn->set_text(TTR("Build Project")); build_project_btn->set_focus_mode(FOCUS_NONE); build_project_btn->connect("pressed", this, "_build_project_pressed"); toolbar_hbc->add_child(build_project_btn); @@ -205,7 +205,7 @@ MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { toolbar_hbc->add_spacer(); warnings_btn = memnew(ToolButton); - warnings_btn->set_text("Warnings"); + warnings_btn->set_text(TTR("Warnings")); warnings_btn->set_toggle_mode(true); warnings_btn->set_pressed(true); warnings_btn->set_visible(false); @@ -214,7 +214,7 @@ MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { toolbar_hbc->add_child(warnings_btn); errors_btn = memnew(ToolButton); - errors_btn->set_text("Errors"); + errors_btn->set_text(TTR("Errors")); errors_btn->set_toggle_mode(true); errors_btn->set_pressed(true); errors_btn->set_visible(false); diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index eb34f9dd3f..63b24f3ee6 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -290,7 +290,7 @@ int GDMonoField::get_int_value(MonoObject *p_object) { String GDMonoField::get_string_value(MonoObject *p_object) { MonoObject *val = get_value(p_object); - return val ? GDMonoMarshal::mono_string_to_godot((MonoString *)val) : String(); + return GDMonoMarshal::mono_string_to_godot((MonoString *)val); } bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) { diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index e473348897..e8aea8624d 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -70,7 +70,9 @@ void gdmono_MonoLogCallback(const char *log_domain, const char *log_level, const } if (fatal) { - ERR_PRINTS("Mono: FALTAL ERROR, ABORTING! Logfile: " + GDMonoLog::get_singleton()->get_log_file_path() + "\n"); + ERR_PRINTS("Mono: FATAL ERROR, ABORTING! Logfile: " + GDMonoLog::get_singleton()->get_log_file_path() + "\n"); + // If we were to abort without flushing, the log wouldn't get written. + f->flush(); abort(); } } diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 8bc2bb5096..d744d24f24 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -490,8 +490,9 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { return unbox<double>(p_obj); case MONO_TYPE_STRING: { - String str = mono_string_to_godot((MonoString *)p_obj); - return str; + if (p_obj == NULL) + return Variant(); // NIL + return mono_string_to_godot_not_null((MonoString *)p_obj); } break; case MONO_TYPE_VALUETYPE: { diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 443e947fb5..1be4be1a1c 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -62,13 +62,20 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type); String mono_to_utf8_string(MonoString *p_mono_string); String mono_to_utf16_string(MonoString *p_mono_string); -_FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) { +_FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) { if (sizeof(CharType) == 2) return mono_to_utf16_string(p_mono_string); return mono_to_utf8_string(p_mono_string); } +_FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) { + if (p_mono_string == NULL) + return String(); + + return mono_string_to_godot_not_null(p_mono_string); +} + _FORCE_INLINE_ MonoString *mono_from_utf8_string(const String &p_string) { return mono_string_new(mono_domain_get(), p_string.utf8().get_data()); } diff --git a/modules/opus/register_types.cpp b/modules/opus/register_types.cpp index a69c8bf9f3..6d7a3575ed 100644 --- a/modules/opus/register_types.cpp +++ b/modules/opus/register_types.cpp @@ -34,13 +34,18 @@ static ResourceFormatLoaderAudioStreamOpus *opus_stream_loader = NULL; void register_opus_types() { - - opus_stream_loader = memnew(ResourceFormatLoaderAudioStreamOpus); - ResourceLoader::add_resource_format_loader(opus_stream_loader); - ClassDB::register_class<AudioStreamOpus>(); + // Sorry guys, do not enable this unless you can figure out a way + // to get Opus to not do any memory allocation or system calls + // in the audio thread. + // Currently the implementation even reads files from the audio thread, + // and this is not how audio programming works. + + //opus_stream_loader = memnew(ResourceFormatLoaderAudioStreamOpus); + //ResourceLoader::add_resource_format_loader(opus_stream_loader); + //ClassDB::register_class<AudioStreamOpus>(); } void unregister_opus_types() { - memdelete(opus_stream_loader); + //memdelete(opus_stream_loader); } diff --git a/modules/thekla_unwrap/register_types.cpp b/modules/thekla_unwrap/register_types.cpp index ab3203068f..da6c1bab2a 100644 --- a/modules/thekla_unwrap/register_types.cpp +++ b/modules/thekla_unwrap/register_types.cpp @@ -65,7 +65,7 @@ bool thekla_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver Thekla::atlas_set_default_options(&options); options.packer_options.witness.packing_quality = 1; options.packer_options.witness.texel_area = 1.0 / p_texel_size; - options.packer_options.witness.conservative = true; + options.packer_options.witness.conservative = false; //generate Thekla::Atlas_Error err; |