diff options
49 files changed, 438 insertions, 546 deletions
diff --git a/core/dictionary.cpp b/core/dictionary.cpp index 1b431f9ec9..48e65c734f 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -61,7 +61,7 @@ Variant &Dictionary::operator[](const Variant &p_key) { const Variant &Dictionary::operator[](const Variant &p_key) const { - return ((const OrderedHashMap<Variant, Variant, _DictionaryVariantHash> *)&_p->variant_map)->operator[](p_key); + return _p->variant_map[p_key]; } const Variant *Dictionary::getptr(const Variant &p_key) const { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 7715e5d6e5..d5135fe414 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -271,7 +271,7 @@ public: #elif defined(_MSC_VER) && _MSC_VER < 1800 __asm fld a __asm fistp b - /*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) +/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) // use AT&T inline assembly style, document that // we use memory as output (=m) and input (m) __asm__ __volatile__ ( diff --git a/core/os/os.h b/core/os/os.h index f5e479ac0b..faecdb0e07 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -109,8 +109,6 @@ protected: virtual int get_video_driver_count() const = 0; virtual const char *get_video_driver_name(int p_driver) const = 0; - virtual VideoMode get_default_video_mode() const = 0; - virtual int get_audio_driver_count() const = 0; virtual const char *get_audio_driver_name(int p_driver) const = 0; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 8ec988bec1..9a92e63c0c 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1134,9 +1134,9 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m state.current_depth_draw = p_material->shader->spatial.depth_draw_mode; } - //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); +//glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - /* +/* if (p_material->flags[VS::MATERIAL_FLAG_WIREFRAME]) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); else diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 87e73534c4..82c7dee3b9 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -49,7 +49,6 @@ protected: //virtual int get_video_driver_count() const; //virtual const char * get_video_driver_name(int p_driver) const; - //virtual VideoMode get_default_video_mode() const; virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3513126a9b..3d171b692c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1933,6 +1933,15 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case FILE_EXPORT_TILESET: { + //Make sure that the scene has a root before trying to convert to tileset + if (!editor_data.get_edited_scene_root()) { + current_option = -1; + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation can't be done without a root node.")); + accept->popup_centered_minsize(); + break; + } + List<String> extensions; Ref<TileSet> ml(memnew(TileSet)); ResourceSaver::get_recognized_extensions(ml, &extensions); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index cd53264437..d2e7feb6e1 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -33,6 +33,8 @@ #include "editor_settings.h" #include "io/json.h" +#include "version_generated.gen.h" + void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, const String &p_category, int p_category_id, const String &p_author, int p_author_id, int p_rating, const String &p_cost) { title->set_text(p_title); @@ -867,6 +869,8 @@ void EditorAssetLibrary::_search(int p_page) { } args += String() + "sort=" + sort_key[sort->get_selected()]; + args += "&godot_version=" + itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR); + String support_list; for (int i = 0; i < SUPPORT_MAX; i++) { if (support->get_popup()->is_item_checked(i)) { @@ -1348,13 +1352,11 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { search_hb2->add_child(memnew(Label(TTR("Site:") + " "))); repository = memnew(OptionButton); - // FIXME: Reenable me once GH-7147 is fixed. - /* repository->add_item("godotengine.org"); repository->set_item_metadata(0, "https://godotengine.org/asset-library/api"); - */ repository->add_item("localhost"); - repository->set_item_metadata(/*1*/ 0, "http://127.0.0.1/asset-library/api"); + repository->set_item_metadata(1, "http://127.0.0.1/asset-library/api"); + repository->connect("item_selected", this, "_repository_changed"); search_hb2->add_child(repository); diff --git a/main/main.cpp b/main/main.cpp index 5e8e52d3e5..aa4dce93a6 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -321,8 +321,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph I = args.front(); - video_mode = OS::get_singleton()->get_default_video_mode(); - String video_driver = ""; String audio_driver = ""; String game_path = "."; @@ -779,38 +777,41 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph //if (video_driver == "") // useless for now, so removing // video_driver = GLOBAL_DEF("display/driver/name", Variant((const char *)OS::get_singleton()->get_video_driver_name(0))); - if (!force_res && use_custom_res && globals->has_setting("display/window/size/width")) - video_mode.width = globals->get("display/window/size/width"); - if (!force_res && use_custom_res && globals->has_setting("display/window/size/height")) - video_mode.height = globals->get("display/window/size/height"); - if (!editor && ((globals->has_setting("display/window/dpi/allow_hidpi") && !globals->get("display/window/dpi/allow_hidpi")) || force_lowdpi)) { - OS::get_singleton()->_allow_hidpi = false; - } - if (use_custom_res && globals->has_setting("display/window/size/fullscreen")) - video_mode.fullscreen = globals->get("display/window/size/fullscreen"); - if (use_custom_res && globals->has_setting("display/window/size/resizable")) - video_mode.resizable = globals->get("display/window/size/resizable"); - if (use_custom_res && globals->has_setting("display/window/size/borderless")) - video_mode.borderless_window = globals->get("display/window/size/borderless"); - - if (!force_res && use_custom_res && globals->has_setting("display/window/size/test_width") && globals->has_setting("display/window/size/test_height")) { - int tw = globals->get("display/window/size/test_width"); - int th = globals->get("display/window/size/test_height"); - if (tw > 0 && th > 0) { - video_mode.width = tw; - video_mode.height = th; + GLOBAL_DEF("display/window/size/width", 1024); + GLOBAL_DEF("display/window/size/height", 600); + GLOBAL_DEF("display/window/size/resizable", true); + GLOBAL_DEF("display/window/size/borderless", false); + GLOBAL_DEF("display/window/size/fullscreen", false); + GLOBAL_DEF("display/window/size/test_width", 0); + GLOBAL_DEF("display/window/size/test_height", 0); + + if (use_custom_res) { + + if (!force_res) { + video_mode.width = GLOBAL_GET("display/window/size/width"); + video_mode.height = GLOBAL_GET("display/window/size/height"); + + if (globals->has_setting("display/window/size/test_width") && globals->has_setting("display/window/size/test_height")) { + int tw = globals->get("display/window/size/test_width"); + int th = globals->get("display/window/size/test_height"); + if (tw > 0 && th > 0) { + video_mode.width = tw; + video_mode.height = th; + } + } } + + video_mode.resizable = GLOBAL_GET("display/window/size/resizable"); + video_mode.borderless_window = GLOBAL_GET("display/window/size/borderless"); + video_mode.fullscreen = GLOBAL_GET("display/window/size/fullscreen"); } - GLOBAL_DEF("display/window/size/width", video_mode.width); - GLOBAL_DEF("display/window/size/height", video_mode.height); - GLOBAL_DEF("display/window/dpi/allow_hidpi", false); - GLOBAL_DEF("display/window/size/fullscreen", video_mode.fullscreen); - GLOBAL_DEF("display/window/size/resizable", video_mode.resizable); - GLOBAL_DEF("display/window/size/borderless", video_mode.borderless_window); - use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", use_vsync); - GLOBAL_DEF("display/window/size/test_width", 0); - GLOBAL_DEF("display/window/size/test_height", 0); + if (!force_lowdpi) { + OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false); + } + + use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", true); + GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2); GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3); diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 96875924a5..7f95d16ba6 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -635,6 +635,28 @@ float BulletPhysicsServer::body_get_param(RID p_body, BodyParameter p_param) con return body->get_param(p_param); } +void BulletPhysicsServer::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { + RigidBodyBullet *body = rigid_body_owner.get(p_body); + ERR_FAIL_COND(!body); + + if (body->get_kinematic_utilities()) { + + body->get_kinematic_utilities()->setSafeMargin(p_margin); + } +} + +real_t BulletPhysicsServer::body_get_kinematic_safe_margin(RID p_body) const { + RigidBodyBullet *body = rigid_body_owner.get(p_body); + ERR_FAIL_COND_V(!body, 0); + + if (body->get_kinematic_utilities()) { + + return body->get_kinematic_utilities()->safe_margin; + } + + return 0; +} + void BulletPhysicsServer::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { RigidBodyBullet *body = rigid_body_owner.get(p_body); ERR_FAIL_COND(!body); @@ -797,12 +819,12 @@ PhysicsDirectBodyState *BulletPhysicsServer::body_get_direct_state(RID p_body) { return BulletPhysicsDirectBodyState::get_singleton(body); } -bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin, MotionResult *r_result) { +bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result) { RigidBodyBullet *body = rigid_body_owner.get(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); - return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result); + return body->get_space()->test_body_motion(body, p_from, p_motion, r_result); } RID BulletPhysicsServer::soft_body_create(bool p_init_sleeping) { diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 04d9d89594..ad8137ee2f 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -210,6 +210,9 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value); virtual float body_get_param(RID p_body, BodyParameter p_param) const; + virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin); + virtual real_t body_get_kinematic_safe_margin(RID p_body) const; + virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant); virtual Variant body_get_state(RID p_body, BodyState p_state) const; @@ -247,7 +250,7 @@ public: // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body); - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL); + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL); /* SOFT BODY API */ diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 769e2c943e..91a049b1f3 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -105,7 +105,7 @@ void CollisionObjectBullet::remove_collision_exception(const CollisionObjectBull } bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const { - return !bt_collision_object->checkCollideWithOverride(p_otherCollisionObject->bt_collision_object); + return !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object); } void CollisionObjectBullet::set_collision_enabled(bool p_enabled) { diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 409d12f080..bc60c9cb6b 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -242,50 +242,3 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp return cp.getDistance(); } - -bool GodotRecoverAndClosestContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { - const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask); - if (needs) { - btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); - CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer()); - if (gObj == m_self_object) { - return false; - } else { - if (m_ignore_areas && gObj->getType() == CollisionObjectBullet::TYPE_AREA) { - return false; - } else if (m_self_object->has_collision_exception(gObj)) { - return false; - } - } - return true; - } else { - return false; - } -} - -btScalar GodotRecoverAndClosestContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) { - - if (cp.getDistance() < -MAX_PENETRATION_DEPTH) { - if (m_most_penetrated_distance > cp.getDistance()) { - m_most_penetrated_distance = cp.getDistance(); - - // take other object - btScalar sign(1); - if (m_self_object == colObj0Wrap->getCollisionObject()->getUserPointer()) { - m_pointCollisionObject = colObj1Wrap->getCollisionObject(); - m_other_compound_shape_index = cp.m_index1; - } else { - m_pointCollisionObject = colObj0Wrap->getCollisionObject(); - sign = -1; - m_other_compound_shape_index = cp.m_index0; - } - - m_pointNormalWorld = cp.m_normalWorldOnB * sign; - m_pointWorld = cp.getPositionWorldOnB(); - m_penetration_distance = cp.getDistance(); - - m_recover_penetration -= cp.m_normalWorldOnB * sign * (cp.getDistance() + MAX_PENETRATION_DEPTH); - } - } - return 1; -} diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index d505bd0de1..68dff5b12a 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -36,8 +36,6 @@ #include "btBulletDynamicsCommon.h" #include "servers/physics_server.h" -#define MAX_PENETRATION_DEPTH 0.005 - class RigidBodyBullet; /// This class is required to implement custom collision behaviour in the broadphase @@ -151,39 +149,4 @@ public: virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); }; -struct GodotRecoverAndClosestContactResultCallback : public btCollisionWorld::ContactResultCallback { -public: - btVector3 m_pointNormalWorld; - btVector3 m_pointWorld; - btScalar m_penetration_distance; - int m_other_compound_shape_index; - const btCollisionObject *m_pointCollisionObject; - - const RigidBodyBullet *m_self_object; - bool m_ignore_areas; - - btScalar m_most_penetrated_distance; - btVector3 m_recover_penetration; - - GodotRecoverAndClosestContactResultCallback() - : m_pointCollisionObject(NULL), m_penetration_distance(0), m_other_compound_shape_index(0), m_self_object(NULL), m_ignore_areas(true), m_most_penetrated_distance(1e20), m_recover_penetration(0, 0, 0) {} - - GodotRecoverAndClosestContactResultCallback(const RigidBodyBullet *p_self_object, bool p_ignore_areas) - : m_pointCollisionObject(NULL), m_penetration_distance(0), m_other_compound_shape_index(0), m_self_object(p_self_object), m_ignore_areas(p_ignore_areas), m_most_penetrated_distance(9999999999), m_recover_penetration(0, 0, 0) {} - - void reset() { - m_pointCollisionObject = NULL; - m_most_penetrated_distance = 1e20; - m_recover_penetration.setZero(); - } - - bool hasHit() { - return m_pointCollisionObject; - } - - virtual bool needsCollision(btBroadphaseProxy *proxy0) const; - - virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); -}; - #endif // GODOT_RESULT_CALLBACKS_H diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 5d0513db76..98ae82bc5f 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -177,31 +177,21 @@ PhysicsDirectSpaceState *BulletPhysicsDirectBodyState::get_space_state() { } RigidBodyBullet::KinematicUtilities::KinematicUtilities(RigidBodyBullet *p_owner) - : m_owner(p_owner), m_margin(0.01) // Godot default margin 0.001 -{ - m_ghostObject = bulletnew(btPairCachingGhostObject); - - int clearedCurrentFlags = m_ghostObject->getCollisionFlags(); - clearedCurrentFlags &= ~(btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT); - - m_ghostObject->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_KINEMATIC_OBJECT); - m_ghostObject->setUserPointer(p_owner); - m_ghostObject->setUserIndex(TYPE_KINEMATIC_GHOST_BODY); - - resetDefShape(); + : owner(p_owner), + safe_margin(0.001) { } RigidBodyBullet::KinematicUtilities::~KinematicUtilities() { - just_delete_shapes(m_shapes.size()); // don't need to resize - bulletdelete(m_ghostObject); + just_delete_shapes(shapes.size()); // don't need to resize } -void RigidBodyBullet::KinematicUtilities::resetDefShape() { - m_ghostObject->setCollisionShape(BulletPhysicsServer::get_empty_shape()); +void RigidBodyBullet::KinematicUtilities::setSafeMargin(btScalar p_margin) { + safe_margin = p_margin; + copyAllOwnerShapes(); } void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { - const Vector<CollisionObjectBullet::ShapeWrapper> &shapes_wrappers(m_owner->get_shapes_wrappers()); + const Vector<CollisionObjectBullet::ShapeWrapper> &shapes_wrappers(owner->get_shapes_wrappers()); const int shapes_count = shapes_wrappers.size(); just_delete_shapes(shapes_count); @@ -213,35 +203,35 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { if (!shape_wrapper->active) { continue; } - m_shapes[i].transform = shape_wrapper->transform; + shapes[i].transform = shape_wrapper->transform; - btConvexShape *&kin_shape_ref = m_shapes[i].shape; + btConvexShape *&kin_shape_ref = shapes[i].shape; 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() * m_owner->body_scale[0] + m_margin); + 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() * m_owner->body_scale) + btVector3(m_margin, m_margin, m_margin)); + 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() * m_owner->body_scale[0] + m_margin, capsule->get_height() * m_owner->body_scale[1] + m_margin); + 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(m_owner->body_scale + btVector3(m_margin, m_margin, m_margin)); + kin_shape_ref->setLocalScaling(owner->body_scale + btVector3(safe_margin, safe_margin, safe_margin)); break; } case PhysicsServer::SHAPE_RAY: { RayShapeBullet *godot_ray = static_cast<RayShapeBullet *>(shape_wrapper->shape); - kin_shape_ref = ShapeBullet::create_shape_ray(godot_ray->length * m_owner->body_scale[1] + m_margin); + kin_shape_ref = ShapeBullet::create_shape_ray(godot_ray->length * owner->body_scale[1] + safe_margin); break; } default: @@ -252,12 +242,12 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { } void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) { - for (int i = m_shapes.size() - 1; 0 <= i; --i) { - if (m_shapes[i].shape) { - bulletdelete(m_shapes[i].shape); + for (int i = shapes.size() - 1; 0 <= i; --i) { + if (shapes[i].shape) { + bulletdelete(shapes[i].shape); } } - m_shapes.resize(new_size); + shapes.resize(new_size); } RigidBodyBullet::RigidBodyBullet() diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 0cf3f9f605..ab3c3e58b2 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -162,17 +162,15 @@ public: }; struct KinematicUtilities { - RigidBodyBullet *m_owner; - btScalar m_margin; - btManifoldArray m_manifoldArray; ///keep track of the contact manifolds - class btPairCachingGhostObject *m_ghostObject; - Vector<KinematicShape> m_shapes; + RigidBodyBullet *owner; + btScalar safe_margin; + Vector<KinematicShape> shapes; KinematicUtilities(RigidBodyBullet *p_owner); ~KinematicUtilities(); + void setSafeMargin(btScalar p_margin); /// Used to set the default shape to ghost - void resetDefShape(); void copyAllOwnerShapes(); private: diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index af7f511fab..9df01aee3e 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -50,9 +50,6 @@ #include "ustring.h" #include <assert.h> -// test only -//#include "scene/3d/immediate_geometry.h" - BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space) : PhysicsDirectSpaceState(), space(p_space) {} @@ -174,7 +171,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf btResult.m_collisionFilterGroup = p_collision_layer; btResult.m_collisionFilterMask = p_object_type_mask; - space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult); + space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, 0.002); if (btResult.hasHit()) { if (btCollisionObject::CO_RIGID_BODY == btResult.m_hitCollisionObject->getInternalType()) { @@ -281,10 +278,6 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_ btVector3 bt_point; G_TO_B(p_point, bt_point); - btGjkEpaPenetrationDepthSolver gjk_epa_pen_solver; - btVoronoiSimplexSolver gjk_simplex_solver; - gjk_simplex_solver.setEqualVertexThreshold(0.); - btSphereShape point_shape(0.); btCollisionShape *shape; @@ -308,7 +301,7 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_ input.m_transformB = body_transform * child_transform; btPointCollector result; - btGjkPairDetector gjk_pair_detector(&point_shape, convex_shape, &gjk_simplex_solver, &gjk_epa_pen_solver); + btGjkPairDetector gjk_pair_detector(&point_shape, convex_shape, space->gjk_simplex_solver, space->gjk_epa_pen_solver); gjk_pair_detector.getClosestPoints(input, result, 0); if (out_distance > result.m_distance) { @@ -558,13 +551,10 @@ btScalar calculateGodotCombinedRestitution(const btCollisionObject *body0, const } void SpaceBullet::create_empty_world(bool p_create_soft_world) { - assert(NULL == broadphase); - assert(NULL == dispatcher); - assert(NULL == solver); - assert(NULL == collisionConfiguration); - assert(NULL == dynamicsWorld); - assert(NULL == ghostPairCallback); - assert(NULL == godotFilterCallback); + + gjk_epa_pen_solver = bulletnew(btGjkEpaPenetrationDepthSolver); + gjk_simplex_solver = bulletnew(btVoronoiSimplexSolver); + gjk_simplex_solver->setEqualVertexThreshold(0.f); void *world_mem; if (p_create_soft_world) { @@ -611,13 +601,6 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) { } void SpaceBullet::destroy_world() { - assert(NULL != broadphase); - assert(NULL != dispatcher); - assert(NULL != solver); - assert(NULL != collisionConfiguration); - assert(NULL != dynamicsWorld); - assert(NULL != ghostPairCallback); - assert(NULL != godotFilterCallback); /// The world elements (like: Collision Objects, Constraints, Shapes) are managed by godot @@ -637,14 +620,13 @@ void SpaceBullet::destroy_world() { bulletdelete(dispatcher); bulletdelete(collisionConfiguration); bulletdelete(soft_body_world_info); + bulletdelete(gjk_simplex_solver); + bulletdelete(gjk_epa_pen_solver); } void SpaceBullet::check_ghost_overlaps() { /// Algorith support variables - btGjkEpaPenetrationDepthSolver gjk_epa_pen_solver; - btVoronoiSimplexSolver gjk_simplex_solver; - gjk_simplex_solver.setEqualVertexThreshold(0.f); btConvexShape *other_body_shape; btConvexShape *area_shape; btGjkPairDetector::ClosestPointInput gjk_input; @@ -701,7 +683,7 @@ void SpaceBullet::check_ghost_overlaps() { gjk_input.m_transformB = otherObject->get_transform__bullet() * otherObject->get_compound_shape()->getChildTransform(z); btPointCollector result; - btGjkPairDetector gjk_pair_detector(area_shape, other_body_shape, &gjk_simplex_solver, &gjk_epa_pen_solver); + btGjkPairDetector gjk_pair_detector(area_shape, other_body_shape, gjk_simplex_solver, gjk_epa_pen_solver); gjk_pair_detector.getClosestPoints(gjk_input, result, 0); if (0 >= result.m_distance) { @@ -743,23 +725,11 @@ void SpaceBullet::check_body_collision() { const int numManifolds = dynamicsWorld->getDispatcher()->getNumManifolds(); for (int i = 0; i < numManifolds; ++i) { btPersistentManifold *contactManifold = dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i); - const btCollisionObject *obA = contactManifold->getBody0(); - const btCollisionObject *obB = contactManifold->getBody1(); - - if (btCollisionObject::CO_RIGID_BODY != obA->getInternalType() || btCollisionObject::CO_RIGID_BODY != obB->getInternalType()) { - // This checks is required to be sure the ghost object is skipped - // The ghost object "getUserPointer" return the BodyBullet owner so this check is required - continue; - } - - // Asserts all Godot objects are assigned - assert(NULL != obA->getUserPointer()); - assert(NULL != obB->getUserPointer()); // I know this static cast is a bit risky. But I'm checking its type just after it. // This allow me to avoid a lot of other cast and checks - RigidBodyBullet *bodyA = static_cast<RigidBodyBullet *>(obA->getUserPointer()); - RigidBodyBullet *bodyB = static_cast<RigidBodyBullet *>(obB->getUserPointer()); + RigidBodyBullet *bodyA = static_cast<RigidBodyBullet *>(contactManifold->getBody0()->getUserPointer()); + RigidBodyBullet *bodyB = static_cast<RigidBodyBullet *>(contactManifold->getBody1()->getUserPointer()); if (CollisionObjectBullet::TYPE_RIGID_BODY == bodyA->getType() && CollisionObjectBullet::TYPE_RIGID_BODY == bodyB->getType()) { if (!bodyA->can_add_collision() && !bodyB->can_add_collision()) { @@ -784,13 +754,13 @@ void SpaceBullet::check_body_collision() { if (bodyA->can_add_collision()) { B_TO_G(pt.getPositionWorldOnB(), collisionWorldPosition); /// pt.m_localPointB Doesn't report the exact point in local space - B_TO_G(pt.getPositionWorldOnB() - obB->getWorldTransform().getOrigin(), collisionLocalPosition); + B_TO_G(pt.getPositionWorldOnB() - contactManifold->getBody1()->getWorldTransform().getOrigin(), collisionLocalPosition); bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, pt.m_index1, pt.m_index0); } if (bodyB->can_add_collision()) { B_TO_G(pt.getPositionWorldOnA(), collisionWorldPosition); /// pt.m_localPointA Doesn't report the exact point in local space - B_TO_G(pt.getPositionWorldOnA() - obA->getWorldTransform().getOrigin(), collisionLocalPosition); + B_TO_G(pt.getPositionWorldOnA() - contactManifold->getBody0()->getWorldTransform().getOrigin(), collisionLocalPosition); bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, pt.m_index0, pt.m_index1); } @@ -817,7 +787,12 @@ 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 + #if debug_test_motion + +#include "scene/3d/immediate_geometry.h" + static ImmediateGeometry *motionVec(NULL); static ImmediateGeometry *normalLine(NULL); static Ref<SpatialMaterial> red_mat; @@ -825,10 +800,10 @@ static Ref<SpatialMaterial> blue_mat; #endif #define IGNORE_AREAS_TRUE true -bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result) { +bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, PhysicsServer::MotionResult *r_result) { #if debug_test_motion - /// Yes I know this is not good, but I've used it as fast debugging. + /// Yes I know this is not good, but I've used it as fast debugging hack. /// I'm leaving it here just for speedup the other eventual debugs if (!normalLine) { motionVec = memnew(ImmediateGeometry); @@ -866,43 +841,21 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f // } //} - btVector3 recover_initial_position; - recover_initial_position.setZero(); + btVector3 recover_initial_position(0, 0, 0); -/// I'm performing the unstack at the end of movement so I'm sure the player is unstacked even after the movement. -/// I've removed the initial unstack because this is useful just for the first tick since after the first -/// the real unstack is performed at the end of process. -/// However I'm leaving here the old code. -/// Note: It has a bug when two shapes touches something simultaneously the body is moved too much away (I'm not fixing it for the reason written above). -#define INITIAL_UNSTACK 0 -#if !INITIAL_UNSTACK btTransform body_safe_position; G_TO_B(p_from, body_safe_position); -//btTransform body_unsafe_positino; -//G_TO_B(p_from, body_unsafe_positino); -#else - btTransform body_safe_position; - btTransform body_unsafe_positino; - { /// Phase one - multi shapes depenetration using margin - G_TO_B(p_from, body_safe_position); - G_TO_B(p_from, body_unsafe_positino); - - // MAX_PENETRATION_DEPTH Is useful have the ghost a bit penetrated so I can detect the floor easily - recover_from_penetration(p_body, body_safe_position, MAX_PENETRATION_DEPTH, /* p_depenetration_speed */ 1, recover_initial_position); - /// Not required if I put p_depenetration_speed = 1 - //for(int t = 0; t<4; ++t){ - // if(!recover_from_penetration(p_body, body_safe_position, MAX_PENETRATION_DEPTH, /* p_depenetration_speed */0.2, recover_initial_position)){ - // break; - // } - //} + { /// Phase one - multi shapes depenetration using margin +#if PERFORM_INITIAL_UNSTACK + if (recover_from_penetration(p_body, body_safe_position, 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; + } #endif + } - int shape_most_recovered(-1); btVector3 recovered_motion; G_TO_B(p_motion, recovered_motion); const int shape_count(p_body->get_shape_count()); @@ -930,127 +883,53 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f continue; } - btTransform shape_xform_from; - G_TO_B(p_body->get_shape_transform(shIndex), shape_xform_from); - //btTransform shape_xform_to(shape_xform_from); + btTransform shape_world_from; + G_TO_B(p_body->get_shape_transform(shIndex), shape_world_from); // Add local shape transform - shape_xform_from.getOrigin() += body_safe_position.getOrigin(); - shape_xform_from.getBasis() *= body_safe_position.getBasis(); + shape_world_from = body_safe_position * shape_world_from; - btTransform shape_xform_to(shape_xform_from); - //shape_xform_to.getOrigin() += body_unsafe_positino.getOrigin(); - //shape_xform_to.getBasis() *= body_unsafe_positino.getBasis(); - shape_xform_to.getOrigin() += recovered_motion; + btTransform shape_world_to(shape_world_from); + shape_world_to.getOrigin() += recovered_motion; - GodotKinClosestConvexResultCallback btResult(shape_xform_from.getOrigin(), shape_xform_to.getOrigin(), p_body, IGNORE_AREAS_TRUE); + GodotKinClosestConvexResultCallback btResult(shape_world_from.getOrigin(), shape_world_to.getOrigin(), p_body, IGNORE_AREAS_TRUE); btResult.m_collisionFilterGroup = p_body->get_collision_layer(); btResult.m_collisionFilterMask = p_body->get_collision_mask(); - dynamicsWorld->convexSweepTest(convex_shape_test, shape_xform_from, shape_xform_to, btResult); + dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, 0.002); if (btResult.hasHit()) { - //recovered_motion *= btResult.m_closestHitFraction; /// Since for each sweep test I fix the motion of new shapes in base the recover result, - /// if another shape will hit something it means that has a deepest recovering respect the previous shape - shape_most_recovered = shIndex; + /// if another shape will hit something it means that has a deepest penetration respect the previous shape + recovered_motion *= btResult.m_closestHitFraction; } } } - bool hasHit = false; - - { /// Phase three - contact test with margin - - btGhostObject *ghost = p_body->get_kinematic_utilities()->m_ghostObject; - - GodotRecoverAndClosestContactResultCallback result_callabck; - - if (false && 0 <= shape_most_recovered) { - result_callabck.m_self_object = p_body; - result_callabck.m_ignore_areas = IGNORE_AREAS_TRUE; - result_callabck.m_collisionFilterGroup = p_body->get_collision_layer(); - result_callabck.m_collisionFilterMask = p_body->get_collision_mask(); - - const RigidBodyBullet::KinematicShape &kin(p_body->get_kinematic_utilities()->m_shapes[shape_most_recovered]); - ghost->setCollisionShape(kin.shape); - ghost->setWorldTransform(body_safe_position); - - ghost->getWorldTransform().getOrigin() += recovered_motion; - ghost->getWorldTransform().getOrigin() += kin.transform.getOrigin(); - ghost->getWorldTransform().getBasis() *= kin.transform.getBasis(); + bool hasPenetration = false; - dynamicsWorld->contactTest(ghost, result_callabck); - - recovered_motion += result_callabck.m_recover_penetration; // Required to avoid all kind of penetration - - } else { - // The sweep result does not return a penetrated shape, so I've to check all shapes - // Then return the most penetrated shape - - GodotRecoverAndClosestContactResultCallback iter_result_callabck(p_body, IGNORE_AREAS_TRUE); - iter_result_callabck.m_collisionFilterGroup = p_body->get_collision_layer(); - iter_result_callabck.m_collisionFilterMask = p_body->get_collision_mask(); - - btScalar max_penetration(99999999999); - for (int i = 0; i < shape_count; ++i) { - - const RigidBodyBullet::KinematicShape &kin(p_body->get_kinematic_utilities()->m_shapes[i]); - if (!kin.is_active()) { - continue; - } + { /// Phase three - Recover + contact test with margin - // reset callback each function - iter_result_callabck.reset(); - - ghost->setCollisionShape(kin.shape); - ghost->setWorldTransform(body_safe_position); - ghost->getWorldTransform().getOrigin() += recovered_motion; - ghost->getWorldTransform().getOrigin() += kin.transform.getOrigin(); - ghost->getWorldTransform().getBasis() *= kin.transform.getBasis(); - - dynamicsWorld->contactTest(ghost, iter_result_callabck); - - if (iter_result_callabck.hasHit()) { - if (max_penetration > iter_result_callabck.m_penetration_distance) { - max_penetration = iter_result_callabck.m_penetration_distance; - shape_most_recovered = i; - // This is more penetrated - result_callabck.m_pointCollisionObject = iter_result_callabck.m_pointCollisionObject; - result_callabck.m_pointNormalWorld = iter_result_callabck.m_pointNormalWorld; - result_callabck.m_pointWorld = iter_result_callabck.m_pointWorld; - result_callabck.m_penetration_distance = iter_result_callabck.m_penetration_distance; - result_callabck.m_other_compound_shape_index = iter_result_callabck.m_other_compound_shape_index; - - recovered_motion += iter_result_callabck.m_recover_penetration; // Required to avoid all kind of penetration - } - } - } - } + RecoverResult recover_result; - hasHit = result_callabck.hasHit(); + hasPenetration = recover_from_penetration(p_body, body_safe_position, recovered_motion, &recover_result); if (r_result) { B_TO_G(recovered_motion + recover_initial_position, r_result->motion); - if (hasHit) { - - if (btCollisionObject::CO_RIGID_BODY != result_callabck.m_pointCollisionObject->getInternalType()) { - ERR_PRINT("The collision is not against a rigid body. Please check what's going on."); - goto EndExecution; - } - const btRigidBody *btRigid = static_cast<const btRigidBody *>(result_callabck.m_pointCollisionObject); + if (hasPenetration) { + const btRigidBody *btRigid = static_cast<const btRigidBody *>(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(result_callabck.m_pointWorld, r_result->collision_point); - B_TO_G(result_callabck.m_pointNormalWorld, r_result->collision_normal); - B_TO_G(btRigid->getVelocityInLocalPoint(result_callabck.m_pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot + B_TO_G(recover_result.pointWorld, r_result->collision_point); + B_TO_G(recover_result.pointNormalWorld, r_result->collision_normal); + B_TO_G(btRigid->getVelocityInLocalPoint(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 = result_callabck.m_other_compound_shape_index; - r_result->collision_local_shape = shape_most_recovered; + r_result->collider_shape = recover_result.other_compound_shape_index; + r_result->collision_local_shape = recover_result.local_shape_most_recovered; //{ /// Add manifold point to manage collisions // btPersistentManifold* manifold = dynamicsWorld->getDispatcher()->getNewManifold(p_body->getBtBody(), btRigid); @@ -1079,85 +958,144 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f } } -EndExecution: - p_body->get_kinematic_utilities()->resetDefShape(); - return hasHit; + return hasPenetration; } -/// Note: It has a bug when two shapes touches something simultaneously the body is moved too much away -/// (I'm not fixing it because I don't use it). -bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btScalar p_maxPenetrationDepth, btScalar p_depenetration_speed, btVector3 &out_recover_position) { +struct RecoverPenetrationBroadPhaseCallback : public btBroadphaseAabbCallback { +private: + const btCollisionObject *self_collision_object; + uint32_t collision_layer; + uint32_t collision_mask; - bool penetration = false; - btPairCachingGhostObject *ghost = p_body->get_kinematic_utilities()->m_ghostObject; +public: + Vector<btCollisionObject *> result_collision_objects; - for (int kinIndex = p_body->get_kinematic_utilities()->m_shapes.size() - 1; 0 <= kinIndex; --kinIndex) { - const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->m_shapes[kinIndex]); - if (!kin_shape.is_active()) { - continue; +public: + RecoverPenetrationBroadPhaseCallback(const btCollisionObject *p_self_collision_object, uint32_t p_collision_layer, uint32_t p_collision_mask) + : self_collision_object(p_self_collision_object), + collision_layer(p_collision_layer), + collision_mask(p_collision_mask) {} + + virtual ~RecoverPenetrationBroadPhaseCallback() {} + + virtual bool process(const btBroadphaseProxy *proxy) { + + btCollisionObject *co = static_cast<btCollisionObject *>(proxy->m_clientObject); + if (co->getInternalType() <= btCollisionObject::CO_RIGID_BODY) { + if (self_collision_object != proxy->m_clientObject && GodotFilterCallback::test_collision_filters(collision_layer, collision_mask, proxy->m_collisionFilterGroup, proxy->m_collisionFilterMask)) { + result_collision_objects.push_back(co); + return true; + } } + return false; + } + + void reset() { + result_collision_objects.empty(); + } +}; + +bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btVector3 &out_recover_position, RecoverResult *recover_result) { - btConvexShape *convexShape = kin_shape.shape; - btTransform shape_xform(kin_shape.transform); + RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask()); - // from local to world - shape_xform.getOrigin() += p_from.getOrigin(); - shape_xform.getBasis() *= p_from.getBasis(); + btTransform body_shape_position; + btTransform body_shape_position_recovered; - // Apply last recovery to avoid doubling the recovering - shape_xform.getOrigin() += out_recover_position; + // Broad phase support + btVector3 minAabb, maxAabb; + + // GJK support + btGjkPairDetector::ClosestPointInput gjk_input; - ghost->setCollisionShape(convexShape); - ghost->setWorldTransform(shape_xform); + bool penetration = false; - btVector3 minAabb, maxAabb; - convexShape->getAabb(shape_xform, minAabb, maxAabb); - dynamicsWorld->getBroadphase()->setAabb(ghost->getBroadphaseHandle(), - minAabb, - maxAabb, - dynamicsWorld->getDispatcher()); + // For each shape + for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) { - dynamicsWorld->getDispatcher()->dispatchAllCollisionPairs(ghost->getOverlappingPairCache(), dynamicsWorld->getDispatchInfo(), dynamicsWorld->getDispatcher()); + recover_broad_result.reset(); - for (int i = 0; i < ghost->getOverlappingPairCache()->getNumOverlappingPairs(); ++i) { - p_body->get_kinematic_utilities()->m_manifoldArray.resize(0); + const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]); + if (!kin_shape.is_active()) { + continue; + } - btBroadphasePair *collisionPair = &ghost->getOverlappingPairCache()->getOverlappingPairArray()[i]; + body_shape_position = p_body_position * kin_shape.transform; + body_shape_position_recovered = body_shape_position; + body_shape_position_recovered.getOrigin() += out_recover_position; - btCollisionObject *obj0 = static_cast<btCollisionObject *>(collisionPair->m_pProxy0->m_clientObject); - btCollisionObject *obj1 = static_cast<btCollisionObject *>(collisionPair->m_pProxy1->m_clientObject); + kin_shape.shape->getAabb(body_shape_position_recovered, minAabb, maxAabb); + dynamicsWorld->getBroadphase()->aabbTest(minAabb, maxAabb, recover_broad_result); - if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse())) + for (int i = recover_broad_result.result_collision_objects.size() - 1; 0 <= i; --i) { + btCollisionObject *otherObject = recover_broad_result.result_collision_objects[i]; + if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) continue; - // This is not required since the dispatched does all the job - //if (!needsCollision(obj0, obj1)) - // continue; + if (otherObject->getCollisionShape()->isCompound()) { /// Execute GJK test against all shapes - if (collisionPair->m_algorithm) - collisionPair->m_algorithm->getAllContactManifolds(p_body->get_kinematic_utilities()->m_manifoldArray); + // Each convex shape + btCompoundShape *cs = static_cast<btCompoundShape *>(otherObject->getCollisionShape()); + for (int x = cs->getNumChildShapes() - 1; 0 <= x; --x) { - for (int j = 0; j < p_body->get_kinematic_utilities()->m_manifoldArray.size(); ++j) { + if (!cs->getChildShape(x)->isConvex()) + continue; - btPersistentManifold *manifold = p_body->get_kinematic_utilities()->m_manifoldArray[j]; - btScalar directionSign = manifold->getBody0() == ghost ? btScalar(-1.0) : btScalar(1.0); - for (int p = 0; p < manifold->getNumContacts(); ++p) { - const btManifoldPoint &pt = manifold->getContactPoint(p); + // Initialize GJK input + gjk_input.m_transformA = body_shape_position; + gjk_input.m_transformA.getOrigin() += out_recover_position; + gjk_input.m_transformB = otherObject->getWorldTransform() * cs->getChildTransform(x); - btScalar dist = pt.getDistance(); - if (dist < -p_maxPenetrationDepth) { + // Perform GJK test + btPointCollector result; + btGjkPairDetector gjk_pair_detector(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), gjk_simplex_solver, gjk_epa_pen_solver); + gjk_pair_detector.getClosestPoints(gjk_input, result, 0); + if (0 > result.m_distance) { + // Has penetration + out_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1); penetration = true; - out_recover_position += pt.m_normalWorldOnB * directionSign * (dist + p_maxPenetrationDepth) * p_depenetration_speed; - //print_line("penetrate distance: " + rtos(dist)); + + if (recover_result) { + + recover_result->hasPenetration = true; + recover_result->other_collision_object = otherObject; + recover_result->other_compound_shape_index = x; + recover_result->penetration_distance = result.m_distance; + recover_result->pointNormalWorld = result.m_normalOnBInWorld; + recover_result->pointWorld = result.m_pointInWorld; + } + } + } + + } else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape + + // Initialize GJK input + gjk_input.m_transformA = body_shape_position; + gjk_input.m_transformA.getOrigin() += out_recover_position; + gjk_input.m_transformB = otherObject->getWorldTransform(); + + // Perform GJK test + btPointCollector result; + btGjkPairDetector gjk_pair_detector(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), gjk_simplex_solver, gjk_epa_pen_solver); + gjk_pair_detector.getClosestPoints(gjk_input, result, 0); + if (0 > result.m_distance) { + // Has penetration + out_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1); + penetration = true; + + if (recover_result) { + + recover_result->hasPenetration = true; + recover_result->other_collision_object = otherObject; + recover_result->other_compound_shape_index = 0; + recover_result->penetration_distance = result.m_distance; + recover_result->pointNormalWorld = result.m_normalOnBInWorld; + recover_result->pointWorld = result.m_pointInWorld; } - //else { - // print_line("touching distance: " + rtos(dist)); - //} } } } } - p_body->get_kinematic_utilities()->resetDefShape(); return penetration; } diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index b36896650b..d9206f8046 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -59,6 +59,7 @@ class CollisionObjectBullet; class RigidBodyBullet; class SpaceBullet; class SoftBodyBullet; +class btGjkEpaPenetrationDepthSolver; class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState { GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState) @@ -93,6 +94,9 @@ private: GodotFilterCallback *godotFilterCallback; btSoftBodyWorldInfo *soft_body_world_info; + btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver; + btVoronoiSimplexSolver *gjk_simplex_solver; + BulletPhysicsDirectSpaceState *direct_access; Vector3 gravityDirection; real_t gravityMagnitude; @@ -164,7 +168,7 @@ public: void update_gravity(); - bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result); + bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, PhysicsServer::MotionResult *r_result); private: void create_empty_world(bool p_create_soft_world); @@ -172,6 +176,19 @@ private: void check_ghost_overlaps(); void check_body_collision(); - bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btScalar p_maxPenetrationDepth, btScalar p_depenetration_speed, btVector3 &out_recover_position); + struct RecoverResult { + bool hasPenetration; + btVector3 pointNormalWorld; + btVector3 pointWorld; + btScalar penetration_distance; // Negative is penetration + int other_compound_shape_index; + const btCollisionObject *other_collision_object; + int local_shape_most_recovered; + + RecoverResult() + : hasPenetration(false) {} + }; + + bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btVector3 &out_recover_position, RecoverResult *recover_result = NULL); }; #endif diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp index ce503b62f2..1a46ad324a 100644 --- a/modules/gdscript/gd_function.cpp +++ b/modules/gdscript/gd_function.cpp @@ -170,7 +170,7 @@ static String _get_var_type(const Variant *p_type) { return basestr; } -#if defined(__GNUC__) && !defined(__clang__) +#if defined(__GNUC__) #define OPCODES_TABLE \ static const void *switch_table_ops[] = { \ &&OPCODE_OPERATOR, \ @@ -427,8 +427,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = ret; #endif ip += 5; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_EXTENDS_TEST) { CHECK_SPACE(4); @@ -492,8 +493,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = extends_ok; ip += 4; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_SET) { CHECK_SPACE(3); @@ -518,8 +520,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #endif ip += 4; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_GET) { CHECK_SPACE(3); @@ -550,8 +553,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = ret; #endif ip += 4; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_SET_NAMED) { CHECK_SPACE(3); @@ -575,8 +579,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #endif ip += 4; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_GET_NAMED) { CHECK_SPACE(4); @@ -609,8 +614,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = ret; #endif ip += 4; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_SET_MEMBER) { CHECK_SPACE(3); @@ -631,8 +637,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #endif ip += 3; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_GET_MEMBER) { CHECK_SPACE(3); @@ -649,8 +656,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #endif ip += 3; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_ASSIGN) { CHECK_SPACE(3); @@ -660,8 +668,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = *src; ip += 3; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_ASSIGN_TRUE) { CHECK_SPACE(2); @@ -670,8 +679,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = true; ip += 2; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_ASSIGN_FALSE) { CHECK_SPACE(2); @@ -680,8 +690,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = false; ip += 2; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_CONSTRUCT) { CHECK_SPACE(2); @@ -708,8 +719,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a ip += 4 + argc; //construct a basic type - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_CONSTRUCT_ARRAY) { CHECK_SPACE(1); @@ -728,8 +740,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = array; ip += 3 + argc; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_CONSTRUCT_DICTIONARY) { CHECK_SPACE(1); @@ -750,8 +763,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a *dst = dict; ip += 3 + argc * 2; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_CALL_RETURN) OPCODE(OPCODE_CALL) { @@ -830,8 +844,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a //_call_func(NULL,base,*methodname,ip,argc,p_instance,stack); ip += argc + 1; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_CALL_BUILT_IN) { CHECK_SPACE(4); @@ -869,12 +884,14 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #endif ip += argc + 1; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_CALL_SELF) { OPCODE_BREAK; } + OPCODE(OPCODE_CALL_SELF_BASE) { CHECK_SPACE(2); @@ -948,8 +965,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } ip += 4 + argc; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_YIELD) OPCODE(OPCODE_YIELD_SIGNAL) { @@ -1032,6 +1050,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a exit_ok = true; OPCODE_BREAK; } + OPCODE(OPCODE_YIELD_RESUME) { CHECK_SPACE(2); @@ -1044,8 +1063,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a GET_VARIANT_PTR(result, 1); *result = p_state->result; ip += 2; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_JUMP) { CHECK_SPACE(2); @@ -1053,8 +1073,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a GD_ERR_BREAK(to < 0 || to > _code_size); ip = to; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_JUMP_IF) { CHECK_SPACE(3); @@ -1067,11 +1088,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a int to = _code_ptr[ip + 2]; GD_ERR_BREAK(to < 0 || to > _code_size); ip = to; - DISPATCH_OPCODE; + } else { + ip += 3; } - ip += 3; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_JUMP_IF_NOT) { CHECK_SPACE(3); @@ -1084,17 +1106,19 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a int to = _code_ptr[ip + 2]; GD_ERR_BREAK(to < 0 || to > _code_size); ip = to; - DISPATCH_OPCODE; + } else { + ip += 3; } - ip += 3; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) { CHECK_SPACE(2); ip = _default_arg_ptr[defarg]; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_RETURN) { CHECK_SPACE(2); @@ -1103,6 +1127,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a exit_ok = true; OPCODE_BREAK; } + OPCODE(OPCODE_ITERATE_BEGIN) { CHECK_SPACE(8); //space for this a regular iterate @@ -1121,20 +1146,21 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a int jumpto = _code_ptr[ip + 3]; GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; - DISPATCH_OPCODE; - } - GET_VARIANT_PTR(iterator, 4); + } else { + GET_VARIANT_PTR(iterator, 4); - *iterator = container->iter_get(*counter, valid); + *iterator = container->iter_get(*counter, valid); #ifdef DEBUG_ENABLED - if (!valid) { - err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "'."; - OPCODE_BREAK; - } + if (!valid) { + err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "'."; + OPCODE_BREAK; + } #endif - ip += 5; //skip regular iterate which is always next - DISPATCH_OPCODE; + ip += 5; //skip regular iterate which is always next + } } + DISPATCH_OPCODE; + OPCODE(OPCODE_ITERATE) { CHECK_SPACE(4); @@ -1153,20 +1179,21 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a int jumpto = _code_ptr[ip + 3]; GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); ip = jumpto; - DISPATCH_OPCODE; - } - GET_VARIANT_PTR(iterator, 4); + } else { + GET_VARIANT_PTR(iterator, 4); - *iterator = container->iter_get(*counter, valid); + *iterator = container->iter_get(*counter, valid); #ifdef DEBUG_ENABLED - if (!valid) { - err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?)."; - OPCODE_BREAK; - } + if (!valid) { + err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?)."; + OPCODE_BREAK; + } #endif - ip += 5; //loop again - DISPATCH_OPCODE; + ip += 5; //loop again + } } + DISPATCH_OPCODE; + OPCODE(OPCODE_ASSERT) { CHECK_SPACE(2); GET_VARIANT_PTR(test, 1); @@ -1182,8 +1209,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a #endif ip += 2; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_BREAKPOINT) { #ifdef DEBUG_ENABLED if (ScriptDebugger::get_singleton()) { @@ -1191,8 +1219,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a } #endif ip += 1; - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_LINE) { CHECK_SPACE(2); @@ -1220,8 +1249,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a ScriptDebugger::get_singleton()->line_poll(); } - DISPATCH_OPCODE; } + DISPATCH_OPCODE; + OPCODE(OPCODE_END) { exit_ok = true; diff --git a/platform/android/detect.py b/platform/android/detect.py index 2666034ef7..966de832e8 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -2,6 +2,7 @@ import os import sys import string import platform +from distutils.version import LooseVersion def is_active(): @@ -25,8 +26,7 @@ def get_opts(): ('ndk_platform', 'Target platform (android-<api>, e.g. "android-18")', "android-18"), EnumVariable('android_arch', 'Target architecture', "armv7", ('armv7', 'armv6', 'arm64v8', 'x86')), BoolVariable('android_neon', 'Enable NEON support (armv7 only)', True), - BoolVariable('android_stl', 'Enable Android STL support (for modules)', True), - BoolVariable('ndk_unified_headers', 'Enable NDK unified headers', True) + BoolVariable('android_stl', 'Enable Android STL support (for modules)', True) ] @@ -179,26 +179,22 @@ def configure(env): env['RANLIB'] = tools_path + "/ranlib" env['AS'] = tools_path + "/as" - ndk_unified_headers = env['ndk_unified_headers'] - ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"]) - common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path] - if not ndk_unified_headers and ndk_version != None and ndk_version[0] >= 16: - ndk_unified_headers = True - print("Turning NDK unified headers on (starting from r16)") - lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH'] ## Compile flags - if ndk_unified_headers: + ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"]) + if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"): + print("Using NDK unified headers") sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot" env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"]) env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath]) # For unified headers this define has to be set manually env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(int(env['ndk_platform'].split("-")[1]))]) else: + print("Using NDK deprecated headers") env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"]) env.Append(CPPFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split()) @@ -266,8 +262,8 @@ def configure(env): env.Append(CFLAGS=["-DOPUS_ARM_OPT"]) env.opus_fixed_point = "yes" -# Return NDK version as [<major>,<minor>,<build>] or None if cannot be figured out (adapted from the Chromium project). -def get_ndk_version (path): +# Return NDK version string in source.properties (adapted from the Chromium project). +def get_ndk_version(path): if path == None: return None prop_file_path = os.path.join(path, "source.properties") @@ -276,8 +272,7 @@ def get_ndk_version (path): for line in prop_file: key_value = map(lambda x: string.strip(x), line.split("=")) if key_value[0] == "Pkg.Revision": - version_parts = key_value[1].split("-")[0].split(".") - return map(int, version_parts[0:3]) + return key_value[1] except: print("Could not read source prop file '%s'" % prop_file_path) return None diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 9d43adf788..970e0cdf68 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -65,12 +65,6 @@ const char *OS_Android::get_video_driver_name(int p_driver) const { return "GLES2"; } - -OS::VideoMode OS_Android::get_default_video_mode() const { - - return OS::VideoMode(); -} - int OS_Android::get_audio_driver_count() const { return 1; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index d9a66b4e3a..fee91b9a55 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -141,8 +141,6 @@ public: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 7a681d46f7..0c34e39655 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -79,10 +79,6 @@ const char *OS_Haiku::get_video_driver_name(int p_driver) const { return "GLES2"; } -OS::VideoMode OS_Haiku::get_default_video_mode() const { - return OS::VideoMode(800, 600, false); -} - void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; current_video_mode = p_desired; diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 501650c94f..86148f1fb4 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -65,7 +65,6 @@ private: protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index 13e3b7670a..0685e961c3 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -62,11 +62,6 @@ OSIPhone *OSIPhone::get_singleton() { return (OSIPhone *)OS::get_singleton(); }; -OS::VideoMode OSIPhone::get_default_video_mode() const { - - return video_mode; -}; - uint8_t OSIPhone::get_orientations() const { return supported_orientations; diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index eccd294d63..6627fddf08 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -83,8 +83,6 @@ private: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; - virtual void initialize_logger(); virtual void initialize_core(); virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 3a57de2646..e5bdcec30d 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -64,11 +64,6 @@ const char *OS_JavaScript::get_video_driver_name(int p_driver) const { return "GLES3"; } -OS::VideoMode OS_JavaScript::get_default_video_mode() const { - - return OS::VideoMode(); -} - int OS_JavaScript::get_audio_driver_count() const { return 1; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 07720e95ec..f478f95dd2 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -83,8 +83,6 @@ public: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index fba53f61b6..53f45511f9 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -120,7 +120,6 @@ public: protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; virtual void initialize_logger(); virtual void initialize_core(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 78acc97676..6faa8e12ed 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -899,16 +899,6 @@ const char *OS_OSX::get_video_driver_name(int p_driver) const { return "GLES2"; } -OS::VideoMode OS_OSX::get_default_video_mode() const { - - VideoMode vm; - vm.width = 1024; - vm.height = 600; - vm.fullscreen = false; - vm.resizable = true; - return vm; -} - void OS_OSX::initialize_core() { crash_handler.initialize(); diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index 80c04aa5ad..ca73f610e4 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -46,10 +46,6 @@ const char *OS_Server::get_video_driver_name(int p_driver) const { return "Dummy"; } -OS::VideoMode OS_Server::get_default_video_mode() const { - - return OS::VideoMode(800, 600, false); -} void OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { diff --git a/platform/server/os_server.h b/platform/server/os_server.h index 630c82ccdd..03f7c2a6c8 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -66,7 +66,6 @@ class OS_Server : public OS_Unix { protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index af53f97446..434c597449 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -84,7 +84,7 @@ def configure(env): ## Architecture arch = "" - if os.getenv('Platform') == "ARM": + if str(os.getenv('Platform')).lower() == "arm": print("Compiled program architecture will be an ARM executable. (forcing bits=32).") diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp index ed3db65cdf..dafe5d5e25 100644 --- a/platform/uwp/gl_context_egl.cpp +++ b/platform/uwp/gl_context_egl.cpp @@ -101,26 +101,25 @@ Error ContextEGL::initialize() { try { - const EGLint displayAttributes[] = - { - /*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, - EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, - EGL_NONE,*/ - // These are the default display attributes, used to request ANGLE's D3D11 renderer. - // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+. - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - - // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. - // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. - //EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, - - // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call - // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. - // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. - EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, - EGL_NONE, - }; + const EGLint displayAttributes[] = { + /*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, + EGL_NONE,*/ + // These are the default display attributes, used to request ANGLE's D3D11 renderer. + // eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+. + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + + // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. + // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. + //EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, + + // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call + // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. + // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, + EGL_NONE, + }; PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")); diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 8db2a749df..acb0ba4bca 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -72,11 +72,6 @@ const char *OSUWP::get_video_driver_name(int p_driver) const { return "GLES2"; } -OS::VideoMode OSUWP::get_default_video_mode() const { - - return video_mode; -} - Size2 OSUWP::get_window_size() const { Size2 size; size.width = video_mode.width; diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index e46e4cc020..2931e9b07d 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -154,8 +154,6 @@ protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 01201beccb..0f62dbb9e8 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -146,11 +146,6 @@ const char *OS_Windows::get_video_driver_name(int p_driver) const { return "GLES2"; } -OS::VideoMode OS_Windows::get_default_video_mode() const { - - return VideoMode(1024, 600, false); -} - int OS_Windows::get_audio_driver_count() const { return AudioDriverManager::get_driver_count(); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index c9c00b5e36..fbd60e5f0d 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -142,8 +142,6 @@ protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index fbcc22c58e..f018145d82 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -82,10 +82,6 @@ const char *OS_X11::get_video_driver_name(int p_driver) const { return "GLES3"; } -OS::VideoMode OS_X11::get_default_video_mode() const { - return OS::VideoMode(1024, 600, false); -} - int OS_X11::get_audio_driver_count() const { return AudioDriverManager::get_driver_count(); } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index bfa8b5b375..0ea5bbfdb6 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -177,7 +177,6 @@ class OS_X11 : public OS_Unix { protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual VideoMode get_default_video_mode() const; virtual int get_audio_driver_count() const; virtual const char *get_audio_driver_name(int p_driver) const; diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 4c661e6a88..bc089e5b41 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -938,7 +938,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli Transform gt = get_global_transform(); PhysicsServer::MotionResult result; - bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result); + bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, &result); if (colliding) { r_collision.collider_metadata = result.collider_metadata; @@ -988,12 +988,15 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve on_floor = true; floor_velocity = collision.collider_vel; - /*if (collision.travel.length() < 0.01 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) { + Vector3 rel_v = lv - floor_velocity; + Vector3 hv = rel_v - p_floor_direction * p_floor_direction.dot(rel_v); + + if (collision.travel.length() < 0.05 && hv.length() < p_slope_stop_min_velocity) { Transform gt = get_global_transform(); - gt.elements[2] -= collision.travel; + gt.origin -= collision.travel; set_global_transform(gt); - return Vector3(); - }*/ + return floor_velocity; + } } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling on_ceiling = true; } else { @@ -1041,12 +1044,13 @@ bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion) ERR_FAIL_COND_V(!is_inside_tree(), false); - return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, margin); + return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion); } void KinematicBody::set_safe_margin(float p_margin) { margin = p_margin; + PhysicsServer::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); } float KinematicBody::get_safe_margin() const { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index eaa16069cf..c99bc3c9ef 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -83,10 +83,10 @@ #include "scene/gui/link_button.h" #include "scene/gui/margin_container.h" #include "scene/gui/menu_button.h" +#include "scene/gui/nine_patch_rect.h" #include "scene/gui/option_button.h" #include "scene/gui/panel.h" #include "scene/gui/panel_container.h" -#include "scene/gui/nine_patch_rect.h" #include "scene/gui/popup_menu.h" #include "scene/gui/progress_bar.h" #include "scene/gui/reference_rect.h" diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 1ee76a4216..48c6add586 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -571,7 +571,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { wr[ofs + 0] = 255; //grayscale as 1 wr[ofs + 1] = slot->bitmap.buffer[i * slot->bitmap.pitch + j]; break; - // TODO: FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_BGRA + // TODO: FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_BGRA default: ERR_EXPLAIN("Font uses unsupported pixel format: " + itos(slot->bitmap.pixel_mode)); ERR_FAIL(); diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 6ced004118..f8cd6ca858 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -736,6 +736,10 @@ void BodySW::set_force_integration_callback(ObjectID p_id, const StringName &p_m } } +void BodySW::set_kinematic_margin(real_t p_margin) { + kinematic_safe_margin = p_margin; +} + BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_update_list(this), direct_state_query_list(this) { @@ -743,6 +747,7 @@ BodySW::BodySW() active = true; mass = 1; + kinematic_safe_margin = 0.01; //_inv_inertia=Transform(); _inv_mass = 1; bounce = 0; diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h index 98095fd3c6..738d99c764 100644 --- a/servers/physics/body_sw.h +++ b/servers/physics/body_sw.h @@ -55,6 +55,7 @@ class BodySW : public CollisionObjectSW { PhysicsServer::BodyAxisLock axis_lock; + real_t kinematic_safe_margin; real_t _inv_mass; Vector3 _inv_inertia; // Relative to the principal axes of inertia @@ -149,6 +150,9 @@ class BodySW : public CollisionObjectSW { public: void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant()); + void set_kinematic_margin(real_t p_margin); + _FORCE_INLINE_ real_t get_kinematic_margin() { return kinematic_safe_margin; } + _FORCE_INLINE_ void add_area(AreaSW *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 5ba935d47c..ce63d84617 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -695,6 +695,19 @@ real_t PhysicsServerSW::body_get_param(RID p_body, BodyParameter p_param) const return body->get_param(p_param); }; +void PhysicsServerSW::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + body->set_kinematic_margin(p_margin); +} + +real_t PhysicsServerSW::body_get_kinematic_safe_margin(RID p_body) const { + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body, 0); + + return body->get_kinematic_margin(); +} + void PhysicsServerSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { BodySW *body = body_owner.get(p_body); @@ -888,7 +901,7 @@ bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const { return body->is_ray_pickable(); } -bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin, MotionResult *r_result) { +bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result) { BodySW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body, false); @@ -897,7 +910,7 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons _update_shapes(); - return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result); + return body->get_space()->test_body_motion(body, p_from, p_motion, body->get_kinematic_margin(), r_result); } PhysicsDirectBodyState *PhysicsServerSW::body_get_direct_state(RID p_body) { diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index f9eb8fa454..fa754a1c8f 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -187,6 +187,9 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value); virtual real_t body_get_param(RID p_body, BodyParameter p_param) const; + virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin); + virtual real_t body_get_kinematic_safe_margin(RID p_body) const; + virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant); virtual Variant body_get_state(RID p_body, BodyState p_state) const; @@ -221,7 +224,7 @@ public: virtual void body_set_ray_pickable(RID p_body, bool p_enable); virtual bool body_is_ray_pickable(RID p_body) const; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL); + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL); // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body); diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index a3efe76e13..76fb5bc46b 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -481,6 +481,9 @@ void PhysicsServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_param", "body", "param", "value"), &PhysicsServer::body_set_param); ClassDB::bind_method(D_METHOD("body_get_param", "body", "param"), &PhysicsServer::body_get_param); + ClassDB::bind_method(D_METHOD("body_set_kinematic_safe_margin", "body", "margin"), &PhysicsServer::body_set_kinematic_safe_margin); + ClassDB::bind_method(D_METHOD("body_get_kinematic_safe_margin", "body"), &PhysicsServer::body_get_kinematic_safe_margin); + ClassDB::bind_method(D_METHOD("body_set_state", "body", "state", "value"), &PhysicsServer::body_set_state); ClassDB::bind_method(D_METHOD("body_get_state", "body", "state"), &PhysicsServer::body_get_state); diff --git a/servers/physics_server.h b/servers/physics_server.h index 7cccd9b4cb..64c67eae2a 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -411,6 +411,9 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0; virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0; + virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) = 0; + virtual real_t body_get_kinematic_safe_margin(RID p_body) const = 0; + //state enum BodyState { BODY_STATE_TRANSFORM, @@ -482,7 +485,7 @@ public: Variant collider_metadata; }; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL) = 0; + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL) = 0; /* JOINT API */ diff --git a/thirdparty/openssl/uwp.cpp b/thirdparty/openssl/uwp.cpp index dcfd22b77f..e00c9d59db 100644 --- a/thirdparty/openssl/uwp.cpp +++ b/thirdparty/openssl/uwp.cpp @@ -103,12 +103,14 @@ extern "C" { return 0; } +#ifndef STD_ERROR_HANDLE int __cdecl GetStdHandle( _In_ DWORD nStdHandle ) { return 0; } +#endif BOOL DeregisterEventSource( _Inout_ HANDLE hEventLog ) |