summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/Control.xml4
-rw-r--r--drivers/unix/os_unix.cpp15
-rw-r--r--editor/dependency_editor.cpp2
-rw-r--r--editor/editor_export.cpp16
-rw-r--r--editor/export_template_manager.cpp2
-rw-r--r--editor/filesystem_dock.cpp14
-rw-r--r--editor/plugins/navigation_mesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp2
-rw-r--r--editor/project_manager.cpp1
-rw-r--r--modules/bullet/bullet_types_converter.cpp11
-rw-r--r--modules/bullet/bullet_types_converter.h1
-rw-r--r--modules/bullet/collision_object_bullet.cpp22
-rw-r--r--modules/bullet/collision_object_bullet.h1
-rw-r--r--modules/bullet/rigid_body_bullet.cpp39
-rw-r--r--modules/bullet/shape_bullet.cpp55
-rw-r--r--modules/bullet/shape_bullet.h20
-rw-r--r--modules/bullet/space_bullet.cpp235
-rw-r--r--modules/bullet/space_bullet.h13
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp15
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h2
-rw-r--r--modules/thekla_unwrap/SCsub12
-rw-r--r--platform/haiku/os_haiku.cpp2
-rw-r--r--platform/javascript/export/export.cpp18
-rw-r--r--platform/javascript/os_javascript.cpp2
-rw-r--r--platform/osx/export/export.cpp25
-rw-r--r--platform/osx/os_osx.mm6
-rw-r--r--platform/server/os_server.cpp3
-rw-r--r--platform/windows/os_windows.cpp11
-rw-r--r--scene/gui/popup_menu.cpp5
-rw-r--r--scene/gui/text_edit.cpp10
-rw-r--r--servers/visual_server.cpp2
31 files changed, 351 insertions, 217 deletions
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 6c30a92ed5..680e008ff1 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -632,6 +632,7 @@
Distance between the node's top edge and its parent container, based on [member anchor_top].
</member>
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" enum="Control.MouseFilter">
+ Controls whether the control will be able to receive mouse button input events through [Control._gui_input] and how these events should be handled. Use one of the [code]MOUSE_FILTER_*[/code] constants. See the constants to learn what each does.
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents">
</member>
@@ -869,10 +870,13 @@
Tells the parent [Container] to align the node with its end, either the bottom or the right edge. It doesn't work with the fill or expand size flags. Use with [member size_flags_horizontal] and [member size_flags_vertical].
</constant>
<constant name="MOUSE_FILTER_STOP" value="0" enum="MouseFilter">
+ The control will receive mouse button input events through [method Control._gui_input] if clicked on. These events are automatically marked as handled and they will not propogate further to other controls.
</constant>
<constant name="MOUSE_FILTER_PASS" value="1" enum="MouseFilter">
+ The control will receive mouse button input events through [method Control._gui_input] if clicked on. If this control does not handle the event, the parent control (if any) will be considered for a mouse click, and so on until there is no more parent control to potentially handle it. Even if no control handled it at all, the event will still be handled automatically.
</constant>
<constant name="MOUSE_FILTER_IGNORE" value="2" enum="MouseFilter">
+ The control will not receive mouse button input events through [method Control._gui_input] and will not block other controls from receiving these events. These events will also not be handled automatically.
</constant>
<constant name="GROW_DIRECTION_BEGIN" value="0" enum="GrowDirection">
</constant>
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index fa8094f31a..e08b58cf5c 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -362,7 +362,20 @@ String OS_Unix::get_locale() const {
}
Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
- p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW);
+
+ String path = p_path;
+
+ if (!FileAccess::exists(path)) {
+ //this code exists so gdnative can load .so files from within the executable path
+ path = get_executable_path().get_base_dir().plus_file(p_path.get_file());
+ }
+
+ if (!FileAccess::exists(path)) {
+ //this code exists so gdnative can load .so files from a standard unix location
+ path = get_executable_path().get_base_dir().plus_file("../lib").plus_file(p_path.get_file());
+ }
+
+ p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
if (!p_library_handle) {
ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
ERR_FAIL_V(ERR_CANT_OPEN);
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index f18a966151..4e753cb342 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -514,7 +514,7 @@ void DependencyRemoveDialog::ok_pressed() {
print_line("Moving to trash: " + path);
Error err = OS::get_singleton()->move_to_trash(path);
if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:\n") + to_delete[i] + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + to_delete[i] + "\n");
}
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 1a10040bac..e6a481eb01 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -1347,7 +1347,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
}
if (template_path != String() && !FileAccess::exists(template_path)) {
- EditorNode::get_singleton()->show_warning(TTR("Template file not found:\n") + template_path);
+ EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
return ERR_FILE_NOT_FOUND;
}
@@ -1361,7 +1361,19 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
String pck_path = p_path.get_basename() + ".pck";
- return save_pack(p_preset, pck_path);
+ Vector<SharedObject> so_files;
+
+ err = save_pack(p_preset, pck_path, &so_files);
+
+ if (err != OK || so_files.empty())
+ return err;
+ //if shared object files, copy them
+ da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ for (int i = 0; i < so_files.size(); i++) {
+ da->copy(so_files[i].path, p_path.get_base_dir().plus_file(so_files[i].path.get_file()));
+ }
+ memdelete(da);
+ return OK;
}
void EditorExportPlatformPC::set_extension(const String &p_extension, const String &p_feature_key) {
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index 0206e37c43..ccc9a52a3e 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -250,7 +250,7 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = d->make_dir_recursive(template_path);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Error creating path for templates:\n") + template_path);
+ EditorNode::get_singleton()->show_warning(TTR("Error creating path for templates:") + "\n" + template_path);
unzClose(pkg);
return;
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index b18cd6b747..e6bc19b571 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -752,7 +752,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
return;
} else if (!p_item.is_file && new_path.begins_with(old_path)) {
//This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/"
- EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.\n") + old_path + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n");
return;
}
@@ -772,7 +772,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
err = da->rename(old_path + ".import", new_path + ".import");
if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Error moving:\n") + old_path + ".import\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Error moving:") + "\n" + old_path + ".import\n");
}
}
@@ -796,7 +796,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
print_line(" Remap: " + changed_paths[i] + " -> " + p_renames[changed_paths[i]]);
}
} else {
- EditorNode::get_singleton()->add_io_error(TTR("Error moving:\n") + old_path + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Error moving:") + "\n" + old_path + "\n");
}
memdelete(da);
}
@@ -813,7 +813,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
return;
} else if (!p_item.is_file && new_path.begins_with(old_path)) {
//This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/"
- EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.\n") + old_path + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n");
return;
}
@@ -825,11 +825,11 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
err = da->copy(old_path + ".import", new_path + ".import");
if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:\n") + old_path + ".import\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import\n");
}
}
} else {
- EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:\n") + old_path + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + "\n");
}
memdelete(da);
}
@@ -901,7 +901,7 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &
if (ResourceLoader::get_resource_type(file) == "PackedScene")
editor->reload_scene(file);
} else {
- EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:\n") + remaps[i] + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:") + "\n" + remaps[i] + "\n");
}
}
}
diff --git a/editor/plugins/navigation_mesh_editor_plugin.cpp b/editor/plugins/navigation_mesh_editor_plugin.cpp
index 8c80225db6..933ab36886 100644
--- a/editor/plugins/navigation_mesh_editor_plugin.cpp
+++ b/editor/plugins/navigation_mesh_editor_plugin.cpp
@@ -107,7 +107,7 @@ NavigationMeshEditor::NavigationMeshEditor() {
button_bake->set_text(TTR("Bake!"));
button_bake->set_toggle_mode(true);
button_reset = memnew(Button);
- button_bake->set_tooltip(TTR("Bake the navigation mesh.\n"));
+ button_bake->set_tooltip(TTR("Bake the navigation mesh.") + "\n");
bake_info = memnew(Label);
bake_hbox->add_child(button_bake);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index f6aef52e8b..71f15a4421 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -4947,7 +4947,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
button_binds[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)\n") + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
+ tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
tool_button[TOOL_MODE_MOVE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index eb5cec2a2e..3d4ae90c89 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1101,6 +1101,7 @@ void ProjectManager::_load_recent_projects() {
hb->add_child(vb);
Control *ec = memnew(Control);
ec->set_custom_minimum_size(Size2(0, 1));
+ ec->set_mouse_filter(MOUSE_FILTER_PASS);
vb->add_child(ec);
Label *title = memnew(Label(project_name));
title->add_font_override("font", gui_base->get_font("title", "EditorFonts"));
diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp
index 03247a91ca..42a6f156a5 100644
--- a/modules/bullet/bullet_types_converter.cpp
+++ b/modules/bullet/bullet_types_converter.cpp
@@ -92,3 +92,14 @@ void G_TO_B(Transform const &inVal, btTransform &outVal) {
G_TO_B(inVal.basis, outVal.getBasis());
G_TO_B(inVal.origin, outVal.getOrigin());
}
+
+void UNSCALE_BT_BASIS(btTransform &scaledBasis) {
+ btMatrix3x3 &m(scaledBasis.getBasis());
+ btVector3 column0(m[0][0], m[1][0], m[2][0]);
+ btVector3 column1(m[0][1], m[1][1], m[2][1]);
+ btVector3 column2(m[0][2], m[1][2], m[2][2]);
+ column0.normalize();
+ column1.normalize();
+ column2.normalize();
+ m.setValue(column0[0], column1[0], column2[0], column0[1], column1[1], column2[1], column0[2], column1[2], column2[2]);
+}
diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h
index 5fa30c1d74..349cad65aa 100644
--- a/modules/bullet/bullet_types_converter.h
+++ b/modules/bullet/bullet_types_converter.h
@@ -54,4 +54,5 @@ extern void G_TO_B(Basis const &inVal, btMatrix3x3 &outVal);
extern void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal);
extern void G_TO_B(Transform const &inVal, btTransform &outVal);
+extern void UNSCALE_BT_BASIS(btTransform &scaledBasis);
#endif
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index 70d604fa70..1350be20b6 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -57,7 +57,8 @@ CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
collisionsEnabled(true),
m_isStatic(false),
bt_collision_object(NULL),
- body_scale(1., 1., 1.) {}
+ body_scale(1., 1., 1.),
+ force_shape_reset(false) {}
CollisionObjectBullet::~CollisionObjectBullet() {
// Remove all overlapping
@@ -88,6 +89,7 @@ btVector3 CollisionObjectBullet::get_bt_body_scale() const {
}
void CollisionObjectBullet::on_body_scale_changed() {
+ force_shape_reset = true;
}
void CollisionObjectBullet::destroyBulletCollisionObject() {
@@ -289,15 +291,27 @@ void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_sha
void RigidCollisionObjectBullet::on_shapes_changed() {
int i;
+
// Remove all shapes, reverse order for performance reason (Array resize)
for (i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
compoundShape->removeChildShapeByIndex(i);
}
- // Insert all shapes
ShapeWrapper *shpWrapper;
- const int size = shapes.size();
- for (i = 0; i < size; ++i) {
+ const int shapes_size = shapes.size();
+
+ // Reset shape if required
+ if (force_shape_reset) {
+ for (i = 0; i < shapes_size; ++i) {
+ shpWrapper = &shapes[i];
+ bulletdelete(shpWrapper->bt_shape);
+ }
+ force_shape_reset = false;
+ }
+
+ // Insert all shapes
+
+ for (i = 0; i < shapes_size; ++i) {
shpWrapper = &shapes[i];
if (shpWrapper->active) {
if (!shpWrapper->bt_shape) {
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index 4168133e0d..6a3fbe65ff 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -115,6 +115,7 @@ protected:
bool ray_pickable;
btCollisionObject *bt_collision_object;
Vector3 body_scale;
+ bool force_shape_reset;
SpaceBullet *space;
VSet<RID> exceptions;
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index e7342e2ae8..c183b012ab 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -205,41 +205,20 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
if (!shape_wrapper->active) {
continue;
}
- shapes[i].transform = shape_wrapper->transform;
-
- btConvexShape *&kin_shape_ref = shapes[i].shape;
+ shapes[i].transform = shape_wrapper->transform;
+ shapes[i].transform.getOrigin() *= owner_body_scale;
switch (shape_wrapper->shape->get_type()) {
- case PhysicsServer::SHAPE_SPHERE: {
- SphereShapeBullet *sphere = static_cast<SphereShapeBullet *>(shape_wrapper->shape);
- kin_shape_ref = ShapeBullet::create_shape_sphere(sphere->get_radius() * owner_body_scale[0] + safe_margin);
- break;
- }
- case PhysicsServer::SHAPE_BOX: {
- BoxShapeBullet *box = static_cast<BoxShapeBullet *>(shape_wrapper->shape);
- kin_shape_ref = ShapeBullet::create_shape_box((box->get_half_extents() * owner_body_scale) + btVector3(safe_margin, safe_margin, safe_margin));
- break;
- }
- case PhysicsServer::SHAPE_CAPSULE: {
- CapsuleShapeBullet *capsule = static_cast<CapsuleShapeBullet *>(shape_wrapper->shape);
-
- kin_shape_ref = ShapeBullet::create_shape_capsule(capsule->get_radius() * owner_body_scale[0] + safe_margin, capsule->get_height() * owner_body_scale[1] + safe_margin);
- break;
- }
- case PhysicsServer::SHAPE_CONVEX_POLYGON: {
- ConvexPolygonShapeBullet *godot_convex = static_cast<ConvexPolygonShapeBullet *>(shape_wrapper->shape);
- kin_shape_ref = ShapeBullet::create_shape_convex(godot_convex->vertices);
- kin_shape_ref->setLocalScaling(owner_body_scale + btVector3(safe_margin, safe_margin, safe_margin));
- break;
- }
+ case PhysicsServer::SHAPE_SPHERE:
+ case PhysicsServer::SHAPE_BOX:
+ case PhysicsServer::SHAPE_CAPSULE:
+ case PhysicsServer::SHAPE_CONVEX_POLYGON:
case PhysicsServer::SHAPE_RAY: {
- RayShapeBullet *godot_ray = static_cast<RayShapeBullet *>(shape_wrapper->shape);
- kin_shape_ref = ShapeBullet::create_shape_ray(godot_ray->length * owner_body_scale[1] + safe_margin);
- break;
- }
+ shapes[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_body_scale, safe_margin));
+ } break;
default:
WARN_PRINT("This shape is not supported to be kinematic!");
- kin_shape_ref = NULL;
+ shapes[i].shape = NULL;
}
}
}
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 55cc742f0a..d5a89e39e2 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -43,6 +43,17 @@ ShapeBullet::ShapeBullet() {}
ShapeBullet::~ShapeBullet() {}
+btCollisionShape *ShapeBullet::create_bt_shape() {
+ btVector3 s(1, 1, 1);
+ return create_bt_shape(s);
+}
+
+btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, real_t p_margin) {
+ btVector3 s;
+ G_TO_B(p_implicit_scale, s);
+ return create_bt_shape(s, p_margin);
+}
+
btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const {
p_btShape->setUserPointer(const_cast<ShapeBullet *>(this));
p_btShape->setMargin(0.);
@@ -150,7 +161,7 @@ void PlaneShapeBullet::setup(const Plane &p_plane) {
notifyShapeChanged();
}
-btCollisionShape *PlaneShapeBullet::create_bt_shape() {
+btCollisionShape *PlaneShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
btVector3 btPlaneNormal;
G_TO_B(plane.normal, btPlaneNormal);
return prepare(PlaneShapeBullet::create_shape_plane(btPlaneNormal, plane.d));
@@ -178,8 +189,8 @@ void SphereShapeBullet::setup(real_t p_radius) {
notifyShapeChanged();
}
-btCollisionShape *SphereShapeBullet::create_bt_shape() {
- return prepare(ShapeBullet::create_shape_sphere(radius));
+btCollisionShape *SphereShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+ return prepare(ShapeBullet::create_shape_sphere(radius * p_implicit_scale[0] + p_margin));
}
/* Box */
@@ -205,8 +216,8 @@ void BoxShapeBullet::setup(const Vector3 &p_half_extents) {
notifyShapeChanged();
}
-btCollisionShape *BoxShapeBullet::create_bt_shape() {
- return prepare(ShapeBullet::create_shape_box(half_extents));
+btCollisionShape *BoxShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+ return prepare(ShapeBullet::create_shape_box((half_extents * p_implicit_scale) + btVector3(p_margin, p_margin, p_margin)));
}
/* Capsule */
@@ -238,8 +249,8 @@ void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) {
notifyShapeChanged();
}
-btCollisionShape *CapsuleShapeBullet::create_bt_shape() {
- return prepare(ShapeBullet::create_shape_capsule(radius, height));
+btCollisionShape *CapsuleShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+ return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_margin, height * p_implicit_scale[1] + p_margin));
}
/* Convex polygon */
@@ -280,8 +291,12 @@ void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) {
notifyShapeChanged();
}
-btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape() {
- return prepare(ShapeBullet::create_shape_convex(vertices));
+btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+ btCollisionShape *cs(ShapeBullet::create_shape_convex(vertices));
+ cs->setLocalScaling(p_implicit_scale);
+ prepare(cs);
+ cs->setMargin(p_margin);
+ return cs;
}
/* Concave polygon */
@@ -349,13 +364,15 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
notifyShapeChanged();
}
-btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape() {
+btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
btCollisionShape *cs = ShapeBullet::create_shape_concave(meshShape);
- if (!cs) {
+ if (!cs)
// This is necessary since if 0 faces the creation of concave return NULL
cs = ShapeBullet::create_shape_empty();
- }
- return prepare(cs);
+ cs->setLocalScaling(p_implicit_scale);
+ prepare(cs);
+ cs->setMargin(p_margin);
+ return cs;
}
/* Height map shape */
@@ -407,8 +424,12 @@ void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int
notifyShapeChanged();
}
-btCollisionShape *HeightMapShapeBullet::create_bt_shape() {
- return prepare(ShapeBullet::create_shape_height_field(heights, width, depth, cell_size));
+btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+ btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, cell_size));
+ cs->setLocalScaling(p_implicit_scale);
+ prepare(cs);
+ cs->setMargin(p_margin);
+ return cs;
}
/* Ray shape */
@@ -433,6 +454,6 @@ void RayShapeBullet::setup(real_t p_length) {
notifyShapeChanged();
}
-btCollisionShape *RayShapeBullet::create_bt_shape() {
- return prepare(ShapeBullet::create_shape_ray(length));
+btCollisionShape *RayShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+ return prepare(ShapeBullet::create_shape_ray(length * p_implicit_scale[1] + p_margin));
}
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index fa12e95efc..a9782a9333 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -58,7 +58,9 @@ public:
ShapeBullet();
virtual ~ShapeBullet();
- virtual btCollisionShape *create_bt_shape() = 0;
+ btCollisionShape *create_bt_shape();
+ btCollisionShape *create_bt_shape(const Vector3 &p_implicit_scale, real_t p_margin = 0);
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0) = 0;
void add_owner(ShapeOwnerBullet *p_owner);
void remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody = false);
@@ -94,7 +96,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(const Plane &p_plane);
@@ -111,7 +113,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(real_t p_radius);
@@ -128,7 +130,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(const Vector3 &p_half_extents);
@@ -147,7 +149,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(real_t p_height, real_t p_radius);
@@ -164,7 +166,7 @@ public:
void get_vertices(Vector<Vector3> &out_vertices);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(const Vector<Vector3> &p_vertices);
@@ -182,7 +184,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(PoolVector<Vector3> p_faces);
@@ -201,7 +203,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size);
@@ -217,7 +219,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
virtual PhysicsServer::ShapeType get_type() const;
- virtual btCollisionShape *create_bt_shape();
+ virtual btCollisionShape *create_bt_shape(const btVector3 &p_scale, real_t p_margin = 0);
private:
void setup(real_t p_length);
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index dc16d8402d..a67c627ba4 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -116,7 +116,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
- btCollisionShape *btShape = shape->create_bt_shape();
+ btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin);
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
@@ -124,12 +124,9 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
}
btConvexShape *btConvex = static_cast<btConvexShape *>(btShape);
- btVector3 scale_with_margin;
- G_TO_B(p_xform.basis.get_scale(), scale_with_margin);
- btConvex->setLocalScaling(scale_with_margin);
-
btTransform bt_xform;
G_TO_B(p_xform, bt_xform);
+ UNSCALE_BT_BASIS(bt_xform);
btCollisionObject collision_object;
collision_object.setCollisionShape(btConvex);
@@ -138,7 +135,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
GodotAllContactResultCallback btQuery(&collision_object, p_results, p_result_max, &p_exclude);
btQuery.m_collisionFilterGroup = 0;
btQuery.m_collisionFilterMask = p_collision_mask;
- btQuery.m_closestDistanceThreshold = p_margin;
+ btQuery.m_closestDistanceThreshold = 0;
space->dynamicsWorld->contactTest(&collision_object, btQuery);
bulletdelete(btConvex);
@@ -149,7 +146,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, ShapeRestInfo *r_info) {
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
- btCollisionShape *btShape = shape->create_bt_shape();
+ btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin);
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
@@ -160,12 +157,9 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
btVector3 bt_motion;
G_TO_B(p_motion, bt_motion);
- btVector3 scale_with_margin;
- G_TO_B(p_xform.basis.get_scale() + Vector3(p_margin, p_margin, p_margin), scale_with_margin);
- bt_convex_shape->setLocalScaling(scale_with_margin);
-
btTransform bt_xform_from;
G_TO_B(p_xform, bt_xform_from);
+ UNSCALE_BT_BASIS(bt_xform_from);
btTransform bt_xform_to(bt_xform_from);
bt_xform_to.getOrigin() += bt_motion;
@@ -202,7 +196,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
- btCollisionShape *btShape = shape->create_bt_shape();
+ btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale(), p_margin);
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
@@ -210,12 +204,9 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
}
btConvexShape *btConvex = static_cast<btConvexShape *>(btShape);
- btVector3 scale_with_margin;
- G_TO_B(p_shape_xform.basis.get_scale(), scale_with_margin);
- btConvex->setLocalScaling(scale_with_margin);
-
btTransform bt_xform;
G_TO_B(p_shape_xform, bt_xform);
+ UNSCALE_BT_BASIS(bt_xform);
btCollisionObject collision_object;
collision_object.setCollisionShape(btConvex);
@@ -224,7 +215,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
GodotContactPairContactResultCallback btQuery(&collision_object, r_results, p_result_max, &p_exclude);
btQuery.m_collisionFilterGroup = 0;
btQuery.m_collisionFilterMask = p_collision_mask;
- btQuery.m_closestDistanceThreshold = p_margin;
+ btQuery.m_closestDistanceThreshold = 0;
space->dynamicsWorld->contactTest(&collision_object, btQuery);
r_result_count = btQuery.m_count;
@@ -237,7 +228,7 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
- btCollisionShape *btShape = shape->create_bt_shape();
+ btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale(), p_margin);
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
@@ -245,12 +236,9 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh
}
btConvexShape *btConvex = static_cast<btConvexShape *>(btShape);
- btVector3 scale_with_margin;
- G_TO_B(p_shape_xform.basis.get_scale() + Vector3(p_margin, p_margin, p_margin), scale_with_margin);
- btConvex->setLocalScaling(scale_with_margin);
-
btTransform bt_xform;
G_TO_B(p_shape_xform, bt_xform);
+ UNSCALE_BT_BASIS(bt_xform);
btCollisionObject collision_object;
collision_object.setCollisionShape(btConvex);
@@ -259,7 +247,7 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh
GodotRestInfoContactResultCallback btQuery(&collision_object, r_info, &p_exclude);
btQuery.m_collisionFilterGroup = 0;
btQuery.m_collisionFilterMask = p_collision_mask;
- btQuery.m_closestDistanceThreshold = p_margin;
+ btQuery.m_closestDistanceThreshold = 0;
space->dynamicsWorld->contactTest(&collision_object, btQuery);
bulletdelete(btConvex);
@@ -796,7 +784,9 @@ void SpaceBullet::update_gravity() {
/// I'm leaving this here just for future tests.
/// Debug motion and normal vector drawing
#define debug_test_motion 0
-#define PERFORM_INITIAL_UNSTACK 1
+#define PERFORM_INITIAL_UNSTACK 0
+#define RECOVERING_MOVEMENT_SCALE 0.4
+#define RECOVERING_MOVEMENT_CYCLES 4
#if debug_test_motion
@@ -820,6 +810,9 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
SceneTree::get_singleton()->get_current_scene()->add_child(motionVec);
SceneTree::get_singleton()->get_current_scene()->add_child(normalLine);
+ motionVec->set_as_toplevel(true);
+ normalLine->set_as_toplevel(true);
+
red_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
red_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
red_mat->set_line_width(20.0);
@@ -850,20 +843,24 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
// }
//}
- btVector3 recover_initial_position(0, 0, 0);
-
btTransform body_safe_position;
G_TO_B(p_from, body_safe_position);
+ UNSCALE_BT_BASIS(body_safe_position);
- { /// Phase one - multi shapes depenetration using margin
#if PERFORM_INITIAL_UNSTACK
- if (recover_from_penetration(p_body, body_safe_position, recover_initial_position)) {
+ btVector3 recover_initial_position(0, 0, 0);
+ { /// Phase one - multi shapes depenetration using margin
+ for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) {
+ if (recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, recover_initial_position)) {
- // Add recover position to "From" and "To" transforms
- body_safe_position.getOrigin() += recover_initial_position;
+ // Add recover position to "From" and "To" transforms
+ body_safe_position.getOrigin() += recover_initial_position;
+ } else {
+ break;
+ }
}
-#endif
}
+#endif
btVector3 recovered_motion;
G_TO_B(p_motion, recovered_motion);
@@ -872,13 +869,13 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
{ /// phase two - sweep test, from a secure position without margin
#if debug_test_motion
- Vector3 sup_line;
- B_TO_G(body_safe_position.getOrigin(), sup_line);
- motionVec->clear();
- motionVec->begin(Mesh::PRIMITIVE_LINES, NULL);
- motionVec->add_vertex(sup_line);
- motionVec->add_vertex(sup_line + p_motion * 10);
- motionVec->end();
+//Vector3 sup_line;
+//B_TO_G(body_safe_position.getOrigin(), sup_line);
+//motionVec->clear();
+//motionVec->begin(Mesh::PRIMITIVE_LINES, NULL);
+//motionVec->add_vertex(sup_line);
+//motionVec->add_vertex(sup_line + p_motion * 10);
+//motionVec->end();
#endif
for (int shIndex = 0; shIndex < shape_count; ++shIndex) {
@@ -892,11 +889,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
}
btConvexShape *convex_shape_test(static_cast<btConvexShape *>(p_body->get_bt_shape(shIndex)));
- btTransform shape_world_from;
- G_TO_B(p_body->get_shape_transform(shIndex), shape_world_from);
-
- // Add local shape transform
- shape_world_from = body_safe_position * shape_world_from;
+ btTransform shape_world_from = body_safe_position * p_body->get_kinematic_utilities()->shapes[shIndex].transform;
btTransform shape_world_to(shape_world_from);
shape_world_to.getOrigin() += recovered_motion;
@@ -915,59 +908,75 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
}
}
- bool hasPenetration = false;
+ bool has_penetration = false;
{ /// Phase three - Recover + contact test with margin
RecoverResult r_recover_result;
+ bool l_has_penetration;
+ real_t l_penetration_distance = 1e20;
- hasPenetration = recover_from_penetration(p_body, body_safe_position, recovered_motion, &r_recover_result);
+ for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) {
+ l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, recovered_motion, &r_recover_result);
- if (r_result) {
-
- B_TO_G(recovered_motion + recover_initial_position, r_result->motion);
-
- if (hasPenetration) {
- const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object);
- CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer());
-
- r_result->remainder = p_motion - r_result->motion; // is the remaining movements
- B_TO_G(r_recover_result.pointWorld, r_result->collision_point);
- B_TO_G(r_recover_result.pointNormalWorld, r_result->collision_normal);
- B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot
- r_result->collider = collisionObject->get_self();
- r_result->collider_id = collisionObject->get_instance_id();
- r_result->collider_shape = r_recover_result.other_compound_shape_index;
- r_result->collision_local_shape = r_recover_result.local_shape_most_recovered;
+ if (r_result) {
+#if PERFORM_INITIAL_UNSTACK
+ B_TO_G(recovered_motion + recover_initial_position, r_result->motion);
+#else
+ B_TO_G(recovered_motion, r_result->motion);
+#endif
+ if (l_has_penetration) {
+ has_penetration = true;
+ if (l_penetration_distance <= r_recover_result.penetration_distance) {
+ continue;
+ }
- //{ /// Add manifold point to manage collisions
- // btPersistentManifold* manifold = dynamicsWorld->getDispatcher()->getNewManifold(p_body->getBtBody(), btRigid);
- // btManifoldPoint manifoldPoint(result_callabck.m_pointWorld, result_callabck.m_pointWorld, result_callabck.m_pointNormalWorld, result_callabck.m_penetration_distance);
- // manifoldPoint.m_index0 = r_result->collision_local_shape;
- // manifoldPoint.m_index1 = r_result->collider_shape;
- // manifold->addManifoldPoint(manifoldPoint);
- // p_body->get_kinematic_utilities()->m_generatedManifold.push_back(manifold);
- //}
+ l_penetration_distance = r_recover_result.penetration_distance;
+
+ const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object);
+ CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer());
+
+ r_result->remainder = p_motion - r_result->motion; // is the remaining movements
+ B_TO_G(r_recover_result.pointWorld, r_result->collision_point);
+ B_TO_G(r_recover_result.normal, r_result->collision_normal);
+ B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot
+ r_result->collider = collisionObject->get_self();
+ r_result->collider_id = collisionObject->get_instance_id();
+ r_result->collider_shape = r_recover_result.other_compound_shape_index;
+ r_result->collision_local_shape = r_recover_result.local_shape_most_recovered;
+
+ //{ /// Add manifold point to manage collisions
+ // btPersistentManifold* manifold = dynamicsWorld->getDispatcher()->getNewManifold(p_body->getBtBody(), btRigid);
+ // btManifoldPoint manifoldPoint(result_callabck.m_pointWorld, result_callabck.m_pointWorld, result_callabck.m_pointNormalWorld, result_callabck.m_penetration_distance);
+ // manifoldPoint.m_index0 = r_result->collision_local_shape;
+ // manifoldPoint.m_index1 = r_result->collider_shape;
+ // manifold->addManifoldPoint(manifoldPoint);
+ // p_body->get_kinematic_utilities()->m_generatedManifold.push_back(manifold);
+ //}
#if debug_test_motion
- Vector3 sup_line2;
- B_TO_G(recovered_motion, sup_line2);
- //Vector3 sup_pos;
- //B_TO_G( pt.getPositionWorldOnB(), sup_pos);
- normalLine->clear();
- normalLine->begin(Mesh::PRIMITIVE_LINES, NULL);
- normalLine->add_vertex(r_result->collision_point);
- normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10);
- normalLine->end();
+//Vector3 sup_line2;
+//B_TO_G(recovered_motion, sup_line2);
+////Vector3 sup_pos;
+////B_TO_G( pt.getPositionWorldOnB(), sup_pos);
+//normalLine->clear();
+//normalLine->begin(Mesh::PRIMITIVE_LINES, NULL);
+//normalLine->add_vertex(r_result->collision_point);
+//normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10);
+//normalLine->end();
#endif
+ } else {
+ r_result->remainder = Vector3();
+ }
} else {
- r_result->remainder = Vector3();
+ if (!l_has_penetration)
+ break;
}
}
}
- return hasPenetration;
+ return has_penetration;
}
struct RecoverPenetrationBroadPhaseCallback : public btBroadphaseAabbCallback {
@@ -1004,7 +1013,7 @@ public:
}
};
-bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btVector3 &r_recover_position, RecoverResult *r_recover_result) {
+bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result) {
RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask());
@@ -1045,24 +1054,24 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
for (int x = cs->getNumChildShapes() - 1; 0 <= x; --x) {
if (cs->getChildShape(x)->isConvex()) {
- if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), otherObject, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), r_recover_position, r_recover_result)) {
+ if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), otherObject, x, body_shape_position_recovered, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_recover_position, r_recover_result)) {
penetration = true;
}
} else {
- if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), r_recover_position, r_recover_result)) {
+ if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position_recovered, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_recover_position, r_recover_result)) {
penetration = true;
}
}
}
} else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape
- if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, 0, body_shape_position, otherObject->getWorldTransform(), r_recover_position, r_recover_result)) {
+ if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, 0, body_shape_position_recovered, otherObject->getWorldTransform(), p_recover_movement_scale, r_recover_position, r_recover_result)) {
penetration = true;
}
} else {
- if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, body_shape_position, otherObject->getWorldTransform(), r_recover_position, r_recover_result)) {
+ if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, body_shape_position_recovered, otherObject->getWorldTransform(), p_recover_movement_scale, r_recover_position, r_recover_result)) {
penetration = true;
}
@@ -1070,15 +1079,26 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
}
}
+#if debug_test_motion
+ Vector3 pos;
+ B_TO_G(p_body_position.getOrigin(), pos);
+ Vector3 sup_line;
+ B_TO_G(sum_recover_normals, sup_line);
+ motionVec->clear();
+ motionVec->begin(Mesh::PRIMITIVE_LINES, NULL);
+ motionVec->add_vertex(pos);
+ motionVec->add_vertex(pos + (sup_line * 10));
+ motionVec->end();
+#endif
+
return penetration;
}
-bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result) {
+bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result) {
// Initialize GJK input
btGjkPairDetector::ClosestPointInput gjk_input;
gjk_input.m_transformA = p_transformA;
- gjk_input.m_transformA.getOrigin() += r_recover_position;
gjk_input.m_transformB = p_transformB;
// Perform GJK test
@@ -1087,30 +1107,28 @@ bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const bt
gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
if (0 > result.m_distance) {
// Has penetration
- r_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1);
+ r_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1 * p_recover_movement_scale);
if (r_recover_result) {
-
- r_recover_result->hasPenetration = true;
- r_recover_result->other_collision_object = p_objectB;
- r_recover_result->other_compound_shape_index = p_shapeId_B;
- r_recover_result->penetration_distance = result.m_distance;
- r_recover_result->pointNormalWorld = result.m_normalOnBInWorld;
- r_recover_result->pointWorld = result.m_pointInWorld;
+ if (result.m_distance < r_recover_result->penetration_distance) {
+ r_recover_result->hasPenetration = true;
+ r_recover_result->other_collision_object = p_objectB;
+ r_recover_result->other_compound_shape_index = p_shapeId_B;
+ r_recover_result->penetration_distance = result.m_distance;
+ r_recover_result->pointWorld = result.m_pointInWorld;
+ r_recover_result->normal = result.m_normalOnBInWorld;
+ }
}
return true;
}
return false;
}
-bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result) {
+bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result) {
/// Contact test
- btTransform p_recovered_transformA(p_transformA);
- p_recovered_transformA.getOrigin() += r_recover_position;
-
- btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, p_recovered_transformA, -1, p_shapeId_A);
+ btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, p_transformA, -1, p_shapeId_A);
btCollisionObjectWrapper obB(NULL, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B);
btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CLOSEST_POINT_ALGORITHMS);
@@ -1123,16 +1141,17 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
dispatcher->freeCollisionAlgorithm(algorithm);
if (contactPointResult.hasHit()) {
- r_recover_position += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1);
+ r_recover_position += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1 * p_recover_movement_scale);
if (r_recover_result) {
-
- r_recover_result->hasPenetration = true;
- r_recover_result->other_collision_object = p_objectB;
- r_recover_result->other_compound_shape_index = p_shapeId_B;
- r_recover_result->penetration_distance = contactPointResult.m_penetration_distance;
- r_recover_result->pointNormalWorld = contactPointResult.m_pointNormalWorld;
- r_recover_result->pointWorld = contactPointResult.m_pointWorld;
+ if (contactPointResult.m_penetration_distance < r_recover_result->penetration_distance) {
+ r_recover_result->hasPenetration = true;
+ r_recover_result->other_collision_object = p_objectB;
+ r_recover_result->other_compound_shape_index = p_shapeId_B;
+ r_recover_result->penetration_distance = contactPointResult.m_penetration_distance;
+ r_recover_result->pointWorld = contactPointResult.m_pointWorld;
+ r_recover_result->normal = contactPointResult.m_pointNormalWorld;
+ }
}
return true;
}
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index 6e71a25773..69ea2fcc58 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -178,23 +178,24 @@ private:
struct RecoverResult {
bool hasPenetration;
- btVector3 pointNormalWorld;
+ btVector3 normal;
btVector3 pointWorld;
- btScalar penetration_distance; // Negative is penetration
+ btScalar penetration_distance; // Negative mean penetration
int other_compound_shape_index;
const btCollisionObject *other_collision_object;
int local_shape_most_recovered;
RecoverResult() :
- hasPenetration(false) {}
+ hasPenetration(false),
+ penetration_distance(1e20) {}
};
- bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL);
+ bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL);
/// This is an API that recover a kinematic object from penetration
/// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions
- bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result);
+ bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL);
/// This is an API that recover a kinematic object from penetration
/// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm
- bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result);
+ bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL);
};
#endif
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 7ab3d0a140..786c2bf051 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -164,6 +164,14 @@ String AudioStreamOGGVorbis::get_stream_name() const {
return ""; //return stream_name;
}
+void AudioStreamOGGVorbis::clear_data() {
+ if (data) {
+ AudioServer::get_singleton()->audio_data_free(data);
+ data = NULL;
+ data_len = 0;
+ }
+}
+
void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
int src_data_len = p_data.size();
@@ -209,6 +217,9 @@ void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
length = stb_vorbis_stream_length_in_seconds(ogg_stream);
stb_vorbis_close(ogg_stream);
+ // free any existing data
+ clear_data();
+
data = AudioServer::get_singleton()->audio_data_alloc(src_data_len, src_datar.ptr());
data_len = src_data_len;
@@ -275,3 +286,7 @@ AudioStreamOGGVorbis::AudioStreamOGGVorbis() {
decode_mem_size = 0;
loop = false;
}
+
+AudioStreamOGGVorbis::~AudioStreamOGGVorbis() {
+ clear_data();
+}
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index f920047703..8644e1ba37 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -93,6 +93,7 @@ class AudioStreamOGGVorbis : public AudioStream {
float length;
bool loop;
float loop_offset;
+ void clear_data();
protected:
static void _bind_methods();
@@ -111,6 +112,7 @@ public:
PoolVector<uint8_t> get_data() const;
AudioStreamOGGVorbis();
+ virtual ~AudioStreamOGGVorbis();
};
#endif
diff --git a/modules/thekla_unwrap/SCsub b/modules/thekla_unwrap/SCsub
index c57bf326ea..d23ba10d4c 100644
--- a/modules/thekla_unwrap/SCsub
+++ b/modules/thekla_unwrap/SCsub
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+import platform
+
Import('env')
Import('env_modules')
@@ -60,7 +62,13 @@ if env['builtin_thekla_atlas']:
env_thekla_unwrap.Append(CXXFLAGS="-std=c++11")
if env["platform"] == 'x11':
- env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_LINUX", "-DPOSH_COMPILER_GCC"])
+ # if not specifically one of the *BSD, then use LINUX as default
+ if platform.system() == "FreeBSD":
+ env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_FREEBSD", "-DPOSH_COMPILER_GCC"])
+ elif platform.system() == "OpenBSD":
+ env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_OPENBSD", "-DPOSH_COMPILER_GCC"])
+ else:
+ env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_LINUX", "-DPOSH_COMPILER_GCC"])
elif env["platform"] == 'osx':
env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_DARWIN", "-DPOSH_COMPILER_GCC"])
elif env["platform"] == 'windows':
@@ -69,6 +77,6 @@ if env['builtin_thekla_atlas']:
else:
env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_MINGW", "-DNV_CC_GNUC", "-DPOSH_COMPILER_GCC", "-U__STRICT_ANSI__"])
env.Append(LIBS=["dbghelp"])
-
+
# Godot source files
env_thekla_unwrap.add_source_files(env.modules_sources, "*.cpp")
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 2d1d976399..1ebadd337e 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -114,7 +114,7 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p
visual_server = memnew(VisualServerRaster(rasterizer));
- ERR_FAIL_COND(!visual_server, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
// TODO: enable multithreaded VS
/*
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 6c2b6799a6..a3514df05c 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -174,14 +174,14 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
}
if (template_path != String() && !FileAccess::exists(template_path)) {
- EditorNode::get_singleton()->show_warning(TTR("Template file not found:\n") + template_path);
+ EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
return ERR_FILE_NOT_FOUND;
}
String pck_path = p_path.get_basename() + ".pck";
Error error = save_pack(p_preset, pck_path);
if (error != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + pck_path);
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
return error;
}
@@ -191,12 +191,12 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
if (!pkg) {
- EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:\n") + template_path);
+ EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + template_path);
return ERR_FILE_NOT_FOUND;
}
if (unzGoToFirstFile(pkg) != UNZ_OK) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid export template:\n") + template_path);
+ EditorNode::get_singleton()->show_warning(TTR("Invalid export template:") + "\n" + template_path);
unzClose(pkg);
return ERR_FILE_CORRUPT;
}
@@ -238,7 +238,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
String dst = p_path.get_base_dir().plus_file(file);
FileAccess *f = FileAccess::open(dst, FileAccess::WRITE);
if (!f) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + dst);
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + dst);
unzClose(pkg);
return ERR_FILE_CANT_WRITE;
}
@@ -252,7 +252,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
FileAccess *f = FileAccess::open(custom_html, FileAccess::READ);
if (!f) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:\n") + custom_html);
+ EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:") + "\n" + custom_html);
return ERR_FILE_CANT_READ;
}
Vector<uint8_t> buf;
@@ -263,7 +263,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
f = FileAccess::open(p_path, FileAccess::WRITE);
if (!f) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + p_path);
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + p_path);
return ERR_FILE_CANT_WRITE;
}
f->store_buffer(buf.ptr(), buf.size());
@@ -277,7 +277,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
splash.instance();
Error err = splash->load(splash_path);
if (err) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:\n") + splash_path + "\nUsing default boot splash image");
+ EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:") + "\n" + splash_path + "\n" + TTR("Using default boot splash image."));
splash.unref();
}
}
@@ -286,7 +286,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
}
String png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png");
if (splash->save_png(png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + png_path);
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + png_path);
return ERR_FILE_CANT_WRITE;
}
return OK;
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 665280df96..26fb380aed 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -429,7 +429,7 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
attributes.antialias = false;
attributes.majorVersion = 2;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
- ERR_FAIL_COND(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE);
video_mode = p_desired;
// can't fulfil fullscreen request due to browser security
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 657a899367..23ca1e3fb9 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -541,7 +541,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
} else {
String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck");
- Error err = save_pack(p_preset, pack_path);
+
+ Vector<SharedObject> shared_objects;
+ Error err = save_pack(p_preset, pack_path, &shared_objects);
if (err == OK) {
zipOpenNewFileInZip(dst_pkg_zip,
@@ -567,11 +569,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
break;
zipWriteInFileInZip(dst_pkg_zip, buf, r);
}
+
zipCloseFileInZip(dst_pkg_zip);
memdelete(pf);
} else {
err = ERR_CANT_OPEN;
}
+
+ //add shared objects
+ for (int i = 0; i < shared_objects.size(); i++) {
+ Vector<uint8_t> file = FileAccess::get_file_as_array(shared_objects[i].path);
+ ERR_CONTINUE(file.empty());
+
+ zipOpenNewFileInZip(dst_pkg_zip,
+ (pkg_name + ".app/Contents/MacOS/").plus_file(shared_objects[i].path.get_file()).utf8().get_data(),
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ Z_DEFLATED,
+ Z_DEFAULT_COMPRESSION);
+
+ zipWriteInFileInZip(dst_pkg_zip, file.ptr(), file.size());
+ zipCloseFileInZip(dst_pkg_zip);
+ }
}
}
}
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index a16391c30f..d8dd2eb1db 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1013,7 +1013,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
backing:NSBackingStoreBuffered
defer:NO];
- ERR_FAIL_COND(window_object == nil, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(window_object == nil, ERR_UNAVAILABLE);
window_view = [[GodotContentView alloc] init];
@@ -1100,11 +1100,11 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
#undef ADD_ATTR2
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
- ERR_FAIL_COND(pixelFormat == nil, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(pixelFormat == nil, ERR_UNAVAILABLE);
context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
- ERR_FAIL_COND(context == nil, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(context == nil, ERR_UNAVAILABLE);
[context setView:window_view];
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index e8d076322c..410fea153a 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -67,7 +67,7 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
spatial_sound_2d_server = memnew(SpatialSound2DServerSW);
spatial_sound_2d_server->init();
- ERR_FAIL_COND(!visual_server, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
visual_server->init();
@@ -77,6 +77,7 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
return OK;
}
+
void OS_Server::finalize() {
if (main_loop)
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index a48ae8cc8c..22294005f6 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1633,6 +1633,13 @@ void OS_Windows::_update_window_style(bool repaint) {
Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+ String path = p_path;
+
+ if (!FileAccess::exists(path)) {
+ //this code exists so gdnative can load .dll files from within the executable path
+ path = get_executable_path().get_base_dir().plus_file(p_path.get_file());
+ }
+
typedef DLL_DIRECTORY_COOKIE(WINAPI * PAddDllDirectory)(PCWSTR);
typedef BOOL(WINAPI * PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
@@ -1643,10 +1650,10 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han
DLL_DIRECTORY_COOKIE cookie;
if (p_also_set_library_path && has_dll_directory_api) {
- cookie = add_dll_directory(p_path.get_base_dir().c_str());
+ cookie = add_dll_directory(path.get_base_dir().c_str());
}
- p_library_handle = (void *)LoadLibraryExW(p_path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
+ p_library_handle = (void *)LoadLibraryExW(path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
if (p_also_set_library_path && has_dll_directory_api) {
remove_dll_directory(cookie);
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 7999f50013..97f7c65cbe 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -122,8 +122,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
for (int i = 0; i < items.size(); i++) {
- if (i > 0)
- ofs.y += vseparation;
+ ofs.y += vseparation;
float h;
if (!items[i].icon.is_null()) {
@@ -459,7 +458,7 @@ void PopupMenu::_notification(int p_what) {
if (i == mouse_over) {
- hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation * 2)));
+ hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation)));
}
if (items[i].separator) {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 87043c65eb..95c4b9058d 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1746,15 +1746,15 @@ void TextEdit::indent_left() {
void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const {
float rows = p_mouse.y;
- rows -= cache.style_normal->get_margin(MARGIN_TOP);
rows /= get_row_height();
- int lsp = get_line_scroll_pos(true);
- int row = cursor.line_ofs + (rows + (round(v_scroll->get_value()) - lsp));
+ rows += v_scroll->get_value();
+ int row = Math::floor(rows);
if (is_hiding_enabled()) {
// row will be offset by the hidden rows
- int f_ofs = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(rows + 1, text.size() - cursor.line_ofs)) - 1;
- row = cursor.line_ofs + (f_ofs + (round(v_scroll->get_value()) - lsp));
+ int lsp = get_line_scroll_pos(true);
+ int f_ofs = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(row + 1 - cursor.line_ofs, text.size() - cursor.line_ofs)) - 1;
+ row = cursor.line_ofs + f_ofs;
row = CLAMP(row, 0, text.size() - num_lines_from(text.size() - 1, -1));
}
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index bf6d425fb9..531c6045d6 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -711,7 +711,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
if (first) {
for (int i = 0; i < total_bones; i++) {
- r_bone_aabb[i].size == Vector3(-1, -1, -1); //negative means unused
+ r_bone_aabb[i].size = Vector3(-1, -1, -1); //negative means unused
}
}