From 32e7786d6774e8df0d0f1893ed040ee99ec2c65d Mon Sep 17 00:00:00 2001 From: sboronczyk Date: Tue, 30 Mar 2021 22:45:25 +0200 Subject: [PATCH] Add bullet 3 physics to godot 4 --- doc/classes/ProjectSettings.xml | 3 + modules/bullet/area_bullet.cpp | 8 +- modules/bullet/area_bullet.h | 6 +- modules/bullet/bullet_physics_server.cpp | 422 ++++++++++++--------- modules/bullet/bullet_physics_server.h | 75 ++-- modules/bullet/cone_twist_joint_bullet.h | 2 +- modules/bullet/config.py | 2 +- modules/bullet/constraint_bullet.cpp | 6 +- modules/bullet/constraint_bullet.h | 1 + modules/bullet/generic_6dof_joint_bullet.h | 2 +- modules/bullet/hinge_joint_bullet.h | 4 +- modules/bullet/joint_bullet.cpp | 7 +- modules/bullet/joint_bullet.h | 8 +- modules/bullet/pin_joint_bullet.h | 2 +- modules/bullet/register_types.cpp | 15 +- modules/bullet/slider_joint_bullet.h | 2 +- modules/bullet/space_bullet.cpp | 39 +- modules/bullet/space_bullet.h | 19 +- 18 files changed, 381 insertions(+), 242 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 5b9150ab04c7..338ad6324c44 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1248,6 +1248,9 @@ The default angular damp in 3D. [b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration. + + Active soft world (only for bullet engine) + The default gravity strength in 3D. [b]Note:[/b] This property is only read when the project starts. To change the default gravity at runtime, use the following code sample: diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index c3bd84c329f2..00fb0b8802ce 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -40,7 +40,7 @@ #include /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ AreaBullet::AreaBullet() : @@ -59,9 +59,13 @@ AreaBullet::AreaBullet() : AreaBullet::~AreaBullet() { // signal are handled by godot, so just clear without notify + //thread issue + for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - overlappingObjects[i].object->on_exit_area(this); + OverlappingObjectData &otherObj = overlappingObjects.write[i]; + otherObj.object->on_exit_area(this); } + } void AreaBullet::dispatch_callbacks() { diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index 7cf666c11921..6007f65df825 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -37,7 +37,7 @@ #include "space_bullet.h" /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ class btGhostObject; @@ -85,6 +85,7 @@ class AreaBullet : public RigidCollisionObjectBullet { btGhostObject *btGhost = nullptr; Vector overlappingObjects; bool monitorable = true; + int priority; PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; bool spOv_gravityPoint = false; @@ -139,6 +140,9 @@ class AreaBullet : public RigidCollisionObjectBullet { _FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; } _FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; } + _FORCE_INLINE_ void set_priority(int p_priority) { priority = p_priority; } + _FORCE_INLINE_ int get_priority() const { return priority; } + virtual void main_shape_changed(); virtual void reload_body(); virtual void set_space(SpaceBullet *p_space); diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 93642f2d5c5b..a1560cdac56f 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -46,81 +46,87 @@ #include /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ -#define CreateThenReturnRID(owner, ridData) \ - RID rid = owner.make_rid(ridData); \ - ridData->set_self(rid); \ - ridData->_set_physics_server(this); \ +#define CreateRID(owner, ridData) \ + RID rid = owner.make_rid(ridData); \ + ridData->set_self(rid); \ + ridData->_set_physics_server(this); + +#define CreateRIDReturn(owner, ridData) \ + RID rid = owner.make_rid(ridData); \ + ridData->set_self(rid); \ + ridData->_set_physics_server(this); \ return rid; -// <--------------- Joint creation asserts -/// Assert the body is assigned to a space -#define JointAssertSpace(body, bIndex, ret) \ - if (!body->get_space()) { \ - ERR_PRINT("Before create a joint the Body" + String(bIndex) + " must be added to a space!"); \ - return ret; \ +#define JointAssertSpace(body, bIndex, ret) \ + if (!body->get_space()) { \ + ERR_PRINTS("Before create a joint the Body" + String(bIndex) + " must be added to a space!"); \ } /// Assert the two bodies of joint are in the same space #define JointAssertSameSpace(bodyA, bodyB, ret) \ if (bodyA->get_space() != bodyB->get_space()) { \ ERR_PRINT("In order to create a joint the Body_A and Body_B must be in the same space!"); \ - return RID(); \ } #define AddJointToSpace(body, joint) \ body->get_space()->add_constraint(joint, joint->is_disabled_collisions_between_bodies()); + // <--------------- Joint creation asserts void BulletPhysicsServer3D::_bind_methods() { //ClassDB::bind_method(D_METHOD("DoTest"), &BulletPhysicsServer3D::DoTest); } - -BulletPhysicsServer3D::BulletPhysicsServer3D() : - PhysicsServer3D() {} +BulletPhysicsServer3D *BulletPhysicsServer3D::singletonbullet = nullptr; +BulletPhysicsServer3D::BulletPhysicsServer3D(bool p_using_threads) { + using_threads = p_using_threads; + singletonbullet = this; + active = true; + doing_sync = false; +}; BulletPhysicsServer3D::~BulletPhysicsServer3D() {} -RID BulletPhysicsServer3D::shape_create(ShapeType p_shape) { - ShapeBullet *shape = nullptr; - - switch (p_shape) { - case SHAPE_PLANE: { - shape = bulletnew(PlaneShapeBullet); - } break; - case SHAPE_SPHERE: { - shape = bulletnew(SphereShapeBullet); - } break; - case SHAPE_BOX: { - shape = bulletnew(BoxShapeBullet); - } break; - case SHAPE_CAPSULE: { - shape = bulletnew(CapsuleShapeBullet); - } break; - case SHAPE_CYLINDER: { - shape = bulletnew(CylinderShapeBullet); - } break; - case SHAPE_CONVEX_POLYGON: { - shape = bulletnew(ConvexPolygonShapeBullet); - } break; - case SHAPE_CONCAVE_POLYGON: { - shape = bulletnew(ConcavePolygonShapeBullet); - } break; - case SHAPE_HEIGHTMAP: { - shape = bulletnew(HeightMapShapeBullet); - } break; - case SHAPE_RAY: { - shape = bulletnew(RayShapeBullet); - } break; - case SHAPE_CUSTOM: - default: - ERR_FAIL_V(RID()); - break; - } - - CreateThenReturnRID(shape_owner, shape) +RID BulletPhysicsServer3D::plane_shape_create() { + ShapeBullet *shape = bulletnew(PlaneShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::ray_shape_create() { + ShapeBullet *shape = bulletnew(RayShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::sphere_shape_create() { + ShapeBullet *shape = bulletnew(SphereShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::box_shape_create() { + ShapeBullet *shape = bulletnew(BoxShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::capsule_shape_create() { + ShapeBullet *shape = bulletnew(CapsuleShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::cylinder_shape_create() { + ShapeBullet *shape = bulletnew(CylinderShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::convex_polygon_shape_create() { + ShapeBullet *shape = bulletnew(ConvexPolygonShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::concave_polygon_shape_create() { + ShapeBullet *shape = bulletnew(ConcavePolygonShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::heightmap_shape_create() { + ShapeBullet *shape = bulletnew(HeightMapShapeBullet); + CreateRIDReturn(shape_owner, shape) +} +RID BulletPhysicsServer3D::custom_shape_create() { + ERR_FAIL_V(RID()); } void BulletPhysicsServer3D::shape_set_data(RID p_shape, const Variant &p_data) { @@ -164,7 +170,11 @@ real_t BulletPhysicsServer3D::shape_get_custom_solver_bias(RID p_shape) const { RID BulletPhysicsServer3D::space_create() { SpaceBullet *space = bulletnew(SpaceBullet); - CreateThenReturnRID(space_owner, space); + CreateRIDReturn(space_owner, space); +} + +void BulletPhysicsServer3D::set_active(bool p_active) { + active = p_active; } void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) { @@ -176,10 +186,8 @@ void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) { } if (p_active) { - ++active_spaces_count; - active_spaces.push_back(space); + active_spaces.insert(space); } else { - --active_spaces_count; active_spaces.erase(space); } } @@ -188,7 +196,7 @@ bool BulletPhysicsServer3D::space_is_active(RID p_space) const { SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, false); - return -1 != active_spaces.find(space); + return active_spaces.has(space); } void BulletPhysicsServer3D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { @@ -206,6 +214,7 @@ real_t BulletPhysicsServer3D::space_get_param(RID p_space, SpaceParameter p_para PhysicsDirectSpaceState3D *BulletPhysicsServer3D::space_get_direct_state(RID p_space) { SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, nullptr); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); return space->get_direct_state(); } @@ -235,9 +244,8 @@ RID BulletPhysicsServer3D::area_create() { AreaBullet *area = bulletnew(AreaBullet); area->set_collision_layer(1); area->set_collision_mask(1); - CreateThenReturnRID(area_owner, area) -} - + CreateRIDReturn(area_owner, area); +}; void BulletPhysicsServer3D::area_set_space(RID p_area, RID p_space) { AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -433,16 +441,13 @@ void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { area->set_ray_pickable(p_enable); } -RID BulletPhysicsServer3D::body_create(BodyMode p_mode, bool p_init_sleeping) { +RID BulletPhysicsServer3D::body_create() { RigidBodyBullet *body = bulletnew(RigidBodyBullet); - body->set_mode(p_mode); body->set_collision_layer(1); body->set_collision_mask(1); - if (p_init_sleeping) { - body->set_state(BODY_STATE_SLEEPING, p_init_sleeping); - } - CreateThenReturnRID(rigid_body_owner, body); -} + + CreateRIDReturn(rigid_body_owner, body); +}; void BulletPhysicsServer3D::body_set_space(RID p_body, RID p_space) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); @@ -837,8 +842,12 @@ void BulletPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) { } PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_body) { + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, nullptr); + ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + return BulletPhysicsDirectBodyState3D::get_singleton(body); } @@ -858,14 +867,12 @@ int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform return body->get_space()->test_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } -RID BulletPhysicsServer3D::soft_body_create(bool p_init_sleeping) { +RID BulletPhysicsServer3D::soft_body_create() { SoftBodyBullet *body = bulletnew(SoftBodyBullet); body->set_collision_layer(1); body->set_collision_mask(1); - if (p_init_sleeping) { - body->set_activation_state(false); - } - CreateThenReturnRID(soft_body_owner, body); + + CreateRIDReturn(soft_body_owner, body); } void BulletPhysicsServer3D::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { @@ -910,8 +917,8 @@ void BulletPhysicsServer3D::soft_body_set_mesh(RID p_body, const REF &p_mesh) { body->set_soft_mesh(p_mesh); } -AABB BulletPhysicsServer::soft_body_get_bounds(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get(p_body); +AABB BulletPhysicsServer3D::soft_body_get_bounds(RID p_body) const { + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, AABB()); return body->get_bounds(); @@ -1015,6 +1022,24 @@ int BulletPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) const return body->get_simulation_precision(); } +RID BulletPhysicsServer3D::joint_create() { + JointBullet *joint = bulletnew(JointBullet); + RID rid = joint_owner.make_rid(joint); + + joint->set_self(rid); + joint->_set_physics_server(this); + + return rid; +} + +void BulletPhysicsServer3D::sync() { + doing_sync = true; +} + +void BulletPhysicsServer3D::end_sync() { + doing_sync = false; +} + void BulletPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -1027,13 +1052,13 @@ real_t BulletPhysicsServer3D::soft_body_get_total_mass(RID p_body) const { return body->get_total_mass(); } -void BulletPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) const { +void BulletPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_linear_stiffness(p_stiffness); } -real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) { +real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_linear_stiffness(); @@ -1109,7 +1134,7 @@ bool BulletPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_in PhysicsServer3D::JointType BulletPhysicsServer3D::joint_get_type(RID p_joint) const { JointBullet *joint = joint_owner.getornull(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_PIN); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); } @@ -1136,31 +1161,47 @@ bool BulletPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_jo return joint->is_disabled_collisions_between_bodies(); } -RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { +void BulletPhysicsServer3D::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - - JointAssertSpace(body_A, "A", RID()); + ERR_FAIL_COND(!body_A); - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); } - ERR_FAIL_COND_V(body_A == body_B, RID()); + RigidBodyBullet *body_B = rigid_body_owner.getornull(p_body_B); + ERR_FAIL_COND(!body_B); + ERR_FAIL_COND(body_A == body_B); + JointBullet *joint = bulletnew(PinJointBullet(body_A, p_local_A, body_B, p_local_B)); + + joint_owner.replace(p_joint, joint); + AddJointToSpace(body_A, joint); + CreateRID(joint_owner, joint); +} + +void BulletPhysicsServer3D::joint_clear(RID p_joint) { + JointBullet *joint = joint_owner.getornull(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + JointBullet *empty_joint = bulletnew(JointBullet); + + empty_joint->copy_settings_from(joint); + + joint->_set_physics_server(this); + joint_owner.replace(p_joint, empty_joint); - CreateThenReturnRID(joint_owner, joint); + bulletdelete(joint); + } } + void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJointBullet *pin_joint = static_cast(joint); pin_joint->set_param(p_param, p_value); } @@ -1168,7 +1209,7 @@ void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_par real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); PinJointBullet *pin_joint = static_cast(joint); return pin_joint->get_param(p_param); } @@ -1176,7 +1217,7 @@ real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_p void BulletPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJointBullet *pin_joint = static_cast(joint); pin_joint->setPivotInA(p_A); } @@ -1184,7 +1225,7 @@ void BulletPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_ Vector3 BulletPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJointBullet *pin_joint = static_cast(joint); return pin_joint->getPivotInA(); } @@ -1192,7 +1233,7 @@ Vector3 BulletPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const { void BulletPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJointBullet *pin_joint = static_cast(joint); pin_joint->setPivotInB(p_B); } @@ -1200,55 +1241,60 @@ void BulletPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_ Vector3 BulletPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJointBullet *pin_joint = static_cast(joint); return pin_joint->getPivotInB(); } -RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) { +void BulletPhysicsServer3D::joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); } - ERR_FAIL_COND_V(body_A == body_B, RID()); + RigidBodyBullet *body_B = rigid_body_owner.getornull(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); JointBullet *joint = bulletnew(HingeJointBullet(body_A, body_B, p_hinge_A, p_hinge_B)); - AddJointToSpace(body_A, joint); - CreateThenReturnRID(joint_owner, joint); + joint_owner.replace(p_joint, joint); + + AddJointToSpace(body_A, joint); + CreateRID(joint_owner, joint); } -RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { +void BulletPhysicsServer3D::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); } - ERR_FAIL_COND_V(body_A == body_B, RID()); + RigidBodyBullet *body_B = rigid_body_owner.getornull(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + JointBullet *joint = bulletnew(HingeJointBullet(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); - AddJointToSpace(body_A, joint); - CreateThenReturnRID(joint_owner, joint); + joint_owner.replace(p_joint, joint); + + AddJointToSpace(body_A, joint); + CreateRID(joint_owner, joint); } void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJointBullet *hinge_joint = static_cast(joint); hinge_joint->set_param(p_param, p_value); } @@ -1256,7 +1302,7 @@ void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0); HingeJointBullet *hinge_joint = static_cast(joint); return hinge_joint->get_param(p_param); } @@ -1264,7 +1310,7 @@ real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam void BulletPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJointBullet *hinge_joint = static_cast(joint); hinge_joint->set_flag(p_flag, p_value); } @@ -1272,35 +1318,37 @@ void BulletPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_f bool BulletPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false); HingeJointBullet *hinge_joint = static_cast(joint); return hinge_joint->get_flag(p_flag); } -RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void BulletPhysicsServer3D::joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); } - ERR_FAIL_COND_V(body_A == body_B, RID()); + RigidBodyBullet *body_B = rigid_body_owner.getornull(p_body_B); + ERR_FAIL_COND(!body_B); + ERR_FAIL_COND(body_A == body_B); + JointBullet *joint = bulletnew(SliderJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B)); - AddJointToSpace(body_A, joint); - CreateThenReturnRID(joint_owner, joint); + joint_owner.replace(p_joint, joint); + + AddJointToSpace(body_A, joint); + CreateRID(joint_owner, joint); } void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER); SliderJointBullet *slider_joint = static_cast(joint); slider_joint->set_param(p_param, p_value); } @@ -1308,33 +1356,35 @@ void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_SLIDER, 0); SliderJointBullet *slider_joint = static_cast(joint); return slider_joint->get_param(p_param); } -RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void BulletPhysicsServer3D::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); } + RigidBodyBullet *body_B = rigid_body_owner.getornull(p_body_B); + ERR_FAIL_COND(!body_B); + ERR_FAIL_COND(body_A == body_B); + JointBullet *joint = bulletnew(ConeTwistJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B)); + AddJointToSpace(body_A, joint); + CreateRID(joint_owner, joint); - CreateThenReturnRID(joint_owner, joint); } void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST); ConeTwistJointBullet *coneTwist_joint = static_cast(joint); coneTwist_joint->set_param(p_param, p_value); } @@ -1342,43 +1392,46 @@ void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJoi real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0.); - ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0.); ConeTwistJointBullet *coneTwist_joint = static_cast(joint); return coneTwist_joint->get_param(p_param); } -RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void BulletPhysicsServer3D::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); - JointAssertSpace(body_A, "A", RID()); - - RigidBodyBullet *body_B = nullptr; - if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); - JointAssertSpace(body_B, "B", RID()); - JointAssertSameSpace(body_A, body_B, RID()); + ERR_FAIL_COND(!body_A); + + if (!p_body_B.is_valid()) { + ERR_FAIL_COND(!body_A->get_space()); + p_body_B = body_A->get_space()->get_static_global_body(); } - ERR_FAIL_COND_V(body_A == body_B, RID()); + RigidBodyBullet *body_B = rigid_body_owner.getornull(p_body_B); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); + + JointBullet *joint = bulletnew(Generic6DOFJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B)); - AddJointToSpace(body_A, joint); + joint_owner.replace(p_joint, joint); - CreateThenReturnRID(joint_owner, joint); + AddJointToSpace(body_A, joint); + CreateRID(joint_owner, joint); } void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast(joint); generic_6dof_joint->set_param(p_axis, p_param, p_value); } -real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { +real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0); Generic6DOFJointBullet *generic_6dof_joint = static_cast(joint); return generic_6dof_joint->get_param(p_axis, p_param); } @@ -1386,31 +1439,32 @@ real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3: void BulletPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast(joint); generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); } -bool BulletPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { +bool BulletPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const { JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false); Generic6DOFJointBullet *generic_6dof_joint = static_cast(joint); return generic_6dof_joint->get_flag(p_axis, p_flag); } void BulletPhysicsServer3D::free(RID p_rid) { if (shape_owner.owns(p_rid)) { - ShapeBullet *shape = shape_owner.getornull(p_rid); + ShapeBullet *shape = shape_owner.getornull(p_rid); //working // Notify the shape is configured - for (Map::Element *element = shape->get_owners().front(); element; element = element->next()) { - static_cast(element->key())->remove_shape_full(shape); + while (shape->get_owners().size()) { + ShapeOwnerBullet *so = shape->get_owners().front()->key(); + so->remove_shape_full(shape); } shape_owner.free(p_rid); bulletdelete(shape); - } else if (rigid_body_owner.owns(p_rid)) { + } else if (rigid_body_owner.owns(p_rid)) { //issue RigidBodyBullet *body = rigid_body_owner.getornull(p_rid); body->set_space(nullptr); @@ -1420,7 +1474,7 @@ void BulletPhysicsServer3D::free(RID p_rid) { rigid_body_owner.free(p_rid); bulletdelete(body); - } else if (soft_body_owner.owns(p_rid)) { + } else if (soft_body_owner.owns(p_rid)) { //working SoftBodyBullet *body = soft_body_owner.getornull(p_rid); body->set_space(nullptr); @@ -1428,23 +1482,22 @@ void BulletPhysicsServer3D::free(RID p_rid) { soft_body_owner.free(p_rid); bulletdelete(body); - } else if (area_owner.owns(p_rid)) { + } else if (area_owner.owns(p_rid)) { //issue AreaBullet *area = area_owner.getornull(p_rid); area->set_space(nullptr); - area->remove_all_shapes(true, true); - area_owner.free(p_rid); + bulletdelete(area); - } else if (joint_owner.owns(p_rid)) { + } else if (joint_owner.owns(p_rid)) { //issue JointBullet *joint = joint_owner.getornull(p_rid); joint->destroy_internal_constraint(); joint_owner.free(p_rid); bulletdelete(joint); - } else if (space_owner.owns(p_rid)) { + } else if (space_owner.owns(p_rid)) { //issue SpaceBullet *space = space_owner.getornull(p_rid); space->remove_all_collision_objects(); @@ -1462,24 +1515,29 @@ void BulletPhysicsServer3D::init() { } void BulletPhysicsServer3D::step(real_t p_deltaTime) { +#ifndef _3D_DISABLED + if (!active) { return; } BulletPhysicsDirectBodyState3D::singleton_setDeltaTime(p_deltaTime); - for (int i = 0; i < active_spaces_count; ++i) { - active_spaces[i]->step(p_deltaTime); + for (Set::Element *E = active_spaces.front(); E; E = E->next()) { + SpaceBullet *space = (SpaceBullet *)E->get(); + space->step(p_deltaTime); } + +#endif } void BulletPhysicsServer3D::flush_queries() { if (!active) { return; } - - for (int i = 0; i < active_spaces_count; ++i) { - active_spaces[i]->flush_queries(); + for (Set::Element *E = active_spaces.front(); E; E = E->next()) { + SpaceBullet *space = (SpaceBullet *)E->get(); + space->flush_queries(); } } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 856ff7496353..37b195708e4d 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -51,44 +51,61 @@ class BulletPhysicsServer3D : public PhysicsServer3D { friend class BulletPhysicsDirectSpaceState; bool active = true; - char active_spaces_count = 0; - Vector active_spaces; + bool using_threads; + bool doing_sync; - mutable RID_PtrOwner space_owner; - mutable RID_PtrOwner shape_owner; - mutable RID_PtrOwner area_owner; - mutable RID_PtrOwner rigid_body_owner; - mutable RID_PtrOwner soft_body_owner; - mutable RID_PtrOwner joint_owner; + Set active_spaces; + + mutable RID_PtrOwner space_owner; + mutable RID_PtrOwner shape_owner; + mutable RID_PtrOwner area_owner; + mutable RID_PtrOwner rigid_body_owner; + mutable RID_PtrOwner soft_body_owner; + mutable RID_PtrOwner joint_owner; + static BulletPhysicsServer3D *singletonbullet; protected: static void _bind_methods(); public: - BulletPhysicsServer3D(); + BulletPhysicsServer3D(bool p_using_threads = false); ~BulletPhysicsServer3D(); - _FORCE_INLINE_ RID_PtrOwner *get_space_owner() { + _FORCE_INLINE_ RID_PtrOwner *get_space_owner() { return &space_owner; } - _FORCE_INLINE_ RID_PtrOwner *get_shape_owner() { + _FORCE_INLINE_ RID_PtrOwner *get_shape_owner() { return &shape_owner; } - _FORCE_INLINE_ RID_PtrOwner *get_area_owner() { + _FORCE_INLINE_ RID_PtrOwner *get_area_owner() { return &area_owner; } - _FORCE_INLINE_ RID_PtrOwner *get_rigid_body_owner() { + _FORCE_INLINE_ RID_PtrOwner *get_rigid_body_owner() { return &rigid_body_owner; } - _FORCE_INLINE_ RID_PtrOwner *get_soft_body_owner() { + _FORCE_INLINE_ RID_PtrOwner *get_soft_body_owner() { return &soft_body_owner; } - _FORCE_INLINE_ RID_PtrOwner *get_joint_owner() { + _FORCE_INLINE_ RID_PtrOwner *get_joint_owner() { return &joint_owner; } /* SHAPE API */ - virtual RID shape_create(ShapeType p_shape) override; + + virtual RID plane_shape_create() override; + virtual RID ray_shape_create() override; + virtual RID sphere_shape_create() override; + virtual RID box_shape_create() override; + virtual RID capsule_shape_create() override; + virtual RID cylinder_shape_create() override; + virtual RID convex_polygon_shape_create() override; + virtual RID concave_polygon_shape_create() override; + virtual RID heightmap_shape_create() override; + virtual RID custom_shape_create() override; + + virtual void end_sync() override; + virtual void sync() override; + virtual void shape_set_data(RID p_shape, const Variant &p_data) override; virtual ShapeType shape_get_type(RID p_shape) const override; virtual Variant shape_get_data(RID p_shape) const override; @@ -166,7 +183,7 @@ class BulletPhysicsServer3D : public PhysicsServer3D { /* RIGID BODY API */ - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) override; + virtual RID body_create() override; virtual void body_set_space(RID p_body, RID p_space) override; virtual RID body_get_space(RID p_body) const override; @@ -258,7 +275,7 @@ class BulletPhysicsServer3D : public PhysicsServer3D { /* SOFT BODY API */ - virtual RID soft_body_create(bool p_init_sleeping = false) override; + virtual RID soft_body_create() override; virtual void soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) override; @@ -315,6 +332,8 @@ class BulletPhysicsServer3D : public PhysicsServer3D { /* JOINT API */ virtual JointType joint_get_type(RID p_joint) const override; + virtual RID joint_create() override; + virtual void joint_clear(RID p_joint) override; //resets type virtual void joint_set_solver_priority(RID p_joint, int p_priority) override; virtual int joint_get_solver_priority(RID p_joint) const override; @@ -322,7 +341,7 @@ class BulletPhysicsServer3D : public PhysicsServer3D { virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) override; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override; - virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; + virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; @@ -333,8 +352,8 @@ class BulletPhysicsServer3D : public PhysicsServer3D { virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override; virtual Vector3 pin_joint_get_local_b(RID p_joint) const override; - virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) override; - virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) override; + virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override; @@ -343,33 +362,31 @@ class BulletPhysicsServer3D : public PhysicsServer3D { virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; /// Reference frame is A - virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; /// Reference frame is A - virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; /// Reference frame is A - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) override; - virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override; + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const override; virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) override; - virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) override; + virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const override; /* MISC */ virtual void free(RID p_rid) override; - virtual void set_active(bool p_active) override { - active = p_active; - } + virtual void set_active(bool p_active) override; static bool singleton_isActive() { return static_cast(get_singleton())->active; diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h index 7d6bafd2920a..77e79d088048 100644 --- a/modules/bullet/cone_twist_joint_bullet.h +++ b/modules/bullet/cone_twist_joint_bullet.h @@ -45,7 +45,7 @@ class ConeTwistJointBullet : public JointBullet { public: ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &rbAFrame, const Transform &rbBFrame); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JointType::JOINT_TYPE_CONE_TWIST; } void set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value); real_t get_param(PhysicsServer3D::ConeTwistJointParam p_param) const; diff --git a/modules/bullet/config.py b/modules/bullet/config.py index be7cf74f6ff4..56251758352c 100644 --- a/modules/bullet/config.py +++ b/modules/bullet/config.py @@ -1,6 +1,6 @@ def can_build(env, platform): # API Changed and bullet is disabled at the moment - return False + return True def configure(env): diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp index e61072768590..3762504dfb0f 100644 --- a/modules/bullet/constraint_bullet.cpp +++ b/modules/bullet/constraint_bullet.cpp @@ -34,7 +34,7 @@ #include "space_bullet.h" /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ ConstraintBullet::ConstraintBullet() {} @@ -49,7 +49,9 @@ void ConstraintBullet::set_space(SpaceBullet *p_space) { } void ConstraintBullet::destroy_internal_constraint() { - space->remove_constraint(this); + if (space) { + space->remove_constraint(this); + } } void ConstraintBullet::disable_collisions_between_bodies(const bool p_disabled) { diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h index 6afd8c9b5211..96358044692f 100644 --- a/modules/bullet/constraint_bullet.h +++ b/modules/bullet/constraint_bullet.h @@ -32,6 +32,7 @@ #define CONSTRAINT_BULLET_H #include "bullet_utilities.h" +#include "core/os/os.h" #include "rid_bullet.h" #include diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h index 62b8e85a81c7..658bdbc2d1b9 100644 --- a/modules/bullet/generic_6dof_joint_bullet.h +++ b/modules/bullet/generic_6dof_joint_bullet.h @@ -50,7 +50,7 @@ class Generic6DOFJointBullet : public JointBullet { public: Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_6DOF; } Transform getFrameOffsetA() const; Transform getFrameOffsetB() const; diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h index 06a95be3741c..aeef064049e8 100644 --- a/modules/bullet/hinge_joint_bullet.h +++ b/modules/bullet/hinge_joint_bullet.h @@ -44,7 +44,9 @@ class HingeJointBullet : public JointBullet { HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameA, const Transform &frameB); HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; } + virtual PhysicsServer3D::JointType get_type() const { + return PhysicsServer3D::JointType::JOINT_TYPE_HINGE; + } real_t get_hinge_angle(); diff --git a/modules/bullet/joint_bullet.cpp b/modules/bullet/joint_bullet.cpp index ac371658f5f6..b51267b23b97 100644 --- a/modules/bullet/joint_bullet.cpp +++ b/modules/bullet/joint_bullet.cpp @@ -37,6 +37,9 @@ */ JointBullet::JointBullet() : - ConstraintBullet() {} + ConstraintBullet() { +} -JointBullet::~JointBullet() {} +JointBullet::~JointBullet() { + +} diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h index 5bb8b5096182..fa46b18bcfbc 100644 --- a/modules/bullet/joint_bullet.h +++ b/modules/bullet/joint_bullet.h @@ -35,7 +35,7 @@ #include "servers/physics_server_3d.h" /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ class RigidBodyBullet; @@ -46,6 +46,10 @@ class JointBullet : public ConstraintBullet { JointBullet(); virtual ~JointBullet(); - virtual PhysicsServer3D::JointType get_type() const = 0; + void copy_settings_from(JointBullet *p_joint) { + set_self(p_joint->get_self()); + } + + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_MAX; } }; #endif diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h index 6fbb6f7e0210..75a141026ce5 100644 --- a/modules/bullet/pin_joint_bullet.h +++ b/modules/bullet/pin_joint_bullet.h @@ -46,7 +46,7 @@ class PinJointBullet : public JointBullet { PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b); ~PinJointBullet(); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_PIN; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JointType::JOINT_TYPE_PIN; } void set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value); real_t get_param(PhysicsServer3D::PinJointParam p_param) const; diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp index b5ad5749a608..7f8cfe0547de 100644 --- a/modules/bullet/register_types.cpp +++ b/modules/bullet/register_types.cpp @@ -33,24 +33,31 @@ #include "bullet_physics_server.h" #include "core/config/project_settings.h" #include "core/object/class_db.h" +#include "servers/physics_3d/physics_server_3d_wrap_mt.h" /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ #ifndef _3D_DISABLED + PhysicsServer3D *_createBulletPhysicsCallback() { - return memnew(BulletPhysicsServer3D); + bool using_threads = GLOBAL_GET("physics/3d/run_on_thread"); + PhysicsServer3D *physics_server = memnew(BulletPhysicsServer3D(using_threads)); + return memnew(PhysicsServer3DWrapMT(physics_server, using_threads)); } + #endif void register_bullet_types() { #ifndef _3D_DISABLED + + GLOBAL_DEF("physics/3d/active_soft_world", true); + PhysicsServer3DManager::register_server("Bullet", &_createBulletPhysicsCallback); PhysicsServer3DManager::set_default_server("Bullet", 1); - GLOBAL_DEF("physics/3d/active_soft_world", true); - ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/active_soft_world", PropertyInfo(Variant::BOOL, "physics/3d/active_soft_world")); + #endif } diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h index 90964671c2d7..cabdfcdb8ee8 100644 --- a/modules/bullet/slider_joint_bullet.h +++ b/modules/bullet/slider_joint_bullet.h @@ -46,7 +46,7 @@ class SliderJointBullet : public JointBullet { /// Reference frame is A SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JointType::JOINT_TYPE_SLIDER; } const RigidBodyBullet *getRigidBodyA() const; const RigidBodyBullet *getRigidBodyB() const; diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index ceae3be8bc19..e59488ef4ed5 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -55,14 +55,17 @@ #include /** - @author AndreaCatania + @author AndreaCatania && sboronczyk */ BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space) : PhysicsDirectSpaceState3D(), - space(p_space) {} + space(p_space) { +} int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { + ERR_FAIL_COND_V(space->locked, false); + if (p_result_max <= 0) { return 0; } @@ -86,6 +89,8 @@ int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, Shape } bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) { + ERR_FAIL_COND_V(space->locked, false); + btVector3 btVec_from; btVector3 btVec_to; @@ -122,7 +127,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra return 0; } - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = BulletPhysicsServer3D::singletonbullet->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale_abs(), p_margin); @@ -158,7 +163,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf btVector3 bt_motion; G_TO_B(p_motion, bt_motion); - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = BulletPhysicsServer3D::singletonbullet->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin); @@ -218,8 +223,8 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & if (p_result_max <= 0) { return false; } + ShapeBullet *shape = BulletPhysicsServer3D::singletonbullet->shape_owner.getornull(p_shape); - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); ERR_FAIL_COND_V(!shape, false); btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); @@ -251,7 +256,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & } bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = BulletPhysicsServer3D::singletonbullet->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); @@ -289,7 +294,8 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh } Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - RigidCollisionObjectBullet *rigid_object = space->get_physics_server()->get_rigid_collision_object(p_object); + RigidCollisionObjectBullet *rigid_object = BulletPhysicsServer3D::singletonbullet->get_rigid_collision_object(p_object); + ERR_FAIL_COND_V(!rigid_object, Vector3()); btVector3 out_closest_point(0, 0, 0); @@ -342,10 +348,25 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_ } SpaceBullet::SpaceBullet() { + area = nullptr; + locked = false; + create_empty_world(GLOBAL_DEF("physics/3d/active_soft_world", true)); direct_access = memnew(BulletPhysicsDirectSpaceState(this)); + direct_access->space = this; } +void SpaceBullet::lock() { + locked = true; +} + +void SpaceBullet::unlock() { + locked = false; +} + +bool SpaceBullet::is_locked() const { + return locked; +} SpaceBullet::~SpaceBullet() { memdelete(direct_access); destroy_world(); @@ -542,8 +563,8 @@ void SpaceBullet::add_constraint(ConstraintBullet *p_constraint, bool disableCol dynamicsWorld->addConstraint(p_constraint->get_bt_constraint(), disableCollisionsBetweenLinkedBodies); } -void SpaceBullet::remove_constraint(ConstraintBullet *p_constraint) { - dynamicsWorld->removeConstraint(p_constraint->get_bt_constraint()); +void SpaceBullet::remove_constraint(ConstraintBullet *p_constraint) { + dynamicsWorld->removeConstraint(p_constraint->get_bt_constraint()); } int SpaceBullet::get_num_collision_objects() const { diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 87aa2b9e93a9..00bc5dfbf54b 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -70,10 +70,8 @@ extern ContactAddedCallback gContactAddedCallback; class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState3D { GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState3D); -private: - SpaceBullet *space; - public: + SpaceBullet *space; BulletPhysicsDirectSpaceState(SpaceBullet *p_space); virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set &p_exclude = Set(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; @@ -87,6 +85,10 @@ class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState3D { }; class SpaceBullet : public RIDBullet { + + RID static_global_body; + AreaBullet *area; + friend class AreaBullet; friend void onBulletTickCallback(btDynamicsWorld *world, btScalar timeStep); friend class BulletPhysicsDirectSpaceState; @@ -111,6 +113,7 @@ class SpaceBullet : public RIDBullet { real_t angular_damp = 0.0; Vector areas; + bool locked = false; Vector contactDebug; int contactDebugCount = 0; @@ -124,6 +127,10 @@ class SpaceBullet : public RIDBullet { real_t get_delta_time() { return delta_time; } void step(real_t p_delta_time); + bool is_locked() const; + void lock(); + void unlock(); + _FORCE_INLINE_ btBroadphaseInterface *get_broadphase() const { return broadphase; } _FORCE_INLINE_ btDefaultCollisionConfiguration *get_collision_configuration() const { return collisionConfiguration; } _FORCE_INLINE_ btCollisionDispatcher *get_dispatcher() const { return dispatcher; } @@ -132,6 +139,12 @@ class SpaceBullet : public RIDBullet { _FORCE_INLINE_ btSoftBodyWorldInfo *get_soft_body_world_info() const { return soft_body_world_info; } _FORCE_INLINE_ bool is_using_soft_world() { return soft_body_world_info; } + void set_default_area(AreaBullet *p_area) { area = p_area; } + AreaBullet *get_default_area() const { return area; } + + void set_static_global_body(RID p_body) { static_global_body = p_body; } + RID get_static_global_body() { return static_global_body; } + /// Used to set some parameters to Bullet world /// @param p_param: /// AREA_PARAM_GRAVITY to set the gravity magnitude of entire world