diff options
Diffstat (limited to 'modules/bullet/rigid_body_bullet.cpp')
-rw-r--r-- | modules/bullet/rigid_body_bullet.cpp | 166 |
1 files changed, 69 insertions, 97 deletions
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index e393396713..4763098584 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -118,8 +118,8 @@ void BulletPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) { body->apply_central_force(p_force); } -void BulletPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_pos) { - body->apply_force(p_force, p_pos); +void BulletPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_position) { + body->apply_force(p_force, p_position); } void BulletPhysicsDirectBodyState3D::add_torque(const Vector3 &p_torque) { @@ -130,8 +130,8 @@ void BulletPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impu body->apply_central_impulse(p_impulse); } -void BulletPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) { - body->apply_impulse(p_pos, p_impulse); +void BulletPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { + body->apply_impulse(p_impulse, p_position); } void BulletPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) { @@ -256,26 +256,7 @@ void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) { } RigidBodyBullet::RigidBodyBullet() : - RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY), - kinematic_utilities(nullptr), - locked_axis(0), - mass(1), - gravity_scale(1), - linearDamp(0), - angularDamp(0), - can_sleep(true), - omit_forces_integration(false), - can_integrate_forces(false), - maxCollisionsDetection(0), - collisionsCount(0), - prev_collision_count(0), - maxAreasWhereIam(10), - areaWhereIamCount(0), - countGravityPointSpaces(0), - isScratchedSpaceOverrideModificator(false), - previousActiveState(true), - force_integration_callback(nullptr) { - + RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY) { godotMotionState = bulletnew(GodotMotionState(this)); // Initial properties @@ -283,6 +264,7 @@ RigidBodyBullet::RigidBodyBullet() : btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, nullptr, localInertia); btBody = bulletnew(btRigidBody(cInfo)); + btBody->setFriction(1.0); reload_shapes(); setupBulletCollisionObject(btBody); @@ -302,8 +284,9 @@ RigidBodyBullet::RigidBodyBullet() : RigidBodyBullet::~RigidBodyBullet() { bulletdelete(godotMotionState); - if (force_integration_callback) + if (force_integration_callback) { memdelete(force_integration_callback); + } destroy_kinematic_utilities(); } @@ -328,8 +311,9 @@ void RigidBodyBullet::main_shape_changed() { void RigidBodyBullet::reload_body() { if (space) { space->remove_rigid_body(this); - if (get_main_shape()) + if (get_main_shape()) { space->add_rigid_body(this); + } } } @@ -337,10 +321,9 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) { // Clear the old space if there is one if (space) { can_integrate_forces = false; - - // Remove all eventual constraints - assert_no_constraints(); - + isScratchedSpaceOverrideModificator = false; + // Remove any constraints + space->remove_rigid_body_constraints(this); // Remove this object form the physics world space->remove_rigid_body(this); } @@ -355,9 +338,9 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) { void RigidBodyBullet::dispatch_callbacks() { /// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) { - - if (omit_forces_integration) + if (omit_forces_integration) { btBody->clearForces(); + } BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this); @@ -389,7 +372,6 @@ void RigidBodyBullet::dispatch_callbacks() { } void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) { - if (force_integration_callback) { memdelete(force_integration_callback); force_integration_callback = nullptr; @@ -416,7 +398,6 @@ void RigidBodyBullet::on_collision_filters_change() { } void RigidBodyBullet::on_collision_checker_start() { - prev_collision_count = collisionsCount; collisionsCount = 0; @@ -432,7 +413,6 @@ void RigidBodyBullet::on_collision_checker_end() { } bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) { - if (collisionsCount >= maxCollisionsDetection) { return false; } @@ -454,23 +434,13 @@ bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const bool RigidBodyBullet::was_colliding(RigidBodyBullet *p_other_object) { for (int i = prev_collision_count - 1; 0 <= i; --i) { - if ((*prev_collision_traces)[i] == p_other_object) + if ((*prev_collision_traces)[i] == p_other_object) { return true; + } } return false; } -void RigidBodyBullet::assert_no_constraints() { - if (btBody->getNumConstraintRefs()) { - WARN_PRINT("A body with a joints is destroyed. Please check the implementation in order to destroy the joint before the body."); - } - /*for(int i = btBody->getNumConstraintRefs()-1; 0<=i; --i){ - btTypedConstraint* btConst = btBody->getConstraintRef(i); - JointBullet* joint = static_cast<JointBullet*>( btConst->getUserConstraintPtr() ); - space->removeConstraint(joint); - }*/ -} - void RigidBodyBullet::set_activation_state(bool p_active) { if (p_active) { btBody->activate(); @@ -578,12 +548,12 @@ void RigidBodyBullet::set_mode(PhysicsServer3D::BodyMode p_mode) { btBody->setAngularVelocity(btVector3(0, 0, 0)); btBody->setLinearVelocity(btVector3(0, 0, 0)); } + PhysicsServer3D::BodyMode RigidBodyBullet::get_mode() const { return mode; } void RigidBodyBullet::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { - switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: set_transform(p_variant); @@ -628,62 +598,69 @@ Variant RigidBodyBullet::get_state(PhysicsServer3D::BodyState p_state) const { } void RigidBodyBullet::apply_central_impulse(const Vector3 &p_impulse) { - btVector3 btImpu; - G_TO_B(p_impulse, btImpu); - if (Vector3() != p_impulse) + btVector3 btImpulse; + G_TO_B(p_impulse, btImpulse); + if (Vector3() != p_impulse) { btBody->activate(); - btBody->applyCentralImpulse(btImpu); + } + btBody->applyCentralImpulse(btImpulse); } -void RigidBodyBullet::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) { - btVector3 btImpu; - btVector3 btPos; - G_TO_B(p_impulse, btImpu); - G_TO_B(p_pos, btPos); - if (Vector3() != p_impulse) +void RigidBodyBullet::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { + btVector3 btImpulse; + btVector3 btPosition; + G_TO_B(p_impulse, btImpulse); + G_TO_B(p_position, btPosition); + if (Vector3() != p_impulse) { btBody->activate(); - btBody->applyImpulse(btImpu, btPos); + } + btBody->applyImpulse(btImpulse, btPosition); } void RigidBodyBullet::apply_torque_impulse(const Vector3 &p_impulse) { btVector3 btImp; G_TO_B(p_impulse, btImp); - if (Vector3() != p_impulse) + if (Vector3() != p_impulse) { btBody->activate(); + } btBody->applyTorqueImpulse(btImp); } -void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_pos) { +void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_position) { btVector3 btForce; - btVector3 btPos; + btVector3 btPosition; G_TO_B(p_force, btForce); - G_TO_B(p_pos, btPos); - if (Vector3() != p_force) + G_TO_B(p_position, btPosition); + if (Vector3() != p_force) { btBody->activate(); - btBody->applyForce(btForce, btPos); + } + btBody->applyForce(btForce, btPosition); } void RigidBodyBullet::apply_central_force(const Vector3 &p_force) { btVector3 btForce; G_TO_B(p_force, btForce); - if (Vector3() != p_force) + if (Vector3() != p_force) { btBody->activate(); + } btBody->applyCentralForce(btForce); } void RigidBodyBullet::apply_torque(const Vector3 &p_torque) { btVector3 btTorq; G_TO_B(p_torque, btTorq); - if (Vector3() != p_torque) + if (Vector3() != p_torque) { btBody->activate(); + } btBody->applyTorque(btTorq); } void RigidBodyBullet::set_applied_force(const Vector3 &p_force) { btVector3 btVec = btBody->getTotalTorque(); - if (Vector3() != p_force) + if (Vector3() != p_force) { btBody->activate(); + } btBody->clearForces(); btBody->applyTorque(btVec); @@ -701,8 +678,9 @@ Vector3 RigidBodyBullet::get_applied_force() const { void RigidBodyBullet::set_applied_torque(const Vector3 &p_torque) { btVector3 btVec = btBody->getTotalForce(); - if (Vector3() != p_torque) + if (Vector3() != p_torque) { btBody->activate(); + } btBody->clearForces(); btBody->applyCentralForce(btVec); @@ -732,7 +710,6 @@ bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { } void RigidBodyBullet::reload_axis_lock() { - btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z)))); if (PhysicsServer3D::BODY_MODE_CHARACTER == mode) { /// When character angular is always locked @@ -759,7 +736,7 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { } btBody->setCcdSweptSphereRadius(radius * 0.2); } else { - btBody->setCcdMotionThreshold(10000.0); + btBody->setCcdMotionThreshold(0.); btBody->setCcdSweptSphereRadius(0.); } } @@ -771,8 +748,9 @@ bool RigidBodyBullet::is_continuous_collision_detection_enabled() const { void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) { btVector3 btVec; G_TO_B(p_velocity, btVec); - if (Vector3() != p_velocity) + if (Vector3() != p_velocity) { btBody->activate(); + } btBody->setLinearVelocity(btVec); } @@ -785,8 +763,9 @@ Vector3 RigidBodyBullet::get_linear_velocity() const { void RigidBodyBullet::set_angular_velocity(const Vector3 &p_velocity) { btVector3 btVec; G_TO_B(p_velocity, btVec); - if (Vector3() != p_velocity) + if (Vector3() != p_velocity) { btBody->activate(); + } btBody->setAngularVelocity(btVec); } @@ -798,8 +777,9 @@ Vector3 RigidBodyBullet::get_angular_velocity() const { void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) { if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { - if (space && space->get_delta_time() != 0) + if (space && space->get_delta_time() != 0) { btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time()); + } // The kinematic use MotionState class godotMotionState->moveBody(p_global_transform); } else { @@ -811,10 +791,8 @@ void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transfor const btTransform &RigidBodyBullet::get_transform__bullet() const { if (is_static()) { - return RigidCollisionObjectBullet::get_transform__bullet(); } else { - return godotMotionState->getCurrentWorldTransform(); } } @@ -830,14 +808,15 @@ void RigidBodyBullet::reload_shapes() { // shapes incorrectly do not set the vector in calculateLocalIntertia. // Arbitrary zero is preferable to undefined behaviour. btVector3 inertia(0, 0, 0); - if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) // Necessary to avoid assertion of the empty shape + if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) { // Necessary to avoid assertion of the empty shape mainShape->calculateLocalInertia(mass, inertia); + } btBody->setMassProps(mass, inertia); } btBody->updateInertiaTensor(); reload_kinematic_shapes(); - set_continuous_collision_detection(btBody->getCcdMotionThreshold() < 9998.0); + set_continuous_collision_detection(is_continuous_collision_detection_enabled()); reload_body(); } @@ -849,7 +828,6 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) { return; } for (int i = 0; i < areaWhereIamCount; ++i) { - if (nullptr == areasWhereIam[i]) { // This area has the highest priority areasWhereIam.write[i] = p_area; @@ -857,8 +835,8 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) { } else { if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) { // The position was found, just shift all elements - for (int j = i; j < areaWhereIamCount; ++j) { - areasWhereIam.write[j + 1] = areasWhereIam[j]; + for (int j = areaWhereIamCount; j > i; j--) { + areasWhereIam.write[j] = areasWhereIam[j - 1]; } areasWhereIam.write[i] = p_area; break; @@ -905,9 +883,9 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { } void RigidBodyBullet::reload_space_override_modificator() { - // Make sure that kinematic bodies have their total gravity calculated - if (!is_active() && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) + if (mode == PhysicsServer3D::BODY_MODE_STATIC) { return; + } Vector3 newGravity(0.0, 0.0, 0.0); real_t newLinearDamp = MAX(0.0, linearDamp); @@ -919,7 +897,6 @@ void RigidBodyBullet::reload_space_override_modificator() { bool stopped = false; for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) { - currentArea = areasWhereIam[i]; if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) { @@ -928,7 +905,6 @@ void RigidBodyBullet::reload_space_override_modificator() { /// Here is calculated the gravity if (currentArea->is_spOv_gravityPoint()) { - /// It calculates the direction of new gravity support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin(); real_t distanceMag = support_gravity.length(); @@ -1022,7 +998,6 @@ void RigidBodyBullet::notify_transform_changed() { } void RigidBodyBullet::_internal_set_mass(real_t p_mass) { - btVector3 localInertia(0, 0, 0); int clearedCurrentFlags = btBody->getCollisionFlags(); @@ -1031,19 +1006,18 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) { // Rigidbody is dynamic if and only if mass is non Zero, otherwise static const bool isDynamic = p_mass != 0.f; if (isDynamic) { - - if (PhysicsServer3D::BODY_MODE_RIGID != mode && PhysicsServer3D::BODY_MODE_CHARACTER != mode) + if (PhysicsServer3D::BODY_MODE_RIGID != mode && PhysicsServer3D::BODY_MODE_CHARACTER != mode) { return; + } m_isStatic = false; - if (mainShape) + if (mainShape) { mainShape->calculateLocalInertia(p_mass, localInertia); + } if (PhysicsServer3D::BODY_MODE_RIGID == mode) { - btBody->setCollisionFlags(clearedCurrentFlags); // Just set the flags without Kin and Static } else { - btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_CHARACTER_OBJECT); } @@ -1053,16 +1027,14 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) { btBody->forceActivationState(DISABLE_DEACTIVATION); // DISABLE_DEACTIVATION 4 } } else { - - if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) + if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) { return; + } m_isStatic = true; if (PhysicsServer3D::BODY_MODE_STATIC == mode) { - btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_STATIC_OBJECT); } else { - btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_KINEMATIC_OBJECT); set_transform__bullet(btBody->getWorldTransform()); // Set current Transform using kinematic method } |