From e5bfa98d0fa6a1acb1d385534c51b8006ef64142 Mon Sep 17 00:00:00 2001 From: Tristan Porteries Date: Tue, 10 Jul 2018 12:50:14 +0000 Subject: [PATCH] Expose bullet shape margin to UI. The margin value is exposed into the UI for shape ressource. This value can be modified through set_margin and get from get_margin or by using the property margin. Each time the margin is modified the associated collision shape is recreated and the margin value is used in ShapeBullet::prepare. --- modules/bullet/bullet_physics_server.cpp | 12 +++++++ modules/bullet/bullet_physics_server.h | 3 ++ modules/bullet/shape_bullet.cpp | 45 ++++++++++++++---------- modules/bullet/shape_bullet.h | 24 +++++++------ scene/resources/shape.cpp | 23 ++++++++++-- scene/resources/shape.h | 6 ++++ servers/physics/physics_server_sw.cpp | 8 +++++ servers/physics/physics_server_sw.h | 4 +++ servers/physics_server.h | 4 +++ 9 files changed, 98 insertions(+), 31 deletions(-) diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 6246a295ecaf..e76798859392 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -159,6 +159,18 @@ Variant BulletPhysicsServer::shape_get_data(RID p_shape) const { return shape->get_data(); } +void BulletPhysicsServer::shape_set_margin(RID p_shape, real_t p_margin) { + ShapeBullet *shape = shape_owner.get(p_shape); + ERR_FAIL_COND(!shape); + shape->set_margin(p_margin); +} + +real_t BulletPhysicsServer::shape_get_margin(RID p_shape) const { + ShapeBullet *shape = shape_owner.get(p_shape); + ERR_FAIL_COND_V(!shape, 0.0); + return shape->get_margin(); +} + real_t BulletPhysicsServer::shape_get_custom_solver_bias(RID p_shape) const { //WARN_PRINT("Bias not supported by Bullet physics engine"); return 0.; diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index e931915bba55..97d5c140c57f 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -99,6 +99,9 @@ public: virtual ShapeType shape_get_type(RID p_shape) const; virtual Variant shape_get_data(RID p_shape) const; + virtual void shape_set_margin(RID p_shape, real_t p_margin); + virtual real_t shape_get_margin(RID p_shape) const; + /// Not supported virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias); /// Not supported diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 76d961446525..cc865bb5be73 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -44,19 +44,20 @@ @author AndreaCatania */ -ShapeBullet::ShapeBullet() {} +ShapeBullet::ShapeBullet() : + margin(0.04) {} ShapeBullet::~ShapeBullet() {} -btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, real_t p_margin) { +btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, real_t p_extra_edge) { btVector3 s; G_TO_B(p_implicit_scale, s); - return create_bt_shape(s, p_margin); + return create_bt_shape(s, p_extra_edge); } btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const { p_btShape->setUserPointer(const_cast(this)); - p_btShape->setMargin(0.); + p_btShape->setMargin(margin); return p_btShape; } @@ -93,6 +94,15 @@ const Map &ShapeBullet::get_owners() const { return owners; } +void ShapeBullet::set_margin(real_t p_margin) { + margin = p_margin; + notifyShapeChanged(); +} + +real_t ShapeBullet::get_margin() const { + return margin; +} + btEmptyShape *ShapeBullet::create_shape_empty() { return bulletnew(btEmptyShape); } @@ -162,7 +172,7 @@ void PlaneShapeBullet::setup(const Plane &p_plane) { notifyShapeChanged(); } -btCollisionShape *PlaneShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { +btCollisionShape *PlaneShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btVector3 btPlaneNormal; G_TO_B(plane.normal, btPlaneNormal); return prepare(PlaneShapeBullet::create_shape_plane(btPlaneNormal, plane.d)); @@ -190,8 +200,8 @@ void SphereShapeBullet::setup(real_t p_radius) { notifyShapeChanged(); } -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)); +btCollisionShape *SphereShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { + return prepare(ShapeBullet::create_shape_sphere(radius * p_implicit_scale[0] + p_extra_edge)); } /* Box */ @@ -217,8 +227,8 @@ void BoxShapeBullet::setup(const Vector3 &p_half_extents) { notifyShapeChanged(); } -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))); +btCollisionShape *BoxShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { + return prepare(ShapeBullet::create_shape_box((half_extents * p_implicit_scale) + btVector3(p_extra_edge, p_extra_edge, p_extra_edge))); } /* Capsule */ @@ -250,8 +260,8 @@ void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) { notifyShapeChanged(); } -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)); +btCollisionShape *CapsuleShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { + return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1] + p_extra_edge)); } /* Convex polygon */ @@ -292,11 +302,10 @@ void ConvexPolygonShapeBullet::setup(const Vector &p_vertices) { notifyShapeChanged(); } -btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { +btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btCollisionShape *cs(ShapeBullet::create_shape_convex(vertices)); cs->setLocalScaling(p_implicit_scale); prepare(cs); - cs->setMargin(p_margin); return cs; } @@ -365,14 +374,13 @@ void ConcavePolygonShapeBullet::setup(PoolVector p_faces) { notifyShapeChanged(); } -btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { +btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btCollisionShape *cs = ShapeBullet::create_shape_concave(meshShape); if (!cs) // This is necessary since if 0 faces the creation of concave return NULL cs = ShapeBullet::create_shape_empty(); cs->setLocalScaling(p_implicit_scale); prepare(cs); - cs->setMargin(p_margin); return cs; } @@ -458,11 +466,10 @@ void HeightMapShapeBullet::setup(PoolVector &p_heights, int p_width, int notifyShapeChanged(); } -btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { +btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, min_height, max_height)); cs->setLocalScaling(p_implicit_scale); prepare(cs); - cs->setMargin(p_margin); return cs; } @@ -496,6 +503,6 @@ void RayShapeBullet::setup(real_t p_length, bool p_slips_on_slope) { notifyShapeChanged(); } -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, slips_on_slope)); +btCollisionShape *RayShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { + return prepare(ShapeBullet::create_shape_ray(length * p_implicit_scale[1] + p_extra_edge, slips_on_slope)); } diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index abeea0f9cec7..ac2000826268 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -52,6 +52,7 @@ class btBvhTriangleMeshShape; class ShapeBullet : public RIDBullet { Map owners; + real_t margin; protected: /// return self @@ -62,14 +63,17 @@ public: ShapeBullet(); virtual ~ShapeBullet(); - 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; + btCollisionShape *create_bt_shape(const Vector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0) = 0; void add_owner(ShapeOwnerBullet *p_owner); void remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody = false); bool is_owner(ShapeOwnerBullet *p_owner) const; const Map &get_owners() const; + void set_margin(real_t p_margin); + real_t get_margin() const; + /// Setup the shape virtual void set_data(const Variant &p_data) = 0; virtual Variant get_data() const = 0; @@ -99,7 +103,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(const Plane &p_plane); @@ -116,7 +120,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(real_t p_radius); @@ -133,7 +137,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(const Vector3 &p_half_extents); @@ -152,7 +156,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(real_t p_height, real_t p_radius); @@ -169,7 +173,7 @@ public: void get_vertices(Vector &out_vertices); virtual Variant get_data() const; virtual PhysicsServer::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(const Vector &p_vertices); @@ -187,7 +191,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(PoolVector p_faces); @@ -207,7 +211,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(PoolVector &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); @@ -224,7 +228,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(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(real_t p_length, bool p_slips_on_slope); diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index 418d8ce819c7..a48ce0564be8 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -50,6 +50,15 @@ void Shape::add_vertices_to_array(PoolVector &array, const Transform &p } } +real_t Shape::get_margin() const { + return margin; +} + +void Shape::set_margin(real_t p_margin) { + margin = p_margin; + PhysicsServer::get_singleton()->shape_set_margin(shape, margin); +} + Ref Shape::get_debug_mesh() { if (debug_mesh_cache.is_valid()) @@ -87,12 +96,22 @@ Ref Shape::get_debug_mesh() { return debug_mesh_cache; } -Shape::Shape() { +void Shape::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin); + ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.04,10,0.01"), "set_margin", "get_margin"); +} + +Shape::Shape() : + margin(0.04) { ERR_PRINT("Constructor must not be called!"); } -Shape::Shape(RID p_shape) { +Shape::Shape(RID p_shape) : + margin(0.04) { shape = p_shape; } diff --git a/scene/resources/shape.h b/scene/resources/shape.h index ad87a69679ba..0c44b86e9227 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -40,10 +40,13 @@ class Shape : public Resource { OBJ_SAVE_TYPE(Shape); RES_BASE_EXTENSION("shape"); RID shape; + real_t margin; Ref debug_mesh_cache; protected: + static void _bind_methods(); + _FORCE_INLINE_ RID get_shape() const { return shape; } Shape(RID p_shape); @@ -55,6 +58,9 @@ public: void add_vertices_to_array(PoolVector &array, const Transform &p_xform); + real_t get_margin() const; + void set_margin(real_t p_margin); + Shape(); ~Shape(); }; diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index f2dbb635f806..7a2d77394420 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -119,6 +119,13 @@ Variant PhysicsServerSW::shape_get_data(RID p_shape) const { return shape->get_data(); }; +void PhysicsServerSW::shape_set_margin(RID p_shape, real_t p_margin) { +} + +real_t PhysicsServerSW::shape_get_margin(RID p_shape) const { + return 0.0; +} + real_t PhysicsServerSW::shape_get_custom_solver_bias(RID p_shape) const { const ShapeSW *shape = shape_owner.get(p_shape); @@ -287,6 +294,7 @@ void PhysicsServerSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { area->set_shape(p_shape_idx, shape); } + void PhysicsServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) { AreaSW *area = area_owner.get(p_area); diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 3f56ba26d09f..c2a4744757e0 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -85,6 +85,10 @@ public: virtual ShapeType shape_get_type(RID p_shape) const; virtual Variant shape_get_data(RID p_shape) const; + + virtual void shape_set_margin(RID p_shape, real_t p_margin); + virtual real_t shape_get_margin(RID p_shape) const; + virtual real_t shape_get_custom_solver_bias(RID p_shape) const; /* SPACE API */ diff --git a/servers/physics_server.h b/servers/physics_server.h index 6712bee8dc9e..f8e7e694f606 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -240,6 +240,10 @@ public: virtual ShapeType shape_get_type(RID p_shape) const = 0; virtual Variant shape_get_data(RID p_shape) const = 0; + + virtual void shape_set_margin(RID p_shape, real_t p_margin) = 0; + virtual real_t shape_get_margin(RID p_shape) const = 0; + virtual real_t shape_get_custom_solver_bias(RID p_shape) const = 0; /* SPACE API */